1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2 | // SPDX-License-Identifier: Apache-2.0
|
3 | import { Framework } from './types';
|
4 | import { detect } from './detection';
|
5 | // We want to cache detection since the framework won't change
|
6 | var frameworkCache;
|
7 | export var frameworkChangeObservers = [];
|
8 | // Setup the detection reset tracking / timeout delays
|
9 | var resetTriggered = false;
|
10 | var SSR_RESET_TIMEOUT = 10; // ms
|
11 | var WEB_RESET_TIMEOUT = 10; // ms
|
12 | var PRIME_FRAMEWORK_DELAY = 1000; // ms
|
13 | export var detectFramework = function () {
|
14 | if (!frameworkCache) {
|
15 | frameworkCache = detect();
|
16 | if (resetTriggered) {
|
17 | // The final run of detectFramework:
|
18 | // Starting from this point, the `frameworkCache` becomes "final".
|
19 | // So we don't need to notify the observers again so the observer
|
20 | // can be removed after the final notice.
|
21 | while (frameworkChangeObservers.length) {
|
22 | frameworkChangeObservers.pop()();
|
23 | }
|
24 | }
|
25 | else {
|
26 | // The first run of detectFramework:
|
27 | // Every time we update the cache, call each observer function
|
28 | frameworkChangeObservers.forEach(function (fcn) { return fcn(); });
|
29 | }
|
30 | // Retry once for either Unknown type after a delay (explained below)
|
31 | resetTimeout(Framework.ServerSideUnknown, SSR_RESET_TIMEOUT);
|
32 | resetTimeout(Framework.WebUnknown, WEB_RESET_TIMEOUT);
|
33 | }
|
34 | return frameworkCache;
|
35 | };
|
36 | /**
|
37 | * @internal Setup observer callback that will be called everytime the framework changes
|
38 | */
|
39 | export var observeFrameworkChanges = function (fcn) {
|
40 | // When the `frameworkCache` won't be updated again, we ignore all incoming
|
41 | // observers.
|
42 | if (resetTriggered) {
|
43 | return;
|
44 | }
|
45 | frameworkChangeObservers.push(fcn);
|
46 | };
|
47 | export function clearCache() {
|
48 | frameworkCache = undefined;
|
49 | }
|
50 | // For a framework type and a delay amount, setup the event to re-detect
|
51 | // During the runtime boot, it is possible that framework detection will
|
52 | // be triggered before the framework has made modifications to the
|
53 | // global/window/etc needed for detection. When no framework is detected
|
54 | // we will reset and try again to ensure we don't use a cached
|
55 | // non-framework detection result for all requests.
|
56 | function resetTimeout(framework, delay) {
|
57 | if (frameworkCache === framework && !resetTriggered) {
|
58 | setTimeout(function () {
|
59 | clearCache();
|
60 | resetTriggered = true;
|
61 | setTimeout(detectFramework, PRIME_FRAMEWORK_DELAY);
|
62 | }, delay);
|
63 | }
|
64 | }
|