@lightningjs/blits 1.29.3 → 1.29.5
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 +16 -0
- package/package.json +2 -2
- package/src/component/base/methods.js +9 -0
- package/src/component/base/timeouts_intervals.js +9 -6
- package/src/component.js +3 -2
- package/src/component.test.js +2 -2
- package/src/engines/L3/element.js +29 -29
- package/src/lib/codegenerator/generator.js +12 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
_12 jun 2025_
|
|
4
|
+
|
|
5
|
+
## v1.29.5
|
|
6
|
+
|
|
7
|
+
- Simplified timeout and interval cleanup
|
|
8
|
+
- Added explicit reset of component state upon destruction
|
|
9
|
+
- Fixed `exit` lifecycle hook
|
|
10
|
+
|
|
11
|
+
_06 jun 2025_
|
|
12
|
+
|
|
13
|
+
## v1.29.4
|
|
14
|
+
|
|
15
|
+
- Removed excessive shader creation for effects
|
|
16
|
+
- Added explicit cleanup of effects in for loop
|
|
17
|
+
- Improved element destruction
|
|
18
|
+
|
|
3
19
|
_03 jun 2025_
|
|
4
20
|
|
|
5
21
|
## v1.29.3
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "1.29.
|
|
3
|
+
"version": "1.29.5",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@lightningjs/msdf-generator": "^1.1.1",
|
|
50
|
-
"@lightningjs/renderer": "^2.13.
|
|
50
|
+
"@lightningjs/renderer": "^2.13.4"
|
|
51
51
|
},
|
|
52
52
|
"repository": {
|
|
53
53
|
"type": "git",
|
|
@@ -66,13 +66,22 @@ export default {
|
|
|
66
66
|
value: function () {
|
|
67
67
|
this.eol = true
|
|
68
68
|
this.lifecycle.state = 'destroy'
|
|
69
|
+
|
|
70
|
+
for (let key in this[symbols.state]) {
|
|
71
|
+
if (Array.isArray(this[symbols.state][key])) {
|
|
72
|
+
this[symbols.state][key] = []
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
69
76
|
this.$clearTimeouts()
|
|
70
77
|
this.$clearIntervals()
|
|
71
78
|
eventListeners.removeListeners(this)
|
|
72
79
|
deleteChildren(this[symbols.children])
|
|
73
80
|
this[symbols.children].length = 0
|
|
74
81
|
removeGlobalEffects(this[symbols.effects])
|
|
82
|
+
|
|
75
83
|
this[symbols.state] = {}
|
|
84
|
+
|
|
76
85
|
this[symbols.props] = {}
|
|
77
86
|
this[symbols.computed] = null
|
|
78
87
|
this.lifecycle = {}
|
|
@@ -22,9 +22,10 @@ export default {
|
|
|
22
22
|
value: function (fn, ms, ...params) {
|
|
23
23
|
// early exit when component is marked as end of life
|
|
24
24
|
if (this.eol === true) return
|
|
25
|
+
|
|
25
26
|
const timeoutId = setTimeout(
|
|
26
27
|
() => {
|
|
27
|
-
this
|
|
28
|
+
this.$clearTimeout(timeoutId)
|
|
28
29
|
fn.apply(null, params)
|
|
29
30
|
},
|
|
30
31
|
ms,
|
|
@@ -39,8 +40,9 @@ export default {
|
|
|
39
40
|
},
|
|
40
41
|
$clearTimeout: {
|
|
41
42
|
value: function (timeoutId) {
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
const index = this[symbols.timeouts].indexOf(timeoutId)
|
|
44
|
+
if (index > -1) {
|
|
45
|
+
this[symbols.timeouts].splice(index, 1)
|
|
44
46
|
clearTimeout(timeoutId)
|
|
45
47
|
}
|
|
46
48
|
},
|
|
@@ -73,9 +75,10 @@ export default {
|
|
|
73
75
|
},
|
|
74
76
|
$clearInterval: {
|
|
75
77
|
value: function (intervalId) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
const index = this[symbols.intervals].indexOf(intervalId)
|
|
79
|
+
if (index > -1) {
|
|
80
|
+
this[symbols.intervals].splice(index, 1)
|
|
81
|
+
clearTimeout(intervalId)
|
|
79
82
|
}
|
|
80
83
|
},
|
|
81
84
|
writable: false,
|
package/src/component.js
CHANGED
|
@@ -195,6 +195,8 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
195
195
|
// generate a human readable ID for the component instance (i.e. Blits::ComponentName1)
|
|
196
196
|
this.componentId = createHumanReadableId(name)
|
|
197
197
|
|
|
198
|
+
this[symbols.effects] = []
|
|
199
|
+
|
|
198
200
|
// instantiate a lifecycle object for this instance
|
|
199
201
|
this.lifecycle = Object.assign(Object.create(Lifecycle), {
|
|
200
202
|
component: this,
|
|
@@ -296,7 +298,7 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
296
298
|
|
|
297
299
|
// outOfViewport event emitting a lifecycle exit event
|
|
298
300
|
if (config.hooks.exit) {
|
|
299
|
-
this[symbols.wrapper].node.on('
|
|
301
|
+
this[symbols.wrapper].node.on('outOfBounds', () => {
|
|
300
302
|
this.lifecycle.state = 'exit'
|
|
301
303
|
})
|
|
302
304
|
}
|
|
@@ -305,7 +307,6 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
305
307
|
// setup (and execute) all the generated side effects based on the
|
|
306
308
|
// reactive bindings define in the template
|
|
307
309
|
const effects = config.code.effects
|
|
308
|
-
this[symbols.effects] = []
|
|
309
310
|
for (let i = 0; i < effects.length; i++) {
|
|
310
311
|
const eff = () => {
|
|
311
312
|
effects[i](this, this[symbols.children], config, globalComponents, rootComponent, effect)
|
package/src/component.test.js
CHANGED
|
@@ -322,8 +322,8 @@ test('Component - Instance should initialize hook events', (assert) => {
|
|
|
322
322
|
)
|
|
323
323
|
assert.equal(
|
|
324
324
|
nodeCalls[3].args[0],
|
|
325
|
-
'
|
|
326
|
-
'`
|
|
325
|
+
'outOfBounds',
|
|
326
|
+
'`outOfBounds` event should be registered in the wrapper'
|
|
327
327
|
)
|
|
328
328
|
assert.end()
|
|
329
329
|
})
|
|
@@ -381,34 +381,12 @@ const propsTransformer = {
|
|
|
381
381
|
v[i].props.color = colors.normalize(v[i].props.color)
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
|
-
const effectNames = {}
|
|
385
384
|
if (this.element.node === undefined) {
|
|
386
|
-
this.element.effectNames = []
|
|
387
385
|
this.props['shader'] = renderer.createShader('DynamicShader', {
|
|
388
386
|
effects: v.map((effect) => {
|
|
389
|
-
|
|
390
|
-
if (effectNames[name] !== undefined) {
|
|
391
|
-
name += ++effectNames[name]
|
|
392
|
-
} else {
|
|
393
|
-
effectNames[name] = 1
|
|
394
|
-
}
|
|
395
|
-
name += this.element.counter
|
|
396
|
-
this.element.effectNames.push(name)
|
|
397
|
-
// temporary add counter to work around shader caching issues
|
|
398
|
-
return renderer.createEffect(effect.type, effect.props, name)
|
|
387
|
+
return renderer.createEffect(effect.type, effect.props)
|
|
399
388
|
}),
|
|
400
389
|
})
|
|
401
|
-
} else {
|
|
402
|
-
for (let i = 0; i < v.length; i++) {
|
|
403
|
-
const name = this.element.effectNames[i]
|
|
404
|
-
// temporary add counter to work around shader caching issues
|
|
405
|
-
const target = this.element.node.shader.props[name]
|
|
406
|
-
const props = Object.keys(v[i].props)
|
|
407
|
-
if (target == undefined) continue
|
|
408
|
-
for (let j = 0; j < props.length; j++) {
|
|
409
|
-
target[props[j]] = v[i].props[props[j]]
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
390
|
}
|
|
413
391
|
},
|
|
414
392
|
set clipping(v) {
|
|
@@ -674,7 +652,7 @@ const Element = {
|
|
|
674
652
|
return
|
|
675
653
|
}
|
|
676
654
|
// fire transition end callback when animation ends (if specified)
|
|
677
|
-
if (transition.end && typeof transition.end === 'function') {
|
|
655
|
+
if (this.node !== undefined && transition.end && typeof transition.end === 'function') {
|
|
678
656
|
transition.end.call(this.component, this, prop, this.node[prop])
|
|
679
657
|
}
|
|
680
658
|
// remove the prop from scheduled transitions
|
|
@@ -687,9 +665,7 @@ const Element = {
|
|
|
687
665
|
destroy() {
|
|
688
666
|
if (this.node === null) return
|
|
689
667
|
|
|
690
|
-
Log.debug('Deleting
|
|
691
|
-
this.node.destroy()
|
|
692
|
-
|
|
668
|
+
Log.debug('Deleting Node', this.nodeId)
|
|
693
669
|
// Clearing transition end callback functions
|
|
694
670
|
const transitionProps = Object.keys(this.scheduledTransitions)
|
|
695
671
|
for (let i = 0; i < transitionProps.length; i++) {
|
|
@@ -700,7 +676,32 @@ const Element = {
|
|
|
700
676
|
}
|
|
701
677
|
}
|
|
702
678
|
|
|
703
|
-
//
|
|
679
|
+
// not setting to null and deleting,
|
|
680
|
+
// because transition stopped might still be fired (maybe a renderer fix resolves that)
|
|
681
|
+
this.scheduledTransitions = {}
|
|
682
|
+
|
|
683
|
+
this.component = null
|
|
684
|
+
delete this.component
|
|
685
|
+
|
|
686
|
+
this.config = null
|
|
687
|
+
delete this.config
|
|
688
|
+
|
|
689
|
+
this.counter = null
|
|
690
|
+
delete this.counter
|
|
691
|
+
|
|
692
|
+
this.props.raw = {}
|
|
693
|
+
this.props.element = null
|
|
694
|
+
this.props.props = null
|
|
695
|
+
this.props = {}
|
|
696
|
+
delete this.props
|
|
697
|
+
|
|
698
|
+
this.triggerLayout = null
|
|
699
|
+
delete this.triggerLayout
|
|
700
|
+
|
|
701
|
+
this.forComponent = null
|
|
702
|
+
delete this.forComponent
|
|
703
|
+
|
|
704
|
+
this.node.destroy()
|
|
704
705
|
this.node = null
|
|
705
706
|
},
|
|
706
707
|
get nodeId() {
|
|
@@ -738,7 +739,6 @@ export default (config, component) => {
|
|
|
738
739
|
scheduledTransitions: {},
|
|
739
740
|
config,
|
|
740
741
|
component,
|
|
741
|
-
effectNames: [],
|
|
742
742
|
counter: counter++,
|
|
743
743
|
})
|
|
744
744
|
}
|
|
@@ -511,6 +511,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
511
511
|
}
|
|
512
512
|
effect(eff${index}, ${key})
|
|
513
513
|
effects.push(eff${index})
|
|
514
|
+
component[Symbol.for('effects')].push(eff${index})
|
|
514
515
|
`)
|
|
515
516
|
} else {
|
|
516
517
|
// props shouldn't be wrapped in an effect, but simply passed on
|
|
@@ -562,17 +563,21 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
562
563
|
|
|
563
564
|
ctx.renderCode.push(`
|
|
564
565
|
let forEffects${forStartCounter}
|
|
565
|
-
|
|
566
|
+
const eff${forStartCounter} = () => {
|
|
566
567
|
component[Symbol.for('removeGlobalEffects')](forEffects${forStartCounter})
|
|
567
568
|
forEffects${forStartCounter} = null
|
|
568
569
|
forEffects${forStartCounter} = forloop${forStartCounter}(${cast(
|
|
569
570
|
result[2],
|
|
570
571
|
':for'
|
|
571
572
|
)}, elms, created${forStartCounter})
|
|
572
|
-
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
component[Symbol.for('effects')].push(eff${forStartCounter})
|
|
576
|
+
|
|
577
|
+
effect(eff${forStartCounter}, ['${effectKey}', ${effectKeys.join(',')}] )
|
|
573
578
|
`)
|
|
574
579
|
|
|
575
|
-
outerScopeEffects.forEach((effect) => {
|
|
580
|
+
outerScopeEffects.forEach((effect, outerScopeEffectsIndex) => {
|
|
576
581
|
const matches = [...effect.matchAll(scopeRegex)]
|
|
577
582
|
|
|
578
583
|
let l = matches.length
|
|
@@ -589,7 +594,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
589
594
|
}
|
|
590
595
|
|
|
591
596
|
ctx.renderCode.push(`
|
|
592
|
-
|
|
597
|
+
const eff${forStartCounter}_${outerScopeEffectsIndex} = () => {
|
|
593
598
|
void ${refs.join(', ')}
|
|
594
599
|
for(let __index = 0; __index < ${interpolate(result[2])}.length; __index++) {
|
|
595
600
|
if(__index < from${forStartCounter} || __index >= to${forStartCounter}) continue
|
|
@@ -602,7 +607,9 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
602
607
|
ctx.renderCode.push(`
|
|
603
608
|
${effect}
|
|
604
609
|
}
|
|
605
|
-
}
|
|
610
|
+
}
|
|
611
|
+
component[Symbol.for('effects')].push(eff${forStartCounter}_${outerScopeEffectsIndex})
|
|
612
|
+
effect(eff${forStartCounter}_${outerScopeEffectsIndex})
|
|
606
613
|
`)
|
|
607
614
|
})
|
|
608
615
|
|