{"version":3,"file":"event-queue.es.min.js","sources":["../../packages/helpers/src/event-queue.ts"],"sourcesContent":["export type Message = null | boolean | string | number | readonly Message[] | { readonly [key: string]: Message }\nexport type Payload<E = string> = {\n name: E;\n message: Message;\n timestamp: number\n}\n\nexport type Listener<E = string> = {\n callback: (payload: Payload<E>) => void;\n pointer: number;\n eventName: E,\n}\n\nconst eventStore: Payload[] = []\n\nconst assertEventName = (eventName: string): string => {\n if (!/^\\*$|^[a-z][0-9a-z\\-]*$/g.test(eventName)) {\n throw TypeError(`Expected \"*\" or a kebab-case string, received: ${eventName}`)\n }\n return eventName\n}\n\nconst listeners: Listener[] = []\n\ntype L = \"a\" | \"b\" | \"c\" | \"d\" | \"e\" | \"f\" | \"g\" | \"h\" | \"i\" | \"j\" | \"k\" | \"l\" | \"m\" | \"n\" | \"o\" | \"p\" | \"q\" | \"r\" | \"s\" | \"t\" | \"u\" | \"v\" | \"w\" | \"x\" | \"y\" | \"z\"\ntype D = \"0\" | \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\";\ntype W = L | D | \"-\"\n\ntype CheckKebabCase<Base extends string, Tail extends string = Base> =\n Base extends `${L}${string}` ?\n (Tail extends `${W}${infer P}` ?\n (P extends \"\" ? Base : CheckKebabCase<Base, P>) :\n never) :\n never;\n\ntype KebabCase<E extends string> = [CheckKebabCase<E> & E] extends [never] ? \"[kebab-case]\" : E;\ntype EventName<E extends string> = string extends E ? string : (\"*\" | KebabCase<E>)\nconst deepFreeze = (value: Message): Message => {\n if (\n typeof value === \"boolean\" ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n value === null\n ) {\n return value\n } else if ((Array.isArray as (value: unknown) => value is any[] | readonly any[])(value)) {\n for (let i = 0; i < value.length; i++) {\n deepFreeze(value[i]);\n }\n return Object.freeze(value)\n }\n if (\n value instanceof Object &&\n Object === Object.getPrototypeOf(value).constructor\n ) {\n for (const key in value) {\n deepFreeze(value[key]);\n }\n return Object.freeze(value)\n }\n throw TypeError(`Unexpected type:\\n\\tExpected: type Message = null | boolean | string | number | readonly Message[] | { readonly [key: string]: Message }\\n\\tRecieved: ${value}`)\n}\n\nconst pushEvents = (listener: Listener) => {\n for (; listener.pointer < eventStore.length; listener.pointer++) {\n const event = eventStore[listener.pointer];\n try {\n if (listener.eventName !== \"*\" && event.name !== listener.eventName) { continue }\n listener.callback(event)\n } catch (error) {\n console.group(`Unhandled Error at ${listener.eventName}`)\n console.error(error)\n console.groupEnd()\n }\n }\n}\n\nexport const emit = <E extends string>(event: EventName<E>, message: Message) => {\n const eventName = assertEventName(event)\n eventStore.push(Object.freeze({\n name: eventName,\n message: deepFreeze(message),\n timestamp: performance.now()\n }));\n\n for (let i = 0; i < listeners.length; i++) {\n pushEvents(listeners[i])\n }\n}\n\nexport const unsubscribe = (callback: (payload: Payload<string>) => void) => {\n const index = listeners.findIndex((listener) => listener.callback === callback);\n if (index === -1) {\n return console.warn(\"Attempted to unsubscribe from a non-existing subscription, this is a noop, but it might mean a problem on the consumer side\")\n }\n listeners.splice(index, 1)\n}\n\ntype SubscribeOptions = {\n /**\n * Whether or not previous events will be passed to the callback\n * @defaultValue `false`\n */\n ignorePrevEvents?: boolean\n\n}\n\n/**\n * @param eventName - A kebab-case string\n * @param callback - A function that receives the event when the event is emitted\n * @param options.ignorePrevEvents - {@link SubscribeOptions.ignorePrevEvents}\n * @returns A function to unsubscribe from the event\n */\nexport const subscribe = <E extends string>(event: EventName<E>, callback: (payload: Payload<E>) => void, options: SubscribeOptions = {}) => {\n const eventName = assertEventName(event)\n const { ignorePrevEvents = false } = options\n const pointer = ignorePrevEvents ? eventStore.length : 0;\n const newListener = {\n callback: callback as (payload: Payload<string>) => void,\n pointer,\n eventName,\n }\n\n listeners.push(newListener)\n pushEvents(newListener)\n\n return () => unsubscribe(callback as (payload: Payload<string>) => void)\n}"],"names":["eventStore","assertEventName","eventName","listeners","deepFreeze","value","i","key","pushEvents","listener","event","error","emit","message","unsubscribe","callback","index","subscribe","options","ignorePrevEvents","pointer","newListener"],"mappings":"AAaA,MAAMA,IAAwB,CAAA,GAExBC,IAAkB,CAACC,MAA8B;AACnD,MAAI,CAAC,2BAA2B,KAAKA,CAAS;AACpC,UAAA,UAAU,kDAAkDA,CAAS,EAAE;AAE1E,SAAAA;AACX,GAEMC,IAAwB,CAAA,GAexBC,IAAa,CAACC,MAA4B;AAExC,MAAA,OAAOA,KAAU,aACjB,OAAOA,KAAU,YACjB,OAAOA,KAAU,YACjBA,MAAU;AAEH,WAAAA;AACC,MAAA,MAAM,QAAgEA,CAAK,GAAG;AACtF,aAASC,IAAI,GAAGA,IAAID,EAAM,QAAQC;AACnB,MAAAF,EAAAC,EAAMC,CAAC,CAAC;AAEhB,WAAA,OAAO,OAAOD,CAAK;AAAA,EAC9B;AACA,MACIA,aAAiB,UACjB,WAAW,OAAO,eAAeA,CAAK,EAAE,aAC1C;AACE,eAAWE,KAAOF;AACH,MAAAD,EAAAC,EAAME,CAAG,CAAC;AAElB,WAAA,OAAO,OAAOF,CAAK;AAAA,EAC9B;AACA,QAAM,UAAU;AAAA;AAAA,aAAyJA,CAAK,EAAE;AACpL,GAEMG,IAAa,CAACC,MAAuB;AACvC,SAAOA,EAAS,UAAUT,EAAW,QAAQS,EAAS,WAAW;AACvD,UAAAC,IAAQV,EAAWS,EAAS,OAAO;AACrC,QAAA;AACA,UAAIA,EAAS,cAAc,OAAOC,EAAM,SAASD,EAAS;AAAa;AACvE,MAAAA,EAAS,SAASC,CAAK;AAAA,aAClBC,GAAO;AACZ,cAAQ,MAAM,sBAAsBF,EAAS,SAAS,EAAE,GACxD,QAAQ,MAAME,CAAK,GACnB,QAAQ,SAAS;AAAA,IACrB;AAAA,EACJ;AACJ,GAEaC,IAAO,CAAmBF,GAAqBG,MAAqB;AACvE,QAAAX,IAAYD,EAAgBS,CAAK;AAC5B,EAAAV,EAAA,KAAK,OAAO,OAAO;AAAA,IAC1B,MAAME;AAAA,IACN,SAASE,EAAWS,CAAO;AAAA,IAC3B,WAAW,YAAY,IAAI;AAAA,EAC9B,CAAA,CAAC;AAEF,WAASP,IAAI,GAAGA,IAAIH,EAAU,QAAQG;AACvB,IAAAE,EAAAL,EAAUG,CAAC,CAAC;AAE/B,GAEaQ,IAAc,CAACC,MAAiD;AACzE,QAAMC,IAAQb,EAAU,UAAU,CAACM,MAAaA,EAAS,aAAaM,CAAQ;AAC9E,MAAIC,MAAU;AACH,WAAA,QAAQ,KAAK,6HAA6H;AAE3I,EAAAb,EAAA,OAAOa,GAAO,CAAC;AAC7B,GAiBaC,IAAY,CAAmBP,GAAqBK,GAAyCG,IAA4B,CAAA,MAAO;AACnI,QAAAhB,IAAYD,EAAgBS,CAAK,GACjC,EAAE,kBAAAS,IAAmB,GAAU,IAAAD,GAC/BE,IAAUD,IAAmBnB,EAAW,SAAS,GACjDqB,IAAc;AAAA,IAChB,UAAAN;AAAA,IACA,SAAAK;AAAA,IACA,WAAAlB;AAAA,EAAA;AAGJ,SAAAC,EAAU,KAAKkB,CAAW,GAC1Bb,EAAWa,CAAW,GAEf,MAAMP,EAAYC,CAA8C;AAC3E;"}