Extract CaptureButton; allow non-singletone connections

This commit is contained in:
Ingvar Stepanyan
2021-07-21 16:38:18 +00:00
parent 73148dbc11
commit 4371da9270
3 changed files with 116 additions and 118 deletions

View File

@@ -2,43 +2,39 @@ import initModule from '../libapi.mjs';
/** @typedef {import('../libapi.mjs').Context} Context */
/** This function should be called once user has selected the camera and other operations can begin. */
export let start;
const ContextPromise = initModule().then(Module => Module.Context);
let started = new Promise(resolve => {
start = resolve;
});
export async function connect() {
let Context = await ContextPromise;
let queue = (async () => {
let { Context } = await initModule();
await started;
let ctx = await new Context();
addEventListener('beforeunload', e => {
ctx.delete();
});
return ctx;
})();
let context = await new Context();
/** Schedules an exclusive async operation on the global context.
* @template T
* @param {(ctx: Context) => Promise<T>} op
* @returns {Promise<T>}
*/
export function scheduleOp(op) {
let caughtRes = queue.then(async ctx => {
let resultPromise = op(ctx);
try {
await resultPromise;
} catch {}
return {
ctx,
resultPromise
};
});
let queue = Promise.resolve();
// Queue should ignore result values as well as errors from singular ops.
queue = caughtRes.then(res => res.ctx);
/** Schedules an exclusive async operation on the global context.
* @template T
* @param {(ctx: Context) => Promise<T>} op
* @returns {Promise<T>}
*/
function schedule(op) {
let res = queue.then(() => op(context));
// Result should contain the unwrapped value or error.
return caughtRes.then(res => res.resultPromise);
// Queue should ignore result values as well as errors from singular ops.
queue = res.then(
() => {},
() => {}
);
// Result should contain the unwrapped value or error.
return res;
}
return {
schedule,
disconnect() {
context.delete();
}
};
}
/** @typedef {ReturnType<typeof connect> extends Promise<infer Connection> ? Connection : never} Connection */