|
|
|
|
|
export function workerConnection() { |
|
|
|
|
|
const workerLoaded = loadWorker(); |
|
|
|
const connection = { |
|
loaded: workerLoaded.then(worker => ({ env: worker.env })), |
|
loadModel, |
|
runPrompt, |
|
listChatModels |
|
}; |
|
|
|
return connection; |
|
|
|
function loadWorker() { |
|
|
|
|
|
|
|
return new Promise((resolve, reject) => { |
|
try { |
|
const scriptUrl = (typeof document !== 'undefined' && (document.currentScript && (document.currentScript).src)) || |
|
(typeof document !== 'undefined' && document.scripts && document.scripts[document.scripts.length - 1] && document.scripts[document.scripts.length - 1].src) || |
|
(typeof window !== 'undefined' && window.location && window.location.href) || ''; |
|
|
|
const worker = new Worker(scriptUrl, { type: 'module' }); |
|
|
|
const pending = new Map(); |
|
let ready = false; |
|
|
|
worker.addEventListener('message', (ev) => { |
|
const msg = ev.data || {}; |
|
if (msg && msg.type === 'ready') { |
|
ready = true; |
|
resolve({ worker, pending, send, env: msg.env }); |
|
return; |
|
} |
|
if (msg && msg.id) { |
|
const id = msg.id; |
|
const entry = pending.get(id); |
|
if (!entry) return; |
|
if (msg.type === 'response') { |
|
pending.delete(id); |
|
entry.resolve(msg.result); |
|
} else if (msg.type === 'error') { |
|
pending.delete(id); |
|
entry.reject(new Error(msg.error)); |
|
} else if (msg.type === 'progress') { |
|
|
|
try { |
|
if (entry.onProgress) entry.onProgress(msg); |
|
} catch (e) { |
|
|
|
} |
|
} |
|
} |
|
}); |
|
|
|
worker.addEventListener('error', (err) => { |
|
if (!ready) reject(err); |
|
}); |
|
|
|
function send(message) { |
|
return new Promise((res, rej) => { |
|
const id = String(Math.random()).slice(2); |
|
pending.set(id, { resolve: res, reject: rej }); |
|
worker.postMessage(Object.assign({}, message, { id })); |
|
}); |
|
} |
|
} catch (err) { |
|
reject(err); |
|
} |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
async function listChatModels(params = {}, onProgress) { |
|
await workerLoaded; |
|
const { worker, pending } = await workerLoaded; |
|
const id = String(Math.random()).slice(2); |
|
let resolved = false; |
|
const promise = new Promise((resolve, reject) => { |
|
pending.set(id, { resolve: (res) => { resolved = true; resolve(res); }, reject, onProgress }); |
|
try { |
|
worker.postMessage(Object.assign({}, params, { type: 'listChatModels', id })); |
|
} catch (err) { |
|
pending.delete(id); |
|
reject(err); |
|
} |
|
}); |
|
|
|
const cancel = () => { |
|
try { |
|
if (!resolved) worker.postMessage({ type: 'cancelListChatModels', id }); |
|
} catch (e) {} |
|
pending.delete(id); |
|
}; |
|
|
|
return { id, promise, cancel }; |
|
} |
|
|
|
|
|
async function loadModel(modelName) { |
|
await workerLoaded; |
|
const { send } = await workerLoaded; |
|
return send({ type: 'loadModel', modelName }); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function runPrompt(promptText, modelName) { |
|
await workerLoaded; |
|
const { send } = await workerLoaded; |
|
const sendPromise = send({ type: 'runPrompt', prompt: promptText, modelName }); |
|
return sendPromise; |
|
} |
|
} |
|
|