Skip to content

Commit 7bb6b32

Browse files
Merge pull request #343 from rdkcentral/dev
Release of v5.1.0
2 parents 2b25d37 + 1067b2d commit 7bb6b32

29 files changed

+4526
-55
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,9 @@ node_modules
33
.idea
44
support/lib
55
support/polyfills
6+
7+
# Prevent `tsc` generated typescript types from ended up in the repo
8+
/types
9+
10+
# Type Docs
11+
/typedocs

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v5.1.0
4+
5+
- Typescript support
6+
37
## v5.0.1
48

59
*22 aug 2022*

docs/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v5.1.0
4+
5+
- Typescript support
6+
37
## v5.0.1
48

59
*22 aug 2022*

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ The available Lightning SDK plugins are, in alphabetical order:
3535
* [Utils](plugins/utils.md)
3636
* [VersionLabel](plugins/versionlabel.md)
3737
* [VideoPlayer](plugins/videoplayer.md)
38+
* [TypeScript Support](typescript.md)
3839
<!---TOC_end--->

docs/package.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
{
22
"name": "@lightningjs/sdk",
3-
"version": "5.0.1",
3+
"version": "5.1.0",
44
"license": "Apache-2.0",
5+
"types": "index.d.ts",
56
"scripts": {
67
"postinstall": "node ./scripts/postinstall.js",
78
"lint": "eslint '**/*.js'",
8-
"release": "npm publish --access public"
9+
"release": "npm publish --access public",
10+
"typedoc": "typedoc --tsconfig tsconfig.typedoc.json",
11+
"tsd": "tsd"
912
},
1013
"lint-staged": {
1114
"*.js": [
@@ -22,7 +25,7 @@
2225
},
2326
"dependencies": {
2427
"@babel/polyfill": "^7.11.5",
25-
"@lightningjs/core": "*",
28+
"@lightningjs/core": "^2.7.0",
2629
"@metrological/sdk": "github:metrological/metrological-sdk",
2730
"@michieljs/execute-as-promise": "^1.0.0",
2831
"deepmerge": "^4.2.2",
@@ -44,7 +47,9 @@
4447
"lint-staged": "^10.4.0",
4548
"prettier": "^1.19.1",
4649
"rollup": "^1.32.1",
47-
"rollup-plugin-babel": "^4.4.0"
50+
"rollup-plugin-babel": "^4.4.0",
51+
"tsd": "^0.22.0",
52+
"typedoc": "^0.23.9"
4853
},
4954
"repository": {
5055
"type": "git",

docs/plugins/router/pagetransitions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Page Transitions
22

3-
If you navigate from one page to another, the default behavior is that the `[visibility](../../../lightning-core-reference/RenderEngine/Elements/Rendering.md#Visibility)` property of the new (incoming) Page is set to `true` and that this same property of the old (outgoing) Page is set to `false`.
3+
If you navigate from one page to another, the default behavior is that the [`visibility`](../../../lightning-core-reference/RenderEngine/Elements/Rendering.md#Visibility) property of the new (incoming) Page is set to `true` and that this same property of the old (outgoing) Page is set to `false`.
44

55
You can *override* this simple 'hide and show' behavior using the Router plugin. By adding a `pageTransition` method to your Page component, you can apply [default](#Default-Page-Transitions) or [custom](#Custom-Page-Transitions) page transitions.
66

docs/typescript.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# TypeScript Support
2+
3+
As of version 5.1.0, Lightning SDK comes bundled with type definitions and in-code documentation which allow you to build Lightning apps in [TypeScript](https://www.typescriptlang.org/). The following documentation assumes to an extent that you are already familiar with the basics of writting a Lightning app in JavaScript, but even if you have no experience at all with Lightning, you may find the tips below as well as the Lightning CLI `lng create` boilerplate (coming soon) and the types/documentation available now in your IDE by using TypeScript enough to get started.
4+
5+
Currently, Lightning SDK includes extensive type definitions for the following plugins:
6+
- [Image](plugins/image.md)
7+
- [Router](plugins/router/index.md)
8+
- [Lightning](plugins/lightning.md)
9+
- Requires Lightning Core version 2.7.0
10+
- [Utils](plugins/utils.md)
11+
12+
All other plugins are stubbed out as the `any` type, so they will still work as they have been without type checking.
13+
14+
If you haven't already, read the [Lightning Core TypeScript Documentation](../lightning-core-reference/TypeScript/index.md) for extensive use guidelines. The rest of this documentation page will focus solely on things you need to know to use the Lightning SDK with TypeScript.
15+
16+
TypeScript compilation is supported out of the box by Lightning CLI as of version [v2.8.0](https://github.com/rdkcentral/Lightning-CLI/blob/master/CHANGELOG.md#v280).
17+
18+
## Requirements
19+
20+
- Minimum TypeScript version: [4.7.3](https://github.com/microsoft/TypeScript/releases/tag/v4.7.3) (as tested)
21+
- Minimum Lightning CLI version: [2.8.0](https://github.com/rdkcentral/Lightning-CLI/blob/master/CHANGELOG.md#v280)
22+
- If using Lightning CLI.
23+
24+
## Router Pages (IsPage)
25+
26+
A Router Page can be any Lightning Component. But because there are some special properties / features (`widgets`, `params`, `pageTransition`, `historyState`, etc) available on Pages that aren't available on other Components, we need need a mechanism to tell TypeScript that a Component is a Router Page. The Lightning SDK adds a new property that can be configured in a Component's [Type Config](../lightning-core-reference/TypeScript/TypeConfigs.md) called `IsPage`.
27+
28+
```ts
29+
interface MyPageTypeConfig extends Lightning.Component.TypeConfig {
30+
IsPage: true;
31+
}
32+
33+
class MyPage extends Lightning.Component</*...*/, MyPageTypeConfig> {
34+
35+
override pageTransition() {
36+
return 'left';
37+
}
38+
39+
override _onUrlParams() {
40+
// These properties are now available:
41+
this.params;
42+
this.widgets; // See CustomWidgets augmentation
43+
this[Router.symbols.hash];
44+
this[Router.symbols.route];
45+
}
46+
}
47+
```
48+
49+
## Augmentation
50+
51+
There are certain global type structures provided by Lightning SDK that your app may need/want to add on to. TypeScript allows such add-ons via [Declaration Merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) and [Module Augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation).
52+
53+
The following are the TypeScript interfaces exported by Lightning SDK that are designed for augmentation. You may find need to augment other available interfaces. In this event, please let us know what interfaces you are augmenting so we may add use guidelines to this page (or submit a [PR](https://github.com/rdkcentral/Lightning-SDK/pulls)!).
54+
55+
### Router.CustomWidgets
56+
57+
If you use the [Widgets](plugins/router/widgets.md) feature of the Router, you can augment this interface with all of the Widgets defined in your application in order to enable strong type-checking, and IDE assitance when interacting with them.
58+
59+
#### Default Behavior
60+
61+
By default, if this interface is not augmented, Widgets still can be used, however in a much looser typed way.
62+
63+
The `widgets` object that is available on any Router Page (See Router Pages above) will accept any key and the value type will always be unknown. This requires you to explicitly assert the Component type of the widget:
64+
```ts
65+
// This statement's type is `unknown`
66+
this.widgets.anythingwillwork;
67+
68+
// You must explicitly assert in order to access methods/etc from it
69+
(this.widgets.anythingwillwork as MyWidgetComponent).doSomething();
70+
```
71+
72+
The `Router.focusWidget()` method will accept any string:
73+
```ts
74+
Router.focusWidget('AnythingWillWork');
75+
```
76+
77+
It will be the responsibility of the developer to ensure the right casing is used in each situation.
78+
79+
#### Augmented Behavior
80+
81+
If this interface is augmented, only the specifically defined widgets will be allowed in the above situations.
82+
83+
When augmenting this interface, the key name is the PascalCase 'ref' key name of the widget and the value type is the `typeof` the Widget's Component.
84+
85+
Example:
86+
```ts
87+
import '@lightningjs/sdk'
88+
89+
declare module '@lightningjs/sdk' {
90+
namespace Router {
91+
interface CustomWidgets {
92+
Menu: typeof MenuComponent;
93+
Overlay: typeof OverlayComponent;
94+
}
95+
}
96+
}
97+
```
98+
99+
By augmenting the above, you will now have strong type checking and IDE assistance when interacting with Widgets.
100+
101+
The `widgets` object only allows the specific Widget names (properly lower-cased) that were augmented, and their values are typed with the defined Widget Component instance types:
102+
```ts
103+
// TypeScript only allows 'menu' and 'overlay' in their proper lower-case forms
104+
this.widgets.menu;
105+
this.widgets.overlay;
106+
107+
// They are typed as their Component instance types, so you may call methods directly on them
108+
this.widgets.menu.selectItem(0);
109+
this.widgets.overlay.animate(/* ... */);
110+
111+
// Widget names not included in the augmentation will now cause errors
112+
// @ts-expect-error
113+
this.widgets.anythingwillnotwork;
114+
```
115+
116+
The `Router.focusWidgets()` method only allows the specific Widget names (properly PascalCased):
117+
```ts
118+
// TypeScript only allows 'Menu' or 'Overlay' in the proper casing.
119+
Router.focusWidget('Menu');
120+
Router.focusWidget('Overlay');
121+
122+
// @ts-expect-error
123+
Router.focusWidget('AnythingWillNotWork');
124+
```
125+
126+
### Application.AppData
127+
128+
When `Launch()` is called to launch your application, an optional last parameter `appData` may be passed in. At any point later your application may access this data by importing `AppData` from the SDK.
129+
130+
The shape of the object you pass into `Launch()` and the run-time variable you can import is defined by the `Application.AppData` interface. By default, this interface is empty any non-null is allowed.
131+
132+
If you'd like to define this structure explicitly, you can augment the interface.
133+
134+
Example:
135+
```ts
136+
import '@lightningjs/sdk'
137+
138+
declare module '@lightningjs/sdk' {
139+
namespace Application {
140+
interface AppData {
141+
myParam1: string;
142+
myParam2: number;
143+
}
144+
}
145+
}
146+
```
147+
148+
By augmenting the above, the structure will be enforced while calling `Launch()` and when importing `AppData` in any part of your application:
149+
150+
**index.ts**
151+
```ts
152+
Launch(App, appSettings, platformSettings, {
153+
myParam1: 'abc',
154+
myParam2: 123
155+
});
156+
```
157+
158+
**AnotherFile.ts**
159+
```ts
160+
import { AppData } from '@lightningjs/sdk';
161+
162+
console.log(AppData.myParam1);
163+
console.log(AppData.myParam2);
164+
```

0 commit comments

Comments
 (0)