Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
89f467c
fix(generator): rewrite plugin helpers in :for loop effects
il-sairamg Nov 26, 2025
3229fa5
Merge pull request #543 from il-sairamg/fix/for-loop-plugin-translate…
michielvandergeest Nov 26, 2025
c6fb0df
added reactivity support to regular shaders
jfboeve Nov 28, 2025
45fb5c0
feat: extend ComponentBase with ComponentCustomProperties for app-spe…
tuncayuk Dec 1, 2025
ed05d52
test(sprite): add tests for texture reuse, mapping, and missing frames
il-sairamg Dec 2, 2025
d15e2be
Updates test cases for sprite
il-sairamg Dec 3, 2025
da98844
let renderer handle shader value null
jfboeve Dec 3, 2025
61efed5
Merge pull request #547 from lightning-js/feat/shader-reactivity
michielvandergeest Dec 4, 2025
b3e32d6
Renamed custom component props interface.
michielvandergeest Dec 4, 2025
25bd269
Merge pull request #548 from tuncayuk/feat/custom-plugin-type-def
michielvandergeest Dec 4, 2025
c87b578
Refactor nested condition checks
il-sairamg Dec 15, 2025
3123bb8
Source map generation with magic string module
suresh-gangumalla Dec 17, 2025
b71d016
feat(types): add ComponentCustomProperties augmentation point and typ…
il-sairamg Dec 17, 2025
96810be
returning empty mapping from reactivity guard
suresh-gangumalla Dec 17, 2025
0804a0b
Removed comments
suresh-gangumalla Dec 17, 2025
2203a1d
Updated to CustomComponentProperties
il-sairamg Dec 23, 2025
5820aa1
Merge pull request #551 from il-sairamg/test-coverage/improve-sprite-…
michielvandergeest Dec 24, 2025
097eca4
Merge pull request #556 from suresh-gangumalla/feat/source-map-genera…
michielvandergeest Dec 24, 2025
3d2d67a
co-locate plugin type definitions with implementations
il-sairamg Dec 29, 2025
69620a5
updated package file
il-sairamg Dec 29, 2025
c3f6b91
Updated documentation
il-sairamg Dec 29, 2025
a5a5a66
Updated docs
il-sairamg Dec 29, 2025
a42c7e2
Merge pull request #555 from il-sairamg/feat/types-component-custom-p…
michielvandergeest Dec 29, 2025
74d0e38
Bumped version to 1.45.0 and updated changelog.
michielvandergeest Dec 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## v1.45.0

_29 dec 2025_

- Added support for defining types for custom plugins on the Blits component definitions
- Added importable type definitions for built-in plugins
- Added support for JS sourcemaps
- Added reactivity for shader props (individual shaders, not effects via dynamic shader)
- Fixed issue with usage of Blits plugins not working in for loops
- Improved test coverage

## v1.44.0

_20 Nov 2025_
Expand Down
14 changes: 14 additions & 0 deletions docs/plugins/global_app_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ When registering the Global App State plugin, you pass it a state object as the

The newly created Global App state works exactly the same as an internal Component state. You can read values and you can directly change values. And when you do change a value, it automatically triggers reactive updates. Either via reactive attributes in the template, or in the form of watchers / computed values in the Component logic.

## TypeScript Support

Enable autocomplete and type inference for the App State plugin by adding a `blits.d.ts` file in the root folder of your app project:

```typescript
import type { AppStatePlugin } from '@lightningjs/blits/plugins/appstate'

declare module '@lightningjs/blits' {
interface CustomComponentProperties {
$appState?: AppStatePlugin
}
}
```

### Using global app state in a Component

Any variable in the Global App state can be used directly in the template, much like a local Component state. Changing values in the global app state also works exactly the same as updating the internal component state.
Expand Down
14 changes: 14 additions & 0 deletions docs/plugins/language.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ The Language plugin accepts an optional configuration object with 2 keys:

After registration of the Language plugin, it will be available in each Blits Component as `this.$language`.

## TypeScript Support

Enable autocomplete and type inference for the Language plugin by adding a `blits.d.ts` file in the root folder of your app project:

```typescript
import type { LanguagePlugin } from '@lightningjs/blits/plugins/language'

declare module '@lightningjs/blits' {
interface CustomComponentProperties {
$language?: LanguagePlugin
}
}
```

## Translations file

The most common way of defining a set of translations, is to use a dedicated JSON file, modeled after
Expand Down
14 changes: 14 additions & 0 deletions docs/plugins/storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ Within the application we can call the storage plugin methods as below
this.$storage.get(key, value)
```

## TypeScript Support

Enable autocomplete and type inference for the Storage plugin by adding a `blits.d.ts` file in the root folder of your app project:

```typescript
import type { StoragePlugin } from '@lightningjs/blits/plugins/storage'

declare module '@lightningjs/blits' {
interface CustomComponentProperties {
$storage?: StoragePlugin
}
}
```

## Available methods

### set
Expand Down
14 changes: 14 additions & 0 deletions docs/plugins/theme.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ Blits.Plugin(theme, {
In the definition above we've specified 3 different themes: `base`, `dark` and `large`. The dark and large theme are not complete definitions,
which means that they will inherit missing values from the base theme.

## TypeScript Support

Enable autocomplete and type inference for the Theme plugin by adding a `blits.d.ts` file in the root folder of your app project:

```typescript
import type { ThemePlugin } from '@lightningjs/blits/plugins/theme'

declare module '@lightningjs/blits' {
interface CustomComponentProperties {
$theme?: ThemePlugin
}
}
```


## Getting theme values

Expand Down
44 changes: 38 additions & 6 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
// blits file type reference
/// <reference path="./blits.d.ts" />

import {type ShaderEffect as RendererShaderEffect, type WebGlCoreShader, type RendererMainSettings} from '@lightningjs/renderer'

declare module '@lightningjs/blits' {

type RendererShaderEffect = import('@lightningjs/renderer').ShaderEffect
type WebGlCoreShader = import('@lightningjs/renderer').WebGlCoreShader
type RendererMainSettings = import('@lightningjs/renderer').RendererMainSettings

export interface AnnouncerUtteranceOptions {
/**
Expand Down Expand Up @@ -209,7 +209,7 @@ declare module '@lightningjs/blits' {
}

export interface Input {
[key: string]: (event: KeyboardEvent) => void | undefined | unknown,
[key: string]: ((event: KeyboardEvent) => unknown) | undefined,
/**
* Catch all input function
*
Expand Down Expand Up @@ -362,7 +362,39 @@ declare module '@lightningjs/blits' {
}
}

export type ComponentBase = {
// Extension point for app- and plugin-specific fields on the component `this`.
// Add your own properties (e.g., `$telemetry`, `componentName`) via TypeScript
// module augmentation in your app, without changing core types.
// Note: `ComponentBase` extends this interface, so augmented fields appear in all
// hooks, methods, input, computed, and watch.
export interface CustomComponentProperties {
// Empty by design: extend in your app via TypeScript module augmentation.
}

export interface LanguagePlugin {
translate(key: string, ...replacements: any[]): string
readonly language: string
set(language: string): void
translations(translationsObject: Record<string, unknown>): void
load(file: string): Promise<void>
}

export interface ThemePlugin {
get<T = unknown>(key: string): T | undefined
get<T>(key: string, fallback: T): T
set(theme: string): void
}

export interface StoragePlugin {
get<T = unknown>(key: string): T | null
set(key: string, value: unknown): boolean
remove(key: string): void
clear(): void
}

export type AppStatePlugin<TState extends Record<string, unknown> = Record<string, unknown>> = TState

export interface ComponentBase extends CustomComponentProperties {
/**
* Indicates whether the component currently has focus
*
Expand Down Expand Up @@ -624,7 +656,7 @@ declare module '@lightningjs/blits' {
}

export interface RouterHooks {
init?: () => Promise<> | void;
init?: () => Promise<void> | void;
beforeEach?: (to: Route, from: Route) => string | Route | Promise<string | Route> | void;
error?: (err: string) => string | Route | Promise<string | Route> | void;
}
Expand Down
21 changes: 16 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 22 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
{
"name": "@lightningjs/blits",
"version": "1.44.0",
"version": "1.45.0",
"description": "Blits: The Lightning 3 App Development Framework",
"bin": "bin/index.js",
"exports": {
".": "./index.js",
"./vite": "./vite/index.js",
"./transitions": "./src/router/transitions/index.js",
"./precompiler": "./src/lib/precompiler/precompiler.js",
"./plugins": "./src/plugins/index.js",
"./plugins": {
"types": "./src/plugins/index.d.ts",
"default": "./src/plugins/index.js"
},
"./plugins/language": {
"types": "./src/plugins/language.d.ts",
"default": "./src/plugins/language.js"
},
"./plugins/theme": {
"types": "./src/plugins/theme.d.ts",
"default": "./src/plugins/theme.js"
},
"./plugins/appstate": {
"types": "./src/plugins/appstate.d.ts",
"default": "./src/plugins/appstate.js"
},
"./plugins/storage": {
"types": "./src/plugins/storage/storage.d.ts",
"default": "./src/plugins/storage/storage.js"
},
"./symbols": "./src/lib/symbols.js",
"./blitsFileConverter": "./src/lib/blitsfileconverter/blitsfileconverter.js"
},
Expand Down Expand Up @@ -48,6 +67,7 @@
"husky": "^9.1.7",
"jsdom": "24.0.0",
"lint-staged": "^15.5.0",
"magic-string": "^0.30.21",
"prettier": "^3.6.2",
"sinon": "^21.0.0",
"tap-diff": "^0.1.1",
Expand Down
19 changes: 12 additions & 7 deletions src/components/Sprite.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,20 @@ export default () =>
// Resolve frame data from sprite map
let options = null
if (
this.map !== undefined &&
this.map !== null &&
this.frame !== undefined &&
this.frame !== null
this.map !== undefined &&
this.frame !== null &&
this.frame !== undefined
) {
options =
'frames' in this.map
? Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
: this.map[this.frame]
if (
this.map.frames !== null &&
this.map.frames !== undefined &&
this.frame in this.map.frames
) {
options = Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
} else if (this.frame in this.map) {
options = this.map[this.frame]
}
}

// If no map but frame is object (manual subtexture)
Expand Down
Loading