UNPKG

ngx-preboot

Version:

Record server view events and play back to Angular client view

76 lines 11.7 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { APP_BOOTSTRAP_LISTENER, ApplicationRef, Inject, InjectionToken, Optional, PLATFORM_ID } from '@angular/core'; import { DOCUMENT, isPlatformBrowser, isPlatformServer } from '@angular/common'; import { filter, take } from 'rxjs/operators'; import { EventReplayer } from './api/event.replayer'; import { PREBOOT_NONCE } from './common/tokens'; import { getInlineDefinition, getInlineInvocation } from './api/inline.preboot.code'; import { validateOptions } from './api'; const PREBOOT_SCRIPT_CLASS = 'preboot-inline-script'; export const PREBOOT_OPTIONS = new InjectionToken('PrebootOptions'); function createScriptFromCode(doc, nonce, inlineCode) { const script = doc.createElement('script'); if (nonce) { script.nonce = nonce; } script.className = PREBOOT_SCRIPT_CLASS; script.textContent = inlineCode; return script; } export function PREBOOT_FACTORY(doc, prebootOpts, nonce, platformId, appRef, eventReplayer) { return () => { validateOptions(prebootOpts); if (isPlatformServer(platformId)) { const inlineCodeDefinition = getInlineDefinition(prebootOpts); const scriptWithDefinition = createScriptFromCode(doc, nonce, inlineCodeDefinition); const inlineCodeInvocation = getInlineInvocation(); const existingScripts = doc.getElementsByClassName(PREBOOT_SCRIPT_CLASS); // Check to see if preboot scripts are already inlined before adding them // to the DOM. If they are, update the nonce to be current. if (existingScripts.length === 0) { const baseList = []; const appRootSelectors = baseList.concat(prebootOpts.appRoot); doc.head.appendChild(scriptWithDefinition); appRootSelectors .map((selector) => ({ selector, appRootElem: doc.querySelector(selector), })) .forEach(({ selector, appRootElem }) => { if (!appRootElem) { console.log(`No server node found for selector: ${selector}`); return; } const scriptWithInvocation = createScriptFromCode(doc, nonce, inlineCodeInvocation); appRootElem.insertBefore(scriptWithInvocation, appRootElem.firstChild); }); } else if (existingScripts.length > 0 && nonce) { existingScripts[0].nonce = nonce; } } if (isPlatformBrowser(platformId)) { const replay = prebootOpts.replay != null ? prebootOpts.replay : true; if (replay) { appRef.isStable .pipe(filter((stable) => stable), take(1)) .subscribe(() => { eventReplayer.replayAll(); }); } } }; } export const PREBOOT_PROVIDER = { provide: APP_BOOTSTRAP_LISTENER, useFactory: PREBOOT_FACTORY, deps: [DOCUMENT, PREBOOT_OPTIONS, [new Optional(), new Inject(PREBOOT_NONCE)], PLATFORM_ID, ApplicationRef, EventReplayer], multi: true, }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vc3JjL2xpYi8iLCJzb3VyY2VzIjpbInByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUNILE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RILE9BQU8sRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRixPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFckYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUV4QyxNQUFNLG9CQUFvQixHQUFHLHVCQUF1QixDQUFDO0FBQ3JELE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxJQUFJLGNBQWMsQ0FBaUIsZ0JBQWdCLENBQUMsQ0FBQztBQUVwRixTQUFTLG9CQUFvQixDQUFDLEdBQWEsRUFBRSxLQUFvQixFQUFFLFVBQWtCO0lBQ25GLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDM0MsSUFBSSxLQUFLLEVBQUU7UUFDUixNQUFjLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztLQUMvQjtJQUNELE1BQU0sQ0FBQyxTQUFTLEdBQUcsb0JBQW9CLENBQUM7SUFDeEMsTUFBTSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUM7SUFFaEMsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELE1BQU0sVUFBVSxlQUFlLENBQzdCLEdBQWEsRUFDYixXQUEyQixFQUMzQixLQUFvQixFQUNwQixVQUFrQixFQUNsQixNQUFzQixFQUN0QixhQUE0QjtJQUU1QixPQUFPLEdBQUcsRUFBRTtRQUNWLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUU3QixJQUFJLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ2hDLE1BQU0sb0JBQW9CLEdBQUcsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDOUQsTUFBTSxvQkFBb0IsR0FBRyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLG9CQUFvQixDQUFDLENBQUM7WUFDcEYsTUFBTSxvQkFBb0IsR0FBRyxtQkFBbUIsRUFBRSxDQUFDO1lBRW5ELE1BQU0sZUFBZSxHQUFHLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBRXpFLHlFQUF5RTtZQUN6RSwyREFBMkQ7WUFDM0QsSUFBSSxlQUFlLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDaEMsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO2dCQUM5QixNQUFNLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM5RCxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO2dCQUMzQyxnQkFBZ0I7cUJBQ2IsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUNsQixRQUFRO29CQUNSLFdBQVcsRUFBRSxHQUFHLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQztpQkFDekMsQ0FBQyxDQUFDO3FCQUNGLE9BQU8sQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUU7b0JBQ3JDLElBQUksQ0FBQyxXQUFXLEVBQUU7d0JBQ2hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLFFBQVEsRUFBRSxDQUFDLENBQUM7d0JBQzlELE9BQU87cUJBQ1I7b0JBQ0QsTUFBTSxvQkFBb0IsR0FBRyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLG9CQUFvQixDQUFDLENBQUM7b0JBQ3BGLFdBQVcsQ0FBQyxZQUFZLENBQUMsb0JBQW9CLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUN6RSxDQUFDLENBQUMsQ0FBQzthQUNOO2lCQUFNLElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxFQUFFO2dCQUM3QyxlQUFlLENBQUMsQ0FBQyxDQUFTLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQzthQUMzQztTQUNGO1FBQ0QsSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUNqQyxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ3RFLElBQUksTUFBTSxFQUFFO2dCQUNWLE1BQU0sQ0FBQyxRQUFRO3FCQUNaLElBQUksQ0FDSCxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUMxQixJQUFJLENBQUMsQ0FBQyxDQUFDLENBQ1I7cUJBQ0EsU0FBUyxDQUFDLEdBQUcsRUFBRTtvQkFDZCxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQzVCLENBQUMsQ0FBQyxDQUFDO2FBQ047U0FDRjtJQUNILENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRztJQUM5QixPQUFPLEVBQThCLHNCQUFzQjtJQUMzRCxVQUFVLEVBQUUsZUFBZTtJQUMzQixJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUUsZUFBZSxFQUFFLENBQUMsSUFBSSxRQUFRLEVBQUUsRUFBRSxJQUFJLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsYUFBYSxDQUFDO0lBQzFILEtBQUssRUFBRSxJQUFJO0NBQ1osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHsgQVBQX0JPT1RTVFJBUF9MSVNURU5FUiwgQXBwbGljYXRpb25SZWYsIEluamVjdCwgSW5qZWN0aW9uVG9rZW4sIE9wdGlvbmFsLCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQsIGlzUGxhdGZvcm1Ccm93c2VyLCBpc1BsYXRmb3JtU2VydmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGZpbHRlciwgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgRXZlbnRSZXBsYXllciB9IGZyb20gJy4vYXBpL2V2ZW50LnJlcGxheWVyJztcbmltcG9ydCB7IFBSRUJPT1RfTk9OQ0UgfSBmcm9tICcuL2NvbW1vbi90b2tlbnMnO1xuaW1wb3J0IHsgZ2V0SW5saW5lRGVmaW5pdGlvbiwgZ2V0SW5saW5lSW52b2NhdGlvbiB9IGZyb20gJy4vYXBpL2lubGluZS5wcmVib290LmNvZGUnO1xuaW1wb3J0IHsgUHJlYm9vdE9wdGlvbnMgfSBmcm9tICcuL2NvbW1vbi9wcmVib290LmludGVyZmFjZXMnO1xuaW1wb3J0IHsgdmFsaWRhdGVPcHRpb25zIH0gZnJvbSAnLi9hcGknO1xuXG5jb25zdCBQUkVCT09UX1NDUklQVF9DTEFTUyA9ICdwcmVib290LWlubGluZS1zY3JpcHQnO1xuZXhwb3J0IGNvbnN0IFBSRUJPT1RfT1BUSU9OUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxQcmVib290T3B0aW9ucz4oJ1ByZWJvb3RPcHRpb25zJyk7XG5cbmZ1bmN0aW9uIGNyZWF0ZVNjcmlwdEZyb21Db2RlKGRvYzogRG9jdW1lbnQsIG5vbmNlOiBzdHJpbmcgfCBudWxsLCBpbmxpbmVDb2RlOiBzdHJpbmcpIHtcbiAgY29uc3Qgc2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICBpZiAobm9uY2UpIHtcbiAgICAoc2NyaXB0IGFzIGFueSkubm9uY2UgPSBub25jZTtcbiAgfVxuICBzY3JpcHQuY2xhc3NOYW1lID0gUFJFQk9PVF9TQ1JJUFRfQ0xBU1M7XG4gIHNjcmlwdC50ZXh0Q29udGVudCA9IGlubGluZUNvZGU7XG5cbiAgcmV0dXJuIHNjcmlwdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFBSRUJPT1RfRkFDVE9SWShcbiAgZG9jOiBEb2N1bWVudCxcbiAgcHJlYm9vdE9wdHM6IFByZWJvb3RPcHRpb25zLFxuICBub25jZTogc3RyaW5nIHwgbnVsbCxcbiAgcGxhdGZvcm1JZDogT2JqZWN0LFxuICBhcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICBldmVudFJlcGxheWVyOiBFdmVudFJlcGxheWVyXG4pIHtcbiAgcmV0dXJuICgpID0+IHtcbiAgICB2YWxpZGF0ZU9wdGlvbnMocHJlYm9vdE9wdHMpO1xuXG4gICAgaWYgKGlzUGxhdGZvcm1TZXJ2ZXIocGxhdGZvcm1JZCkpIHtcbiAgICAgIGNvbnN0IGlubGluZUNvZGVEZWZpbml0aW9uID0gZ2V0SW5saW5lRGVmaW5pdGlvbihwcmVib290T3B0cyk7XG4gICAgICBjb25zdCBzY3JpcHRXaXRoRGVmaW5pdGlvbiA9IGNyZWF0ZVNjcmlwdEZyb21Db2RlKGRvYywgbm9uY2UsIGlubGluZUNvZGVEZWZpbml0aW9uKTtcbiAgICAgIGNvbnN0IGlubGluZUNvZGVJbnZvY2F0aW9uID0gZ2V0SW5saW5lSW52b2NhdGlvbigpO1xuXG4gICAgICBjb25zdCBleGlzdGluZ1NjcmlwdHMgPSBkb2MuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShQUkVCT09UX1NDUklQVF9DTEFTUyk7XG5cbiAgICAgIC8vIENoZWNrIHRvIHNlZSBpZiBwcmVib290IHNjcmlwdHMgYXJlIGFscmVhZHkgaW5saW5lZCBiZWZvcmUgYWRkaW5nIHRoZW1cbiAgICAgIC8vIHRvIHRoZSBET00uIElmIHRoZXkgYXJlLCB1cGRhdGUgdGhlIG5vbmNlIHRvIGJlIGN1cnJlbnQuXG4gICAgICBpZiAoZXhpc3RpbmdTY3JpcHRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb25zdCBiYXNlTGlzdDogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgY29uc3QgYXBwUm9vdFNlbGVjdG9ycyA9IGJhc2VMaXN0LmNvbmNhdChwcmVib290T3B0cy5hcHBSb290KTtcbiAgICAgICAgZG9jLmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0V2l0aERlZmluaXRpb24pO1xuICAgICAgICBhcHBSb290U2VsZWN0b3JzXG4gICAgICAgICAgLm1hcCgoc2VsZWN0b3IpID0+ICh7XG4gICAgICAgICAgICBzZWxlY3RvcixcbiAgICAgICAgICAgIGFwcFJvb3RFbGVtOiBkb2MucXVlcnlTZWxlY3RvcihzZWxlY3RvciksXG4gICAgICAgICAgfSkpXG4gICAgICAgICAgLmZvckVhY2goKHsgc2VsZWN0b3IsIGFwcFJvb3RFbGVtIH0pID0+IHtcbiAgICAgICAgICAgIGlmICghYXBwUm9vdEVsZW0pIHtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coYE5vIHNlcnZlciBub2RlIGZvdW5kIGZvciBzZWxlY3RvcjogJHtzZWxlY3Rvcn1gKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2NyaXB0V2l0aEludm9jYXRpb24gPSBjcmVhdGVTY3JpcHRGcm9tQ29kZShkb2MsIG5vbmNlLCBpbmxpbmVDb2RlSW52b2NhdGlvbik7XG4gICAgICAgICAgICBhcHBSb290RWxlbS5pbnNlcnRCZWZvcmUoc2NyaXB0V2l0aEludm9jYXRpb24sIGFwcFJvb3RFbGVtLmZpcnN0Q2hpbGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChleGlzdGluZ1NjcmlwdHMubGVuZ3RoID4gMCAmJiBub25jZSkge1xuICAgICAgICAoZXhpc3RpbmdTY3JpcHRzWzBdIGFzIGFueSkubm9uY2UgPSBub25jZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHBsYXRmb3JtSWQpKSB7XG4gICAgICBjb25zdCByZXBsYXkgPSBwcmVib290T3B0cy5yZXBsYXkgIT0gbnVsbCA/IHByZWJvb3RPcHRzLnJlcGxheSA6IHRydWU7XG4gICAgICBpZiAocmVwbGF5KSB7XG4gICAgICAgIGFwcFJlZi5pc1N0YWJsZVxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgZmlsdGVyKChzdGFibGUpID0+IHN0YWJsZSksXG4gICAgICAgICAgICB0YWtlKDEpXG4gICAgICAgICAgKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgZXZlbnRSZXBsYXllci5yZXBsYXlBbGwoKTtcbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBQUkVCT09UX1BST1ZJREVSID0ge1xuICBwcm92aWRlOiA8SW5qZWN0aW9uVG9rZW48KCkgPT4gdm9pZD4+QVBQX0JPT1RTVFJBUF9MSVNURU5FUixcbiAgdXNlRmFjdG9yeTogUFJFQk9PVF9GQUNUT1JZLFxuICBkZXBzOiBbRE9DVU1FTlQsIFBSRUJPT1RfT1BUSU9OUywgW25ldyBPcHRpb25hbCgpLCBuZXcgSW5qZWN0KFBSRUJPT1RfTk9OQ0UpXSwgUExBVEZPUk1fSUQsIEFwcGxpY2F0aW9uUmVmLCBFdmVudFJlcGxheWVyXSxcbiAgbXVsdGk6IHRydWUsXG59O1xuIl19