62 lines
1.8 KiB
JavaScript
62 lines
1.8 KiB
JavaScript
const FrankieSDK = (() => {
|
|
const _handlers = {}
|
|
const _llmResolvers = {}
|
|
|
|
// _handle dispatches an inbound postMessage event to the registered hook.
|
|
function _handle(type, payload) {
|
|
const hook = _handlers[type]
|
|
if (typeof hook === 'function') hook(payload)
|
|
}
|
|
|
|
// Boot: listen for messages from the Frankie parent frame.
|
|
window.addEventListener('message', (event) => {
|
|
const { type, payload, id } = event.data || {}
|
|
if (typeof type !== 'string' || !type.startsWith('FRANKIE_')) return
|
|
|
|
const hook = type.slice(8).toLowerCase() // FRANKIE_INIT → 'init'
|
|
|
|
// LLM responses are resolved as promises rather than dispatched as hooks.
|
|
if (hook === 'llm_response') {
|
|
const resolve = _llmResolvers[id]
|
|
if (typeof resolve === 'function') {
|
|
resolve(payload?.content ?? '')
|
|
delete _llmResolvers[id]
|
|
}
|
|
return
|
|
}
|
|
|
|
_handle(hook, payload)
|
|
})
|
|
|
|
return {
|
|
// on registers a lifecycle hook. Returns the SDK for chaining.
|
|
on(event, handler) {
|
|
_handlers[event] = handler
|
|
return this
|
|
},
|
|
|
|
// emit sends a typed event to the Frankie parent frame.
|
|
emit(event, payload = {}) {
|
|
window.parent.postMessage(
|
|
{ type: `FRANKIE_${event.toUpperCase()}`, payload },
|
|
'*'
|
|
)
|
|
},
|
|
|
|
// llm sends a chat-completion request to Frankie's LLM and returns a Promise
|
|
// that resolves with the model's reply as a string.
|
|
llm(messages) {
|
|
return new Promise((resolve) => {
|
|
const id = `llm_${Date.now()}_${Math.random().toString(36).slice(2)}`
|
|
_llmResolvers[id] = resolve
|
|
window.parent.postMessage(
|
|
{ type: 'FRANKIE_LLM_REQUEST', id, payload: { messages } },
|
|
'*'
|
|
)
|
|
})
|
|
}
|
|
}
|
|
})()
|
|
|
|
export default FrankieSDK
|