@lightningjs/blits 1.43.2 → 1.45.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 +20 -0
- package/README.md +2 -0
- package/index.d.ts +44 -6
- package/package.json +23 -3
- package/scripts/prepublishOnly.js +4 -1
- package/src/application.js +10 -21
- package/src/component/base/methods.js +37 -0
- package/src/components/Sprite.js +12 -7
- package/src/constants.js +19 -0
- package/src/engines/L3/element.js +23 -6
- package/src/focus.js +1 -1
- package/src/lib/codegenerator/generator.js +1 -1
- package/src/lib/precompiler/precompiler.js +23 -14
- package/src/lib/reactivityguard/computedprops.js +6 -1
- package/src/plugins/appstate.d.ts +29 -0
- package/src/plugins/index.d.ts +29 -0
- package/src/plugins/language.d.ts +34 -0
- package/src/plugins/storage/storage.d.ts +29 -0
- package/src/plugins/theme.d.ts +35 -0
- package/vite/preCompiler.js +15 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.45.0
|
|
4
|
+
|
|
5
|
+
_29 dec 2025_
|
|
6
|
+
|
|
7
|
+
- Added support for defining types for custom plugins on the Blits component definitions
|
|
8
|
+
- Added importable type definitions for built-in plugins
|
|
9
|
+
- Added support for JS sourcemaps
|
|
10
|
+
- Added reactivity for shader props (individual shaders, not effects via dynamic shader)
|
|
11
|
+
- Fixed issue with usage of Blits plugins not working in for loops
|
|
12
|
+
- Improved test coverage
|
|
13
|
+
|
|
14
|
+
## v1.44.0
|
|
15
|
+
|
|
16
|
+
_20 Nov 2025_
|
|
17
|
+
|
|
18
|
+
- Added `$input` method to facilitate key handling _without_ also passing focus
|
|
19
|
+
- Added support for passing `type` of image in the `src`-attribute (`regular`, `svg`, `compressed` for cases the file type can't be derived from the file name)
|
|
20
|
+
- Bumped Lightning renderer to v2.20.0 with improved support for compressed textures
|
|
21
|
+
|
|
22
|
+
|
|
3
23
|
## v1.43.2
|
|
4
24
|
|
|
5
25
|
_13 Nov 2025_
|
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# Blits - Lightning 3 App Development Framework
|
|
4
4
|
|
|
5
|
+
    
|
|
6
|
+
|
|
5
7
|
With Blits, the App Development Framework for Lightning 3, it becomes a breeze to build great Lightning 3 applications.
|
|
6
8
|
|
|
7
9
|
Blits is built on top of the Lightning 3 Rendererer and aims to provide a **great developer experience**, making it fun and easy to build your apps!
|
package/index.d.ts
CHANGED
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
// blits file type reference
|
|
19
19
|
/// <reference path="./blits.d.ts" />
|
|
20
20
|
|
|
21
|
-
import {type ShaderEffect as RendererShaderEffect, type WebGlCoreShader, type RendererMainSettings} from '@lightningjs/renderer'
|
|
22
|
-
|
|
23
21
|
declare module '@lightningjs/blits' {
|
|
24
|
-
|
|
22
|
+
type RendererShaderEffect = import('@lightningjs/renderer').ShaderEffect
|
|
23
|
+
type WebGlCoreShader = import('@lightningjs/renderer').WebGlCoreShader
|
|
24
|
+
type RendererMainSettings = import('@lightningjs/renderer').RendererMainSettings
|
|
25
25
|
|
|
26
26
|
export interface AnnouncerUtteranceOptions {
|
|
27
27
|
/**
|
|
@@ -209,7 +209,7 @@ declare module '@lightningjs/blits' {
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
export interface Input {
|
|
212
|
-
[key: string]: (event: KeyboardEvent) =>
|
|
212
|
+
[key: string]: ((event: KeyboardEvent) => unknown) | undefined,
|
|
213
213
|
/**
|
|
214
214
|
* Catch all input function
|
|
215
215
|
*
|
|
@@ -362,7 +362,39 @@ declare module '@lightningjs/blits' {
|
|
|
362
362
|
}
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
|
|
365
|
+
// Extension point for app- and plugin-specific fields on the component `this`.
|
|
366
|
+
// Add your own properties (e.g., `$telemetry`, `componentName`) via TypeScript
|
|
367
|
+
// module augmentation in your app, without changing core types.
|
|
368
|
+
// Note: `ComponentBase` extends this interface, so augmented fields appear in all
|
|
369
|
+
// hooks, methods, input, computed, and watch.
|
|
370
|
+
export interface CustomComponentProperties {
|
|
371
|
+
// Empty by design: extend in your app via TypeScript module augmentation.
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export interface LanguagePlugin {
|
|
375
|
+
translate(key: string, ...replacements: any[]): string
|
|
376
|
+
readonly language: string
|
|
377
|
+
set(language: string): void
|
|
378
|
+
translations(translationsObject: Record<string, unknown>): void
|
|
379
|
+
load(file: string): Promise<void>
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export interface ThemePlugin {
|
|
383
|
+
get<T = unknown>(key: string): T | undefined
|
|
384
|
+
get<T>(key: string, fallback: T): T
|
|
385
|
+
set(theme: string): void
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export interface StoragePlugin {
|
|
389
|
+
get<T = unknown>(key: string): T | null
|
|
390
|
+
set(key: string, value: unknown): boolean
|
|
391
|
+
remove(key: string): void
|
|
392
|
+
clear(): void
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export type AppStatePlugin<TState extends Record<string, unknown> = Record<string, unknown>> = TState
|
|
396
|
+
|
|
397
|
+
export interface ComponentBase extends CustomComponentProperties {
|
|
366
398
|
/**
|
|
367
399
|
* Indicates whether the component currently has focus
|
|
368
400
|
*
|
|
@@ -431,6 +463,12 @@ declare module '@lightningjs/blits' {
|
|
|
431
463
|
* Set focus to the Component, optionally pass a KeyboardEvent for instant event bubbling
|
|
432
464
|
*/
|
|
433
465
|
$focus: (event?: KeyboardEvent) => void
|
|
466
|
+
/**
|
|
467
|
+
* Handle a keyboard event on this component without changing focus
|
|
468
|
+
* @param event - The keyboard event to handle
|
|
469
|
+
* @returns Returns true if this component or a parent component handled the event, false otherwise
|
|
470
|
+
*/
|
|
471
|
+
$input: (event: KeyboardEvent) => boolean
|
|
434
472
|
/**
|
|
435
473
|
* @deprecated
|
|
436
474
|
* Deprecated: use `this.$focus()` instead
|
|
@@ -618,7 +656,7 @@ declare module '@lightningjs/blits' {
|
|
|
618
656
|
}
|
|
619
657
|
|
|
620
658
|
export interface RouterHooks {
|
|
621
|
-
init?: () => Promise
|
|
659
|
+
init?: () => Promise<void> | void;
|
|
622
660
|
beforeEach?: (to: Route, from: Route) => string | Route | Promise<string | Route> | void;
|
|
623
661
|
error?: (err: string) => string | Route | Promise<string | Route> | void;
|
|
624
662
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.45.0",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -8,7 +8,26 @@
|
|
|
8
8
|
"./vite": "./vite/index.js",
|
|
9
9
|
"./transitions": "./src/router/transitions/index.js",
|
|
10
10
|
"./precompiler": "./src/lib/precompiler/precompiler.js",
|
|
11
|
-
"./plugins":
|
|
11
|
+
"./plugins": {
|
|
12
|
+
"types": "./src/plugins/index.d.ts",
|
|
13
|
+
"default": "./src/plugins/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./plugins/language": {
|
|
16
|
+
"types": "./src/plugins/language.d.ts",
|
|
17
|
+
"default": "./src/plugins/language.js"
|
|
18
|
+
},
|
|
19
|
+
"./plugins/theme": {
|
|
20
|
+
"types": "./src/plugins/theme.d.ts",
|
|
21
|
+
"default": "./src/plugins/theme.js"
|
|
22
|
+
},
|
|
23
|
+
"./plugins/appstate": {
|
|
24
|
+
"types": "./src/plugins/appstate.d.ts",
|
|
25
|
+
"default": "./src/plugins/appstate.js"
|
|
26
|
+
},
|
|
27
|
+
"./plugins/storage": {
|
|
28
|
+
"types": "./src/plugins/storage/storage.d.ts",
|
|
29
|
+
"default": "./src/plugins/storage/storage.js"
|
|
30
|
+
},
|
|
12
31
|
"./symbols": "./src/lib/symbols.js",
|
|
13
32
|
"./blitsFileConverter": "./src/lib/blitsfileconverter/blitsfileconverter.js"
|
|
14
33
|
},
|
|
@@ -48,6 +67,7 @@
|
|
|
48
67
|
"husky": "^9.1.7",
|
|
49
68
|
"jsdom": "24.0.0",
|
|
50
69
|
"lint-staged": "^15.5.0",
|
|
70
|
+
"magic-string": "^0.30.21",
|
|
51
71
|
"prettier": "^3.6.2",
|
|
52
72
|
"sinon": "^21.0.0",
|
|
53
73
|
"tap-diff": "^0.1.1",
|
|
@@ -55,7 +75,7 @@
|
|
|
55
75
|
},
|
|
56
76
|
"dependencies": {
|
|
57
77
|
"@lightningjs/msdf-generator": "^1.2.0",
|
|
58
|
-
"@lightningjs/renderer": "^2.
|
|
78
|
+
"@lightningjs/renderer": "^2.20.0"
|
|
59
79
|
},
|
|
60
80
|
"repository": {
|
|
61
81
|
"type": "git",
|
|
@@ -55,7 +55,10 @@ function processFile(filePath) {
|
|
|
55
55
|
fs.copyFileSync(filePath, backupFilePath)
|
|
56
56
|
|
|
57
57
|
const source = fs.readFileSync(filePath, 'utf-8')
|
|
58
|
-
const
|
|
58
|
+
const result = compiler(source, filePath)
|
|
59
|
+
|
|
60
|
+
// Handle both string and object return types
|
|
61
|
+
const newSource = typeof result === 'object' && result.code ? result.code : result
|
|
59
62
|
fs.writeFileSync(filePath, newSource)
|
|
60
63
|
|
|
61
64
|
// only format the file if it was changed
|
package/src/application.js
CHANGED
|
@@ -20,28 +20,16 @@ import { default as Focus, keyUpCallbacks } from './focus.js'
|
|
|
20
20
|
import Settings from './settings.js'
|
|
21
21
|
|
|
22
22
|
import symbols from './lib/symbols.js'
|
|
23
|
-
import { DEFAULT_HOLD_TIMEOUT_MS } from './constants.js'
|
|
23
|
+
import { DEFAULT_HOLD_TIMEOUT_MS, DEFAULT_KEYMAP } from './constants.js'
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Enter: 'enter',
|
|
32
|
-
' ': 'space',
|
|
33
|
-
Backspace: 'back',
|
|
34
|
-
Escape: 'escape',
|
|
35
|
-
37: 'left',
|
|
36
|
-
39: 'right',
|
|
37
|
-
38: 'up',
|
|
38
|
-
40: 'down',
|
|
39
|
-
13: 'enter',
|
|
40
|
-
32: 'space',
|
|
41
|
-
8: 'back',
|
|
42
|
-
27: 'escape',
|
|
43
|
-
}
|
|
25
|
+
/**
|
|
26
|
+
* Merged keyMap (default + custom settings).
|
|
27
|
+
* Initialized once during application init.
|
|
28
|
+
* @type {Object<string, string>}
|
|
29
|
+
*/
|
|
30
|
+
export let keyMap = {}
|
|
44
31
|
|
|
32
|
+
const Application = (config) => {
|
|
45
33
|
config.hooks = config.hooks || {}
|
|
46
34
|
|
|
47
35
|
let keyDownHandler
|
|
@@ -63,7 +51,8 @@ const Application = (config) => {
|
|
|
63
51
|
if (announcerOptions && typeof announcerOptions === 'object') {
|
|
64
52
|
this.$announcer.configure(announcerOptions)
|
|
65
53
|
}
|
|
66
|
-
|
|
54
|
+
// Initialize merged keyMap once during application init
|
|
55
|
+
keyMap = { ...DEFAULT_KEYMAP, ...Settings.get('keymap', {}) }
|
|
67
56
|
|
|
68
57
|
/** @type {number} Input throttle time in milliseconds (0 = disabled) */
|
|
69
58
|
const throttleMs = Settings.get('inputThrottle', 0)
|
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
|
|
18
18
|
import symbols from '../../lib/symbols.js'
|
|
19
19
|
import Focus from '../../focus.js'
|
|
20
|
+
import { keyUpCallbacks, getComponentWithInputEvent } from '../../focus.js'
|
|
20
21
|
import eventListeners from '../../lib/eventListeners.js'
|
|
21
22
|
import { trigger } from '../../lib/reactivity/effect.js'
|
|
22
23
|
import { Log } from '../../lib/log.js'
|
|
23
24
|
import { removeGlobalEffects } from '../../lib/reactivity/effect.js'
|
|
24
25
|
import { renderer } from '../../launch.js'
|
|
26
|
+
import { keyMap } from '../../application.js'
|
|
25
27
|
|
|
26
28
|
export default {
|
|
27
29
|
focus: {
|
|
@@ -51,6 +53,41 @@ export default {
|
|
|
51
53
|
enumerable: true,
|
|
52
54
|
configurable: false,
|
|
53
55
|
},
|
|
56
|
+
$input: {
|
|
57
|
+
/**
|
|
58
|
+
* Handle a keyboard event on this component without changing focus
|
|
59
|
+
* @this {import('../../component').BlitsComponent}
|
|
60
|
+
* @param {KeyboardEvent} event - The keyboard event to handle
|
|
61
|
+
* @returns {boolean} - Returns true if this component or a parent component handled the event, false otherwise
|
|
62
|
+
*/
|
|
63
|
+
value: function (event) {
|
|
64
|
+
if (event === null || event === undefined || event instanceof KeyboardEvent === false)
|
|
65
|
+
return false
|
|
66
|
+
|
|
67
|
+
const key = keyMap[event.key] || keyMap[event.keyCode] || event.key || event.keyCode
|
|
68
|
+
|
|
69
|
+
const componentWithInputEvent = getComponentWithInputEvent(this, key)
|
|
70
|
+
if (componentWithInputEvent === null) return false
|
|
71
|
+
|
|
72
|
+
const inputEvents = componentWithInputEvent[symbols.inputEvents] || {}
|
|
73
|
+
|
|
74
|
+
let cb
|
|
75
|
+
if (inputEvents[key]) {
|
|
76
|
+
cb = inputEvents[key].call(componentWithInputEvent, event)
|
|
77
|
+
} else if (inputEvents.any) {
|
|
78
|
+
cb = inputEvents.any.call(componentWithInputEvent, event)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (cb !== undefined && event.code) {
|
|
82
|
+
keyUpCallbacks.set(event.code, cb)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return true
|
|
86
|
+
},
|
|
87
|
+
writable: false,
|
|
88
|
+
enumerable: true,
|
|
89
|
+
configurable: false,
|
|
90
|
+
},
|
|
54
91
|
unfocus: {
|
|
55
92
|
/**
|
|
56
93
|
* @this {import('../../component').BlitsComponent}
|
package/src/components/Sprite.js
CHANGED
|
@@ -121,15 +121,20 @@ export default () =>
|
|
|
121
121
|
// Resolve frame data from sprite map
|
|
122
122
|
let options = null
|
|
123
123
|
if (
|
|
124
|
-
this.map !== undefined &&
|
|
125
124
|
this.map !== null &&
|
|
126
|
-
this.
|
|
127
|
-
this.frame !== null
|
|
125
|
+
this.map !== undefined &&
|
|
126
|
+
this.frame !== null &&
|
|
127
|
+
this.frame !== undefined
|
|
128
128
|
) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
if (
|
|
130
|
+
this.map.frames !== null &&
|
|
131
|
+
this.map.frames !== undefined &&
|
|
132
|
+
this.frame in this.map.frames
|
|
133
|
+
) {
|
|
134
|
+
options = Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
|
|
135
|
+
} else if (this.frame in this.map) {
|
|
136
|
+
options = this.map[this.frame]
|
|
137
|
+
}
|
|
133
138
|
}
|
|
134
139
|
|
|
135
140
|
// If no map but frame is object (manual subtexture)
|
package/src/constants.js
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
export const DEFAULT_HOLD_TIMEOUT_MS = 50
|
|
2
2
|
|
|
3
|
+
export const DEFAULT_KEYMAP = {
|
|
4
|
+
ArrowLeft: 'left',
|
|
5
|
+
ArrowRight: 'right',
|
|
6
|
+
ArrowUp: 'up',
|
|
7
|
+
ArrowDown: 'down',
|
|
8
|
+
Enter: 'enter',
|
|
9
|
+
' ': 'space',
|
|
10
|
+
Backspace: 'back',
|
|
11
|
+
Escape: 'escape',
|
|
12
|
+
37: 'left',
|
|
13
|
+
39: 'right',
|
|
14
|
+
38: 'up',
|
|
15
|
+
40: 'down',
|
|
16
|
+
13: 'enter',
|
|
17
|
+
32: 'space',
|
|
18
|
+
8: 'back',
|
|
19
|
+
27: 'escape',
|
|
20
|
+
}
|
|
21
|
+
|
|
3
22
|
export const SCREEN_RESOLUTIONS = {
|
|
4
23
|
hd: 0.66666667,
|
|
5
24
|
'720p': 0.66666667,
|
|
@@ -168,7 +168,7 @@ const isObjectString = (str) => {
|
|
|
168
168
|
* @returns {object} The parsed object.
|
|
169
169
|
*/
|
|
170
170
|
const parseToObject = (str) => {
|
|
171
|
-
return JSON.parse(str.replace(/'/g, '"').replace(/([\w-_]+)\s
|
|
171
|
+
return JSON.parse(str.replace(/'/g, '"').replace(/([{,]\s*)([\w-_]+)(\s*:)/g, '$1"$2"$3'))
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
/**
|
|
@@ -276,7 +276,13 @@ const propsTransformer = {
|
|
|
276
276
|
}
|
|
277
277
|
},
|
|
278
278
|
set src(v) {
|
|
279
|
-
|
|
279
|
+
if (typeof v === 'object' || (isObjectString(v) === true && (v = parseToObject(v)))) {
|
|
280
|
+
this.props['src'] = v.src
|
|
281
|
+
this.props['imageType'] = v.type
|
|
282
|
+
} else {
|
|
283
|
+
this.props['src'] = v
|
|
284
|
+
}
|
|
285
|
+
|
|
280
286
|
if (this.raw['color'] === undefined) {
|
|
281
287
|
this.props['color'] = this.props['src'] ? 0xffffffff : 0x00000000
|
|
282
288
|
}
|
|
@@ -374,10 +380,21 @@ const propsTransformer = {
|
|
|
374
380
|
}
|
|
375
381
|
},
|
|
376
382
|
set shader(v) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
383
|
+
const target = this.element.node !== undefined ? this.element.node : this.props
|
|
384
|
+
|
|
385
|
+
if (v === null) {
|
|
386
|
+
target['shader'] = null
|
|
387
|
+
return
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (typeof v === 'object' || (isObjectString(v) === true && (v = parseToObject(v)))) {
|
|
391
|
+
if (target.shader !== undefined && target.shader.type === v.type) {
|
|
392
|
+
for (const prop in v.props) {
|
|
393
|
+
target.shader.props[prop] = v.props[prop]
|
|
394
|
+
}
|
|
395
|
+
return
|
|
396
|
+
}
|
|
397
|
+
target['shader'] = renderer.createShader(v.type, v.props)
|
|
381
398
|
}
|
|
382
399
|
},
|
|
383
400
|
set effects(v) {
|
package/src/focus.js
CHANGED
|
@@ -118,7 +118,7 @@ const getAncestors = (components) => {
|
|
|
118
118
|
* @param {String} key
|
|
119
119
|
* @returns component
|
|
120
120
|
*/
|
|
121
|
-
const getComponentWithInputEvent = (component, key) => {
|
|
121
|
+
export const getComponentWithInputEvent = (component, key) => {
|
|
122
122
|
if (
|
|
123
123
|
component[symbols.inputEvents] &&
|
|
124
124
|
(typeof component[symbols.inputEvents][key] === 'function' ||
|
|
@@ -409,7 +409,7 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
409
409
|
.replace(')', '')
|
|
410
410
|
.split(/\s*,\s*/)
|
|
411
411
|
|
|
412
|
-
const scopeRegex = new RegExp(`(scope\\.(?!${item}\\.|${index}|key)(\\w+))`, 'gi')
|
|
412
|
+
const scopeRegex = new RegExp(`(scope\\.(?!${item}\\.|${index}|key)([\\w$]+))`, 'gi')
|
|
413
413
|
|
|
414
414
|
// local context
|
|
415
415
|
const ctx = {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import parser from '../templateparser/parser.js'
|
|
19
19
|
import generator from '../codegenerator/generator.js'
|
|
20
|
+
import MagicString from 'magic-string'
|
|
20
21
|
|
|
21
22
|
export default (source, filePath, mode) => {
|
|
22
23
|
if (
|
|
@@ -26,12 +27,9 @@ export default (source, filePath, mode) => {
|
|
|
26
27
|
/\{.*?template\s*:\s*(['"`])((?:\\?.)*?)\1.*?\}/s.test(source) // object with template key
|
|
27
28
|
) {
|
|
28
29
|
const templates = source.matchAll(/(?<!\/\/\s*)template\s*:\s*(['"`])((?:\\?.)*?)\1/gs)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
track of the offset caused by the previous replacements
|
|
33
|
-
*/
|
|
34
|
-
let offset = 0
|
|
30
|
+
|
|
31
|
+
// Use MagicString to track changes
|
|
32
|
+
const s = new MagicString(source)
|
|
35
33
|
|
|
36
34
|
for (const template of templates) {
|
|
37
35
|
if (template[2]) {
|
|
@@ -39,7 +37,8 @@ export default (source, filePath, mode) => {
|
|
|
39
37
|
|
|
40
38
|
// Only process if it looks like a Blits template
|
|
41
39
|
if (templateContent.match(/^\s*(<!--[\s\S]*?-->|<[A-Za-z][^>]*>)/s)) {
|
|
42
|
-
|
|
40
|
+
// Use original indices - MagicString handles position tracking automatically
|
|
41
|
+
const templateStartIndex = template.index
|
|
43
42
|
const templateEndIndex = templateStartIndex + template[0].length
|
|
44
43
|
|
|
45
44
|
// Parse the template
|
|
@@ -58,16 +57,26 @@ export default (source, filePath, mode) => {
|
|
|
58
57
|
(fn) => fn.toString()
|
|
59
58
|
)}], context: {}}`
|
|
60
59
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
newSource =
|
|
64
|
-
newSource.substring(0, templateStartIndex) +
|
|
65
|
-
replacement +
|
|
66
|
-
newSource.substring(templateEndIndex)
|
|
60
|
+
// MagicString tracks all changes automatically, no offset needed
|
|
61
|
+
s.overwrite(templateStartIndex, templateEndIndex, replacement)
|
|
67
62
|
}
|
|
68
63
|
}
|
|
69
64
|
}
|
|
70
|
-
|
|
65
|
+
|
|
66
|
+
const newSource = s.toString()
|
|
67
|
+
|
|
68
|
+
if (newSource !== source) {
|
|
69
|
+
const fileName = filePath.split(/[\\/]/).pop()
|
|
70
|
+
return {
|
|
71
|
+
code: newSource,
|
|
72
|
+
map: s.generateMap({
|
|
73
|
+
hires: true,
|
|
74
|
+
source: fileName,
|
|
75
|
+
includeContent: true,
|
|
76
|
+
file: fileName,
|
|
77
|
+
}),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
71
80
|
}
|
|
72
81
|
return source
|
|
73
82
|
}
|
|
@@ -213,7 +213,12 @@ export default (code) => {
|
|
|
213
213
|
modifiedCode = modifiedCode.replace(mod.original, mod.replacement)
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
|
|
216
|
+
// Returning code without a source map
|
|
217
|
+
// Vite will automatically chain this with the next plugin's source map (preCompiler)
|
|
218
|
+
return {
|
|
219
|
+
code: modifiedCode,
|
|
220
|
+
map: { mappings: '' },
|
|
221
|
+
}
|
|
217
222
|
}
|
|
218
223
|
|
|
219
224
|
return null
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Comcast Cable Communications Management, LLC
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { AppStatePlugin } from '@lightningjs/blits'
|
|
19
|
+
|
|
20
|
+
// Re-export AppStatePlugin for direct imports
|
|
21
|
+
export type { AppStatePlugin }
|
|
22
|
+
|
|
23
|
+
declare const appState: {
|
|
24
|
+
readonly name: 'appState'
|
|
25
|
+
plugin: <TState extends Record<string, unknown>>(state?: TState) => AppStatePlugin<TState>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default appState
|
|
29
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Comcast Cable Communications Management, LLC
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export { default as language } from './language.js'
|
|
19
|
+
export { default as theme } from './theme.js'
|
|
20
|
+
export { default as appState } from './appstate.js'
|
|
21
|
+
export { default as storage } from './storage/storage.js'
|
|
22
|
+
|
|
23
|
+
// Re-export plugin interfaces for convenience
|
|
24
|
+
export type { LanguagePlugin, ThemePlugin, StoragePlugin, AppStatePlugin } from '@lightningjs/blits'
|
|
25
|
+
|
|
26
|
+
// Re-export option types
|
|
27
|
+
export type { LanguagePluginOptions } from './language.js'
|
|
28
|
+
export type { ThemePluginConfig } from './theme.js'
|
|
29
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Comcast Cable Communications Management, LLC
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { LanguagePlugin } from '@lightningjs/blits'
|
|
19
|
+
|
|
20
|
+
export interface LanguagePluginOptions {
|
|
21
|
+
file?: string
|
|
22
|
+
language?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Re-export LanguagePlugin for direct imports
|
|
26
|
+
export type { LanguagePlugin }
|
|
27
|
+
|
|
28
|
+
declare const language: {
|
|
29
|
+
readonly name: 'language'
|
|
30
|
+
plugin: (options?: LanguagePluginOptions) => LanguagePlugin
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default language
|
|
34
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Comcast Cable Communications Management, LLC
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { StoragePlugin } from '@lightningjs/blits'
|
|
19
|
+
|
|
20
|
+
// Re-export StoragePlugin for direct imports
|
|
21
|
+
export type { StoragePlugin }
|
|
22
|
+
|
|
23
|
+
declare const storage: {
|
|
24
|
+
readonly name: 'storage'
|
|
25
|
+
plugin: () => StoragePlugin
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default storage
|
|
29
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Comcast Cable Communications Management, LLC
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { ThemePlugin } from '@lightningjs/blits'
|
|
19
|
+
|
|
20
|
+
export interface ThemePluginConfig {
|
|
21
|
+
themes?: Record<string, Record<string, unknown>>
|
|
22
|
+
current?: string
|
|
23
|
+
base?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Re-export ThemePlugin for direct imports
|
|
27
|
+
export type { ThemePlugin }
|
|
28
|
+
|
|
29
|
+
declare const theme: {
|
|
30
|
+
readonly name: 'theme'
|
|
31
|
+
plugin: (config?: ThemePluginConfig | Record<string, unknown>) => ThemePlugin
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default theme
|
|
35
|
+
|
package/vite/preCompiler.js
CHANGED
|
@@ -32,12 +32,22 @@ export default function () {
|
|
|
32
32
|
|
|
33
33
|
// we should only precompile .blits, .js and .ts files
|
|
34
34
|
if (
|
|
35
|
-
|
|
36
|
-
fileExtension === '.
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
filePath.indexOf('node_modules') === -1 &&
|
|
36
|
+
(fileExtension === '.js' ||
|
|
37
|
+
fileExtension === '.ts' ||
|
|
38
|
+
fileExtension === '.blits' ||
|
|
39
|
+
fileExtension === '.mjs')
|
|
39
40
|
) {
|
|
40
|
-
|
|
41
|
+
const result = compiler(source, filePath, config.mode)
|
|
42
|
+
|
|
43
|
+
if (typeof result === 'object') {
|
|
44
|
+
return {
|
|
45
|
+
code: result.code,
|
|
46
|
+
map: result.map,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// No transformation needed - return null so Vite knows no changes were made
|
|
50
|
+
return null
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
// vite expects null if there is no modification
|