;
}
export interface RouterConfig {
/**
* Register hooks for the router
*/
hooks?: RouterHooks & ComponentContext
,
/**
* Routes definition
*
* @example
*
* ```js
* routes: [
* { path: '/', component: Home },
* { path: '/details', component: Details },
* { path: '/account', component: Account },
* ]
* ```
*/
routes?: Route[]
/**
* Enable or disable RouterView history navigation on Back input
*
* @default true
*
* @remarks
* This is an app-wide setting that affects all RouterView instances in your application.
* The router state is global and shared across all router instances.
*
* @example
* ```js
* router: {
* backNavigation: false, // Disable automatic back navigation
* routes: [...]
* }
* ```
*/
backNavigation?: boolean
}
export type ApplicationConfig
= Omit<
ComponentConfig
,
'hooks' | 'methods' | 'input' | 'computed' | 'watch' | 'state' | 'router' | 'routes'
> & {
hooks?: Hooks & ApplicationContext
methods?: M & ApplicationContext
input?: Input & ApplicationContext
computed?: C & ApplicationContext
watch?: W & ApplicationContext
state?: (this: Readonly> & ApplicationBase) => S
} & (
| {
/**
* Router Configuration
*/
router?: RouterConfig
routes?: never
}
| {
router?: never
/**
* Routes definition
*
* @example
*
* ```js
* routes: [
* { path: '/', component: Home },
* { path: '/details', component: Details },
* { path: '/account', component: Account },
* ]
* ```
*/
routes?: Route[]
}
)
export interface Transition {
/**
* Name of the prop to transition (i.e. 'x', 'y', 'alpha', 'color')
*/
prop: string,
/**
* Value the prop should transition to (i.e. 0, 100, '#223388')
*/
value: any,
/**
* Duration of the transition in milliseconds, defaults to 300
*/
duration?: number,
/**
* Easing function to apply to the transition
*/
easing?: string,
/**
* Delay before the transition starts in milliseconds
*/
delay?: number
}
export interface Before {
/**
* Name of the prop to set before the transition starts
*/
prop: string,
/**
* Value the prop to set before the transition starts
*/
value: any,
}
export interface RouteTransition {
/**
* Setting or Array of Settings before new view enters into the router view
*/
before: Before | Before[],
/**
* Transition or Array of Transitions for new view to enters into the router view
*/
in: Transition | Transition[],
/**
* Transition or Array of Transitions for old view to leave the router view
*/
out: Transition | Transition[],
}
export type RouteTransitionFunction = (previousRoute: Route, currentRoute: Route) => RequireAtLeastOne
export interface RouteAnnounce {
/**
* Message to be announced
*/
message: String,
/**
* Politeness level
*
* Defaults to 'off'
*/
politeness?: 'off' | 'polite' | 'assertive'
}
export type RequireAtLeastOne = {
[K in keyof T]-?: Required> & Partial>>
}[keyof T]
export interface RouteHooks {
before?: (to: Route, from: Route) => string | Route | void | boolean | Promise;
after?: (to: Route, from: Route) => string | Route | void | boolean | Promise;
}
export type Route = {
/**
* URI path for the route
*/
path: string,
/**
* Component to load when activating the route
*/
component: ComponentFactory // todo: or promise returning a component instance
/**
* Transition configuration for the route
*/
transition?: RequireAtLeastOne | RouteTransitionFunction,
/**
* Extra route options
*/
options?: RouteOptions
/**
* Message to be announced when visiting the route (often used for accessibility purposes)
*
* Can be either a `String` with the message or an object that defines the message and the
* politeness level
*/
announce?: String | RouteAnnounce
/**
* Register hooks for the route
*/
hooks?: RouteHooks
/**
* Route path parameters
*/
readonly params?: {
[key: string]: string | number
}
/**
* Allows for attaching custom data to a route, either hardcoded in the
* route definition or asigned to the route object in a before hook
*
* Will be merged with the route params and navigation data and passed as
* props into the route component
*/
data?: {
[key: string]: any
}
/**
* Metadata attached to the route, can be used to add any arbitrary
* data to a route such as `auth: true/false`, a route ID or route description
* Note that this data is not reactive and not passed as props to components.
* The metadata is available in the router `before` or `beforeEach` hooks
*
*/
meta?: {
[key: string]: any
}
}
type ComponentFactory = () => void
// Launch Related
type DebugLevel = 0 | 1 | 2
type LogTypes = 'info' | 'warn' | 'error' | 'debug'
interface WebFont {
/**
* Name of the font family
*/
family: string,
/**
* Type of font (web)
*/
type: 'web',
/**
* Location to the font file (i.e. `/fonts/OpenSans-Medium.ttf`)
*/
file: string
}
interface SdfFontWithFile {
/**
* Location of the font file (i.e. `/fonts/OpenSans-Medium.ttf`)
*/
file: string
}
interface SdfFontWithPngJson {
/**
* Location of the font map (i.e. `'/fonts/Lato-Regular.msdf.json'`)
*/
json: string,
/**
* Location of the font png (i.e. `'/fonts/Lato-Regular.msdf.png'`)
*/
png: string
}
type SdfFont = {
/**
* Name of the font family
*/
family: string,
/**
* Type of font (web)
*/
type: 'msdf' | 'sdf',
} & (SdfFontWithFile | SdfFontWithPngJson)
type Font = WebFont | SdfFont
type ShaderEffect = {
name: string,
type: RendererShaderEffect
}
type Shader = {
name: string,
type: WebGlShaderType | CanvasShaderType
}
type ScreenResolutions = 'hd' | '720p' | 720 | 'fhd' | 'fullhd' | '1080p' | 1080 | '4k' | '2160p' | 2160
type RenderQualities = 'low' | 'medium' | 'high' | 'retina' | number
type ReactivityModes = 'Proxy' | 'defineProperty'
type RenderModes = 'webgl' | 'canvas'
interface Platform {
/**
* Target used for keyboard and pointer input listeners.
*/
input?: EventTarget | any,
/**
* Target used for viewport-level listeners such as resize, scroll, and hashchange.
*/
viewport?: EventTarget | any,
/**
* Dispatch an event through the platform's event system.
*/
dispatchEvent?: (event: any) => boolean | void,
/**
* Persistent key/value storage API.
*/
localStorage?: Storage | any,
/**
* Read the platform cookie string.
*/
getCookie?: () => string,
/**
* Write a cookie string.
*/
setCookie?: (value: string) => void,
/**
* Navigate back in the platform history, when available.
*/
historyBack?: () => void,
/**
* Current viewport/screen height.
*/
screenHeight?: number,
/**
* Available hardware concurrency.
*/
hardwareConcurrency?: number,
/**
* User agent string for platform-specific defaults.
*/
userAgent?: string,
/**
* KeyboardEvent constructor used for event creation and type checks.
*/
KeyboardEvent?: typeof KeyboardEvent | any,
/**
* Check whether an object should be treated as a keyboard event.
*/
isKeyboardEvent?: (event: any) => boolean,
/**
* Create a keyboard event for the current platform.
*/
createKeyboardEvent?: (type: string, init?: KeyboardEventInit | any) => any,
/**
* Platform-specific announcer driver used instead of the default Web Speech driver.
*/
announcer?: AnnouncerDriver,
/**
* Monotonic timestamp provider used for input throttling.
*/
now?: () => number,
[key: string]: any,
}
/**
* Settings
*
* Launcher function that sets up the Lightning renderer and instantiates
* the Blits App
*/
export interface Settings {
/**
* Start the performance profiler when the App launches
*
* The profiler is also available on `globalThis.__BLITS_PROFILER__`, so it
* can be started and stopped from the devtools console
*
* @default false
*/
profiler?: boolean,
/**
* Width of the Application
*/
w?: number,
/**
* Height of the Application
*/
h?: number,
/**
* Whether to enable multithreaded
*/
multithreaded?: boolean,
/**
* Debug level for console log messages
*/
debugLevel?: DebugLevel | LogTypes[],
/**
* Fonts to be used in the Application
*/
fonts?: Font[],
/**
* Shaders to be used in the application
*/
shaders?: Shader[],
/**
* Default font family to use in the Application when no font attribute is specified
* on a Text-component
*
* The default font must be registered in the `fonts` array in the settings.
*
* Defaults to `sans-serif` font family, which is the default of the Lightning Renderer
*/
defaultFont?: string,
/**
* Custom keymapping
*/
keymap?: object,
/**
* Mode of reactivity (`Proxy` or `defineProperty`)
*/
reactivityMode?: ReactivityModes,
/**
* Screen resolution of the device, defining the pixelRatio used to convert dimensions
* and positions in the App code to the actual device logical coordinates
*
* If not supplied, Blits will try to autodetect the device screen resolution. Otherwise
* the exact dimensions and positions used the app code are used.
*
* Note: If the option `pixelRatio` is specified in the Settings object, this value will take presedence
* over the screen resolution setting.
*
* Currently 3 screen resolutions are supported, which can be defined with different alias values:
*
* For 720x1280 (1px = 0.66666667px)
* - hd
* - 720p
* - 720
*
* For 1080x1920 (1px = 1px)
* - fhd
* - fullhd
* - 1080p
* - 1080
*
* For 2160x3840 (1px = 2px)
* - 4k
* - 2160p
* - 2160
*/
screenResolution?: ScreenResolutions,
/**
* Controls the quality of the rendered App.
*
* Setting a lower quality leads to less detail on screen, but can positively affect overall
* performance and smoothness of the App (i.e. a higher FPS).
*
* The render quality can be one of the following presets:
*
* - `low` => 66% quality
* - `medium` => 85% quality
* - `high` => 100% quality
* - `retina` => 200% quality
*
* It's also possible to provide a custom value as a (decimal) number:
*
* - `0.2` => 20% quality
* - `1.5` => 150% quality
*
* Defaults to 1 (high quality) when not specified
*/
renderQuality?: RenderQualities,
/**
* Custom pixel ratio of the device used to convert dimensions
* and positions in the App code to the actual device logical coordinates
*
* Takes presedence over the `screenResolution` setting
*
* Defaults to 1 if not specified
*/
pixelRatio?: number
/**
* Interval in milliseconds to receive FPS updates
*
* @remarks
* If set to `0`, FPS updates will be disabled.
*
* @defaultValue `1000` (disabled)
*/
fpsInterval?: number
/**
* Maximum number of web workers to spin up simultaneously for offloading functionality such
* as image loading to separate threads (when supported by the browser)
*
* If not specified defaults to the number of logical processers available on the device, as reported by
* `navigator.hardwareConcurrency`, with a maximum of 2. If `navigator.hardwareConcurrency` is
* not supported the default value will be 2
*/
webWorkersLimit?: number
/**
* Background color of the canvas (also known as the clearColor)
*
* Can be a color name (red, blue, silver), a hexadecimal color (`#000000`, `#ccc`),
* or a color number in rgba order (`0xff0033ff`)
*
* Defauls to transparent (`0x00000000`)
*
*/
canvasColor?: string,
/**
* Enable inspector
*
* Enables the inspector tool for debugging and inspecting the application, the node tree
* will be replicated in the DOM and can be inspected using the browser's developer tools
*
* Defaults to `false`
*/
inspector?: boolean,
/**
* Add an extra margin to the viewport for earlier pre-loading of elements and components
*
* By default the Lightning renderer, only renders elements that are inside the defined viewport.
* Everything outside of these bounds is removed from the render tree.
*
* With the viewportMargin you have the option to _virtually_ increase the viewport area,
* to expedite the pre-loading of elements and / or delay the unloading of elements depending
* on their position in the (virtual) viewport
*
* The margin can be specified in 4 directions by defining an array [top, right, bottom, left],
* or as a single number which is then applied to all 4 directions equally.
*
* Defaults to `0`
*/
viewportMargin?: number | [number, number, number, number],
/**
* Configures the gpu memory settings used by the renderer
*/
gpuMemory?: {
/**
* Maximum GPU memory threshold (in `mb`) after which
* the renderer will immediately start cleaning up textures to free
* up graphical memory
*
* When setting to `0`, texture memory management is disabled
*
* @default `200`
*/
max?: number,
/**
* Target threshold of GPU memory usage, defined as a fraction of
* the max threshold. The renderer will attempt to keep memory
* usage below this target by cleaning up non-renderable textures
*
* @default `0.8`
*/
target?: number,
/**
* Interval at which regular texture cleanups occur (in `ms`)
*
* @default `5000`
*/
cleanupInterval?: number,
/**
* Baseline GPU memory usage of the App (in `mb`), without rendering any
* textures. This value will be used as a basis when calculating
* the total memory usage towards the max and target memory
* usage
*
* @default `25`
*/
baseline?: number,
/**
* Whether or not the max threshold should be considered
* as a strict number that can not be exceeded in any way
*
* When set to `true`, new textures won't be created when the
* max threshold has been reached, until agressive texture cleanup
* has brought the memory back down
*
* @default false
*/
strict?: boolean,
},
/**
* Defines which mode the renderer should operate in: `webgl` or `canvas`
*
* SDF fonts are not supported in _canvas_ renderMode. Instead, _web_ fonts should
* be used. Also note that Canvas2d rendering doesnt support the use of shaders.
*
* Defaults to `webgl`
*/
renderMode?: RenderModes,
/**
* The time, in milliseconds, after which Blits considers a key press a _hold_ key press
*
* During a hold key press the focus delegation behaviour is different: when scrolling
* through a long list, focus is not handed over to each individual list item, creating a
* smoother experience
*
* Defaults to `50` (ms)
*/
holdTimeout?: number,
/**
* Input throttle time in milliseconds to prevent rapid successive inputs
*
* Within the throttle window, only one input will be processed immediately.
* Subsequent inputs _of the same key_ are ignored until the scheduled input is processed.
*
* Pressing a different key will be processed immediately.
*
* Set to `0` to disable input throttling.
*
* Defaults to `0` (disabled)
*/
inputThrottle?: number,
/**
* Custom canvas object used to render the App to.
*
* When not provided, the Lightning renderer will create a
* new Canvas element and inject it into the DOM
*/
canvas?: HTMLCanvasElement,
/**
* The maximum amount of time the renderer is allowed to process textures in a
* single frame. If the processing time exceeds this limit, the renderer will
* skip processing the remaining textures and continue rendering the frame.
*
* Defaults to `10`
*/
textureProcessingTimeLimit?: number,
/**
* Advanced renderer settings to override Blits launch settings, or configure
* settings that are not officially exposed in Blits yet
*
* @important if you dont know what you're doing here, you probably shouldn't be doing it!
*/
advanced?: Partial,
/**
* Whether or not the announcer should be activated on initialization
*
* When set to `false` announcements via `this.$annoucer.speak()` will
* be ignored. When set to `true` announcement will be spoken out via the
* text to speech API
*
* Announcer can be enabled / disabled run time as well via:
* - this.$announcer.enable()
* - this.$announcer.disable()
* - this.$announcer.toggle(true/false)
*
* @default false
*/
announcer?: boolean,
/**
* Global default utterance options for the announcer.
*
* These options will be applied to all announcements unless overridden
* by per-call options passed to `speak()`, `polite()`, or `assertive()`.
*
* @example
* ```js
* announcerOptions: {
* rate: 1.0,
* pitch: 1.0,
* lang: 'en-US',
* volume: 1.0
* }
* ```
*/
announcerOptions?: AnnouncerUtteranceOptions,
/**
* Enable mouse support (hover and click-to-focus).
*
* When set to `true`, pointer movement over the canvas updates hover state on components
* and click dispatches focus and Enter key input to the component under the cursor.
* When set to `false`, no mouse or pointer listeners are registered.
*
* @default false
*/
enableMouse?: boolean,
/**
* Minimum time in milliseconds between two pointer moves that are processed for hover.
*
* Moves arriving sooner are dropped, not delayed.
*
* @default 100
*/
mouseMoveThrottle?: number,
/**
* Maximum FPS at which the App will be rendered
*
* Lowering the maximum FPS value can improve the overall experience on lower end devices.
* Targetting a lower FPS may gives the CPU more time to construct each frame leading to a smoother rendering.
*
* Defaults to `0` which means no maximum
*/
maxFPS?: number,
/**
* Custom platform layer to be used by the App.
*
* Allows replacing platform capabilities such as input targets, storage,
* keyboard event constructors, and speech APIs.
* A callback receives Blits' browser defaults and should return the platform overrides.
*/
platform?: (defaults: Platform) => Partial,
/**
* Custom platform layer to be used by the renderer.
*
* For renderer-specific platform implementations. Passing a renderer platform
* through `platform` is deprecated.
*/
rendererPlatform?: RendererMainSettings['platform']
}
interface State {
[key: string]: any
}
interface Methods {
[key: string]: any
}
interface Watch {
[key: string]: any
}
interface Computed {
[key: string]: () => any
}
interface Plugin {
/**
* Name of the plugin. The plugin will be accessible on each Component's
* `this` scope under this name, prefixed with a `$` (i.e. myplugin => `this.$myplugin`)
*/
name: string,
/**
* Singleton function that will be used to instantiate the plugin.
* Should do all necessary setup and ideally return an object with
* properties or methods that can be used in the App
*/
plugin: (options?: any) => any
}
export interface ProfilerEntry {
/**
* Number of times the measurement was recorded
*/
calls: number,
/**
* Total time spent, in milliseconds
*/
totalMs: number,
/**
* Slowest single measurement, in milliseconds
*/
maxMs: number,
/**
* Average time per call, in milliseconds
*/
averageMs: number
}
export interface ProfilerFrameSummary {
medianMs: number,
p95Ms: number,
p99Ms: number,
maxMs: number
}
export interface ProfilerFrameLabel {
calls: number,
totalMs: number
}
export interface ProfilerFrameSnapshot {
frameCount: number,
retainedFrameLimit: number,
frameInterval: ProfilerFrameSummary,
instrumentedTime: ProfilerFrameSummary,
slowFramePercent: number,
slowestFrames: Array<{
intervalMs: number,
instrumentedMs: number,
labels: Record
}>,
labels: Record
}
export interface ProfilerSnapshot {
measurements: Record,
frames: ProfilerFrameSnapshot
}
export interface Profiler {
/**
* Marks the start of a measurement
*/
mark(name: string): void,
/**
* Ends the most recent measurement started with the same name
*/
markEnd(name: string): void,
/**
* Clears previously collected measurements and starts recording
*/
start(options?: { frames?: boolean, maxFrames?: number, targetFps?: number }): void,
/**
* Stops recording and returns the collected measurements
*/
stop(): ProfilerSnapshot,
/**
* Clears all collected measurements, without changing the enabled state
*/
reset(): void,
/**
* Returns the measurements collected so far
*/
snapshot(): ProfilerSnapshot,
/**
* Returns frame-oriented results collected by default or with start({ frames: true })
*/
frameSnapshot(): ProfilerFrameSnapshot,
/**
* Logs marker and frame results as console tables and returns the combined snapshot
*/
report(): ProfilerSnapshot,
/**
* Whether the profiler is currently recording
*/
readonly enabled: boolean
}
/**
* Blits App Framework
*/
export interface Blits {
/**
* Blits Application
* @param {ApplicationConfig} config - Application Configuration object
*/
Application<
P extends Props,
S extends State,
M extends Methods,
C extends Computed = Record,
W extends Watch>(config: ApplicationConfig) : ComponentFactory
/**
* Blits Component
* @param {string} name - The name of the Component
* @param {ComponentConfig} config - Component Configuration object
*/
Component<
P extends Props,
S extends State,
M extends Methods,
C extends Computed = Record,
W extends Watch>(name: string, config: ComponentConfig) : ComponentFactory
/**
* Blits Launch
*/
Launch(App: ComponentFactory, target: HTMLElement | String, settings?: Settings) : void
/**
* Blits Plugin
*
* @param plugin
* Plugin object or singleton function that will be used to instantiate the
* plugin. Should do all necessary setup and ideally return an object with
* properties or methods that can be used in the App
*
* @param nameOrOptions
* Name of the plugin or options object, to be passed into the plugin instantiation.
*
* When passing a string, the value will be used as **name** of the plugin. The plugin
* will be accessible on each Component's `this` scope under this name, prefixed with a `$`
* (i.e. myplugin => `this.$myplugin`)
*
* Passing a name is **required** when `plugin` argument is a singleton function
*
* When passing an object, the value will be considered to be an `options` object.
* The options object will be passed into the plugin instantiation method. Can
* be used to set default values
*
* @param options
* Object with options to be passed into the plugin instantiation method.
* Can be used to set default values
*/
Plugin(plugin: Plugin | ((options?: any) => any), nameOrOptions?: string | object , options?: object) : void
}
const Blits: Blits;
export default Blits;
}