const MamiEventTargetScoped = function(eventTarget, prefix) { if(typeof eventTarget !== 'object' || eventTarget === null) throw 'eventTarget must be a non-null object'; if(typeof prefix !== 'string') throw 'prefix must be a string'; if(!prefix.endsWith(':')) prefix = prefix + ':'; return { scopeTo: name => eventTarget.scopeTo(prefix + name), create: (name, ...args) => eventTarget.create(prefix + name, ...args), watch: (name, ...args) => eventTarget.watch(prefix + name, ...args), unwatch: (name, ...args) => eventTarget.unwatch(prefix + name, ...args), dispatch: (nameOrEvent, ...args) => eventTarget.dispatch(nameOrEvent instanceof Event ? nameOrEvent : (prefix + nameOrEvent), ...args), }; }; const MamiEventTargetWindow = function() { const createEvent = (name, detail) => new CustomEvent( name, (typeof detail === 'object' && detail !== null && 'detail' in detail ? detail : { detail: detail })); const public = { scopeTo: name => new MamiEventTargetScoped(public, name), create: createEvent, watch: (...args) => { window.addEventListener(...args); }, unwatch: (...args) => { window.removeEventListener(...args); }, dispatch: (nameOrEvent, ...args) => { window.dispatchEvent(nameOrEvent instanceof Event ? nameOrEvent : createEvent(nameOrEvent, ...args)); }, }; return public; };