@dataemergencia/emergency 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -84,13 +84,8 @@ function isFiniteNumber(value) {
84
84
  function isArrayOf(value, guard) {
85
85
  return Array.isArray(value) && value.every(guard);
86
86
  }
87
- function isRealtimeConfig(value) {
88
- if (!isRecord(value) || value["mode"] !== "public" || !isRecord(value["pusher"])) return false;
89
- const pusher = value["pusher"];
90
- return isString(pusher["key"]) && isString(pusher["cluster"]) && isString(pusher["channel_pattern"]);
91
- }
92
87
  function isConfigResponse(value) {
93
- return isRecord(value) && isString(value["route_prefix"]) && isString(value["csrf_token"]) && isRealtimeConfig(value["realtime"]);
88
+ return isRecord(value) && isString(value["route_prefix"]) && isString(value["csrf_token"]);
94
89
  }
95
90
  function isSessionResponse(value) {
96
91
  return isRecord(value) && isString(value["code"]) && isString(value["csrf_token"]) && isFiniteNumber(value["expires_in"]);
@@ -108,11 +103,11 @@ function isEmergencyResultPayload(value) {
108
103
  return (value["emergency_id"] === null || isString(value["emergency_id"])) && isBoolean(value["simulated"]) && isArrayOf(value["responders"], isResponderPayload) && isArrayOf(value["failures"], isFailurePayload);
109
104
  }
110
105
  function isCurrentResponse(value) {
111
- if (!isRecord(value) || !isBoolean(value["active"]) || !isRealtimeConfig(value["realtime"])) return false;
106
+ if (!isRecord(value) || !isBoolean(value["active"])) return false;
112
107
  return value["emergency"] === null || isRecord(value["emergency"]) && !Array.isArray(value["emergency"]);
113
108
  }
114
109
  function isRefreshResponse(value) {
115
- return isRecord(value) && isRecord(value["emergency"]) && isArrayOf(value["responders"], isResponderPayload);
110
+ return isRecord(value) && isRecord(value["emergency"]);
116
111
  }
117
112
  function isAbortResponse(value) {
118
113
  return isEmergencyResultPayload(value) && isRecord(value) && isBoolean(value["deleted"]);
@@ -634,8 +629,9 @@ function themeToCssVariables(theme) {
634
629
  }
635
630
 
636
631
  // src/core/realtime.ts
632
+ const DEFAULT_CHANNEL_PATTERN = "whatsapp.{phone}";
637
633
  function channelForPhone(pattern, phone) {
638
- return pattern.replace("{phone}", phone.replace(/^\+/, ""));
634
+ return pattern.replace("{phone}", phone.replace(/\D/g, ""));
639
635
  }
640
636
  function toStatus(state) {
641
637
  switch (state) {
@@ -650,11 +646,11 @@ function toStatus(state) {
650
646
  }
651
647
  function createPusherRealtimeProvider() {
652
648
  return { subscribe(config, phones, handlers) {
653
- if (typeof window === "undefined" || !config.pusher.key || !config.pusher.cluster) return null;
649
+ if (typeof window === "undefined" || !config.key || !config.cluster) return null;
654
650
  let pusher;
655
651
  try {
656
- pusher = new pusher_js.default(config.pusher.key, {
657
- cluster: config.pusher.cluster,
652
+ pusher = new pusher_js.default(config.key, {
653
+ cluster: config.cluster,
658
654
  forceTLS: true
659
655
  });
660
656
  } catch {
@@ -666,7 +662,7 @@ function createPusherRealtimeProvider() {
666
662
  handlers.onStatus(toStatus(change.current));
667
663
  });
668
664
  const channels = [...new Set(phones.filter((phone) => phone !== ""))].map((phone) => {
669
- const channelName = channelForPhone(config.pusher.channel_pattern, phone);
665
+ const channelName = channelForPhone(config.channelPattern ?? DEFAULT_CHANNEL_PATTERN, phone);
670
666
  pusher.subscribe(channelName).bind_global((eventName, data) => {
671
667
  handlers.onEvent(channelName, eventName, data);
672
668
  });
@@ -795,7 +791,6 @@ function createEmergencyController(deps) {
795
791
  let sessionPromise = null;
796
792
  let refreshing = false;
797
793
  let realtimeSubscription = null;
798
- let realtimeConfig = null;
799
794
  let subscribedPhones = [];
800
795
  let messageSequence = 0;
801
796
  let lastReconcileAt = 0;
@@ -853,9 +848,12 @@ function createEmergencyController(deps) {
853
848
  realtimeSubscription = null;
854
849
  subscribedPhones = [];
855
850
  }
856
- function startRealtime(realtime, responders) {
857
- if (!realtime) return;
858
- realtimeConfig = realtime;
851
+ function startRealtime(responders) {
852
+ const realtime = config.realtime ?? null;
853
+ if (!realtime) {
854
+ if (responders.length > 0) patch({ realtimeStatus: "unavailable" });
855
+ return;
856
+ }
859
857
  const phones = [...new Set(responders.map((responder) => responder.phone))];
860
858
  if (realtimeSubscription && phones.length === subscribedPhones.length && phones.every((phone, index) => phone === subscribedPhones[index])) return;
861
859
  realtimeSubscription?.disconnect();
@@ -889,7 +887,7 @@ function createEmergencyController(deps) {
889
887
  const phase = get().phase.kind;
890
888
  if (phase === "idle" || phase === "error") transition({ kind: "initializing" });
891
889
  try {
892
- realtimeConfig = (await bff.config()).realtime;
890
+ await bff.config();
893
891
  const session = await bff.session(config.code);
894
892
  patch({
895
893
  sessionReady: true,
@@ -919,7 +917,6 @@ function createEmergencyController(deps) {
919
917
  async function hydrateCurrent() {
920
918
  try {
921
919
  const current = await bff.current();
922
- realtimeConfig = current.realtime;
923
920
  if (current.active && current.emergency) {
924
921
  const snapshot = payloadToSnapshot(current.emergency, { code: config.code });
925
922
  patch({
@@ -935,7 +932,7 @@ function createEmergencyController(deps) {
935
932
  emergencyId: snapshot.emergencyId,
936
933
  simulated: snapshot.simulated
937
934
  });
938
- startRealtime(current.realtime, snapshot.responders);
935
+ startRealtime(snapshot.responders);
939
936
  events.emit("emergency:resumed", { snapshot });
940
937
  return;
941
938
  }
@@ -1017,7 +1014,7 @@ function createEmergencyController(deps) {
1017
1014
  });
1018
1015
  pushMessage(failures.length > 0 ? "warning" : "success", failures.length > 0 ? copy.partialFailure : copy.activeBanner);
1019
1016
  events.emit("emergency:activated", { snapshot: hydrated });
1020
- startRealtime(realtimeConfig, responders);
1017
+ startRealtime(responders);
1021
1018
  } catch (error) {
1022
1019
  const normalized = toEmergencyError(error, "network");
1023
1020
  if (normalized.code === "emergency_already_active") {
@@ -1094,7 +1091,7 @@ function createEmergencyController(deps) {
1094
1091
  code: config.code,
1095
1092
  simulated: snapshot.simulated
1096
1093
  });
1097
- const responders = result.responders.length > 0 ? result.responders.map(toResponder) : next.responders.length > 0 ? next.responders : get().responders;
1094
+ const responders = next.responders.length > 0 ? next.responders : get().responders;
1098
1095
  const updated = {
1099
1096
  ...next,
1100
1097
  responders
@@ -1109,7 +1106,7 @@ function createEmergencyController(deps) {
1109
1106
  emergencyId: updated.emergencyId,
1110
1107
  simulated: updated.simulated
1111
1108
  });
1112
- startRealtime(realtimeConfig, responders);
1109
+ startRealtime(responders);
1113
1110
  events.emit("emergency:updated", { snapshot: updated });
1114
1111
  } catch (error) {
1115
1112
  const normalized = toEmergencyError(error, "network");
@@ -1242,7 +1239,6 @@ function createEmergencyController(deps) {
1242
1239
  bff.destroy();
1243
1240
  realtimeSubscription?.disconnect();
1244
1241
  realtimeSubscription = null;
1245
- realtimeConfig = null;
1246
1242
  subscribedPhones = [];
1247
1243
  patch({
1248
1244
  destroyed: true,
@@ -1373,6 +1369,24 @@ function installEmergencyFonts(input) {
1373
1369
 
1374
1370
  // src/core/config.ts
1375
1371
  const EMERGENCY_CODE_PATTERN = /^[A-Za-z][A-Za-z0-9]{5}$/;
1372
+ const DEFAULT_REALTIME_CHANNEL_PATTERN = "whatsapp.{phone}";
1373
+ /**
1374
+ * Validates the host-supplied realtime block. Returns `null` when the value is
1375
+ * present but invalid; callers treat `undefined` as "realtime not requested".
1376
+ */
1377
+ function normalizeRealtimeConfig(value) {
1378
+ if (!isRecord(value)) return null;
1379
+ const key = value["key"];
1380
+ const cluster = value["cluster"];
1381
+ const channelPattern = value["channelPattern"];
1382
+ if (typeof key !== "string" || key.trim() === "" || typeof cluster !== "string" || cluster.trim() === "") return null;
1383
+ if (channelPattern !== void 0 && (typeof channelPattern !== "string" || channelPattern.trim() === "" || !channelPattern.includes("{phone}"))) return null;
1384
+ return {
1385
+ key,
1386
+ cluster,
1387
+ channelPattern: channelPattern ?? "whatsapp.{phone}"
1388
+ };
1389
+ }
1376
1390
  const LOOPBACK_HOSTS = /* @__PURE__ */ new Set([
1377
1391
  "localhost",
1378
1392
  "127.0.0.1",
@@ -1433,6 +1447,12 @@ function validateConfig(config) {
1433
1447
  config: null,
1434
1448
  error: createEmergencyError("configuration", "The fallback requires a non-empty phone and label.")
1435
1449
  };
1450
+ const realtime = config.realtime === void 0 ? void 0 : normalizeRealtimeConfig(config.realtime);
1451
+ if (realtime === null) return {
1452
+ ok: false,
1453
+ config: null,
1454
+ error: createEmergencyError("configuration", "The realtime configuration requires a non-empty key and cluster, and a channel pattern containing {phone}.")
1455
+ };
1436
1456
  return {
1437
1457
  ok: true,
1438
1458
  error: null,
@@ -1443,7 +1463,8 @@ function validateConfig(config) {
1443
1463
  locale: config.locale ?? "es",
1444
1464
  geolocationTimeoutMs: config.geolocationTimeoutMs ?? 8e3,
1445
1465
  requestTimeoutMs: config.requestTimeoutMs ?? 15e3,
1446
- fontLoading: normalizeFontLoading(config.fontLoading)
1466
+ fontLoading: normalizeFontLoading(config.fontLoading),
1467
+ realtime
1447
1468
  }
1448
1469
  };
1449
1470
  }
@@ -1595,88 +1616,88 @@ function Icon({ name, className, title }) {
1595
1616
 
1596
1617
  // src/styles/panel.module.css
1597
1618
  var panel_module_default = {
1598
- "de-emergency-fade-in": "de-emergency-de-emergency-fade-in-kMlO0G",
1599
- "de-emergency-pulse": "de-emergency-de-emergency-pulse-kMlO0G",
1600
- "de-emergency-pulse-error": "de-emergency-de-emergency-pulse-error-kMlO0G",
1601
- "de-emergency-slide-in": "de-emergency-de-emergency-slide-in-kMlO0G",
1602
- "de-emergency-slide-up": "de-emergency-de-emergency-slide-up-kMlO0G",
1603
- "de-emergency-spin": "de-emergency-de-emergency-spin-kMlO0G",
1604
- "emergency-confirmation": "de-emergency-emergency-confirmation-kMlO0G",
1605
- "emergency-confirmation__body": "de-emergency-emergency-confirmation__body-kMlO0G",
1606
- "emergency-confirmation__button": "de-emergency-emergency-confirmation__button-kMlO0G",
1607
- "emergency-confirmation__button--cancel": "de-emergency-emergency-confirmation__button--cancel-kMlO0G",
1608
- "emergency-confirmation__button--confirm": "de-emergency-emergency-confirmation__button--confirm-kMlO0G",
1609
- "emergency-confirmation__button--danger": "de-emergency-emergency-confirmation__button--danger-kMlO0G",
1610
- "emergency-confirmation__card": "de-emergency-emergency-confirmation__card-kMlO0G",
1611
- "emergency-confirmation__footer": "de-emergency-emergency-confirmation__footer-kMlO0G",
1612
- "emergency-confirmation__icon": "de-emergency-emergency-confirmation__icon-kMlO0G",
1613
- "emergency-confirmation__icon--danger": "de-emergency-emergency-confirmation__icon--danger-kMlO0G",
1614
- "emergency-confirmation__icon--information": "de-emergency-emergency-confirmation__icon--information-kMlO0G",
1615
- "emergency-confirmation__text": "de-emergency-emergency-confirmation__text-kMlO0G",
1616
- "emergency-confirmation__title": "de-emergency-emergency-confirmation__title-kMlO0G",
1617
- "emergency-error-message": "de-emergency-emergency-error-message-kMlO0G",
1618
- "emergency-error-message__container": "de-emergency-emergency-error-message__container-kMlO0G",
1619
- "emergency-error-message__content": "de-emergency-emergency-error-message__content-kMlO0G",
1620
- "emergency-error-message__detail": "de-emergency-emergency-error-message__detail-kMlO0G",
1621
- "emergency-error-message__details": "de-emergency-emergency-error-message__details-kMlO0G",
1622
- "emergency-error-message__icon": "de-emergency-emergency-error-message__icon-kMlO0G",
1623
- "emergency-error-message__text": "de-emergency-emergency-error-message__text-kMlO0G",
1624
- "emergency-error-message__title": "de-emergency-emergency-error-message__title-kMlO0G",
1625
- "emergency-feedback": "de-emergency-emergency-feedback-kMlO0G",
1626
- "emergency-feedback__dismiss": "de-emergency-emergency-feedback__dismiss-kMlO0G",
1627
- "emergency-panel": "de-emergency-emergency-panel-kMlO0G",
1628
- "emergency-panel__body": "de-emergency-emergency-panel__body-kMlO0G",
1629
- "emergency-panel__body-title": "de-emergency-emergency-panel__body-title-kMlO0G",
1630
- "emergency-panel__body-title-container": "de-emergency-emergency-panel__body-title-container-kMlO0G",
1631
- "emergency-panel__button": "de-emergency-emergency-panel__button-kMlO0G",
1632
- "emergency-panel__button--emergency": "de-emergency-emergency-panel__button--emergency-kMlO0G",
1633
- "emergency-panel__button--simulation": "de-emergency-emergency-panel__button--simulation-kMlO0G",
1634
- "emergency-panel__close-button": "de-emergency-emergency-panel__close-button-kMlO0G",
1635
- "emergency-panel__close-icon": "de-emergency-emergency-panel__close-icon-kMlO0G",
1636
- "emergency-panel__footer": "de-emergency-emergency-panel__footer-kMlO0G",
1637
- "emergency-panel__header": "de-emergency-emergency-panel__header-kMlO0G",
1638
- "emergency-panel__title": "de-emergency-emergency-panel__title-kMlO0G",
1639
- "emergency-panel--hidden": "de-emergency-emergency-panel--hidden-kMlO0G",
1640
- "emergency-resume-notification-button": "de-emergency-emergency-resume-notification-button-kMlO0G",
1641
- "emergency-resume-notification-card": "de-emergency-emergency-resume-notification-card-kMlO0G",
1642
- "emergency-resume-notification-icon": "de-emergency-emergency-resume-notification-icon-kMlO0G",
1643
- "emergency-resume-notification-message": "de-emergency-emergency-resume-notification-message-kMlO0G",
1644
- "emergency-resume-notification-overlay": "de-emergency-emergency-resume-notification-overlay-kMlO0G",
1645
- "emergency-resume-notification-title": "de-emergency-emergency-resume-notification-title-kMlO0G",
1646
- "emergency-status__abort-btn": "de-emergency-emergency-status__abort-btn-kMlO0G",
1647
- "emergency-status__body": "de-emergency-emergency-status__body-kMlO0G",
1648
- "emergency-status__cell": "de-emergency-emergency-status__cell-kMlO0G",
1649
- "emergency-status__cell-icon": "de-emergency-emergency-status__cell-icon-kMlO0G",
1650
- "emergency-status__cell-text": "de-emergency-emergency-status__cell-text-kMlO0G",
1651
- "emergency-status__cell-time": "de-emergency-emergency-status__cell-time-kMlO0G",
1652
- "emergency-status__grid": "de-emergency-emergency-status__grid-kMlO0G",
1653
- "emergency-status__header": "de-emergency-emergency-status__header-kMlO0G",
1654
- "emergency-status__loading": "de-emergency-emergency-status__loading-kMlO0G",
1655
- "emergency-status__loading-text": "de-emergency-emergency-status__loading-text-kMlO0G",
1656
- "emergency-status__panel": "de-emergency-emergency-status__panel-kMlO0G",
1657
- "emergency-status__row": "de-emergency-emergency-status__row-kMlO0G",
1658
- "emergency-status__row-container": "de-emergency-emergency-status__row-container-kMlO0G",
1659
- "emergency-status__spinner": "de-emergency-emergency-status__spinner-kMlO0G",
1660
- "emergency-status-panel__header": "de-emergency-emergency-status-panel__header-kMlO0G",
1661
- "emergency-status-panel__refresh-btn": "de-emergency-emergency-status-panel__refresh-btn-kMlO0G",
1662
- "emergency-status-panel__refresh-btn-container": "de-emergency-emergency-status-panel__refresh-btn-container-kMlO0G",
1663
- "emergency-status-panel__refresh-icon": "de-emergency-emergency-status-panel__refresh-icon-kMlO0G",
1664
- "emergency-status-panel__title": "de-emergency-emergency-status-panel__title-kMlO0G",
1665
- "responder-name": "de-emergency-responder-name-kMlO0G",
1666
- "simulacrum-success-message": "de-emergency-simulacrum-success-message-kMlO0G",
1667
- "simulacrum-success-message__container": "de-emergency-simulacrum-success-message__container-kMlO0G",
1668
- "simulacrum-success-message__content": "de-emergency-simulacrum-success-message__content-kMlO0G",
1669
- "simulacrum-success-message__detail": "de-emergency-simulacrum-success-message__detail-kMlO0G",
1670
- "simulacrum-success-message__details": "de-emergency-simulacrum-success-message__details-kMlO0G",
1671
- "simulacrum-success-message__icon": "de-emergency-simulacrum-success-message__icon-kMlO0G",
1672
- "simulacrum-success-message__text": "de-emergency-simulacrum-success-message__text-kMlO0G",
1673
- "simulacrum-success-message__title": "de-emergency-simulacrum-success-message__title-kMlO0G",
1674
- "sos-img": "de-emergency-sos-img-kMlO0G",
1675
- "sos-img__container": "de-emergency-sos-img__container-kMlO0G",
1676
- "status-icon": "de-emergency-status-icon-kMlO0G",
1677
- "status-icon--checked": "de-emergency-status-icon--checked-kMlO0G",
1678
- "status-icon--failed": "de-emergency-status-icon--failed-kMlO0G",
1679
- "status-icon--unchecked": "de-emergency-status-icon--unchecked-kMlO0G"
1619
+ "de-emergency-fade-in": "de-emergency-de-emergency-fade-in-nA5Hwa",
1620
+ "de-emergency-pulse": "de-emergency-de-emergency-pulse-nA5Hwa",
1621
+ "de-emergency-pulse-error": "de-emergency-de-emergency-pulse-error-nA5Hwa",
1622
+ "de-emergency-slide-in": "de-emergency-de-emergency-slide-in-nA5Hwa",
1623
+ "de-emergency-slide-up": "de-emergency-de-emergency-slide-up-nA5Hwa",
1624
+ "de-emergency-spin": "de-emergency-de-emergency-spin-nA5Hwa",
1625
+ "emergency-confirmation": "de-emergency-emergency-confirmation-nA5Hwa",
1626
+ "emergency-confirmation__body": "de-emergency-emergency-confirmation__body-nA5Hwa",
1627
+ "emergency-confirmation__button": "de-emergency-emergency-confirmation__button-nA5Hwa",
1628
+ "emergency-confirmation__button--cancel": "de-emergency-emergency-confirmation__button--cancel-nA5Hwa",
1629
+ "emergency-confirmation__button--confirm": "de-emergency-emergency-confirmation__button--confirm-nA5Hwa",
1630
+ "emergency-confirmation__button--danger": "de-emergency-emergency-confirmation__button--danger-nA5Hwa",
1631
+ "emergency-confirmation__card": "de-emergency-emergency-confirmation__card-nA5Hwa",
1632
+ "emergency-confirmation__footer": "de-emergency-emergency-confirmation__footer-nA5Hwa",
1633
+ "emergency-confirmation__icon": "de-emergency-emergency-confirmation__icon-nA5Hwa",
1634
+ "emergency-confirmation__icon--danger": "de-emergency-emergency-confirmation__icon--danger-nA5Hwa",
1635
+ "emergency-confirmation__icon--information": "de-emergency-emergency-confirmation__icon--information-nA5Hwa",
1636
+ "emergency-confirmation__text": "de-emergency-emergency-confirmation__text-nA5Hwa",
1637
+ "emergency-confirmation__title": "de-emergency-emergency-confirmation__title-nA5Hwa",
1638
+ "emergency-error-message": "de-emergency-emergency-error-message-nA5Hwa",
1639
+ "emergency-error-message__container": "de-emergency-emergency-error-message__container-nA5Hwa",
1640
+ "emergency-error-message__content": "de-emergency-emergency-error-message__content-nA5Hwa",
1641
+ "emergency-error-message__detail": "de-emergency-emergency-error-message__detail-nA5Hwa",
1642
+ "emergency-error-message__details": "de-emergency-emergency-error-message__details-nA5Hwa",
1643
+ "emergency-error-message__icon": "de-emergency-emergency-error-message__icon-nA5Hwa",
1644
+ "emergency-error-message__text": "de-emergency-emergency-error-message__text-nA5Hwa",
1645
+ "emergency-error-message__title": "de-emergency-emergency-error-message__title-nA5Hwa",
1646
+ "emergency-feedback": "de-emergency-emergency-feedback-nA5Hwa",
1647
+ "emergency-feedback__dismiss": "de-emergency-emergency-feedback__dismiss-nA5Hwa",
1648
+ "emergency-panel": "de-emergency-emergency-panel-nA5Hwa",
1649
+ "emergency-panel__body": "de-emergency-emergency-panel__body-nA5Hwa",
1650
+ "emergency-panel__body-title": "de-emergency-emergency-panel__body-title-nA5Hwa",
1651
+ "emergency-panel__body-title-container": "de-emergency-emergency-panel__body-title-container-nA5Hwa",
1652
+ "emergency-panel__button": "de-emergency-emergency-panel__button-nA5Hwa",
1653
+ "emergency-panel__button--emergency": "de-emergency-emergency-panel__button--emergency-nA5Hwa",
1654
+ "emergency-panel__button--simulation": "de-emergency-emergency-panel__button--simulation-nA5Hwa",
1655
+ "emergency-panel__close-button": "de-emergency-emergency-panel__close-button-nA5Hwa",
1656
+ "emergency-panel__close-icon": "de-emergency-emergency-panel__close-icon-nA5Hwa",
1657
+ "emergency-panel__footer": "de-emergency-emergency-panel__footer-nA5Hwa",
1658
+ "emergency-panel__header": "de-emergency-emergency-panel__header-nA5Hwa",
1659
+ "emergency-panel__title": "de-emergency-emergency-panel__title-nA5Hwa",
1660
+ "emergency-panel--hidden": "de-emergency-emergency-panel--hidden-nA5Hwa",
1661
+ "emergency-resume-notification-button": "de-emergency-emergency-resume-notification-button-nA5Hwa",
1662
+ "emergency-resume-notification-card": "de-emergency-emergency-resume-notification-card-nA5Hwa",
1663
+ "emergency-resume-notification-icon": "de-emergency-emergency-resume-notification-icon-nA5Hwa",
1664
+ "emergency-resume-notification-message": "de-emergency-emergency-resume-notification-message-nA5Hwa",
1665
+ "emergency-resume-notification-overlay": "de-emergency-emergency-resume-notification-overlay-nA5Hwa",
1666
+ "emergency-resume-notification-title": "de-emergency-emergency-resume-notification-title-nA5Hwa",
1667
+ "emergency-status__abort-btn": "de-emergency-emergency-status__abort-btn-nA5Hwa",
1668
+ "emergency-status__body": "de-emergency-emergency-status__body-nA5Hwa",
1669
+ "emergency-status__cell": "de-emergency-emergency-status__cell-nA5Hwa",
1670
+ "emergency-status__cell-icon": "de-emergency-emergency-status__cell-icon-nA5Hwa",
1671
+ "emergency-status__cell-text": "de-emergency-emergency-status__cell-text-nA5Hwa",
1672
+ "emergency-status__cell-time": "de-emergency-emergency-status__cell-time-nA5Hwa",
1673
+ "emergency-status__grid": "de-emergency-emergency-status__grid-nA5Hwa",
1674
+ "emergency-status__header": "de-emergency-emergency-status__header-nA5Hwa",
1675
+ "emergency-status__loading": "de-emergency-emergency-status__loading-nA5Hwa",
1676
+ "emergency-status__loading-text": "de-emergency-emergency-status__loading-text-nA5Hwa",
1677
+ "emergency-status__panel": "de-emergency-emergency-status__panel-nA5Hwa",
1678
+ "emergency-status__row": "de-emergency-emergency-status__row-nA5Hwa",
1679
+ "emergency-status__row-container": "de-emergency-emergency-status__row-container-nA5Hwa",
1680
+ "emergency-status__spinner": "de-emergency-emergency-status__spinner-nA5Hwa",
1681
+ "emergency-status-panel__header": "de-emergency-emergency-status-panel__header-nA5Hwa",
1682
+ "emergency-status-panel__refresh-btn": "de-emergency-emergency-status-panel__refresh-btn-nA5Hwa",
1683
+ "emergency-status-panel__refresh-btn-container": "de-emergency-emergency-status-panel__refresh-btn-container-nA5Hwa",
1684
+ "emergency-status-panel__refresh-icon": "de-emergency-emergency-status-panel__refresh-icon-nA5Hwa",
1685
+ "emergency-status-panel__title": "de-emergency-emergency-status-panel__title-nA5Hwa",
1686
+ "responder-name": "de-emergency-responder-name-nA5Hwa",
1687
+ "simulacrum-success-message": "de-emergency-simulacrum-success-message-nA5Hwa",
1688
+ "simulacrum-success-message__container": "de-emergency-simulacrum-success-message__container-nA5Hwa",
1689
+ "simulacrum-success-message__content": "de-emergency-simulacrum-success-message__content-nA5Hwa",
1690
+ "simulacrum-success-message__detail": "de-emergency-simulacrum-success-message__detail-nA5Hwa",
1691
+ "simulacrum-success-message__details": "de-emergency-simulacrum-success-message__details-nA5Hwa",
1692
+ "simulacrum-success-message__icon": "de-emergency-simulacrum-success-message__icon-nA5Hwa",
1693
+ "simulacrum-success-message__text": "de-emergency-simulacrum-success-message__text-nA5Hwa",
1694
+ "simulacrum-success-message__title": "de-emergency-simulacrum-success-message__title-nA5Hwa",
1695
+ "sos-img": "de-emergency-sos-img-nA5Hwa",
1696
+ "sos-img__container": "de-emergency-sos-img__container-nA5Hwa",
1697
+ "status-icon": "de-emergency-status-icon-nA5Hwa",
1698
+ "status-icon--checked": "de-emergency-status-icon--checked-nA5Hwa",
1699
+ "status-icon--failed": "de-emergency-status-icon--failed-nA5Hwa",
1700
+ "status-icon--unchecked": "de-emergency-status-icon--unchecked-nA5Hwa"
1680
1701
  };
1681
1702
 
1682
1703
  // src/react/classnames.ts
package/dist/index.d.cts CHANGED
@@ -101,6 +101,17 @@ interface EmergencyGeolocation {
101
101
  readonly longitude: number;
102
102
  readonly accuracy?: number;
103
103
  }
104
+ interface EmergencyRealtimeConfig {
105
+ /** Public Pusher app key supplied by the host. */
106
+ readonly key: string;
107
+ /** Pusher cluster that serves the app key. */
108
+ readonly cluster: string;
109
+ /**
110
+ * Channel name pattern. `{phone}` is replaced with the responder phone in
111
+ * digits-only form. Defaults to `whatsapp.{phone}`.
112
+ */
113
+ readonly channelPattern?: string;
114
+ }
104
115
  interface EmergencyConfig {
105
116
  /** Full BFF route prefix, for example `https://example.com/de-bff/emergency`. */
106
117
  readonly bffBaseUrl: string;
@@ -122,6 +133,11 @@ interface EmergencyConfig {
122
133
  readonly geolocationTimeoutMs?: number;
123
134
  /** Request timeout in milliseconds. Defaults to 15000. */
124
135
  readonly requestTimeoutMs?: number;
136
+ /**
137
+ * Public Pusher values supplied by the host. When omitted, the client stays
138
+ * in pull mode and never opens a realtime connection.
139
+ */
140
+ readonly realtime?: EmergencyRealtimeConfig;
125
141
  }
126
142
  interface EmergencySnapshot {
127
143
  readonly emergencyId: string;
@@ -239,18 +255,8 @@ interface EmergencyMountOptions extends EmergencyConfig {
239
255
  * message, and an inert client.
240
256
  */
241
257
  export declare function mount(options: EmergencyMountOptions): EmergencyClient;
242
- interface RealtimePusherConfig {
243
- readonly key: string;
244
- readonly cluster: string;
245
- readonly channel_pattern: string;
246
- }
247
- interface RealtimePublicConfig {
248
- readonly mode: 'public';
249
- readonly pusher: RealtimePusherConfig;
250
- }
251
258
  interface ConfigResponse {
252
259
  readonly route_prefix: string;
253
- readonly realtime: RealtimePublicConfig;
254
260
  readonly csrf_token: string;
255
261
  }
256
262
  interface SessionResponse {
@@ -292,7 +298,6 @@ type EmergencyPayload = Readonly<Record<string, unknown>>;
292
298
  interface CurrentResponse {
293
299
  readonly active: boolean;
294
300
  readonly emergency: EmergencyPayload | null;
295
- readonly realtime: RealtimePublicConfig;
296
301
  }
297
302
  interface GeolocationRequest {
298
303
  readonly latitude: number;
@@ -304,7 +309,6 @@ interface ActivateRequest {
304
309
  }
305
310
  interface RefreshResponse {
306
311
  readonly emergency: EmergencyPayload;
307
- readonly responders: readonly ResponderPayload[];
308
312
  }
309
313
  interface AbortResponse extends EmergencyResultPayload {
310
314
  readonly deleted: boolean;
@@ -378,7 +382,7 @@ interface RealtimeProvider {
378
382
  * Returns `null` when the realtime configuration is unusable, in which case
379
383
  * the client keeps working in pull mode.
380
384
  */
381
- subscribe(config: RealtimePublicConfig, phones: readonly string[], handlers: RealtimeHandlers): RealtimeSubscription | null;
385
+ subscribe(config: EmergencyRealtimeConfig, phones: readonly string[], handlers: RealtimeHandlers): RealtimeSubscription | null;
382
386
  }
383
387
  export declare function createPusherRealtimeProvider(): RealtimeProvider;
384
388
  type EmergencyStore = StoreApi<EmergencyClientState>;
@@ -410,7 +414,10 @@ interface ConfigValidationResult {
410
414
  readonly error: EmergencyError | null;
411
415
  readonly config: EmergencyConfig | null;
412
416
  }
413
- export declare function validateConfig(config: EmergencyConfig): ConfigValidationResult;
417
+ type EmergencyConfigInput = Omit<EmergencyConfig, 'realtime'> & {
418
+ readonly realtime?: unknown;
419
+ };
420
+ export declare function validateConfig(config: EmergencyConfigInput): ConfigValidationResult;
414
421
  export declare function themeToCssVariables(theme: EmergencyTheme | undefined): Record<string, string>;
415
422
  interface EmergencyErrorOptions {
416
423
  status?: number | null;
@@ -429,5 +436,5 @@ export declare class EmergencyClientError extends Error {
429
436
  readonly error: EmergencyError;
430
437
  constructor(error: EmergencyError);
431
438
  }
432
- export type { AbortResponse, AbortResult, ActivateRequest, BffClient, BffClientOptions, ConfigResponse, CsrfStrategy, CurrentResponse, EmergencyClient, EmergencyClientState, EmergencyConfig, EmergencyController, EmergencyControllerDeps, EmergencyError, EmergencyErrorCode, EmergencyEventEmitter, EmergencyEventMap, EmergencyEventName, EmergencyFailure, EmergencyFallback, EmergencyFontFamilyFlags, EmergencyFontLoading, EmergencyGeolocation, EmergencyMountOptions, EmergencyOperation, EmergencyPhase, EmergencyPhaseName, EmergencyResultPayload, EmergencySnapshot, EmergencyStore, EmergencyTheme, EmergencyTrigger, FailurePayload, Message, MessageKind, PanelCloseReason, PanelOpenReason, RealtimeStatus, RefreshResponse, Responder, ResponderPayload, ResponderStatus, SessionResponse, SimulationResult };
439
+ export type { AbortResponse, AbortResult, ActivateRequest, BffClient, BffClientOptions, ConfigResponse, CsrfStrategy, CurrentResponse, EmergencyClient, EmergencyClientState, EmergencyConfig, EmergencyConfigInput, EmergencyController, EmergencyControllerDeps, EmergencyError, EmergencyErrorCode, EmergencyEventEmitter, EmergencyEventMap, EmergencyEventName, EmergencyFailure, EmergencyFallback, EmergencyFontFamilyFlags, EmergencyFontLoading, EmergencyGeolocation, EmergencyMountOptions, EmergencyOperation, EmergencyPhase, EmergencyPhaseName, EmergencyRealtimeConfig, EmergencyResultPayload, EmergencySnapshot, EmergencyStore, EmergencyTheme, EmergencyTrigger, FailurePayload, Message, MessageKind, PanelCloseReason, PanelOpenReason, RealtimeStatus, RefreshResponse, Responder, ResponderPayload, ResponderStatus, SessionResponse, SimulationResult };
433
440
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.ts CHANGED
@@ -101,6 +101,17 @@ interface EmergencyGeolocation {
101
101
  readonly longitude: number;
102
102
  readonly accuracy?: number;
103
103
  }
104
+ interface EmergencyRealtimeConfig {
105
+ /** Public Pusher app key supplied by the host. */
106
+ readonly key: string;
107
+ /** Pusher cluster that serves the app key. */
108
+ readonly cluster: string;
109
+ /**
110
+ * Channel name pattern. `{phone}` is replaced with the responder phone in
111
+ * digits-only form. Defaults to `whatsapp.{phone}`.
112
+ */
113
+ readonly channelPattern?: string;
114
+ }
104
115
  interface EmergencyConfig {
105
116
  /** Full BFF route prefix, for example `https://example.com/de-bff/emergency`. */
106
117
  readonly bffBaseUrl: string;
@@ -122,6 +133,11 @@ interface EmergencyConfig {
122
133
  readonly geolocationTimeoutMs?: number;
123
134
  /** Request timeout in milliseconds. Defaults to 15000. */
124
135
  readonly requestTimeoutMs?: number;
136
+ /**
137
+ * Public Pusher values supplied by the host. When omitted, the client stays
138
+ * in pull mode and never opens a realtime connection.
139
+ */
140
+ readonly realtime?: EmergencyRealtimeConfig;
125
141
  }
126
142
  interface EmergencySnapshot {
127
143
  readonly emergencyId: string;
@@ -239,18 +255,8 @@ interface EmergencyMountOptions extends EmergencyConfig {
239
255
  * message, and an inert client.
240
256
  */
241
257
  export declare function mount(options: EmergencyMountOptions): EmergencyClient;
242
- interface RealtimePusherConfig {
243
- readonly key: string;
244
- readonly cluster: string;
245
- readonly channel_pattern: string;
246
- }
247
- interface RealtimePublicConfig {
248
- readonly mode: 'public';
249
- readonly pusher: RealtimePusherConfig;
250
- }
251
258
  interface ConfigResponse {
252
259
  readonly route_prefix: string;
253
- readonly realtime: RealtimePublicConfig;
254
260
  readonly csrf_token: string;
255
261
  }
256
262
  interface SessionResponse {
@@ -292,7 +298,6 @@ type EmergencyPayload = Readonly<Record<string, unknown>>;
292
298
  interface CurrentResponse {
293
299
  readonly active: boolean;
294
300
  readonly emergency: EmergencyPayload | null;
295
- readonly realtime: RealtimePublicConfig;
296
301
  }
297
302
  interface GeolocationRequest {
298
303
  readonly latitude: number;
@@ -304,7 +309,6 @@ interface ActivateRequest {
304
309
  }
305
310
  interface RefreshResponse {
306
311
  readonly emergency: EmergencyPayload;
307
- readonly responders: readonly ResponderPayload[];
308
312
  }
309
313
  interface AbortResponse extends EmergencyResultPayload {
310
314
  readonly deleted: boolean;
@@ -378,7 +382,7 @@ interface RealtimeProvider {
378
382
  * Returns `null` when the realtime configuration is unusable, in which case
379
383
  * the client keeps working in pull mode.
380
384
  */
381
- subscribe(config: RealtimePublicConfig, phones: readonly string[], handlers: RealtimeHandlers): RealtimeSubscription | null;
385
+ subscribe(config: EmergencyRealtimeConfig, phones: readonly string[], handlers: RealtimeHandlers): RealtimeSubscription | null;
382
386
  }
383
387
  export declare function createPusherRealtimeProvider(): RealtimeProvider;
384
388
  type EmergencyStore = StoreApi<EmergencyClientState>;
@@ -410,7 +414,10 @@ interface ConfigValidationResult {
410
414
  readonly error: EmergencyError | null;
411
415
  readonly config: EmergencyConfig | null;
412
416
  }
413
- export declare function validateConfig(config: EmergencyConfig): ConfigValidationResult;
417
+ type EmergencyConfigInput = Omit<EmergencyConfig, 'realtime'> & {
418
+ readonly realtime?: unknown;
419
+ };
420
+ export declare function validateConfig(config: EmergencyConfigInput): ConfigValidationResult;
414
421
  export declare function themeToCssVariables(theme: EmergencyTheme | undefined): Record<string, string>;
415
422
  interface EmergencyErrorOptions {
416
423
  status?: number | null;
@@ -429,5 +436,5 @@ export declare class EmergencyClientError extends Error {
429
436
  readonly error: EmergencyError;
430
437
  constructor(error: EmergencyError);
431
438
  }
432
- export type { AbortResponse, AbortResult, ActivateRequest, BffClient, BffClientOptions, ConfigResponse, CsrfStrategy, CurrentResponse, EmergencyClient, EmergencyClientState, EmergencyConfig, EmergencyController, EmergencyControllerDeps, EmergencyError, EmergencyErrorCode, EmergencyEventEmitter, EmergencyEventMap, EmergencyEventName, EmergencyFailure, EmergencyFallback, EmergencyFontFamilyFlags, EmergencyFontLoading, EmergencyGeolocation, EmergencyMountOptions, EmergencyOperation, EmergencyPhase, EmergencyPhaseName, EmergencyResultPayload, EmergencySnapshot, EmergencyStore, EmergencyTheme, EmergencyTrigger, FailurePayload, Message, MessageKind, PanelCloseReason, PanelOpenReason, RealtimeStatus, RefreshResponse, Responder, ResponderPayload, ResponderStatus, SessionResponse, SimulationResult };
439
+ export type { AbortResponse, AbortResult, ActivateRequest, BffClient, BffClientOptions, ConfigResponse, CsrfStrategy, CurrentResponse, EmergencyClient, EmergencyClientState, EmergencyConfig, EmergencyConfigInput, EmergencyController, EmergencyControllerDeps, EmergencyError, EmergencyErrorCode, EmergencyEventEmitter, EmergencyEventMap, EmergencyEventName, EmergencyFailure, EmergencyFallback, EmergencyFontFamilyFlags, EmergencyFontLoading, EmergencyGeolocation, EmergencyMountOptions, EmergencyOperation, EmergencyPhase, EmergencyPhaseName, EmergencyRealtimeConfig, EmergencyResultPayload, EmergencySnapshot, EmergencyStore, EmergencyTheme, EmergencyTrigger, FailurePayload, Message, MessageKind, PanelCloseReason, PanelOpenReason, RealtimeStatus, RefreshResponse, Responder, ResponderPayload, ResponderStatus, SessionResponse, SimulationResult };
433
440
  //# sourceMappingURL=index.d.ts.map