frontend-hamroun
Version:
A lightweight frontend JavaScript framework with React-like syntax
75 lines (74 loc) • 2.41 kB
JavaScript
export function createEventBus() {
const events = new Map();
const onceHandlers = new WeakMap();
const on = (event, handler) => {
if (!events.has(event)) {
events.set(event, new Set());
}
events.get(event).add(handler);
// Return a function to remove this handler
return () => off(event, handler);
};
const once = (event, handler) => {
// Create a wrapper that will call the handler and remove itself
const onceWrapper = (...args) => {
off(event, onceWrapper);
handler(...args);
};
// Store the mapping between the original handler and the wrapper
onceHandlers.set(handler, onceWrapper);
// Register the wrapper
return on(event, onceWrapper);
};
const off = (event, handler) => {
// If no handler is provided, remove all handlers for the event
if (!handler) {
events.delete(event);
return;
}
// Check if it's a once handler wrapper
const wrappedHandler = onceHandlers.get(handler);
const handlerToRemove = wrappedHandler || handler;
if (events.has(event)) {
events.get(event).delete(handlerToRemove);
// Clean up empty event sets
if (events.get(event).size === 0) {
events.delete(event);
}
}
};
const emit = (event, ...args) => {
if (!events.has(event)) {
return;
}
// Create a copy of the handlers to avoid issues if handlers modify the set
const handlers = Array.from(events.get(event));
// Call each handler with the arguments
for (const handler of handlers) {
handler(...args);
}
};
const clear = (event) => {
if (event) {
events.delete(event);
}
else {
events.clear();
}
};
return { on, once, off, emit, clear };
}
// Create a global event bus instance
const globalEventBus = createEventBus();
// Hook to use the event bus in components
export function useEvent(event, handler, options = {}) {
return options.once
? globalEventBus.once(event, handler)
: globalEventBus.on(event, handler);
}
export { globalEventBus as eventBus };
export default {
createEventBus,
eventBus: globalEventBus,
useEvent
};