Skip to content

Commit

Permalink
Switch to single queue
Browse files Browse the repository at this point in the history
  • Loading branch information
istarkov committed Apr 24, 2024
1 parent dd1657c commit 2bfa87d
Showing 1 changed file with 33 additions and 11 deletions.
44 changes: 33 additions & 11 deletions packages/sdk-components-react/src/html-embed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ export const __testing__ = {
scriptTestIdPrefix: "client-",
};

const insertScript = (
sourceScript: HTMLScriptElement
): Promise<HTMLScriptElement> => {
const insertScript = (sourceScript: HTMLScriptElement): Promise<void> => {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
const hasSrc = sourceScript.hasAttribute("src");
Expand All @@ -35,7 +33,7 @@ const insertScript = (

if (hasSrc) {
script.addEventListener("load", () => {
resolve(script);
resolve();
});
script.addEventListener("error", reject);
} else {
Expand All @@ -46,21 +44,48 @@ const insertScript = (

// Run the callback immediately for inline scripts.
if (hasSrc === false) {
resolve(script);
resolve();
}
});
};

type ScriptTask = () => Promise<HTMLScriptElement>;
type ScriptTask = () => Promise<void>;

/**
* We want to execute scripts from all embeds sequentially to preserve execution order.
*/
const syncTasksQueue: ScriptTask[] = [];
let processing = false;

const processSyncTasks = async (syncTasks: ScriptTask[]) => {
syncTasksQueue.push(...syncTasks);

// await 1 tick so tasks from all HTMLEmbeds are added to the queue
await Promise.resolve();

if (processing) {
return;
}

processing = true;

while (syncTasksQueue.length > 0) {
const task = syncTasksQueue.shift()!;
await task();
}

processing = false;
};

// Inspiration https://ghinda.net/article/script-tags
const execute = async (container: HTMLElement) => {
const execute = (container: HTMLElement) => {
const scripts = container.querySelectorAll("script");
const syncTasks: Array<ScriptTask> = [];
const asyncTasks: Array<ScriptTask> = [];

scripts.forEach((script) => {
const tasks = script.hasAttribute("async") ? asyncTasks : syncTasks;

tasks.push(() => {
return insertScript(script);
});
Expand All @@ -71,10 +96,7 @@ const execute = async (container: HTMLElement) => {
task();
}

// Insert the script tags sequentially to preserve execution order.
for (const task of syncTasks) {
await task();
}
processSyncTasks(syncTasks);
};

type ChildProps = {
Expand Down

0 comments on commit 2bfa87d

Please sign in to comment.