Skip to content

Commit c70bb59

Browse files
committed
Refactor: moving script generation into scriptCache
1 parent abea7fd commit c70bb59

File tree

2 files changed

+61
-66
lines changed

2 files changed

+61
-66
lines changed

src/scriptCache.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,59 @@ export function removeScriptUpdater(
9494
(currentUpdater) => currentUpdater !== updater
9595
);
9696
}
97+
98+
const getNewScript = (source: string): HTMLScriptElement => {
99+
const newScript = document.createElement("script");
100+
newScript.async = true;
101+
newScript.setAttribute("src", source);
102+
return newScript;
103+
};
104+
105+
const setupListeners = (scriptRef: HTMLScriptElement, source: string): void => {
106+
const removeListeners = () => {
107+
scriptRef.removeEventListener("load", loadEvent);
108+
scriptRef.removeEventListener("error", errorEvent);
109+
};
110+
111+
const generateScriptEventListener = (
112+
getResultingCachedScript: (ev: Event) => Partial<CachedScript>
113+
) => (ev: Event) => {
114+
updateCachedScript(source, getResultingCachedScript(ev));
115+
removeListeners();
116+
};
117+
118+
const loadEvent = generateScriptEventListener(() => ({
119+
loading: false,
120+
failed: false,
121+
}));
122+
123+
const errorEvent = generateScriptEventListener((err: ErrorEvent) => ({
124+
loading: false,
125+
failed: true,
126+
failureEvent: err,
127+
}));
128+
129+
scriptRef.addEventListener("load", loadEvent);
130+
scriptRef.addEventListener("error", errorEvent);
131+
};
132+
133+
export function retrieveCachedScript(source: string): CachedScript {
134+
return document.querySelector<HTMLScriptElement>(`script[src="${source}"]`)
135+
? (() => {
136+
const cachedScriptInfo = getFromWindowCache(source);
137+
// if we did not create the script, assume it has loaded
138+
if (!cachedScriptInfo.scriptCreated)
139+
return updateCachedScript(source, {
140+
loading: false,
141+
failed: false,
142+
});
143+
144+
return cachedScriptInfo;
145+
})()
146+
: (() => {
147+
const newRef = getNewScript(source);
148+
setupListeners(newRef, source);
149+
document.body.appendChild(newRef);
150+
return updateCachedScript(source, { scriptCreated: true });
151+
})();
152+
}

src/scriptloader-support/index.tsx

Lines changed: 5 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,10 @@
11
import {
2-
getFromWindowCache,
3-
updateCachedScript,
42
CachedScript,
53
addScriptUpdater,
64
removeScriptUpdater,
5+
retrieveCachedScript,
76
} from "../scriptCache";
87

9-
const getNewScript = (source: string): HTMLScriptElement => {
10-
const newScript = document.createElement("script");
11-
newScript.async = true;
12-
newScript.setAttribute("src", source);
13-
return newScript;
14-
};
15-
16-
const setupListeners = (scriptRef: HTMLScriptElement, source: string): void => {
17-
const removeListeners = () => {
18-
scriptRef.removeEventListener("load", loadEvent);
19-
scriptRef.removeEventListener("error", errorEvent);
20-
};
21-
22-
const generateScriptEventListener = (
23-
getResultingCachedScript: (ev: Event) => Partial<CachedScript>
24-
) => (ev: Event) => {
25-
updateCachedScript(source, getResultingCachedScript(ev));
26-
removeListeners();
27-
};
28-
29-
const loadEvent = generateScriptEventListener(() => ({
30-
loading: false,
31-
failed: false,
32-
}));
33-
34-
const errorEvent = generateScriptEventListener((err: ErrorEvent) => ({
35-
loading: false,
36-
failed: true,
37-
failureEvent: err,
38-
}));
39-
40-
scriptRef.addEventListener("load", loadEvent);
41-
scriptRef.addEventListener("error", errorEvent);
42-
};
43-
448
export const waitForScript = (source: string): Promise<void> =>
459
new Promise<void>((resolve, reject) => {
4610
const updater = ({ loading, failed, failureEvent }: CachedScript) => {
@@ -53,36 +17,11 @@ export const waitForScript = (source: string): Promise<void> =>
5317
removeScriptUpdater(source, updater);
5418
}
5519
};
56-
const handleExistingScript = (ref) => {
57-
const cachedScriptInfo = getFromWindowCache(source);
58-
if (!cachedScriptInfo.scriptCreated) {
59-
// if we did not create the script, assume it has loaded
60-
updater(
61-
updateCachedScript(source, {
62-
loading: false,
63-
failed: false,
64-
})
65-
);
66-
} else if (!cachedScriptInfo.loading) {
67-
updater(cachedScriptInfo);
68-
} else {
69-
addScriptUpdater(source, updater);
70-
}
71-
};
72-
const handleNewScript = () => {
73-
const newRef = getNewScript(source);
74-
updater(updateCachedScript(source, { scriptCreated: true }));
75-
addScriptUpdater(source, updater);
76-
setupListeners(newRef, source);
77-
document.body.appendChild(newRef);
78-
};
79-
const scriptRef = document.querySelector<HTMLScriptElement>(
80-
`script[src="${source}"]`
81-
);
20+
const cachedScriptInfo = retrieveCachedScript(source);
8221

83-
if (scriptRef) {
84-
handleExistingScript(scriptRef);
22+
if (!cachedScriptInfo.loading) {
23+
updater(cachedScriptInfo);
8524
} else {
86-
handleNewScript();
25+
addScriptUpdater(source, updater);
8726
}
8827
});

0 commit comments

Comments
 (0)