Two Primary Messaging Patterns
The event bus supports two distinct communication protocols accessed via the sandbox wrapper:
1. Asynchronous Broadcast (Pub/Sub)
Use x.emit(event, data) to broadcast events to any listening components without expecting a return value, and x.on(event, callback) to listen for broadcast messages.
2. RPC Request-Response (Request / Handle)
Use x.handle(key, handlerFn) to register a request receiver that processes data and optionally returns a result, and x.request(key, payload) to invoke a registered request handler anywhere across the app.
Production Code Implementation Examples
1. Registering Handlers & Emitting Events in a Modal Controller
Shows how a component uses x.handle() and x.on() inside its module closure to control interface overlays:
import { Component } from "../HuchiOS/Component.js";
export default class Modal extends Component {
get _ui_html() {
return `
<div class="huchi-modal-card relative bg-white w-full max-w-xl rounded-[2.5rem] p-8">
<button type="button" class="huchi-modal-close-trigger absolute top-6 right-6">
<i class="fa-solid fa-xmark"></i>
</button>
<div id="modal-content"></div>
</div>
`;
}
module() {
return (x) => {
let modalRoot = x.mod();
let container = x.id("modal-content");
const showModal = (config) => {
const { content, callback } = config;
x.manualSwap(container.node(), content);
modalRoot.removeClass("hidden").addClass("flex modal-visible");
if (typeof callback === "function") {
callback(modalRoot.node(), container.node());
}
};
const hideModal = () => {
modalRoot.removeClass("flex modal-visible").addClass("hidden");
x.manualSwap(container.node(), "");
};
return {
init: () => {
// Register system RPC request handlers on the sandbox
x.handle("SYSTEM_MODAL_OPEN", showModal);
x.handle("SYSTEM_MODAL_CLOSE", hideModal);
// Subscribe to broadcast events
x.on("SYSTEM_MODAL_OPEN", showModal);
x.on("SYSTEM_MODAL_CLOSE", hideModal);
const closeTrigger = modalRoot.node().querySelector('.huchi-modal-close-trigger');
if (closeTrigger) {
closeTrigger.addEventListener('click', () => {
hideModal();
// Broadcast event to notify application components of dismissal
x.emit("MODAL_DISMISSED", { timestamp: Date.now() });
});
}
}
};
};
}
}
2. Invoking RPC Requests Across Components
Shows how a separate utility component dispatches requests via x.request() without needing a direct import or reference to the target component:
import { Component } from "../HuchiOS/Component.js";
import { dom } from "../HuchiOS/Utils.js";
export default class Dialogue extends Component {
module() {
return (x) => {
const openDialogue = (body, onConfirm, onCancel) => {
// Dispatch RPC request to the Modal component via the Sandbox
x.request("SYSTEM_MODAL_OPEN", {
size: 'md',
content: `
<div class="huchi-dialogue flex flex-col">
<div class="dialogue-body">${body}</div>
<div class="mt-6 flex justify-end gap-2">
<button type="button" class="btn-cancel">Cancel</button>
<button type="button" class="btn-confirm">Confirm</button>
</div>
</div>
`,
callback: (modalParent, modalBody) => {
const bodyWrapper = dom(modalBody);
bodyWrapper.select('.btn-confirm').on('click', async (e) => {
x.stop(e);
if (typeof onConfirm === "function") await onConfirm(bodyWrapper);
// Close modal by firing request
x.request("SYSTEM_MODAL_CLOSE");
});
bodyWrapper.select('.btn-cancel').on('click', (e) => {
x.stop(e);
if (typeof onCancel === "function") onCancel(bodyWrapper);
x.request("SYSTEM_MODAL_CLOSE");
});
}
});
};
return {
init: () => {
window.confirmDialogue = (body, onConfirm, onCancel) => {
openDialogue(body, onConfirm, onCancel);
};
}
};
};
}
}