@lightningjs/blits 2.0.0-beta.1 → 2.0.0-beta.10
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 +83 -0
- package/README.md +2 -0
- package/element-test-full.txt +0 -0
- package/index.d.ts +114 -14
- package/package.json +28 -8
- package/scripts/lint.js +17 -0
- package/scripts/prepublishOnly.js +15 -6
- package/scripts/prepush.js +25 -7
- package/src/announcer/announcer.js +54 -6
- package/src/announcer/speechSynthesis.js +156 -37
- package/src/application.js +98 -3
- package/src/component/base/methods.js +5 -2
- package/src/component/base/router.js +6 -0
- package/src/component/base/timeouts_intervals.js +56 -0
- package/src/component/setup/routes.js +5 -0
- package/src/component/setup/state.js +2 -0
- package/src/component.js +64 -24
- package/src/components/Circle.js +5 -3
- package/src/components/FPScounter.js +1591 -1577
- package/src/components/RouterView.js +141 -124
- package/src/components/Sprite.js +65 -8
- package/src/components/index.js +0 -2
- package/src/constants.js +17 -0
- package/src/engine.js +17 -0
- package/src/engines/L3/element.js +101 -7
- package/src/engines/L3/fontLoader.js +17 -0
- package/src/engines/L3/index.js +17 -0
- package/src/engines/L3/launch.js +4 -1
- package/src/engines/L3/shaderLoader.js +17 -0
- package/src/engines/index.js +17 -0
- package/src/{focus.js → focus/focus.js} +6 -18
- package/src/focus/helpers.js +31 -0
- package/src/focus/hover.js +94 -0
- package/src/helpers/fetchJson.js +4 -6
- package/src/launch.js +1 -0
- package/src/lib/codegenerator/generator.js +55 -9
- package/src/lib/lifecycle.js +34 -3
- package/src/lib/log.js +4 -4
- package/src/lib/precompiler/precompiler.js +23 -14
- package/src/lib/reactivity/effect.js +3 -2
- package/src/lib/reactivityguard/computedprops.js +113 -28
- package/src/lib/shaders/shaders.js +2 -1
- package/src/lib/symbols.js +19 -0
- package/src/lib/utils.js +17 -0
- package/src/plugin.js +17 -0
- package/src/plugins/appstate.d.ts +26 -0
- package/src/plugins/index.d.ts +28 -0
- package/src/plugins/language.d.ts +37 -0
- package/src/plugins/storage/localCookie.js +4 -6
- package/src/plugins/storage/storage.d.ts +31 -0
- package/src/plugins/theme.d.ts +43 -0
- package/src/plugins/theme.js +30 -3
- package/src/router/router.js +78 -14
- package/test-output.txt +0 -0
- package/vite/inject-dev-config.js +17 -0
- package/vite/preCompiler.js +15 -5
- package/vscode/data/template-attributes.json +335 -86
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,88 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.51.0
|
|
4
|
+
|
|
5
|
+
_04 mar 2026_
|
|
6
|
+
|
|
7
|
+
- Fixed wrong message from being interrupted in announcer
|
|
8
|
+
- Added `@loaded` and `@error` callbacks to Sprites
|
|
9
|
+
|
|
10
|
+
## v1.50.0
|
|
11
|
+
|
|
12
|
+
_27 feb 2026_
|
|
13
|
+
|
|
14
|
+
- Fixed issue with router navigation options not properly being overriden
|
|
15
|
+
- Fixed FPS counter component and made it into a separate importable component (`import { FPScounter } from @lightningjs/blits/components`)
|
|
16
|
+
- Added mouse (magic wand) support (including new `hover` lifecycle hook and `isHovered` state indicator)
|
|
17
|
+
- Updated template attributes for VScode extension
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## v1.49.0
|
|
21
|
+
|
|
22
|
+
_20 feb 2026_
|
|
23
|
+
|
|
24
|
+
- Added `data-blits-renderstate` inspector attribute
|
|
25
|
+
- Fixed `data-blits-hasfocus` inspector attribute to always be available
|
|
26
|
+
- Added boolean attribute to `idle` lifecycle hook to indicate `idle` or `active` state
|
|
27
|
+
- Fixed type definitions for router beforeEach hooks
|
|
28
|
+
- Fixed double processing of reactivity guard
|
|
29
|
+
|
|
30
|
+
## v1.48.0
|
|
31
|
+
|
|
32
|
+
_10 feb 2026_
|
|
33
|
+
|
|
34
|
+
- Improved cleanup of for-loop effects
|
|
35
|
+
- Fixed router issue with params not being reset
|
|
36
|
+
- Added next tick debouncing for transitions on multiple props
|
|
37
|
+
- Bumped renderer to 2.21.0
|
|
38
|
+
- Added support for using function-notation in `@loaded`, `@error` and `@updated` callbacks
|
|
39
|
+
- Added displaying of correct component type in inspector data when using `is`-attribute
|
|
40
|
+
- Replaced `$`-prefix for automatic inspector data with `blits-` prefix (fixes fatal error in Safari)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
## v1.47.0
|
|
44
|
+
|
|
45
|
+
_26 jan 2026_
|
|
46
|
+
|
|
47
|
+
- Fixed issue with reactivity guard vite plugin failing for commented-out code
|
|
48
|
+
- Fixed issue with autosizing of holder node by adding extra `eol` check
|
|
49
|
+
- Added support for _variants_ to the Theme plugin
|
|
50
|
+
|
|
51
|
+
## v1.46.0
|
|
52
|
+
|
|
53
|
+
_22 jan 2026_
|
|
54
|
+
|
|
55
|
+
- Improved Announcer on Comcast devices
|
|
56
|
+
- Added new `afterEach` router hook
|
|
57
|
+
- Added router option to dynamically disable `back`-key handling by the router
|
|
58
|
+
- Added `this.$debounce`-method
|
|
59
|
+
- Added automatic inspector data items (`$componentType`, `$hasFocus` and `$isTransitioning`)
|
|
60
|
+
- Added functionality to auto size the holder node of a Component when the wrapper Element has dimensions
|
|
61
|
+
- Bumped Lightning renderer to v2.20.4 with correct handling of failed textures
|
|
62
|
+
|
|
63
|
+
## v1.45.2
|
|
64
|
+
|
|
65
|
+
_13 jan 2026_
|
|
66
|
+
|
|
67
|
+
- Updated renderer to v2.20.2
|
|
68
|
+
|
|
69
|
+
## v1.45.1
|
|
70
|
+
|
|
71
|
+
_29 dec 2025_
|
|
72
|
+
|
|
73
|
+
- fixed issue `magic-string` package being a dev dependency
|
|
74
|
+
|
|
75
|
+
## v1.45.0
|
|
76
|
+
|
|
77
|
+
_29 dec 2025_
|
|
78
|
+
|
|
79
|
+
- Added support for defining types for custom plugins on the Blits component definitions
|
|
80
|
+
- Added importable type definitions for built-in plugins
|
|
81
|
+
- Added support for JS sourcemaps
|
|
82
|
+
- Added reactivity for shader props (individual shaders, not effects via dynamic shader)
|
|
83
|
+
- Fixed issue with usage of Blits plugins not working in for loops
|
|
84
|
+
- Improved test coverage
|
|
85
|
+
|
|
3
86
|
## v1.44.0
|
|
4
87
|
|
|
5
88
|
_20 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!
|
|
Binary file
|
package/index.d.ts
CHANGED
|
@@ -23,7 +23,9 @@ import { CanvasShaderType } from '@lightningjs/renderer/canvas';
|
|
|
23
23
|
import { WebGlShaderType } from '@lightningjs/renderer/webgl';
|
|
24
24
|
|
|
25
25
|
declare module '@lightningjs/blits' {
|
|
26
|
-
|
|
26
|
+
type RendererShaderEffect = import('@lightningjs/renderer').ShaderEffect
|
|
27
|
+
type WebGlCoreShader = import('@lightningjs/renderer').WebGlCoreShader
|
|
28
|
+
type RendererMainSettings = import('@lightningjs/renderer').RendererMainSettings
|
|
27
29
|
|
|
28
30
|
export interface AnnouncerUtteranceOptions {
|
|
29
31
|
/**
|
|
@@ -56,6 +58,12 @@ declare module '@lightningjs/blits' {
|
|
|
56
58
|
* @default 1
|
|
57
59
|
*/
|
|
58
60
|
volume?: number,
|
|
61
|
+
/**
|
|
62
|
+
* Whether to enable utterance keep-alive (prevents pausing on some platforms)
|
|
63
|
+
*
|
|
64
|
+
* @default undefined
|
|
65
|
+
*/
|
|
66
|
+
enableUtteranceKeepAlive?: boolean
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
export interface AnnouncerUtterance<T = any> extends Promise<T> {
|
|
@@ -166,6 +174,8 @@ declare module '@lightningjs/blits' {
|
|
|
166
174
|
* Fires when the Component is being destroyed and removed.
|
|
167
175
|
*/
|
|
168
176
|
destroy?: () => void;
|
|
177
|
+
hover?: () => void;
|
|
178
|
+
unhover?: () => void;
|
|
169
179
|
/**
|
|
170
180
|
* Fires upon each frame start (allowing you to tap directly into the renderloop)
|
|
171
181
|
*
|
|
@@ -197,11 +207,14 @@ declare module '@lightningjs/blits' {
|
|
|
197
207
|
*/
|
|
198
208
|
exit?: () => void;
|
|
199
209
|
/**
|
|
200
|
-
* Fires when the renderer is done rendering and enters an idle state
|
|
210
|
+
* Fires when the renderer is done rendering and enters an idle state (idle = true)
|
|
211
|
+
* and when the renderer starts rendering again and leaves the idle state (idle = false)
|
|
212
|
+
*
|
|
213
|
+
* @param idle - boolean to indicate whether the renderer is in idle state or not
|
|
201
214
|
*
|
|
202
215
|
* Note: This event can fire multiple times
|
|
203
216
|
*/
|
|
204
|
-
idle?: () => void;
|
|
217
|
+
idle?: (idle: boolean) => void;
|
|
205
218
|
/**
|
|
206
219
|
* Fires at a predefined interval and reports the current FPS value
|
|
207
220
|
*
|
|
@@ -211,7 +224,7 @@ declare module '@lightningjs/blits' {
|
|
|
211
224
|
}
|
|
212
225
|
|
|
213
226
|
export interface Input {
|
|
214
|
-
[key: string]: (event: KeyboardEvent) =>
|
|
227
|
+
[key: string]: ((event: KeyboardEvent) => unknown) | undefined,
|
|
215
228
|
/**
|
|
216
229
|
* Catch all input function
|
|
217
230
|
*
|
|
@@ -323,6 +336,11 @@ declare module '@lightningjs/blits' {
|
|
|
323
336
|
*/
|
|
324
337
|
back(): boolean;
|
|
325
338
|
|
|
339
|
+
/**
|
|
340
|
+
* Enable or disable RouterView history navigation on Back input
|
|
341
|
+
*/
|
|
342
|
+
backNavigation: boolean;
|
|
343
|
+
|
|
326
344
|
/**
|
|
327
345
|
* Get the current route read-only
|
|
328
346
|
*/
|
|
@@ -330,17 +348,17 @@ declare module '@lightningjs/blits' {
|
|
|
330
348
|
|
|
331
349
|
/**
|
|
332
350
|
* Get the list of all routes
|
|
333
|
-
|
|
351
|
+
*/
|
|
334
352
|
readonly routes: Route[];
|
|
335
353
|
|
|
336
354
|
/**
|
|
337
355
|
* Get navigating state
|
|
338
|
-
|
|
356
|
+
*/
|
|
339
357
|
readonly navigating: boolean;
|
|
340
358
|
|
|
341
359
|
/**
|
|
342
360
|
* Reactive router state
|
|
343
|
-
|
|
361
|
+
*/
|
|
344
362
|
state: {
|
|
345
363
|
/**
|
|
346
364
|
* Path of the current route
|
|
@@ -364,7 +382,17 @@ declare module '@lightningjs/blits' {
|
|
|
364
382
|
}
|
|
365
383
|
}
|
|
366
384
|
|
|
367
|
-
|
|
385
|
+
// Extension point for app- and plugin-specific fields on the component `this`.
|
|
386
|
+
// Add your own properties (e.g., `$telemetry`, `componentName`) via TypeScript
|
|
387
|
+
// module augmentation in your app, without changing core types.
|
|
388
|
+
// Note: `ComponentBase` extends this interface, so augmented fields appear in all
|
|
389
|
+
// hooks, methods, input, computed, and watch.
|
|
390
|
+
export interface CustomComponentProperties {
|
|
391
|
+
// Empty by design: extend in your app via TypeScript module augmentation.
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
export interface ComponentBase extends CustomComponentProperties {
|
|
368
396
|
/**
|
|
369
397
|
* Indicates whether the component currently has focus
|
|
370
398
|
*
|
|
@@ -372,6 +400,20 @@ declare module '@lightningjs/blits' {
|
|
|
372
400
|
*/
|
|
373
401
|
readonly $hasFocus: boolean,
|
|
374
402
|
|
|
403
|
+
/**
|
|
404
|
+
* Parent component instance.
|
|
405
|
+
* Note: will be undefined for the root Application component or after destroy.
|
|
406
|
+
*
|
|
407
|
+
*/
|
|
408
|
+
readonly $parent: ComponentBase,
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Indicates whether the component currently is hovered
|
|
412
|
+
*
|
|
413
|
+
* @returns Boolean
|
|
414
|
+
*/
|
|
415
|
+
$isHovered: boolean,
|
|
416
|
+
|
|
375
417
|
/**
|
|
376
418
|
* Listen to events emitted by other components
|
|
377
419
|
*/
|
|
@@ -414,6 +456,26 @@ declare module '@lightningjs/blits' {
|
|
|
414
456
|
*/
|
|
415
457
|
$clearTimeout: (id: ReturnType<typeof setTimeout>) => void
|
|
416
458
|
|
|
459
|
+
/**
|
|
460
|
+
* Debounce a function execution, preventing memory leaks and function re-allocation
|
|
461
|
+
* @param name - Unique identifier for this debounce instance (unique per component instance)
|
|
462
|
+
* @param callback - Function to debounce
|
|
463
|
+
* @param ms - Delay in milliseconds
|
|
464
|
+
* @param args - Arguments to pass to the callback
|
|
465
|
+
*/
|
|
466
|
+
$debounce: (name: string, callback: (...args: any[]) => void, ms?: number, ...args: any[]) => ReturnType<typeof setTimeout>
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Clear a specific debounce by name
|
|
470
|
+
* @param name - The name of the debounce to clear
|
|
471
|
+
*/
|
|
472
|
+
$clearDebounce: (name: string) => void
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Clear all debounces registered on the component (automatically called on component destroy)
|
|
476
|
+
*/
|
|
477
|
+
$clearDebounces: () => void
|
|
478
|
+
|
|
417
479
|
/**
|
|
418
480
|
* Set an interval that is automatically cleaned upon component destroy
|
|
419
481
|
*/
|
|
@@ -585,7 +647,7 @@ declare module '@lightningjs/blits' {
|
|
|
585
647
|
* }
|
|
586
648
|
* ```
|
|
587
649
|
*/
|
|
588
|
-
state?: (this: InferProps<P
|
|
650
|
+
state?: (this: Readonly<InferProps<P>> & ComponentBase) => S;
|
|
589
651
|
/**
|
|
590
652
|
* Methods for abstracting more complex business logic into separate function
|
|
591
653
|
*/
|
|
@@ -609,9 +671,10 @@ declare module '@lightningjs/blits' {
|
|
|
609
671
|
}
|
|
610
672
|
|
|
611
673
|
export interface RouterHooks {
|
|
612
|
-
init?: () => Promise
|
|
613
|
-
beforeEach?: (to: Route, from: Route) => string | Route | Promise<string | Route
|
|
614
|
-
|
|
674
|
+
init?: () => Promise<void> | void;
|
|
675
|
+
beforeEach?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
676
|
+
afterEach?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
677
|
+
error?: (err: string) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
615
678
|
}
|
|
616
679
|
|
|
617
680
|
export interface RouterConfig<P extends Props, S, M, C> {
|
|
@@ -634,6 +697,25 @@ declare module '@lightningjs/blits' {
|
|
|
634
697
|
* ```
|
|
635
698
|
*/
|
|
636
699
|
routes?: Route[]
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Enable or disable RouterView history navigation on Back input
|
|
703
|
+
*
|
|
704
|
+
* @default true
|
|
705
|
+
*
|
|
706
|
+
* @remarks
|
|
707
|
+
* This is an app-wide setting that affects all RouterView instances in your application.
|
|
708
|
+
* The router state is global and shared across all router instances.
|
|
709
|
+
*
|
|
710
|
+
* @example
|
|
711
|
+
* ```js
|
|
712
|
+
* router: {
|
|
713
|
+
* backNavigation: false, // Disable automatic back navigation
|
|
714
|
+
* routes: [...]
|
|
715
|
+
* }
|
|
716
|
+
* ```
|
|
717
|
+
*/
|
|
718
|
+
backNavigation?: boolean
|
|
637
719
|
}
|
|
638
720
|
|
|
639
721
|
export type ApplicationConfig<P extends Props, S, M, C, W> = ComponentConfig<P, S, M, C, W> & (
|
|
@@ -733,7 +815,8 @@ declare module '@lightningjs/blits' {
|
|
|
733
815
|
}[keyof T]
|
|
734
816
|
|
|
735
817
|
export interface RouteHooks {
|
|
736
|
-
before?: (to: Route, from: Route) => string | Route | Promise<string | Route>;
|
|
818
|
+
before?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
819
|
+
after?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
737
820
|
}
|
|
738
821
|
|
|
739
822
|
export type Route = {
|
|
@@ -1157,6 +1240,16 @@ declare module '@lightningjs/blits' {
|
|
|
1157
1240
|
* ```
|
|
1158
1241
|
*/
|
|
1159
1242
|
announcerOptions?: AnnouncerUtteranceOptions,
|
|
1243
|
+
/**
|
|
1244
|
+
* Enable mouse support (hover and click-to-focus).
|
|
1245
|
+
*
|
|
1246
|
+
* When set to `true`, pointer movement over the canvas updates hover state on components
|
|
1247
|
+
* and click dispatches focus and Enter key input to the component under the cursor.
|
|
1248
|
+
* When set to `false`, no mouse or pointer listeners are registered.
|
|
1249
|
+
*
|
|
1250
|
+
* @default false
|
|
1251
|
+
*/
|
|
1252
|
+
enableMouse?: boolean,
|
|
1160
1253
|
/**
|
|
1161
1254
|
* Maximum FPS at which the App will be rendered
|
|
1162
1255
|
*
|
|
@@ -1165,7 +1258,14 @@ declare module '@lightningjs/blits' {
|
|
|
1165
1258
|
*
|
|
1166
1259
|
* Defaults to `0` which means no maximum
|
|
1167
1260
|
*/
|
|
1168
|
-
maxFPS?: number
|
|
1261
|
+
maxFPS?: number,
|
|
1262
|
+
/**
|
|
1263
|
+
* Custom platform layer to be used by the App (experimental)
|
|
1264
|
+
*
|
|
1265
|
+
* Defaults to `null` which will be resolved internally to WebPlatform
|
|
1266
|
+
*/
|
|
1267
|
+
platform?: any
|
|
1268
|
+
|
|
1169
1269
|
}
|
|
1170
1270
|
|
|
1171
1271
|
interface State {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.10",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -8,15 +8,34 @@
|
|
|
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
|
-
"./blitsFileConverter": "./src/lib/blitsfileconverter/blitsfileconverter.js"
|
|
32
|
+
"./blitsFileConverter": "./src/lib/blitsfileconverter/blitsfileconverter.js",
|
|
33
|
+
"./components": "./src/components/FPScounter.js"
|
|
14
34
|
},
|
|
15
35
|
"scripts": {
|
|
16
|
-
"test": "c8
|
|
17
|
-
"test:
|
|
18
|
-
"test:run": "node -r global-jsdom/register
|
|
19
|
-
"test:run:failures": "node -r global-jsdom/register ./node_modules/.bin/tape '{,!(node_modules|packages)/**/}*.test.js' | tap-filter test-fail | tap-diff",
|
|
36
|
+
"test": "c8 npm run test:run | tap-diff",
|
|
37
|
+
"test:run": "node -r global-jsdom/register node_modules/tape/bin/tape \"scripts/**/*.test.js\" \"src/**/*.test.js\"",
|
|
38
|
+
"test:run:failures": "node -r global-jsdom/register node_modules/tape/bin/tape \"scripts/**/*.test.js\" \"src/**/*.test.js\" | tap-filter test-fail | tap-diff",
|
|
20
39
|
"lint": "node scripts/lint.js",
|
|
21
40
|
"lint:fix": "node scripts/lint.js fix",
|
|
22
41
|
"prepublishOnly": "node scripts/prepublishOnly.js",
|
|
@@ -56,7 +75,8 @@
|
|
|
56
75
|
"tape": "^5.5.0"
|
|
57
76
|
},
|
|
58
77
|
"dependencies": {
|
|
59
|
-
"@lightningjs/renderer": "3.0.0-
|
|
78
|
+
"@lightningjs/renderer": "3.0.0-beta23",
|
|
79
|
+
"magic-string": "^0.30.21"
|
|
60
80
|
},
|
|
61
81
|
"repository": {
|
|
62
82
|
"type": "git",
|
package/scripts/lint.js
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 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
|
+
|
|
1
18
|
import fg from 'fast-glob'
|
|
2
19
|
import { resolve } from 'path'
|
|
3
20
|
import { fileURLToPath } from 'url'
|
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
import fs from 'fs'
|
|
19
19
|
import path from 'path'
|
|
20
|
+
import { fileURLToPath } from 'url'
|
|
20
21
|
import compiler from '../src/lib/precompiler/precompiler.js'
|
|
21
|
-
import
|
|
22
|
+
import childProcess from 'child_process'
|
|
22
23
|
|
|
23
24
|
const currentDir = process.cwd()
|
|
24
25
|
const componentDirs = ['src/components']
|
|
@@ -55,11 +56,14 @@ function processFile(filePath) {
|
|
|
55
56
|
fs.copyFileSync(filePath, backupFilePath)
|
|
56
57
|
|
|
57
58
|
const source = fs.readFileSync(filePath, 'utf-8')
|
|
58
|
-
const
|
|
59
|
+
const result = compiler(source, filePath)
|
|
60
|
+
|
|
61
|
+
// Handle both string and object return types
|
|
62
|
+
const newSource = typeof result === 'object' && result.code ? result.code : result
|
|
59
63
|
fs.writeFileSync(filePath, newSource)
|
|
60
64
|
|
|
61
|
-
// only format the file if it was changed
|
|
62
|
-
if (source !== newSource) {
|
|
65
|
+
// only format the file if it was changed (compiler returns undefined for non-Blits files)
|
|
66
|
+
if (newSource !== undefined && source !== newSource) {
|
|
63
67
|
formatFileWithESLint(filePath)
|
|
64
68
|
}
|
|
65
69
|
}
|
|
@@ -67,7 +71,7 @@ function processFile(filePath) {
|
|
|
67
71
|
function formatFileWithESLint(filePath) {
|
|
68
72
|
const command = `eslint "${filePath}" --fix`
|
|
69
73
|
|
|
70
|
-
exec(command, (error, stdout, stderr) => {
|
|
74
|
+
childProcess.exec(command, (error, stdout, stderr) => {
|
|
71
75
|
if (error) {
|
|
72
76
|
console.error(`Execution Error: ${error.message}`)
|
|
73
77
|
console.error(`Exit Code: ${error.code}`)
|
|
@@ -81,4 +85,9 @@ function formatFileWithESLint(filePath) {
|
|
|
81
85
|
})
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
|
|
88
|
+
// Only run if this file is executed directly (not imported)
|
|
89
|
+
if (fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
90
|
+
precompileComponents()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { precompileComponents, processDirectory, processFile, formatFileWithESLint }
|
package/scripts/prepush.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Copyright 2023 Comcast
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the Apache License, Version 2.0 (the License);
|
|
2
|
+
* Copyright 2025 Comcast Cable Communications Management, LLC
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
4
|
* you may not use this file except in compliance with the License.
|
|
9
5
|
* You may obtain a copy of the License at
|
|
10
6
|
*
|
|
@@ -15,6 +11,8 @@
|
|
|
15
11
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
12
|
* See the License for the specific language governing permissions and
|
|
17
13
|
* limitations under the License.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
18
16
|
*/
|
|
19
17
|
|
|
20
18
|
import { execSync } from 'child_process'
|
|
@@ -69,7 +67,6 @@ try {
|
|
|
69
67
|
// Run ESLint on the changed files
|
|
70
68
|
execSync(`npx eslint ${fileList.join(' ')}`, { stdio: 'inherit' })
|
|
71
69
|
console.log('Linting passed successfully!\n')
|
|
72
|
-
process.exit(0)
|
|
73
70
|
} catch (error) {
|
|
74
71
|
console.log('\n==========================================================================')
|
|
75
72
|
console.log('ESLint found issues in your code. Please fix them before pushing.')
|
|
@@ -79,3 +76,24 @@ try {
|
|
|
79
76
|
console.log('==========================================================================\n')
|
|
80
77
|
process.exit(1)
|
|
81
78
|
}
|
|
79
|
+
|
|
80
|
+
// By default, always run tests unless RUN_TEST=skip
|
|
81
|
+
const runTestsFlag = process.env.RUN_TEST || ''
|
|
82
|
+
|
|
83
|
+
if (runTestsFlag.toLowerCase() === 'skip') {
|
|
84
|
+
console.log('Skipping tests due to RUN_TEST=skip. Proceeding with push.')
|
|
85
|
+
process.exit(0)
|
|
86
|
+
} else {
|
|
87
|
+
// For any other value (including empty or unknown), run tests
|
|
88
|
+
try {
|
|
89
|
+
console.log('Running tests...\n')
|
|
90
|
+
execSync('npm run test', { stdio: 'inherit' })
|
|
91
|
+
console.log('Tests passed successfully!\n')
|
|
92
|
+
process.exit(0)
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.log('\n==========================================================================')
|
|
95
|
+
console.log('Some tests failed. Please fix them before pushing.')
|
|
96
|
+
console.log('==========================================================================\n')
|
|
97
|
+
process.exit(1)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -26,7 +26,9 @@ let currentId = null
|
|
|
26
26
|
let debounce = null
|
|
27
27
|
|
|
28
28
|
// Global default utterance options
|
|
29
|
-
let globalDefaultOptions = {
|
|
29
|
+
let globalDefaultOptions = {
|
|
30
|
+
enableUtteranceKeepAlive: !/android/i.test((window.navigator || {}).userAgent || ''),
|
|
31
|
+
}
|
|
30
32
|
|
|
31
33
|
const noopAnnouncement = {
|
|
32
34
|
then() {},
|
|
@@ -50,7 +52,6 @@ const toggle = (v) => {
|
|
|
50
52
|
|
|
51
53
|
const speak = (message, politeness = 'off', options = {}) => {
|
|
52
54
|
if (active === false) return noopAnnouncement
|
|
53
|
-
|
|
54
55
|
return addToQueue(message, politeness, false, options)
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -106,6 +107,8 @@ const addToQueue = (message, politeness, delay = false, options = {}) => {
|
|
|
106
107
|
return done
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
let currentResolveFn = null
|
|
111
|
+
|
|
109
112
|
const processQueue = async () => {
|
|
110
113
|
if (isProcessing === true || queue.length === 0) return
|
|
111
114
|
isProcessing = true
|
|
@@ -113,11 +116,13 @@ const processQueue = async () => {
|
|
|
113
116
|
const { message, resolveFn, delay, id, options = {} } = queue.shift()
|
|
114
117
|
|
|
115
118
|
currentId = id
|
|
119
|
+
currentResolveFn = resolveFn
|
|
116
120
|
|
|
117
121
|
if (delay) {
|
|
118
122
|
setTimeout(() => {
|
|
119
123
|
isProcessing = false
|
|
120
124
|
currentId = null
|
|
125
|
+
currentResolveFn = null
|
|
121
126
|
resolveFn('finished')
|
|
122
127
|
processQueue()
|
|
123
128
|
}, delay)
|
|
@@ -138,19 +143,23 @@ const processQueue = async () => {
|
|
|
138
143
|
Log.debug(`Announcer - finished speaking: "${message}" (id: ${id})`)
|
|
139
144
|
|
|
140
145
|
currentId = null
|
|
146
|
+
currentResolveFn = null
|
|
141
147
|
isProcessing = false
|
|
142
148
|
resolveFn('finished')
|
|
143
149
|
processQueue()
|
|
144
150
|
})
|
|
145
151
|
.catch((e) => {
|
|
146
|
-
currentId
|
|
147
|
-
|
|
152
|
+
if (id === currentId) {
|
|
153
|
+
currentId = null
|
|
154
|
+
currentResolveFn = null
|
|
155
|
+
isProcessing = false
|
|
156
|
+
}
|
|
148
157
|
Log.debug(`Announcer - error ("${e.error}") while speaking: "${message}" (id: ${id})`)
|
|
149
158
|
resolveFn(e.error)
|
|
150
159
|
processQueue()
|
|
151
160
|
})
|
|
152
161
|
debounce = null
|
|
153
|
-
},
|
|
162
|
+
}, 300)
|
|
154
163
|
}
|
|
155
164
|
}
|
|
156
165
|
|
|
@@ -158,13 +167,52 @@ const polite = (message, options = {}) => speak(message, 'polite', options)
|
|
|
158
167
|
|
|
159
168
|
const assertive = (message, options = {}) => speak(message, 'assertive', options)
|
|
160
169
|
|
|
170
|
+
// Clear debounce timer
|
|
171
|
+
const clearDebounceTimer = () => {
|
|
172
|
+
if (debounce !== null) {
|
|
173
|
+
clearTimeout(debounce)
|
|
174
|
+
debounce = null
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
161
178
|
const stop = () => {
|
|
179
|
+
// Clear debounce timer if speech hasn't started yet
|
|
180
|
+
clearDebounceTimer()
|
|
181
|
+
|
|
182
|
+
// Always cancel speech synthesis to ensure clean state
|
|
162
183
|
speechSynthesis.cancel()
|
|
184
|
+
|
|
185
|
+
// Store resolve function before resetting state
|
|
186
|
+
const resolveFn = currentResolveFn
|
|
187
|
+
|
|
188
|
+
// Reset state
|
|
189
|
+
currentId = null
|
|
190
|
+
currentResolveFn = null
|
|
191
|
+
isProcessing = false
|
|
192
|
+
|
|
193
|
+
// Resolve promise if there was an active utterance
|
|
194
|
+
if (resolveFn !== null) {
|
|
195
|
+
resolveFn('interrupted')
|
|
196
|
+
}
|
|
163
197
|
}
|
|
164
198
|
|
|
165
199
|
const clear = () => {
|
|
200
|
+
// Clear debounce timer
|
|
201
|
+
clearDebounceTimer()
|
|
202
|
+
|
|
203
|
+
// Resolve all pending items in queue
|
|
204
|
+
while (queue.length > 0) {
|
|
205
|
+
const item = queue.shift()
|
|
206
|
+
if (item.resolveFn) {
|
|
207
|
+
Log.debug(`Announcer - clearing queued item: "${item.message}" (id: ${item.id})`)
|
|
208
|
+
item.resolveFn('cleared')
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Reset state
|
|
213
|
+
currentId = null
|
|
214
|
+
currentResolveFn = null
|
|
166
215
|
isProcessing = false
|
|
167
|
-
queue.length = 0
|
|
168
216
|
}
|
|
169
217
|
|
|
170
218
|
const configure = (options = {}) => {
|