@lightningjs/blits 1.48.0 → 1.49.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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## v1.49.0
5
+
6
+ _20 feb 2026_
7
+
8
+ - Added `data-blits-renderstate` inspector attribute
9
+ - Fixed `data-blits-hasfocus` inspector attribute to always be available
10
+ - Added boolean attribute to `idle` lifecycle hook to indicate `idle` or `active` state
11
+ - Fixed type definitions for
12
+ - Fixed double processiong of reactivity guard
13
+
4
14
  ## v1.48.0
5
15
 
6
16
  _10 feb 2026_
package/index.d.ts CHANGED
@@ -201,11 +201,14 @@ declare module '@lightningjs/blits' {
201
201
  */
202
202
  exit?: () => void;
203
203
  /**
204
- * Fires when the renderer is done rendering and enters an idle state
204
+ * Fires when the renderer is done rendering and enters an idle state (idle = true)
205
+ * and when the renderer starts rendering again and leaves the idle state (idle = false)
206
+ *
207
+ * @param idle - boolean to indicate whether the renderer is in idle state or not
205
208
  *
206
209
  * Note: This event can fire multiple times
207
210
  */
208
- idle?: () => void;
211
+ idle?: (idle: boolean) => void;
209
212
  /**
210
213
  * Fires at a predefined interval and reports the current FPS value
211
214
  *
@@ -666,9 +669,9 @@ declare module '@lightningjs/blits' {
666
669
 
667
670
  export interface RouterHooks {
668
671
  init?: () => Promise<void> | void;
669
- beforeEach?: (to: Route, from: Route) => string | Route | Promise<string | Route> | void;
670
- afterEach?: (to: Route, from: Route) => string | Route | Promise<string | Route> | void;
671
- error?: (err: string) => string | Route | Promise<string | Route> | void;
672
+ beforeEach?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
673
+ afterEach?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
674
+ error?: (err: string) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
672
675
  }
673
676
 
674
677
  export interface RouterConfig<P extends Props, S, M, C> {
@@ -694,13 +697,13 @@ declare module '@lightningjs/blits' {
694
697
 
695
698
  /**
696
699
  * Enable or disable RouterView history navigation on Back input
697
- *
700
+ *
698
701
  * @default true
699
- *
702
+ *
700
703
  * @remarks
701
704
  * This is an app-wide setting that affects all RouterView instances in your application.
702
705
  * The router state is global and shared across all router instances.
703
- *
706
+ *
704
707
  * @example
705
708
  * ```js
706
709
  * router: {
@@ -809,8 +812,8 @@ declare module '@lightningjs/blits' {
809
812
  }[keyof T]
810
813
 
811
814
  export interface RouteHooks {
812
- before?: (to: Route, from: Route) => string | Route | Promise<string | Route>;
813
- after?: (to: Route, from: Route) => string | Route | Promise<string | Route>;
815
+ before?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
816
+ after?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
814
817
  }
815
818
 
816
819
  export type Route = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightningjs/blits",
3
- "version": "1.48.0",
3
+ "version": "1.49.0",
4
4
  "description": "Blits: The Lightning 3 App Development Framework",
5
5
  "bin": "bin/index.js",
6
6
  "exports": {
@@ -74,7 +74,7 @@
74
74
  },
75
75
  "dependencies": {
76
76
  "@lightningjs/msdf-generator": "^1.2.0",
77
- "@lightningjs/renderer": "^2.21.0",
77
+ "@lightningjs/renderer": "^2.23.0",
78
78
  "magic-string": "^0.30.21"
79
79
  },
80
80
  "repository": {
@@ -19,7 +19,7 @@ import fs from 'fs'
19
19
  import path from 'path'
20
20
  import { fileURLToPath } from 'url'
21
21
  import compiler from '../src/lib/precompiler/precompiler.js'
22
- import { exec } from 'child_process'
22
+ import childProcess from 'child_process'
23
23
 
24
24
  const currentDir = process.cwd()
25
25
  const componentDirs = ['src/components']
@@ -71,7 +71,7 @@ function processFile(filePath) {
71
71
  function formatFileWithESLint(filePath) {
72
72
  const command = `eslint "${filePath}" --fix`
73
73
 
74
- exec(command, (error, stdout, stderr) => {
74
+ childProcess.exec(command, (error, stdout, stderr) => {
75
75
  if (error) {
76
76
  console.error(`Execution Error: ${error.message}`)
77
77
  console.error(`Exit Code: ${error.code}`)
package/src/component.js CHANGED
@@ -267,33 +267,60 @@ const Component = (name = required('name'), config = required('config')) => {
267
267
  this[symbols.slots] = this[symbols.children].filter((child) => child[symbols.isSlot])
268
268
 
269
269
  this[symbols.rendererEventListeners] = []
270
+
271
+ if (this[symbols.holder] !== undefined && Settings.get('inspector', false)) {
272
+ this[symbols.holder].setInspectorMetadata({ 'blits-hasFocus': false })
273
+ }
274
+
275
+ // setup inspector data for render state
276
+ if (name === 'App' && Settings.get('inspector', false)) {
277
+ this.$setTimeout(() => {
278
+ const wrapperEl = this[symbols.wrapper]
279
+ const idleCb = () => {
280
+ wrapperEl.setInspectorMetadata({ 'blits-renderState': 'idle' })
281
+ }
282
+ const activeCb = () => {
283
+ wrapperEl.setInspectorMetadata({ 'blits-renderState': 'active' })
284
+ }
285
+ renderer.on('idle', idleCb)
286
+ renderer.on('active', activeCb)
287
+ this[symbols.rendererEventListeners].push({ event: 'idle', cb: idleCb })
288
+ this[symbols.rendererEventListeners].push({ event: 'active', cb: activeCb })
289
+ })
290
+ }
291
+
270
292
  // register hooks if component has hooks specified
271
293
  if (config.hooks) {
272
294
  // push to next tick to ensure
273
- setTimeout(() => {
295
+ this.$setTimeout(() => {
274
296
  // frame tick event
275
297
  if (config.hooks.frameTick) {
276
- const cb = (r, data) => emit('frameTick', this[symbols.identifier], this, [data])
277
- this[symbols.rendererEventListeners].push({ event: 'frameTick', cb })
298
+ const cb = (_r, data) => emit('frameTick', this[symbols.identifier], this, [data])
278
299
  renderer.on('frameTick', cb)
300
+ this[symbols.rendererEventListeners].push({ event: 'frameTick', cb })
279
301
  }
280
302
 
281
303
  // idle event
282
304
  if (config.hooks.idle) {
283
- const cb = () => {
284
- emit('idle', this[symbols.identifier], this)
305
+ const idleCb = () => {
306
+ emit('idle', this[symbols.identifier], this, [true])
285
307
  }
286
- this[symbols.rendererEventListeners].push({ event: 'idle', cb })
287
- renderer.on('idle', cb)
308
+ const activeCb = () => {
309
+ emit('idle', this[symbols.identifier], this, [false])
310
+ }
311
+ renderer.on('idle', idleCb)
312
+ renderer.on('active', activeCb)
313
+ this[symbols.rendererEventListeners].push({ event: 'idle', cb: idleCb })
314
+ this[symbols.rendererEventListeners].push({ event: 'active', cb: activeCb })
288
315
  }
289
316
 
290
317
  // fpsUpdate event
291
318
  if (config.hooks.fpsUpdate) {
292
- const cb = (r, data) => {
319
+ const cb = (_r, data) => {
293
320
  emit('fpsUpdate', this[symbols.identifier], this, [data.fps])
294
321
  }
295
- this[symbols.rendererEventListeners].push({ event: 'fpsUpdate', cb })
296
322
  renderer.on('fpsUpdate', cb)
323
+ this[symbols.rendererEventListeners].push({ event: 'fpsUpdate', cb })
297
324
  }
298
325
  })
299
326
 
@@ -195,7 +195,7 @@ export default (code) => {
195
195
  if (thisRefs.size > 0) {
196
196
  // Skip if already modified
197
197
  if (
198
- prop.body.includes(commentText) ||
198
+ prop.body.includes(commentText.trim()) ||
199
199
  Array.from(thisRefs).some((ref) => prop.body.startsWith(ref))
200
200
  ) {
201
201
  continue