{"version":3,"sources":["../src/api/notification-type-guards.ts","../src/store/notification-store.ts","../src/interceptor/fetch-notification-interceptor.ts","../src/interceptor/xhr-notification-interceptor.ts","../src/hook/use-notifications.ts"],"sourcesContent":["/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport { NotificationResponse } from \"./notification-types\";\n\n/**\n * Checks whether the given response matches the proposed notification format,\n * i.e. if it contains 'notification' nested object.\n *\n * Used internally in {@link fetchNotificationInterceptor} and {@link xhrNotificationInterceptor}.\n *\n * @param body the response body\n */\nexport const isNotificationResponse = (body: any): body is NotificationResponse => body && \"notification\" in body;\n","/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport { create } from \"zustand\";\n\nimport { Notification } from \"../api\";\n\nexport interface NotificationState {\n\n  /**\n   * Array of current state notifications.\n   */\n  notifications: Notification[];\n\n  /**\n   * Adds notification to state.\n   * @param notification notification to add\n   */\n  add: (notification: Notification) => void;\n\n  /**\n   * Removes notification from state.\n   * @param notification\n   */\n  remove: (notification: Notification) => void;\n\n}\n\n/**\n * Creation of the API for managing internal notification state.\n * Used internally in the {@link useNotifications} hook.\n *\n * @returns A hook for managing notification state usable in a React environment.\n */\nconst store = create<NotificationState>((set) => ({\n  notifications: [],\n  add: (notification) => set((state) => ({\n    notifications: [...state.notifications, { ...notification, timestamp: new Date(notification.timestamp) || new Date() }],\n  })),\n  remove: (notification) => set((state) => ({\n    notifications: state.notifications.filter((currentNotification) => currentNotification !== notification),\n  })),\n}));\n\nexport const useNotificationStore = store;\nexport const addNotification = store.getState().add;\nexport const removeNotification = store.getState().remove;\n","/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport { isNotificationResponse } from \"../api/notification-type-guards\";\nimport { useNotificationStore } from \"../store\";\n\n/**\n * Fetch API interceptor which clones the response and checks\n * whether the response matches the proposed notification format.\n *\n * @returns A function which can be called to register the interceptor.\n */\nexport const fetchNotificationInterceptor = () => {\n  window.fetch = new Proxy(window.fetch, {\n    apply(fetch, that, request) {\n      // @ts-ignore\n      const result = fetch.apply(that, request);\n\n      result.then((response) => response.clone().json())\n        .then((body) => {\n          if (isNotificationResponse(body)) {\n            useNotificationStore.getState().add(body.notification);\n          }\n        });\n\n      return result;\n    },\n  });\n};\n","/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport { isNotificationResponse } from \"../api/notification-type-guards\";\nimport { useNotificationStore } from \"../store\";\n\n/**\n * XHR interceptor which listens for the response to be acquired\n * and checks whether the response matches the proposed notification format.\n *\n * @returns A function which can be called to register the interceptor.\n */\nexport const xhrNotificationInterceptor = () => {\n  const old = XMLHttpRequest.prototype.open;\n  // eslint-disable-next-line func-names\n  XMLHttpRequest.prototype.open = function (...args) {\n    // eslint-disable-next-line func-names\n    this.addEventListener(\"readystatechange\", function () {\n      if (this.readyState === 4) {\n        try {\n          const body = JSON.parse(this.responseText);\n          if (isNotificationResponse(body)) {\n            useNotificationStore.getState().add(body.notification);\n          }\n        }\n        catch (e) {\n          // ignore non-json responses\n        }\n      }\n    }, false);\n    // @ts-ignore\n    old.apply(this, args);\n  };\n};\n","/*\n *    Copyright 2022 CROZ d.o.o, the original author or authors.\n *\n *    Licensed under the Apache License, Version 2.0 (the \"License\");\n *    you may not use this file except in compliance with the License.\n *    You may obtain a copy of the License at\n *\n *        http://www.apache.org/licenses/LICENSE-2.0\n *\n *    Unless required by applicable law or agreed to in writing, software\n *    distributed under the License is distributed on an \"AS IS\" BASIS,\n *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *    See the License for the specific language governing permissions and\n *    limitations under the License.\n *\n */\n\nimport { Notification } from \"../api\";\nimport { useNotificationStore } from \"../store\";\n\nexport type NotificationOptions = {\n  /**\n   * Array of current state notifications.\n   */\n  notifications: Notification[],\n  /**\n   * Adds notification to state.\n   * @param notification notification to add\n   */\n  add: (notification: Notification) => void,\n  /**\n   * Removes notification from state.\n   * @param notification\n   */\n  remove: (notification: Notification) => void\n};\nexport type UseNotifications = () => NotificationOptions;\n/**\n * A hook which simplifies the usage of the intercepted notification state.\n * Uses the internal {@link useNotificationStore} hook for managing the notification state.\n *\n * @returns An array of options to access the notification state and remove a single notification.\n */\nexport const useNotifications: UseNotifications = () => {\n  const notifications = useNotificationStore((state) => state.notifications);\n  const add = useNotificationStore((state) => state.add);\n  const remove = useNotificationStore((state) => state.remove);\n\n  return { notifications, add, remove };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2BO,IAAM,yBAAyB,CAAC,SAA4C,QAAQ,kBAAkB;;;ACV7G,SAAS,cAAc;AA+BvB,IAAM,QAAQ,OAA0B,CAAC,SAAS;AAAA,EAChD,eAAe,CAAC;AAAA,EAChB,KAAK,CAAC,iBAAiB,IAAI,CAAC,WAAW;AAAA,IACrC,eAAe,CAAC,GAAG,MAAM,eAAe,iCAAK,eAAL,EAAmB,WAAW,IAAI,KAAK,aAAa,SAAS,KAAK,IAAI,KAAK,EAAE,EAAC;AAAA,EACxH,EAAE;AAAA,EACF,QAAQ,CAAC,iBAAiB,IAAI,CAAC,WAAW;AAAA,IACxC,eAAe,MAAM,cAAc,OAAO,CAAC,wBAAwB,wBAAwB,YAAY;AAAA,EACzG,EAAE;AACJ,EAAE;AAEK,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB,MAAM,SAAS,EAAE;AACzC,IAAM,qBAAqB,MAAM,SAAS,EAAE;;;AClC5C,IAAM,+BAA+B,MAAM;AAChD,SAAO,QAAQ,IAAI,MAAM,OAAO,OAAO;AAAA,IACrC,MAAM,OAAO,MAAM,SAAS;AAE1B,YAAM,SAAS,MAAM,MAAM,MAAM,OAAO;AAExC,aAAO,KAAK,CAAC,aAAa,SAAS,MAAM,EAAE,KAAK,CAAC,EAC9C,KAAK,CAAC,SAAS;AACd,YAAI,uBAAuB,IAAI,GAAG;AAChC,+BAAqB,SAAS,EAAE,IAAI,KAAK,YAAY;AAAA,QACvD;AAAA,MACF,CAAC;AAEH,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;;;AChBO,IAAM,6BAA6B,MAAM;AAC9C,QAAM,MAAM,eAAe,UAAU;AAErC,iBAAe,UAAU,OAAO,YAAa,MAAM;AAEjD,SAAK,iBAAiB,oBAAoB,WAAY;AACpD,UAAI,KAAK,eAAe,GAAG;AACzB,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,KAAK,YAAY;AACzC,cAAI,uBAAuB,IAAI,GAAG;AAChC,iCAAqB,SAAS,EAAE,IAAI,KAAK,YAAY;AAAA,UACvD;AAAA,QACF,SACO,GAAP;AAAA,QAEA;AAAA,MACF;AAAA,IACF,GAAG,KAAK;AAER,QAAI,MAAM,MAAM,IAAI;AAAA,EACtB;AACF;;;ACJO,IAAM,mBAAqC,MAAM;AACtD,QAAM,gBAAgB,qBAAqB,CAAC,UAAU,MAAM,aAAa;AACzE,QAAM,MAAM,qBAAqB,CAAC,UAAU,MAAM,GAAG;AACrD,QAAM,SAAS,qBAAqB,CAAC,UAAU,MAAM,MAAM;AAE3D,SAAO,EAAE,eAAe,KAAK,OAAO;AACtC;","names":[]}