UNPKG

preboot

Version:

Record server view events and play back to Angular client view

82 lines 12 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vc3JjL2xpYi8iLCJzb3VyY2VzIjpbInByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUNILE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsY0FBYyxFQUNkLE1BQU0sRUFDTixjQUFjLEVBQ2QsUUFBUSxFQUNSLFdBQVcsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDOUUsT0FBTyxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1QyxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDbkQsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sRUFBQyxtQkFBbUIsRUFBRSxtQkFBbUIsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBRW5GLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxPQUFPLENBQUM7QUFFdEMsTUFBTSxvQkFBb0IsR0FBRyx1QkFBdUIsQ0FBQztBQUNyRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsSUFBSSxjQUFjLENBQWlCLGdCQUFnQixDQUFDLENBQUM7QUFFcEYsU0FBUyxvQkFBb0IsQ0FBQyxHQUFhLEVBQUUsS0FBa0IsRUFBRSxVQUFrQjtJQUNqRixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzNDLElBQUksS0FBSyxFQUFFO1FBQ1IsTUFBYyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7S0FDL0I7SUFDRCxNQUFNLENBQUMsU0FBUyxHQUFHLG9CQUFvQixDQUFDO0lBQ3hDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDO0lBRWhDLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFF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Iiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQge1xuICBBUFBfQk9PVFNUUkFQX0xJU1RFTkVSLFxuICBBcHBsaWNhdGlvblJlZixcbiAgSW5qZWN0LFxuICBJbmplY3Rpb25Ub2tlbixcbiAgT3B0aW9uYWwsXG4gIFBMQVRGT1JNX0lEXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtET0NVTUVOVCwgaXNQbGF0Zm9ybUJyb3dzZXIsIGlzUGxhdGZvcm1TZXJ2ZXJ9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge2ZpbHRlciwgdGFrZX0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge0V2ZW50UmVwbGF5ZXJ9IGZyb20gJy4vYXBpL2V2ZW50LnJlcGxheWVyJztcbmltcG9ydCB7UFJFQk9PVF9OT05DRX0gZnJvbSAnLi9jb21tb24vdG9rZW5zJztcbmltcG9ydCB7Z2V0SW5saW5lRGVmaW5pdGlvbiwgZ2V0SW5saW5lSW52b2NhdGlvbn0gZnJvbSAnLi9hcGkvaW5saW5lLnByZWJvb3QuY29kZSc7XG5pbXBvcnQge1ByZWJvb3RPcHRpb25zfSBmcm9tICcuL2NvbW1vbi9wcmVib290LmludGVyZmFjZXMnO1xuaW1wb3J0IHt2YWxpZGF0ZU9wdGlvbnN9IGZyb20gJy4vYXBpJztcblxuY29uc3QgUFJFQk9PVF9TQ1JJUFRfQ0xBU1MgPSAncHJlYm9vdC1pbmxpbmUtc2NyaXB0JztcbmV4cG9ydCBjb25zdCBQUkVCT09UX09QVElPTlMgPSBuZXcgSW5qZWN0aW9uVG9rZW48UHJlYm9vdE9wdGlvbnM+KCdQcmVib290T3B0aW9ucycpO1xuXG5mdW5jdGlvbiBjcmVhdGVTY3JpcHRGcm9tQ29kZShkb2M6IERvY3VtZW50LCBub25jZTogc3RyaW5nfG51bGwsIGlubGluZUNvZGU6IHN0cmluZykge1xuICBjb25zdCBzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gIGlmIChub25jZSkge1xuICAgIChzY3JpcHQgYXMgYW55KS5ub25jZSA9IG5vbmNlO1xuICB9XG4gIHNjcmlwdC5jbGFzc05hbWUgPSBQUkVCT09UX1NDUklQVF9DTEFTUztcbiAgc2NyaXB0LnRleHRDb250ZW50ID0gaW5saW5lQ29kZTtcblxuICByZXR1cm4gc2NyaXB0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gUFJFQk9PVF9GQUNUT1JZKGRvYzogRG9jdW1lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWJvb3RPcHRzOiBQcmVib290T3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHN0cmluZ3xudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybUlkOiBPYmplY3QsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcFJlZjogQXBwbGljYXRpb25SZWYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50UmVwbGF5ZXI6IEV2ZW50UmVwbGF5ZXIpIHtcbiAgcmV0dXJuICgpID0+IHtcbiAgICB2YWxpZGF0ZU9wdGlvbnMocHJlYm9vdE9wdHMpO1xuXG4gICAgaWYgKGlzUGxhdGZvcm1TZXJ2ZXIocGxhdGZvcm1JZCkpIHtcbiAgICAgIGNvbnN0IGlubGluZUNvZGVEZWZpbml0aW9uID0gZ2V0SW5saW5lRGVmaW5pdGlvbihwcmVib290T3B0cyk7XG4gICAgICBjb25zdCBzY3JpcHRXaXRoRGVmaW5pdGlvbiA9IGNyZWF0ZVNjcmlwdEZyb21Db2RlKGRvYywgbm9uY2UsIGlubGluZUNvZGVEZWZpbml0aW9uKTtcbiAgICAgIGNvbnN0IGlubGluZUNvZGVJbnZvY2F0aW9uID0gZ2V0SW5saW5lSW52b2NhdGlvbigpO1xuXG4gICAgICBjb25zdCBleGlzdGluZ1NjcmlwdHMgPSBkb2MuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShQUkVCT09UX1NDUklQVF9DTEFTUyk7XG5cbiAgICAgIC8vIENoZWNrIHRvIHNlZSBpZiBwcmVib290IHNjcmlwdHMgYXJlIGFscmVhZHkgaW5saW5lZCBiZWZvcmUgYWRkaW5nIHRoZW1cbiAgICAgIC8vIHRvIHRoZSBET00uIElmIHRoZXkgYXJlLCB1cGRhdGUgdGhlIG5vbmNlIHRvIGJlIGN1cnJlbnQuXG4gICAgICBpZiAoZXhpc3RpbmdTY3JpcHRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb25zdCBiYXNlTGlzdDogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgY29uc3QgYXBwUm9vdFNlbGVjdG9ycyA9IGJhc2VMaXN0LmNvbmNhdChwcmVib290T3B0cy5hcHBSb290KTtcbiAgICAgICAgZG9jLmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0V2l0aERlZmluaXRpb24pO1xuICAgICAgICBhcHBSb290U2VsZWN0b3JzXG4gICAgICAgICAgLm1hcChzZWxlY3RvciA9PiAoe1xuICAgICAgICAgICAgc2VsZWN0b3IsXG4gICAgICAgICAgICBhcHBSb290RWxlbTogZG9jLnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpXG4gICAgICAgICAgfSkpXG4gICAgICAgICAgLmZvckVhY2goKHtzZWxlY3RvciwgYXBwUm9vdEVsZW19KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWFwcFJvb3RFbGVtKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBObyBzZXJ2ZXIgbm9kZSBmb3VuZCBmb3Igc2VsZWN0b3I6ICR7c2VsZWN0b3J9YCk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHNjcmlwdFdpdGhJbnZvY2F0aW9uID0gY3JlYXRlU2NyaXB0RnJvbUNvZGUoZG9jLCBub25jZSwgaW5saW5lQ29kZUludm9jYXRpb24pO1xuICAgICAgICAgICAgYXBwUm9vdEVsZW0uaW5zZXJ0QmVmb3JlKHNjcmlwdFdpdGhJbnZvY2F0aW9uLCBhcHBSb290RWxlbS5maXJzdENoaWxkKTtcbiAgICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZXhpc3RpbmdTY3JpcHRzLmxlbmd0aCA+IDAgJiYgbm9uY2UpIHtcbiAgICAgICAgKGV4aXN0aW5nU2NyaXB0c1swXSBhcyBhbnkpLm5vbmNlID0gbm9uY2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKSkge1xuICAgICAgY29uc3QgcmVwbGF5ID0gcHJlYm9vdE9wdHMucmVwbGF5ICE9IG51bGwgPyBwcmVib290T3B0cy5yZXBsYXkgOiB0cnVlO1xuICAgICAgaWYgKHJlcGxheSkge1xuICAgICAgICBhcHBSZWYuaXNTdGFibGVcbiAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgIGZpbHRlcihzdGFibGUgPT4gc3RhYmxlKSxcbiAgICAgICAgICAgIHRha2UoMSlcbiAgICAgICAgICApLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgZXZlbnRSZXBsYXllci5yZXBsYXlBbGwoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgY29uc3QgUFJFQk9PVF9QUk9WSURFUiA9IHtcbiAgcHJvdmlkZTogPEluamVjdGlvblRva2VuPCgpID0+IHZvaWQ+PkFQUF9CT09UU1RSQVBfTElTVEVORVIsXG4gIHVzZUZhY3Rvcnk6IFBSRUJPT1RfRkFDVE9SWSxcbiAgZGVwczogW1xuICAgIERPQ1VNRU5ULFxuICAgIFBSRUJPT1RfT1BUSU9OUyxcbiAgICBbbmV3IE9wdGlvbmFsKCksIG5ldyBJbmplY3QoUFJFQk9PVF9OT05DRSldLFxuICAgIFBMQVRGT1JNX0lELFxuICAgIEFwcGxpY2F0aW9uUmVmLFxuICAgIEV2ZW50UmVwbGF5ZXIsXG4gIF0sXG4gIG11bHRpOiB0cnVlXG59O1xuIl19