@stencil/core
Version:
A Compiler for Web Components and Progressive Web Apps
1,632 lines (1,631 loc) • 72.7 kB
TypeScript
import { result } from './utils';
import type { InMemoryFileSystem } from '../compiler/sys/in-memory-fs';
import type { CPSerializable } from './child_process';
import type { BuildEvents, BuildLog, BuildResultsComponentGraph, CompilerBuildResults, CompilerFsStats, CompilerRequestResponse, CompilerSystem, Config, CopyResults, DevServerConfig, DevServerEditor, Diagnostic, Logger, LoggerLineUpdater, LoggerTimeSpan, OptimizeCssInput, OptimizeCssOutput, OutputTarget, OutputTargetWww, PageReloadStrategy, PrerenderConfig, StyleDoc, TaskCommand, ValidatedConfig } from './stencil-public-compiler';
import type { JsonDocMethodParameter } from './stencil-public-docs';
import type { ComponentInterface, ListenTargetOptions, VNode } from './stencil-public-runtime';
export interface DocData {
hostIds: number;
rootLevelIds: number;
staticComponents: Set<string>;
}
export type StencilDocument = Document & {
_stencilDocData: DocData;
};
export interface SourceMap {
file: string;
mappings: string;
names: string[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: number;
}
export interface PrintLine {
lineIndex: number;
lineNumber: number;
text: string;
errorCharStart: number;
errorLength?: number;
}
export interface AssetsMeta {
absolutePath: string;
cmpRelativePath: string;
originalComponentPath: string;
}
export interface ParsedImport {
importPath: string;
basename: string;
ext: string;
data: ImportData;
}
export interface ImportData {
tag?: string;
encapsulation?: string;
mode?: string;
}
export interface SerializeImportData extends ImportData {
importeePath: string;
importerPath?: string;
}
export interface BuildFeatures {
style: boolean;
mode: boolean;
formAssociated: boolean;
shadowDom: boolean;
shadowDelegatesFocus: boolean;
scoped: boolean;
/**
* Every component has a render function
*/
allRenderFn: boolean;
/**
* At least one component has a render function
*/
hasRenderFn: boolean;
vdomRender: boolean;
vdomAttribute: boolean;
vdomClass: boolean;
vdomFunctional: boolean;
vdomKey: boolean;
vdomListener: boolean;
vdomPropOrAttr: boolean;
vdomRef: boolean;
vdomStyle: boolean;
vdomText: boolean;
vdomXlink: boolean;
slotRelocation: boolean;
slot: boolean;
svg: boolean;
element: boolean;
event: boolean;
hostListener: boolean;
hostListenerTargetWindow: boolean;
hostListenerTargetDocument: boolean;
hostListenerTargetBody: boolean;
/**
* @deprecated Prevented from new apps, but left in for older collections
*/
hostListenerTargetParent: boolean;
hostListenerTarget: boolean;
method: boolean;
prop: boolean;
propMutable: boolean;
state: boolean;
watchCallback: boolean;
member: boolean;
updatable: boolean;
propBoolean: boolean;
propNumber: boolean;
propString: boolean;
lifecycle: boolean;
cmpDidLoad: boolean;
cmpShouldUpdate: boolean;
cmpWillLoad: boolean;
cmpDidUpdate: boolean;
cmpWillUpdate: boolean;
cmpWillRender: boolean;
cmpDidRender: boolean;
cmpDidUnload: boolean;
connectedCallback: boolean;
disconnectedCallback: boolean;
asyncLoading: boolean;
observeAttribute: boolean;
reflect: boolean;
taskQueue: boolean;
}
export interface BuildConditionals extends Partial<BuildFeatures> {
hotModuleReplacement?: boolean;
isDebug?: boolean;
isTesting?: boolean;
isDev?: boolean;
devTools?: boolean;
invisiblePrehydration?: boolean;
hydrateServerSide?: boolean;
hydrateClientSide?: boolean;
lifecycleDOMEvents?: boolean;
cssAnnotations?: boolean;
lazyLoad?: boolean;
profile?: boolean;
constructableCSS?: boolean;
appendChildSlotFix?: boolean;
slotChildNodesFix?: boolean;
scopedSlotTextContentFix?: boolean;
cloneNodeFix?: boolean;
hydratedAttribute?: boolean;
hydratedClass?: boolean;
hydratedSelectorName?: string;
initializeNextTick?: boolean;
scriptDataOpts?: boolean;
shadowDomShim?: boolean;
asyncQueue?: boolean;
transformTagName?: boolean;
attachStyles?: boolean;
experimentalSlotFixes?: boolean;
experimentalScopedSlotChanges?: boolean;
}
export type ModuleFormat = 'amd' | 'cjs' | 'es' | 'iife' | 'system' | 'umd' | 'commonjs' | 'esm' | 'module' | 'systemjs';
export interface RollupResultModule {
id: string;
}
export interface RollupResults {
modules: RollupResultModule[];
}
export interface UpdatedLazyBuildCtx {
name: 'esm-browser' | 'esm' | 'cjs' | 'system';
buildCtx: BuildCtx;
}
export interface BuildCtx {
buildId: number;
buildResults: CompilerBuildResults;
buildStats?: result.Result<CompilerBuildStats, {
diagnostics: Diagnostic[];
}>;
buildMessages: string[];
bundleBuildCount: number;
collections: CollectionCompilerMeta[];
compilerCtx: CompilerCtx;
esmBrowserComponentBundle: ReadonlyArray<BundleModule>;
esmComponentBundle: ReadonlyArray<BundleModule>;
es5ComponentBundle: ReadonlyArray<BundleModule>;
systemComponentBundle: ReadonlyArray<BundleModule>;
commonJsComponentBundle: ReadonlyArray<BundleModule>;
components: ComponentCompilerMeta[];
componentGraph: Map<string, string[]>;
config: ValidatedConfig;
createTimeSpan(msg: string, debug?: boolean): LoggerTimeSpan;
data: any;
debug: (msg: string) => void;
diagnostics: Diagnostic[];
dirsAdded: string[];
dirsDeleted: string[];
entryModules: EntryModule[];
filesAdded: string[];
filesChanged: string[];
filesDeleted: string[];
filesUpdated: string[];
filesWritten: string[];
globalStyle: string | undefined;
hasConfigChanges: boolean;
hasError: boolean;
hasFinished: boolean;
hasHtmlChanges: boolean;
hasPrintedResults: boolean;
hasServiceWorkerChanges: boolean;
hasScriptChanges: boolean;
hasStyleChanges: boolean;
hasWarning: boolean;
hydrateAppFilePath: string;
indexBuildCount: number;
indexDoc: Document;
isRebuild: boolean;
/**
* A collection of Stencil's intermediate representation of components, tied to the current build
*/
moduleFiles: Module[];
packageJson: PackageJsonData;
pendingCopyTasks: Promise<CopyResults>[];
progress(task: BuildTask): void;
requiresFullBuild: boolean;
rollupResults?: RollupResults;
scriptsAdded: string[];
scriptsDeleted: string[];
startTime: number;
styleBuildCount: number;
stylesPromise: Promise<void>;
stylesUpdated: BuildStyleUpdate[];
timeSpan: LoggerTimeSpan;
timestamp: string;
transpileBuildCount: number;
validateTypesBuild?(): Promise<void>;
validateTypesHandler?: (results: any) => Promise<void>;
validateTypesPromise?: Promise<any>;
}
export interface BuildStyleUpdate {
styleTag: string;
styleText: string;
styleMode: string;
}
export type BuildTask = any;
export interface CompilerBuildStats {
timestamp: string;
compiler: {
name: string;
version: string;
};
app: {
namespace: string;
fsNamespace: string;
components: number;
entries: number;
bundles: number;
outputs: any;
};
options: {
minifyJs: boolean;
minifyCss: boolean;
hashFileNames: boolean;
hashedFileNameLength: number;
buildEs5: boolean | 'prod';
};
formats: {
esmBrowser: ReadonlyArray<CompilerBuildStatBundle>;
esm: ReadonlyArray<CompilerBuildStatBundle>;
es5: ReadonlyArray<CompilerBuildStatBundle>;
system: ReadonlyArray<CompilerBuildStatBundle>;
commonjs: ReadonlyArray<CompilerBuildStatBundle>;
};
components: BuildComponent[];
entries: EntryModule[];
rollupResults: RollupResults;
sourceGraph?: BuildSourceGraph;
componentGraph: BuildResultsComponentGraph;
collections: CompilerBuildStatCollection[];
}
export interface CompilerBuildStatCollection {
name: string;
source: string;
tags: string[][];
}
export interface CompilerBuildStatBundle {
key: string;
components: string[];
bundleId: string;
fileName: string;
imports: string[];
originalByteSize: number;
}
export interface BuildSourceGraph {
[filePath: string]: string[];
}
export interface BuildComponent {
tag: string;
dependencyOf?: string[];
dependencies?: string[];
}
export type SourceTarget = 'es5' | 'es2017' | 'latest';
/**
* A note regarding Rollup types:
* As of this writing, there is no great way to import external types for packages that are directly embedded in the
* Stencil source. As a result, some types are duplicated here for Rollup that will be used within the codebase.
* Updates to rollup may require these typings to be updated.
*/
export type RollupResult = RollupChunkResult | RollupAssetResult;
export interface RollupAssetResult {
type: 'asset';
fileName: string;
content: string;
}
export interface RollupChunkResult {
type: 'chunk';
entryKey: string;
fileName: string;
code: string;
isEntry: boolean;
isComponent: boolean;
isCore: boolean;
isIndex: boolean;
isBrowserLoader: boolean;
imports: string[];
moduleFormat: ModuleFormat;
map?: RollupSourceMap;
}
export interface RollupSourceMap {
file: string;
mappings: string;
names: string[];
sources: string[];
sourcesContent: string[];
version: number;
toString(): string;
toUrl(): string;
}
/**
* Result of Stencil compressing, mangling, and otherwise 'minifying' JavaScript
*/
export type OptimizeJsResult = {
output: string;
diagnostics: Diagnostic[];
sourceMap?: SourceMap;
};
export interface BundleModule {
entryKey: string;
rollupResult: RollupChunkResult;
cmps: ComponentCompilerMeta[];
output: BundleModuleOutput;
}
export interface BundleModuleOutput {
bundleId: string;
fileName: string;
code: string;
}
export interface Cache {
get(key: string): Promise<string | null>;
put(key: string, value: string): Promise<boolean>;
has(key: string): Promise<boolean>;
createKey(domain: string, ...args: any[]): Promise<string>;
commit(): Promise<void>;
clear(): void;
clearDiskCache(): Promise<void>;
getMemoryStats(): string;
initCacheDir(): Promise<void>;
}
export interface CollectionCompilerMeta {
collectionName: string;
moduleId?: string;
moduleDir: string;
moduleFiles: Module[];
global?: Module;
compiler?: CollectionCompilerVersion;
isInitialized?: boolean;
hasExports?: boolean;
dependencies?: string[];
bundles?: {
components: string[];
}[];
}
export interface CollectionCompilerVersion {
name: string;
version: string;
typescriptVersion?: string;
}
export interface CollectionManifest {
entries?: CollectionComponentEntryPath[];
collections?: CollectionDependencyManifest[];
global?: string;
compiler?: CollectionCompilerVersion;
bundles?: CollectionBundleManifest[];
}
export type CollectionComponentEntryPath = string;
export interface CollectionBundleManifest {
components: string[];
}
export interface CollectionDependencyManifest {
name: string;
tags: string[];
}
export interface CollectionCompiler {
name: string;
version: string;
typescriptVersion?: string;
}
export interface CollectionDependencyData {
name: string;
tags: string[];
}
export interface CompilerCtx {
version: number;
activeBuildId: number;
activeDirsAdded: string[];
activeDirsDeleted: string[];
activeFilesAdded: string[];
activeFilesDeleted: string[];
activeFilesUpdated: string[];
addWatchDir: (path: string, recursive: boolean) => void;
addWatchFile: (path: string) => void;
cache: Cache;
cssModuleImports: Map<string, string[]>;
cachedGlobalStyle: string;
collections: CollectionCompilerMeta[];
compilerOptions: any;
events: BuildEvents;
fs: InMemoryFileSystem;
hasSuccessfulBuild: boolean;
isActivelyBuilding: boolean;
lastBuildResults: CompilerBuildResults;
/**
* A mapping of a file path to a Stencil {@link Module}
*/
moduleMap: ModuleMap;
nodeMap: NodeMap;
resolvedCollections: Set<string>;
rollupCacheHydrate: any;
rollupCacheLazy: any;
rollupCacheNative: any;
styleModeNames: Set<string>;
changedModules: Set<string>;
changedFiles: Set<string>;
worker?: CompilerWorkerContext;
rollupCache: Map<string, any>;
reset(): void;
}
export type NodeMap = WeakMap<any, ComponentCompilerMeta>;
/**
* Record, for a specific component, whether or not it has various features
* which need to be handled correctly in the compilation pipeline.
*
* Note: this must be serializable to JSON.
*/
export interface ComponentCompilerFeatures {
hasAttribute: boolean;
hasAttributeChangedCallbackFn: boolean;
hasComponentWillLoadFn: boolean;
hasComponentDidLoadFn: boolean;
hasComponentShouldUpdateFn: boolean;
hasComponentWillUpdateFn: boolean;
hasComponentDidUpdateFn: boolean;
hasComponentWillRenderFn: boolean;
hasComponentDidRenderFn: boolean;
hasComponentDidUnloadFn: boolean;
hasConnectedCallbackFn: boolean;
hasDisconnectedCallbackFn: boolean;
hasElement: boolean;
hasEvent: boolean;
hasLifecycle: boolean;
hasListener: boolean;
hasListenerTarget: boolean;
hasListenerTargetWindow: boolean;
hasListenerTargetDocument: boolean;
hasListenerTargetBody: boolean;
/**
* @deprecated Prevented from new apps, but left in for older collections
*/
hasListenerTargetParent: boolean;
hasMember: boolean;
hasMethod: boolean;
hasMode: boolean;
hasProp: boolean;
hasPropBoolean: boolean;
hasPropNumber: boolean;
hasPropString: boolean;
hasPropMutable: boolean;
hasReflect: boolean;
hasRenderFn: boolean;
hasState: boolean;
hasStyle: boolean;
hasVdomAttribute: boolean;
hasVdomClass: boolean;
hasVdomFunctional: boolean;
hasVdomKey: boolean;
hasVdomListener: boolean;
hasVdomPropOrAttr: boolean;
hasVdomRef: boolean;
hasVdomRender: boolean;
hasVdomStyle: boolean;
hasVdomText: boolean;
hasVdomXlink: boolean;
hasWatchCallback: boolean;
htmlAttrNames: string[];
htmlTagNames: string[];
htmlParts: string[];
isUpdateable: boolean;
/**
* A plain component is one that doesn't have:
* - any members decorated with `@Prop()`, `@State()`, `@Element()`, `@Method()`
* - any methods decorated with `@Listen()`
* - any styles
* - any lifecycle methods, including `render()`
*/
isPlain: boolean;
/**
* A collection of tag names of web components that a component references in its JSX/h() function
*/
potentialCmpRefs: string[];
}
/**
* Metadata about a given component
*
* Note: must be serializable to JSON!
*/
export interface ComponentCompilerMeta extends ComponentCompilerFeatures {
assetsDirs: CompilerAssetDir[];
/**
* The name to which an `ElementInternals` object (the return value of
* `HTMLElement.attachInternals`) should be attached at runtime. If this is
* `null` then `attachInternals` should not be called.
*/
attachInternalsMemberName: string | null;
componentClassName: string;
/**
* A list of web component tag names that are either:
* - directly referenced in a Stencil component's JSX/h() function
* - are referenced by a web component that is directly referenced in a Stencil component's JSX/h() function
*/
dependencies: string[];
/**
* A list of web component tag names that either:
* - directly reference the current component directly in their JSX/h() function
* - indirectly/transitively reference the current component directly in their JSX/h() function
*/
dependents: string[];
/**
* A list of web component tag names that are directly referenced in a Stencil component's JSX/h() function
*/
directDependencies: string[];
/**
* A list of web component tag names that the current component directly in their JSX/h() function
*/
directDependents: string[];
docs: CompilerJsDoc;
elementRef: string;
encapsulation: Encapsulation;
events: ComponentCompilerEvent[];
excludeFromCollection: boolean;
/**
* Whether or not the component is form-associated
*/
formAssociated: boolean;
internal: boolean;
isCollectionDependency: boolean;
jsFilePath: string;
listeners: ComponentCompilerListener[];
methods: ComponentCompilerMethod[];
properties: ComponentCompilerProperty[];
shadowDelegatesFocus: boolean;
sourceFilePath: string;
sourceMapPath: string;
states: ComponentCompilerState[];
styleDocs: CompilerStyleDoc[];
styles: StyleCompiler[];
tagName: string;
virtualProperties: ComponentCompilerVirtualProperty[];
watchers: ComponentCompilerWatch[];
}
/**
* The supported style encapsulation modes on a Stencil component:
* 1. 'shadow' - native Shadow DOM
* 2. 'scoped' - encapsulated styles and polyfilled slots
* 3. 'none' - a basic HTML element
*/
export type Encapsulation = 'shadow' | 'scoped' | 'none';
/**
* Intermediate Representation (IR) of a static property on a Stencil component
*/
export interface ComponentCompilerStaticProperty {
mutable: boolean;
optional: boolean;
required: boolean;
type: ComponentCompilerPropertyType;
complexType: ComponentCompilerPropertyComplexType;
attribute?: string;
reflect?: boolean;
docs: CompilerJsDoc;
defaultValue?: string;
}
/**
* Intermediate Representation (IR) of a property on a Stencil component
*/
export interface ComponentCompilerProperty extends ComponentCompilerStaticProperty {
name: string;
internal: boolean;
}
export interface ComponentCompilerVirtualProperty {
name: string;
type: string;
docs: string;
}
export type ComponentCompilerPropertyType = 'any' | 'string' | 'boolean' | 'number' | 'unknown';
/**
* Information about a type used in a Stencil component or exported
* from a Stencil project.
*/
export interface ComponentCompilerPropertyComplexType {
/**
* The string of the original type annotation in the Stencil source code
*/
original: string;
/**
* A 'resolved' type, where e.g. imported types have been resolved and inlined
*
* For instance, an annotation like `(foo: Foo) => string;` will be
* converted to `(foo: { foo: string }) => string;`.
*/
resolved: string;
/**
* A record of the types which were referenced in the assorted type
* annotation in the original source file.
*/
references: ComponentCompilerTypeReferences;
}
/**
* A record of `ComponentCompilerTypeReference` entities.
*
* Each key in this record is intended to be the names of the types used by a component. However, this is not enforced
* by the type system (I.E. any string can be used as a key).
*
* Note any key can be a user defined type or a TypeScript standard type.
*/
export type ComponentCompilerTypeReferences = Record<string, ComponentCompilerTypeReference>;
/**
* Describes a reference to a type used by a component.
*/
export interface ComponentCompilerTypeReference {
/**
* A type may be defined:
* - locally (in the same file as the component that uses it)
* - globally
* - by importing it into a file (and is defined elsewhere)
*/
location: 'local' | 'global' | 'import';
/**
* The path to the type reference, if applicable (global types should not need a path associated with them)
*/
path?: string;
/**
* An ID for this type which is unique within a Stencil project.
*/
id: string;
}
/**
* Information about a type which is referenced by another type on a Stencil
* component, for instance a {@link ComponentCompilerPropertyComplexType} or a
* {@link ComponentCompilerEventComplexType}.
*/
export interface ComponentCompilerReferencedType {
/**
* The path to the module where the type is declared.
*/
path: string;
/**
* The string of the original type annotation in the Stencil source code
*/
declaration: string;
/**
* An extracted docstring
*/
docstring: string;
}
export interface ComponentCompilerStaticEvent {
name: string;
method: string;
bubbles: boolean;
cancelable: boolean;
composed: boolean;
docs: CompilerJsDoc;
complexType: ComponentCompilerEventComplexType;
}
export interface ComponentCompilerEvent extends ComponentCompilerStaticEvent {
internal: boolean;
}
export interface ComponentCompilerEventComplexType {
original: string;
resolved: string;
references: ComponentCompilerTypeReferences;
}
export interface ComponentCompilerListener {
name: string;
method: string;
capture: boolean;
passive: boolean;
target: ListenTargetOptions | undefined;
}
export interface ComponentCompilerStaticMethod {
docs: CompilerJsDoc;
complexType: ComponentCompilerMethodComplexType;
}
export interface ComponentCompilerMethodComplexType {
signature: string;
parameters: JsonDocMethodParameter[];
references: ComponentCompilerTypeReferences;
return: string;
}
export interface ComponentCompilerWatch {
propName: string;
methodName: string;
}
export interface ComponentCompilerMethod extends ComponentCompilerStaticMethod {
name: string;
internal: boolean;
}
export interface ComponentCompilerState {
name: string;
}
/**
* Representation of JSDoc that is pulled off a node in the AST
*/
export interface CompilerJsDoc {
/**
* The text associated with the JSDoc
*/
text: string;
/**
* Tags included in the JSDoc
*/
tags: CompilerJsDocTagInfo[];
}
/**
* Representation of a tag that exists in a JSDoc
*/
export interface CompilerJsDocTagInfo {
/**
* The name of the tag - e.g. `@deprecated`
*/
name: string;
/**
* Additional text that is associated with the tag - e.g. `@deprecated use v2 of this API`
*/
text?: string;
}
/**
* The (internal) representation of a CSS block comment in a CSS, Sass, etc. file. This data structure is used during
* the initial compilation phases of Stencil, as a piece of {@link ComponentCompilerMeta}.
*/
export interface CompilerStyleDoc {
/**
* The name of the CSS property
*/
name: string;
/**
* The user-defined description of the CSS property
*/
docs: string;
/**
* The JSDoc-style annotation (e.g. `@prop`) that was used in the block comment to detect the comment.
* Used to inform Stencil where the start of a new property's description starts (and where the previous description
* ends).
*/
annotation: 'prop';
/**
* The Stencil style-mode that is associated with this property.
*/
mode: string;
}
export interface CompilerAssetDir {
absolutePath?: string;
cmpRelativePath?: string;
originalComponentPath?: string;
}
export interface ComponentCompilerData {
exportLine: string;
filePath: string;
cmp: ComponentCompilerMeta;
uniqueComponentClassName?: string;
importLine?: string;
}
export interface ComponentConstructor {
is?: string;
properties?: ComponentConstructorProperties;
watchers?: ComponentConstructorWatchers;
events?: ComponentConstructorEvent[];
listeners?: ComponentConstructorListener[];
style?: string;
styleId?: string;
encapsulation?: ComponentConstructorEncapsulation;
observedAttributes?: string[];
cmpMeta?: ComponentRuntimeMeta;
isProxied?: boolean;
isStyleRegistered?: boolean;
}
/**
* A mapping from class member names to a list of methods which are watching
* them.
*/
export interface ComponentConstructorWatchers {
[propName: string]: string[];
}
export interface ComponentTestingConstructor extends ComponentConstructor {
COMPILER_META: ComponentCompilerMeta;
prototype?: {
componentWillLoad?: Function;
componentWillUpdate?: Function;
componentWillRender?: Function;
__componentWillLoad?: Function | null;
__componentWillUpdate?: Function | null;
__componentWillRender?: Function | null;
};
}
export interface ComponentNativeConstructor extends ComponentConstructor {
cmpMeta: ComponentRuntimeMeta;
}
export type ComponentConstructorEncapsulation = 'shadow' | 'scoped' | 'none';
export interface ComponentConstructorProperties {
[propName: string]: ComponentConstructorProperty;
}
export interface ComponentConstructorProperty {
attribute?: string;
elementRef?: boolean;
method?: boolean;
mutable?: boolean;
reflect?: boolean;
state?: boolean;
type?: ComponentConstructorPropertyType;
watchCallbacks?: string[];
}
export type ComponentConstructorPropertyType = StringConstructor | BooleanConstructor | NumberConstructor | 'string' | 'boolean' | 'number';
export interface ComponentConstructorEvent {
name: string;
method: string;
bubbles: boolean;
cancelable: boolean;
composed: boolean;
}
export interface ComponentConstructorListener {
name: string;
method: string;
capture?: boolean;
passive?: boolean;
}
export interface DevClientWindow extends Window {
['s-dev-server']: boolean;
['s-initial-load']: boolean;
['s-build-id']: number;
WebSocket: new (socketUrl: string, protos: string[]) => WebSocket;
devServerConfig?: DevClientConfig;
}
export interface DevClientConfig {
basePath: string;
editors: DevServerEditor[];
reloadStrategy: PageReloadStrategy;
socketUrl?: string;
}
export interface HttpRequest {
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS';
acceptHeader: string;
url: URL;
searchParams: URLSearchParams;
pathname?: string;
filePath?: string;
stats?: CompilerFsStats;
headers?: {
[name: string]: string;
};
host?: string;
}
export interface DevServerMessage {
startServer?: DevServerConfig;
closeServer?: boolean;
serverStarted?: DevServerConfig;
serverClosed?: boolean;
buildStart?: boolean;
buildLog?: BuildLog;
buildResults?: CompilerBuildResults;
requestBuildResults?: boolean;
error?: {
message?: string;
type?: string;
stack?: any;
};
isActivelyBuilding?: boolean;
compilerRequestPath?: string;
compilerRequestResults?: CompilerRequestResponse;
requestLog?: {
method: string;
url: string;
status: number;
};
}
export type DevServerSendMessage = (msg: DevServerMessage) => void;
export interface DevServerContext {
connectorHtml: string;
dirTemplate: string;
getBuildResults: () => Promise<CompilerBuildResults>;
getCompilerRequest: (path: string) => Promise<CompilerRequestResponse>;
isServerListening: boolean;
logRequest: (req: HttpRequest, status: number) => void;
prerenderConfig: PrerenderConfig;
serve302: (req: any, res: any, pathname?: string) => void;
serve404: (req: any, res: any, xSource: string, content?: string) => void;
serve500: (req: any, res: any, error: any, xSource: string) => void;
sys: CompilerSystem;
}
export type InitServerProcess = (sendMsg: (msg: DevServerMessage) => void) => (msg: DevServerMessage) => void;
export interface DevResponseHeaders {
'cache-control'?: string;
expires?: string;
'content-type'?: string;
'content-length'?: number;
date?: string;
'access-control-allow-origin'?: string;
'access-control-expose-headers'?: string;
'content-encoding'?: 'gzip';
vary?: 'Accept-Encoding';
server?: string;
'x-directory-index'?: string;
'x-source'?: string;
}
export interface OpenInEditorData {
file?: string;
line?: number;
column?: number;
open?: string;
editor?: string;
exists?: boolean;
error?: string;
}
export interface EntryModule {
entryKey: string;
cmps: ComponentCompilerMeta[];
}
/**
* An interface extending `HTMLElement` which describes the fields added onto
* host HTML elements by the Stencil runtime.
*/
export interface HostElement extends HTMLElement {
connectedCallback?: () => void;
attributeChangedCallback?: (attribName: string, oldVal: string, newVal: string, namespace: string) => void;
disconnectedCallback?: () => void;
host?: Element;
forceUpdate?: () => void;
/**
* Unique stencil id for this element
*/
['s-id']?: string;
/**
* Content Reference:
* Reference to the HTML Comment that's placed inside of the
* host element's original content. This comment is used to
* always represent where host element's light dom is.
*/
['s-cr']?: RenderNode;
/**
* Lifecycle ready
*/
['s-lr']?: boolean;
/**
* A reference to the `ElementInternals` object for the current host
*
* This is used for maintaining a reference to the object between HMR
* refreshes in the lazy build.
*
* "stencil-element-internals"
*/
['s-ei']?: ElementInternals;
/**
* On Render Callbacks:
* Array of callbacks to fire off after it has rendered.
*/
['s-rc']?: (() => void)[];
/**
* Scope Id
* The scope id of this component when using scoped css encapsulation
* or using shadow dom but the browser doesn't support it
*/
['s-sc']?: string;
/**
* Scope Ids
* All the possible scope ids of this component when using scoped css encapsulation
* or using shadow dom but the browser doesn't support it
*/
['s-scs']?: string[];
/**
* Hot Module Replacement, dev mode only
*
* This function should be defined by the HMR-supporting runtime and should
* do the work of actually updating the component in-place.
*/
['s-hmr']?: (versionId: string) => void;
['s-p']?: Promise<void>[];
componentOnReady?: () => Promise<this>;
}
export interface HydrateResults {
buildId: string;
diagnostics: Diagnostic[];
url: string;
host: string | null;
hostname: string | null;
href: string | null;
port: string | null;
pathname: string | null;
search: string | null;
hash: string | null;
html: string | null;
components: HydrateComponent[];
anchors: HydrateAnchorElement[];
imgs: HydrateImgElement[];
scripts: HydrateScriptElement[];
styles: HydrateStyleElement[];
staticData: HydrateStaticData[];
title: string | null;
hydratedCount: number;
httpStatus: number | null;
}
export interface HydrateComponent {
tag: string;
mode: string;
count: number;
depth: number;
}
export interface HydrateElement {
[attrName: string]: string | undefined;
}
export interface HydrateAnchorElement extends HydrateElement {
href?: string;
target?: string;
}
export interface HydrateImgElement extends HydrateElement {
src?: string;
}
export interface HydrateScriptElement extends HydrateElement {
src?: string;
type?: string;
}
export interface HydrateStyleElement extends HydrateElement {
href?: string;
}
export interface HydrateStaticData {
id: string;
type: string;
content: string;
}
export interface JsDoc {
name: string;
documentation: string;
type: string;
tags: JSDocTagInfo[];
default?: string;
parameters?: JsDoc[];
returns?: {
type: string;
documentation: string;
};
}
export interface JSDocTagInfo {
name: string;
text?: string;
}
/**
* A mapping from a TypeScript or JavaScript source file path on disk, to a Stencil {@link Module}.
*
* It is advised that the key (path) be normalized before storing/retrieving the `Module` to avoid unnecessary lookup
* failures.
*/
export type ModuleMap = Map<string, Module>;
/**
* Stencil's Intermediate Representation (IR) of a module, bundling together
* various pieces of information like the classes declared within it, the path
* to the original source file, HTML tag names defined in the file, and so on.
*
* Note that this gets serialized/parsed as JSON and therefore cannot contain a
* `Map` or a `Set`.
*/
export interface Module {
cmps: ComponentCompilerMeta[];
/**
* A collection of modules that a component will need. The modules in this list must have import statements generated
* in order for the component to function.
*/
coreRuntimeApis: string[];
/**
* A collection of modules that a component will need for a specific output target. The modules in this list must
* have import statements generated in order for the component to function, but only for a specific output target.
*/
outputTargetCoreRuntimeApis: Partial<Record<OutputTarget['type'], string[]>>;
collectionName: string;
dtsFilePath: string;
excludeFromCollection: boolean;
externalImports: string[];
htmlAttrNames: string[];
htmlTagNames: string[];
htmlParts: string[];
isCollectionDependency: boolean;
isLegacy: boolean;
jsFilePath: string;
localImports: string[];
originalImports: string[];
originalCollectionComponentPath: string;
potentialCmpRefs: string[];
sourceFilePath: string;
staticSourceFile: any;
staticSourceFileText: string;
sourceMapPath: string;
sourceMapFileText: string;
hasVdomAttribute: boolean;
hasVdomClass: boolean;
hasVdomFunctional: boolean;
hasVdomKey: boolean;
hasVdomListener: boolean;
hasVdomPropOrAttr: boolean;
hasVdomRef: boolean;
hasVdomRender: boolean;
hasVdomStyle: boolean;
hasVdomText: boolean;
hasVdomXlink: boolean;
}
export interface Plugin {
name?: string;
pluginType?: string;
load?: (id: string, context: PluginCtx) => Promise<string> | string;
resolveId?: (importee: string, importer: string, context: PluginCtx) => Promise<string> | string;
transform?: (sourceText: string, id: string, context: PluginCtx) => Promise<PluginTransformResults> | PluginTransformResults | string;
}
export interface PluginTransformResults {
code?: string;
map?: string;
id?: string;
diagnostics?: Diagnostic[];
dependencies?: string[];
}
export interface PluginCtx {
config: Config;
sys: CompilerSystem;
fs: InMemoryFileSystem;
cache: Cache;
diagnostics: Diagnostic[];
}
export interface PrerenderUrlResults {
anchorUrls: string[];
diagnostics: Diagnostic[];
filePath: string;
}
export interface PrerenderUrlRequest {
appDir: string;
buildId: string;
baseUrl: string;
componentGraphPath: string;
devServerHostUrl: string;
hydrateAppFilePath: string;
isDebug: boolean;
prerenderConfigPath: string;
staticSite: boolean;
templateId: string;
url: string;
writeToFilePath: string;
}
export interface PrerenderManager {
config: Config;
prerenderUrlWorker: (prerenderRequest: PrerenderUrlRequest) => Promise<PrerenderUrlResults>;
devServerHostUrl: string;
diagnostics: Diagnostic[];
hydrateAppFilePath: string;
isDebug: boolean;
logCount: number;
outputTarget: OutputTargetWww;
prerenderConfig: PrerenderConfig;
prerenderConfigPath: string;
progressLogger?: LoggerLineUpdater;
resolve: Function;
staticSite: boolean;
templateId: string;
componentGraphPath: string;
urlsProcessing: Set<string>;
urlsPending: Set<string>;
urlsCompleted: Set<string>;
maxConcurrency: number;
}
/**
* Generic node that represents all of the
* different types of nodes we'd see when rendering
*/
export interface RenderNode extends HostElement {
/**
* Shadow root's host
*/
host?: Element;
/**
* On Ref Function:
* Callback function to be called when the slotted node ref is ready.
*/
['s-rf']?: (elm: Element) => unknown;
/**
* Is initially hidden
* Whether this node was originally rendered with the `hidden` attribute.
*
* Used to reset the `hidden` state of a node during slot relocation.
*/
['s-ih']?: boolean;
/**
* Is Content Reference Node:
* This node is a content reference node.
*/
['s-cn']?: boolean;
/**
* Is a slot reference node:
* This is a node that represents where a slot
* was originally located.
*/
['s-sr']?: boolean;
/**
* Slot name
*/
['s-sn']?: string;
/**
* Host element tag name:
* The tag name of the host element that this
* node was created in.
*/
['s-hn']?: string;
/**
* Slot host tag name:
* This is the tag name of the element where this node
* has been moved to during slot relocation.
*
* This allows us to check if the node has been moved and prevent
* us from thinking a node _should_ be moved when it may already be in
* its final destination.
*
* This value is set to `undefined` whenever the node is put back into its original location.
*/
['s-sh']?: string;
/**
* Original Location Reference:
* A reference pointing to the comment
* which represents the original location
* before it was moved to its slot.
*/
['s-ol']?: RenderNode;
/**
* Node reference:
* This is a reference for a original location node
* back to the node that's been moved around.
*/
['s-nr']?: RenderNode;
/**
* Scope Id
*/
['s-si']?: string;
/**
* Host Id (hydrate only)
*/
['s-host-id']?: number;
/**
* Node Id (hydrate only)
*/
['s-node-id']?: number;
/**
* Used to know the components encapsulation.
* empty "" for shadow, "c" from scoped
*/
['s-en']?: '' | /*shadow*/ 'c';
}
export type LazyBundlesRuntimeData = LazyBundleRuntimeData[];
export type LazyBundleRuntimeData = [
/** bundleIds */
string,
ComponentRuntimeMetaCompact[]
];
export type ComponentRuntimeMetaCompact = [
/** flags */
number,
/** tagname */
string,
/** members */
{
[memberName: string]: ComponentRuntimeMember;
}?,
/** listeners */
ComponentRuntimeHostListener[]?,
/** watchers */
ComponentConstructorWatchers?
];
/**
* Runtime metadata for a Stencil component
*/
export interface ComponentRuntimeMeta {
/**
* This number is used to hold a series of bitflags for various features we
* support on components. The flags which this value is intended to store are
* documented in the `CMP_FLAGS` enum.
*/
$flags$: number;
/**
* Just what it says on the tin - the tag name for the component, as set in
* the `@Component` decorator.
*/
$tagName$: string;
/**
* A map of the component's members, which could include fields decorated
* with `@Prop`, `@State`, etc as well as methods.
*/
$members$?: ComponentRuntimeMembers;
/**
* Information about listeners on the component.
*/
$listeners$?: ComponentRuntimeHostListener[];
/**
* Tuples containing information about `@Prop` fields on the component which
* are set to be reflected (i.e. kept in sync) as HTML attributes when
* updated.
*/
$attrsToReflect$?: ComponentRuntimeReflectingAttr[];
/**
* Information about which class members have watchers attached on the component.
*/
$watchers$?: ComponentConstructorWatchers;
/**
* A bundle ID used for lazy loading.
*/
$lazyBundleId$?: string;
}
/**
* A mapping of the names of members on the component to some runtime-specific
* information about them.
*/
export interface ComponentRuntimeMembers {
[memberName: string]: ComponentRuntimeMember;
}
/**
* A tuple with information about a class member that's relevant at runtime.
* The fields are:
*
* 1. A number used to hold bitflags for component members. The bit flags which
* this is intended to store are documented in the `MEMBER_FLAGS` enum.
* 2. The attribute name to observe.
*/
export type ComponentRuntimeMember = [number, string?];
/**
* A tuple holding information about a host listener which is relevant at
* runtime. The field are:
*
* 1. A number used to hold bitflags for listeners. The bit flags which this is
* intended to store are documented in the `LISTENER_FLAGS` enum.
* 2. The event name.
* 3. The method name.
*/
export type ComponentRuntimeHostListener = [number, string, string];
/**
* A tuple containing information about props which are "reflected" at runtime,
* meaning that HTML attributes on the component instance are kept in sync with
* the prop value.
*
* The fields are:
*
* 1. the prop name
* 2. the prop attribute.
*/
export type ComponentRuntimeReflectingAttr = [string, string | undefined];
/**
* A runtime component reference, consistent of either a host element _or_ an
* empty object. This is used in particular in a few different places as the
* keys in a `WeakMap` which maps {@link HostElement} instances to their
* associated {@link HostRef} instance.
*/
export type RuntimeRef = HostElement | {};
/**
* Interface used to track an Element, it's virtual Node (`VNode`), and other data
*/
export interface HostRef {
$ancestorComponent$?: HostElement;
$flags$: number;
$cmpMeta$: ComponentRuntimeMeta;
$hostElement$: HostElement;
$instanceValues$?: Map<string, any>;
$lazyInstance$?: ComponentInterface;
/**
* A promise that gets resolved if `BUILD.asyncLoading` is enabled and after the `componentDidLoad`
* and before the `componentDidUpdate` lifecycle events are triggered.
*/
$onReadyPromise$?: Promise<HostElement>;
/**
* A callback which resolves {@link HostRef.$onReadyPromise$}
* @param elm host element
*/
$onReadyResolve$?: (elm: HostElement) => void;
/**
* A promise which resolves with the host component once it has finished rendering
* for the first time. This is primarily used to wait for the first `update` to be
* called on a component.
*/
$onInstancePromise$?: Promise<HostElement>;
/**
* A callback which resolves {@link HostRef.$onInstancePromise$}
* @param elm host element
*/
$onInstanceResolve$?: (elm: HostElement) => void;
/**
* A promise which resolves when the component has finished rendering for the first time.
* It is called after {@link HostRef.$onInstancePromise$} resolves.
*/
$onRenderResolve$?: () => void;
$vnode$?: VNode;
$queuedListeners$?: [string, any][];
$rmListeners$?: (() => void)[];
$modeName$?: string;
$renderCount$?: number;
}
export interface PlatformRuntime {
/**
* This number is used to hold a series of bitflags for various features we
* support within the runtime. The flags which this value is intended to store are
* documented in the {@link PLATFORM_FLAGS} enum.
*/
$flags$: number;
/**
* Holds a map of nodes to be hydrated.
*/
$orgLocNodes$?: Map<string, RenderNode>;
/**
* Holds the resource url for given platform environment.
*/
$resourcesUrl$: string;
/**
* The nonce value to be applied to all script/style tags at runtime.
* If `null`, the nonce attribute will not be applied.
*/
$nonce$?: string | null;
/**
* A utility function that executes a given function and returns the result.
* @param c The callback function to execute
*/
jmp: (c: Function) => any;
/**
* A wrapper for {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame `requestAnimationFrame`}
*/
raf: (c: FrameRequestCallback) => number;
/**
* A wrapper for {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener `addEventListener`}
*/
ael: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;
/**
* A wrapper for {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener `removeEventListener`}
*/
rel: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;
/**
* A wrapper for creating a {@link https://developer.mozilla.org/docs/Web/API/CustomEvent `CustomEvent`}
*/
ce: (eventName: string, opts?: any) => CustomEvent;
}
export type StyleMap = Map<string, CSSStyleSheet | string>;
export type RootAppliedStyleMap = WeakMap<Element, Set<string>>;
export interface ScreenshotConnector {
initBuild(opts: ScreenshotConnectorOptions): Promise<void>;
completeBuild(masterBuild: ScreenshotBuild): Promise<ScreenshotBuildResults>;
getMasterBuild(): Promise<ScreenshotBuild>;
pullMasterBuild(): Promise<void>;
publishBuild(buildResults: ScreenshotBuildResults): Promise<ScreenshotBuildResults>;
getScreenshotCache(): Promise<ScreenshotCache>;
updateScreenshotCache(screenshotCache: ScreenshotCache, buildResults: ScreenshotBuildResults): Promise<ScreenshotCache>;
generateJsonpDataUris(build: ScreenshotBuild): Promise<void>;
sortScreenshots(screenshots: Screenshot[]): Screenshot[];
toJson(masterBuild: ScreenshotBuild, screenshotCache: ScreenshotCache): string;
}
export interface ScreenshotBuildResults {
appNamespace: string;
masterBuild: ScreenshotBuild;
currentBuild: ScreenshotBuild;
compare: ScreenshotCompareResults;
}
export interface ScreenshotCompareResults {
id: string;
a: {
id: string;
message: string;
author: string;
url: string;
previewUrl: string;
};
b: {
id: string;
message: string;
author: string;
url: string;
previewUrl: string;
};
timestamp: number;
url: string;
appNamespace: string;
diffs: ScreenshotDiff[];
}
export interface ScreenshotConnectorOptions {
buildId: string;
buildMessage: string;
buildAuthor?: string;
buildUrl?: string;
previewUrl?: string;
appNamespace: string;
buildTimestamp: number;
logger: Logger;
rootDir: string;
cacheDir: string;
packageDir: string;
screenshotDirName?: string;
imagesDirName?: string;
buildsDirName?: string;
currentBuildDir?: string;
updateMaster?: boolean;
allowableMismatchedPixels?: number;
allowableMismatchedRatio?: number;
pixelmatchThreshold?: number;
waitBeforeScreenshot?: number;
pixelmatchModulePath?: string;
}
export interface ScreenshotBuildData {
buildId: string;
rootDir: string;
screenshotDir: string;
imagesDir: string;
buildsDir: string;
currentBuildDir: string;
updateMaster: boolean;
allowableMismatchedPixels: number;
allowableMismatchedRatio: number;
pixelmatchThreshold: number;
masterScreenshots: {
[screenshotId: string]: string;
};
cache: {
[cacheKey: string]: number;
};
timeoutBeforeScreenshot: number;
pixelmatchModulePath: string;
}
export interface PixelMatchInput {
imageAPath: string;
imageBPath: string;
width: number;
height: number;
pixelmatchThreshold: number;
}
export interface ScreenshotBuild {
id: string;
message: string;
author?: string;
url?: string;
previewUrl?: string;
appNamespace: string;
timestamp: number;
screenshots: Screenshot[];
}
export interface ScreenshotCache {
timestamp?: number;
lastBuildId?: string;
size?: number;
items?: {
/**
* Cache key
*/
key: string;
/**
* Timestamp used to remove the oldest data
*/
ts: number;
/**
* Mismatched pixels
*/
mp: number;
}[];
}
export interface Screenshot {
id: string;
desc?: string;
image: string;
device?: string;
userAgent?: string;
width: number;
height: number;
deviceScaleFactor?: number;
hasTouch?: boolean;
isLandscape?: boolean;
isMobile?: boolean;
testPath?: string;
diff?: ScreenshotDiff;
}
export interface ScreenshotDiff {
mismatchedPixels: number;
id: string;
desc?: string;
imageA?: string;
imageB?: string;
device?: string;
userAgent?: string;
width: number;
height: number;
deviceScaleFactor?: number;
hasTouch?: boolean;
isLandscape?: boolean;
isMobile?: boolean;
allowableMismatchedPixels: number;
allowableMismatchedRatio: number;
testPath?: string;
cacheKey?: string;
}
export interface ScreenshotOptions {
/**
* When true, takes a screenshot of the full scrollable page.
* Default: `false`
*/
fullPage?: boolean;
/**
* An object which specifies clipping region of the page.
*/
clip?: ScreenshotBoundingBox;
/**
* Hides default white background and allows capturing screenshots with transparency.
* Default: `false`
*/
omitBackground?: boolean;
/**
* Matching threshold, ranges from `0` to 1. Smaller values make the comparison
* more sensitive. Defaults to the testing config `pixelmatchThreshold` value;
*/
pixelmatchThreshold?: number;
/**
* Capture the screenshot beyond the viewport.
*
* @defaultValue `false` if there is no `clip`. `true` otherwise.
*/
captureBeyondViewport?: boolean;
}
export interface ScreenshotBoundingBox {
/**
* The x-coordinate of top-left corner.
*/