
// marked does not support asynchronous steps in the rendering process.
// as such, in order to support external renderers that do their processing
// async, this handles swapping out a placeholder for the additionally processed
// content after marked is finished rendering

let next_task_id = 1;
const data_binding = /{{@@!@!@@ MARKED ASYNC DATA BINDING PLACEHOLDER {{([0-9]+)}} @@!@!@@}}/g;

const pending_tasks: Record<number, Promise<string>> = { };

export function bind_data_async(data_generator: Promise<string>) {
	const task_id = next_task_id++;
	const placeholder = `{{@@!@!@@ MARKED ASYNC DATA BINDING PLACEHOLDER {{${task_id}}} @@!@!@@}}`;
	pending_tasks[task_id] = data_generator;
	return placeholder;
}

export async function resolve_async_bindings(html: string) {
	const bindings: string[] = [ ];
	const promises: Promise<string>[] = [ ];

	let match: RegExpMatchArray;

	while (match = data_binding.exec(html)) {
		bindings.push(match[0]);
		promises.push(pending_tasks[match[1]]);
		delete pending_tasks[match[1]];
	}

	data_binding.lastIndex = 0;

	const results = await Promise.all(promises);

	for (let i = 0; i < results.length; i++) {
		html = html.replace(bindings[i], results[i]);
	}

	return html;
}

