diff --git a/package.json b/package.json index 84de8403..dec1b09c 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "build:css": "esbuild src/lib.css --outfile=dist/discovery.css --bundle --minify --loader:.svg=dataurl", "build:embed-host": "esbuild src/extensions/embed-host.js --outfile=dist/discovery-embed-host.js --bundle --define:global=window --format=esm --minify --sourcemap=external", "build:preloader": "npm run build:preloader:js && npm run build:preloader:css", - "build:preloader:js": "esbuild src/preloader.js --outfile=dist/discovery-preloader.js --bundle --define:global=window --format=esm --minify --sourcemap=external", + "build:preloader:js": "esbuild src/preloader.ts --outfile=dist/discovery-preloader.js --bundle --define:global=window --format=esm --minify --sourcemap=external", "build:preloader:css": "esbuild src/preloader.css --outfile=dist/discovery-preloader.css --bundle --minify --loader:.svg=dataurl", "build-gh-pages": "discovery-build -o .gh-pages --clean", "transpile": "node scripts/transpile.js", diff --git a/src/preloader.js b/src/preloader.ts similarity index 62% rename from src/preloader.js rename to src/preloader.ts index b09e36c0..a772a753 100644 --- a/src/preloader.js +++ b/src/preloader.ts @@ -1,20 +1,34 @@ import Progressbar from './core/utils/progressbar.js'; import { dataSource, syncLoaderWithProgressbar } from './core/utils/load-data.js'; import { applyContainerStyles } from './core/utils/container-styles.js'; -import injectStyles from './core/utils/inject-styles.js'; +import injectStyles, { Style } from './core/utils/inject-styles.js'; import { randomId } from './core/utils/id.js'; - -function createProgressbar(domReady, title) { +import type { InitValue } from './core/darkmode.js'; +import type { LoadDataBaseOptions, LoadDataFetchOptions, LoadDataResult } from './core/utils/load-data.js'; + +type PushDataLoading = ReturnType; +export type PreloaderOptions = { + dataSource: keyof typeof dataSource; + container: HTMLElement; + styles: Style[]; + darkmode: InitValue; + darkmodePersistent: boolean; + embed: boolean; + progressbar: Progressbar; + loadDataOptions: LoadDataBaseOptions | LoadDataFetchOptions; + data: any; +}; + +function createProgressbar(domReady: Promise) { return new Progressbar({ delay: 300, domReady, - title, onTiming: ({ title, duration }) => console.log(`[Discovery/preloader] ${title} – ${duration}ms`) }); } -export function preloader(options) { +export function preloader(options: Partial) { options = options || {}; const dataSourceType = options.dataSource; @@ -32,29 +46,32 @@ export function preloader(options) { el.setAttribute('darkmode', ''); } - const loadData = dataSource[dataSourceType || 'url']; - const loading = options.data + const optionsData = options.data; + const loading = optionsData ? dataSourceType === 'push' - ? loadData(options.loadDataOptions) - : loadData(options.data, options.loadDataOptions) + ? dataSource['push'](options.loadDataOptions) + : dataSource[dataSourceType || 'url'](options.data, options.loadDataOptions) : { - dataset: Promise.resolve() + dataset: Promise.resolve(), + state: undefined }; - if (loading.push) { - window.discoveryLoader = { - start: loading.start, - push: loading.push, - finish(...args) { - delete window.discoveryLoader; - loading.finish(...args); + if (optionsData && dataSourceType === 'push') { + const { start, push, finish } = loading as PushDataLoading; + + globalThis.discoveryLoader = { + start, + push, + finish(...args: Parameters) { + delete globalThis.discoveryLoader; + finish(...args); } }; } const domReady = injectStyles(shadowRoot, options.styles); - const progressbar = options.progressbar || createProgressbar(domReady, loading.title); - const disposeEmbed = options.embed ? initPreloadEmbedApi(loading) : () => {}; + const progressbar = options.progressbar || createProgressbar(domReady); + const disposeEmbed = options.embed ? initPreloadEmbedApi(loading.state) : () => {}; if (loading.state) { syncLoaderWithProgressbar(loading, progressbar).catch(() => {}); @@ -69,11 +86,11 @@ export function preloader(options) { ); } -function initPreloadEmbedApi(loading) { +function initPreloadEmbedApi(loadingState?: LoadDataResult['state']) { const hostId = randomId(); const parentWindow = window.parent; - const postponeMessages = []; - const sendMessage = (type, payload = null) => { + const postponeMessages: unknown[] = []; + const sendMessage = (type: string, payload: any = null) => { // console.log('[post-message]', type, payload); parentWindow.postMessage({ from: 'discoveryjs-app', @@ -84,7 +101,7 @@ function initPreloadEmbedApi(loading) { }; const sendDestroyMessage = () => sendMessage('destroy'); - const processIncomingMessage = (event) => { + const processIncomingMessage = (event: MessageEvent) => { const { id, type } = event.data || {}; if (id === hostId) { @@ -115,13 +132,15 @@ function initPreloadEmbedApi(loading) { } }); - const unsubscribeLoading = loading.state - ? loading.state.subscribeSync(({ stage, progress, error }) => { - if (error || stage === 'received') { + const unsubscribeLoading = loadingState + ? loadingState.subscribeSync((loadDataState) => { + const { stage } = loadDataState; + + if (stage === 'error' || stage === 'received') { unsubscribeLoading(); } - return sendMessage('loadingState', { stage, progress, error }); + return sendMessage('loadingState', loadDataState); }) : () => {}; diff --git a/tsconfig.json b/tsconfig.json index 7ad3f7d3..1d1516e9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,9 @@ "module": "NodeNext", "target": "ES2022", "allowJs": true, - "outDir": "./build", // there are errors without the option (a value doesn't make sense) because of allowJs: true - "strictNullChecks": true + "outDir": "./lib", // there are errors without the option (a value doesn't make sense) because of allowJs: true + // "noImplicitAny": true, + "strictNullChecks": true, + "declaration": true } }