gold-sight
Version:
Test your code on realistic content, precisely
343 lines • 11.6 kB
JavaScript
class EventBus {
constructor(events = {}) {
this.isEventBus = true;
this.events = {};
this.overwrittenEvents = {};
this.emitOnceEvents = {};
this.events = events;
}
emit(name, ctx, payload) {
if (!payload)
payload = {};
const newEvent = {
name,
payload,
uuidStack: ctx.eventUUIDs,
funcData: ctx.funcData,
eventUUID: ctx.eventUUID,
};
let events = this.events[name];
if (!events) {
events = this.events[name] = [];
}
events.push(newEvent);
return newEvent;
}
emitOne(name, uuid, key, payload) {
const exisitingEvents = filterEventsByPayload(this, "*", key);
for (const [name, events] of Object.entries(this.events)) {
this.events[name] = events.filter((event) => !exisitingEvents.includes(event));
}
for (const event of exisitingEvents) {
if (!this.overwrittenEvents[event.name]) {
this.overwrittenEvents[event.name] = [];
}
this.overwrittenEvents[event.name].push(event);
}
if (!payload)
payload = {};
payload = { ...payload, ...key };
return this.emit(name, uuid, payload);
}
emitOnce(name, ctx, payload) {
let emitOnceEvents = this.emitOnceEvents[name];
if (!emitOnceEvents)
this.emitOnceEvents[name] = emitOnceEvents = [];
if (emitOnceEvents.find((event) => event.uuidStack.includes(ctx.eventUUID)))
return null;
emitOnceEvents.push({
name,
payload,
uuidStack: ctx.eventUUIDs,
funcData: ctx.funcData,
eventUUID: ctx.eventUUID,
});
return this.emit(name, ctx, payload);
}
getAllEventsForUUID(uuid) {
let events = Object.values(this.events).flat();
events = events.concat(Object.values(this.overwrittenEvents).flat());
return filterEventsByUUID(events, uuid, undefined, {
includeRecursive: true,
});
}
filterEventsByName(name, options) {
return filterEventsByName(this, name, options);
}
getEventByState(name, state, options) {
return getEventByState(this, name, state, options);
}
getEventByPayload(name, payload, options) {
return getEventByPayload(this, name, payload, options);
}
getEvent(name, payload, state, options) {
return getEvent(this, name, payload, state, options);
}
getEventByUUID(name, uuid, funcData, options) {
return getEventByUUID(this, name, uuid, funcData, options);
}
filterEventsByState(name, state, options) {
return filterEventsByState(this, name, state, options);
}
filterEventsByPayload(name, payload, options) {
return filterEventsByPayload(this, name, payload, options);
}
filterEvents(name, payload, state, options) {
return filterEvents(this, name, payload, state, options);
}
}
function getEventBus(args) {
for (const arg of args) {
if (arg?.isEventBus)
return arg;
if (typeof arg === "object") {
if ("events" in arg) {
return arg.events;
}
if ("eventBus" in arg) {
return arg.eventBus;
}
if ("event" in arg) {
return arg.event;
}
for (const value of Object.values(arg)) {
if (value?.isEventBus)
return value;
}
}
}
return null;
}
function getEventUUID(args) {
for (const arg of args) {
if (typeof arg === "object" && "eventUUID" in arg) {
return arg.eventUUID;
}
}
return undefined;
}
function getFuncData(args) {
for (const arg of args) {
if (typeof arg === "object" && "funcData" in arg) {
return arg.funcData;
}
}
}
function getEventByState(eventBus, name, state, options) {
const events = filterEventsByName(eventBus, name, options);
const event = events.find((e) => {
for (const key in state) {
if (state[key] !== e.state[key]) {
return false;
}
}
return true;
});
return event || null;
}
function getEventByPayload(eventBus, name, payload, options) {
const events = filterEventsByName(eventBus, name, options);
const event = events.find((e) => {
for (const key in payload) {
if (payload[key] !== e.payload[key]) {
return false;
}
}
return true;
});
return event || null;
}
function getEvent(eventBus, name, payload, state, options) {
const events = filterEventsByName(eventBus, name, options);
const event = events.find((e) => {
for (const key in state) {
if (state[key] !== e.state[key]) {
return false;
}
}
for (const key in payload) {
if (payload[key] !== e.payload[key]) {
return false;
}
}
return true;
});
return event || null;
}
function getEventByUUID(eventBus, name, uuid, funcData, options) {
let events = filterEventsByName(eventBus, name, options);
events = events.filter((event) => event.uuidStack.includes(uuid));
if (funcData && !options?.includeRecursive) {
events = filterRecursion(events, funcData);
}
return events[0] || null;
}
function filterRecursion(events, funcData) {
const names = new Set([...events.map((e) => e.funcData.funcName)]);
events = events.filter((e) => {
return e.funcData.funcIndex >= funcData.funcIndex;
});
let newEvents = [];
for (const name of names) {
newEvents = newEvents.concat(filterRecursionForName(events, name));
}
return newEvents;
}
function filterRecursionForName(events, name) {
events = events.filter((e) => e.funcData.funcName === name);
// Helper function to check if stackB extends stackA (stackA is a prefix of stackB)
const isExtension = (stackA, stackB) => {
if (stackA.length >= stackB.length)
return false;
return stackA.every((uuid, index) => uuid === stackB[index]);
};
// Filter out events that are recursive calls (their uuidStack extends another event's stack)
const nonRecursiveEvents = events.filter((event) => {
// Check if this event is a recursive call of another event
const isRecursive = events.some((otherEvent) => {
return (otherEvent !== event &&
otherEvent.funcData.funcIndex < event.funcData.funcIndex &&
isExtension(otherEvent.uuidStack, event.uuidStack));
});
return !isRecursive;
});
return nonRecursiveEvents;
}
function filterEventsByState(eventBus, name, state, options) {
const events = filterEventsByName(eventBus, name, options);
return events.filter((event) => {
for (const key in state) {
if (state[key] !== event.state[key]) {
return false;
}
}
return true;
});
}
function filterEventsByPayload(eventBus, name, payload, options) {
const events = filterEventsByName(eventBus, name, options);
return events.filter((event) => {
for (const key in payload) {
if (payload[key] !== event.payload[key]) {
return false;
}
}
return true;
});
}
function filterEventsByUUID(events, uuid, funcData, options) {
events = events.filter((event) => event.uuidStack.includes(uuid));
if (funcData && !options?.includeRecursive)
events = filterRecursion(events, funcData);
return events;
}
function filterEvents(eventBus, name, payload, state, options) {
let events = filterEventsByName(eventBus, name, options);
events = events.filter((event) => {
for (const key in payload) {
if (payload[key] !== event.payload[key]) {
return false;
}
}
return true;
});
return events.filter((event) => {
for (const key in state) {
if (state[key] !== event.state[key]) {
return false;
}
}
return true;
});
}
function withEventBus(args, func) {
const eventBus = getEventBus(args);
if (!eventBus) {
throw new Error("Event bus not found");
}
return func(eventBus);
}
function withEvents(args, func) {
const eventBus = getEventBus(args);
const eventUUID = getEventUUID(args);
const funcData = getFuncData(args);
if (!eventBus) {
throw new Error("Event bus not found");
}
if (!eventUUID) {
throw new Error("Event UUID not found");
}
if (!funcData) {
throw new Error("Function data not found");
}
return func(eventBus, eventUUID, funcData);
}
function withEventNames(args, eventNames, func, options) {
const eventBus = getEventBus(args);
const eventUUID = getEventUUID(args);
if (!eventBus) {
throw new Error("Event bus not found");
}
if (!eventUUID) {
throw new Error("Event UUID not found");
}
const funcData = getFuncData(args);
const events = [];
for (const eventName of eventNames) {
events.push(...filterEventsByName(eventBus, eventName, options));
}
// Fetch all events into a record keyed by their name
const eventsMap = {};
const filteredEvents = filterEventsByUUID(events, eventUUID, funcData, options);
for (const event of filteredEvents) {
eventsMap[event.name] = event;
}
return func(eventsMap, eventBus, eventUUID);
}
function withEventNamesList(args, eventNames, func, options) {
const eventBus = getEventBus(args);
const eventUUID = getEventUUID(args);
if (!eventBus) {
throw new Error("Event bus not found");
}
if (!eventUUID) {
throw new Error("Event UUID not found");
}
const funcData = getFuncData(args);
const eventsMap = {};
const events = [];
for (const eventName of eventNames) {
eventsMap[eventName] = [];
events.push(...filterEventsByName(eventBus, eventName, options));
}
const filteredEvents = filterEventsByUUID(events, eventUUID, funcData, options);
for (const event of filteredEvents) {
eventsMap[event.name].push(event);
}
return func(eventsMap, eventBus, eventUUID);
}
function filterEventsByName(eventBus, name, options) {
let events = name === "*"
? Object.values(eventBus.events).flat()
: eventBus.events[name];
if (options?.includeOverwritten) {
if (name === "*")
events = events.concat(Object.values(eventBus.overwrittenEvents).flat());
else
events = events.concat(eventBus.overwrittenEvents[name] || []);
}
if (!events) {
return [];
}
return events;
}
function makeEventContext() {
return {
event: new EventBus(),
eventUUID: "",
eventUUIDs: [],
funcData: undefined,
};
}
export { getEventBus, EventBus, getEventByState, getEventByPayload, getEvent, filterEventsByState, filterEventsByPayload, filterEvents, getEventUUID, getEventByUUID, filterEventsByUUID, withEventBus, withEvents, withEventNames, getFuncData, filterEventsByName, makeEventContext, withEventNamesList, filterRecursion, filterRecursionForName, };
//# sourceMappingURL=eventBus.js.map