@sincpro/mobile 0.1.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.
Files changed (232) hide show
  1. package/README.md +74 -0
  2. package/dist/adapters/Bluetooth.adapter.d.ts +14 -0
  3. package/dist/adapters/Bluetooth.adapter.js +100 -0
  4. package/dist/adapters/Geo.adapter.d.ts +8 -0
  5. package/dist/adapters/Geo.adapter.js +30 -0
  6. package/dist/adapters/JsonSerializer.adapter.d.ts +28 -0
  7. package/dist/adapters/JsonSerializer.adapter.js +47 -0
  8. package/dist/adapters/Network.adapter.d.ts +4 -0
  9. package/dist/adapters/Network.adapter.js +13 -0
  10. package/dist/adapters/ReceiptExporter.adapter.d.ts +19 -0
  11. package/dist/adapters/ReceiptExporter.adapter.js +142 -0
  12. package/dist/adapters/repositories/database_table.repository.d.ts +13 -0
  13. package/dist/adapters/repositories/database_table.repository.js +29 -0
  14. package/dist/adapters/repositories/domain_event.repository.d.ts +32 -0
  15. package/dist/adapters/repositories/domain_event.repository.js +147 -0
  16. package/dist/adapters/repositories/domain_event_dead_letter.repository.d.ts +23 -0
  17. package/dist/adapters/repositories/domain_event_dead_letter.repository.js +81 -0
  18. package/dist/adapters/repositories/setting.repository.d.ts +10 -0
  19. package/dist/adapters/repositories/setting.repository.js +21 -0
  20. package/dist/adapters/webview.adapter.d.ts +10 -0
  21. package/dist/adapters/webview.adapter.js +166 -0
  22. package/dist/domain/connectivity/bluetooth.d.ts +19 -0
  23. package/dist/domain/connectivity/bluetooth.js +1 -0
  24. package/dist/domain/connectivity/events.d.ts +17 -0
  25. package/dist/domain/connectivity/events.js +17 -0
  26. package/dist/domain/connectivity/geo.d.ts +4 -0
  27. package/dist/domain/connectivity/geo.js +1 -0
  28. package/dist/domain/connectivity/index.d.ts +3 -0
  29. package/dist/domain/connectivity/index.js +3 -0
  30. package/dist/domain/connectivity/network.d.ts +7 -0
  31. package/dist/domain/connectivity/network.js +1 -0
  32. package/dist/domain/database/database.d.ts +16 -0
  33. package/dist/domain/database/database.js +1 -0
  34. package/dist/domain/database/index.d.ts +2 -0
  35. package/dist/domain/database/index.js +2 -0
  36. package/dist/domain/database/repository.d.ts +19 -0
  37. package/dist/domain/database/repository.js +1 -0
  38. package/dist/domain/entity/entity.d.ts +109 -0
  39. package/dist/domain/entity/entity.js +246 -0
  40. package/dist/domain/entity/entity_collection.d.ts +396 -0
  41. package/dist/domain/entity/entity_collection.js +824 -0
  42. package/dist/domain/entity/index.d.ts +3 -0
  43. package/dist/domain/entity/index.js +3 -0
  44. package/dist/domain/entity/value_object.d.ts +12 -0
  45. package/dist/domain/entity/value_object.js +39 -0
  46. package/dist/domain/event_sourcing/domain_event.d.ts +58 -0
  47. package/dist/domain/event_sourcing/domain_event.js +164 -0
  48. package/dist/domain/event_sourcing/event.d.ts +25 -0
  49. package/dist/domain/event_sourcing/event.js +25 -0
  50. package/dist/domain/event_sourcing/event_handler.d.ts +7 -0
  51. package/dist/domain/event_sourcing/event_handler.js +13 -0
  52. package/dist/domain/event_sourcing/index.d.ts +2 -0
  53. package/dist/domain/event_sourcing/index.js +2 -0
  54. package/dist/domain/events.d.ts +33 -0
  55. package/dist/domain/events.js +32 -0
  56. package/dist/domain/icon.d.ts +1 -0
  57. package/dist/domain/icon.js +1 -0
  58. package/dist/domain/index.d.ts +9 -0
  59. package/dist/domain/index.js +9 -0
  60. package/dist/domain/print/driver_registry.d.ts +4 -0
  61. package/dist/domain/print/driver_registry.js +29 -0
  62. package/dist/domain/print/events.d.ts +13 -0
  63. package/dist/domain/print/events.js +13 -0
  64. package/dist/domain/print/index.d.ts +2 -0
  65. package/dist/domain/print/index.js +1 -0
  66. package/dist/domain/print/printer.d.ts +35 -0
  67. package/dist/domain/print/printer.js +1 -0
  68. package/dist/domain/receipt.d.ts +31 -0
  69. package/dist/domain/receipt.js +1 -0
  70. package/dist/domain/repositories.d.ts +6 -0
  71. package/dist/domain/repositories.js +7 -0
  72. package/dist/domain/settings.d.ts +7 -0
  73. package/dist/domain/settings.js +1 -0
  74. package/dist/domain/webview/events.d.ts +11 -0
  75. package/dist/domain/webview/events.js +11 -0
  76. package/dist/domain/webview/index.d.ts +1 -0
  77. package/dist/domain/webview/index.js +1 -0
  78. package/dist/domain/webview/webview.d.ts +57 -0
  79. package/dist/domain/webview/webview.js +9 -0
  80. package/dist/entrypoints/cron/Cron.d.ts +13 -0
  81. package/dist/entrypoints/cron/Cron.js +57 -0
  82. package/dist/entrypoints/cron/checkNetworkStatus.cron.d.ts +3 -0
  83. package/dist/entrypoints/cron/checkNetworkStatus.cron.js +10 -0
  84. package/dist/entrypoints/db/index.d.ts +2 -0
  85. package/dist/entrypoints/db/index.js +2 -0
  86. package/dist/entrypoints/db/migrations.d.ts +10 -0
  87. package/dist/entrypoints/db/migrations.js +115 -0
  88. package/dist/entrypoints/db/repositories.d.ts +8 -0
  89. package/dist/entrypoints/db/repositories.js +34 -0
  90. package/dist/entrypoints/queue/QueueProcessor.d.ts +12 -0
  91. package/dist/entrypoints/queue/QueueProcessor.js +75 -0
  92. package/dist/entrypoints/queue/activateDomain.subscriber.d.ts +7 -0
  93. package/dist/entrypoints/queue/activateDomain.subscriber.js +15 -0
  94. package/dist/entrypoints/queue/newAppSettings.handler.d.ts +7 -0
  95. package/dist/entrypoints/queue/newAppSettings.handler.js +17 -0
  96. package/dist/entrypoints/queue/printImage.subscriber.d.ts +7 -0
  97. package/dist/entrypoints/queue/printImage.subscriber.js +14 -0
  98. package/dist/entrypoints/queue/processWebViewMessage.subscriber.d.ts +7 -0
  99. package/dist/entrypoints/queue/processWebViewMessage.subscriber.js +23 -0
  100. package/dist/entrypoints/ui/AppShell.d.ts +15 -0
  101. package/dist/entrypoints/ui/AppShell.js +58 -0
  102. package/dist/entrypoints/ui/common_provider.d.ts +35 -0
  103. package/dist/entrypoints/ui/common_provider.js +244 -0
  104. package/dist/entrypoints/ui/domain_switcher.d.ts +19 -0
  105. package/dist/entrypoints/ui/domain_switcher.js +22 -0
  106. package/dist/entrypoints/ui/theme.d.ts +15 -0
  107. package/dist/entrypoints/ui/theme.js +16 -0
  108. package/dist/exceptions.d.ts +22 -0
  109. package/dist/exceptions.js +60 -0
  110. package/dist/framework/base_module.d.ts +14 -0
  111. package/dist/framework/base_module.js +40 -0
  112. package/dist/framework/createApp.d.ts +6 -0
  113. package/dist/framework/createApp.js +9 -0
  114. package/dist/framework/domain_module.d.ts +13 -0
  115. package/dist/framework/domain_module.js +18 -0
  116. package/dist/framework/kernel.d.ts +18 -0
  117. package/dist/framework/kernel.js +60 -0
  118. package/dist/framework/orchestrator.d.ts +29 -0
  119. package/dist/framework/orchestrator.js +118 -0
  120. package/dist/index.d.ts +16 -0
  121. package/dist/index.js +11 -0
  122. package/dist/infrastructure/database/connector.d.ts +13 -0
  123. package/dist/infrastructure/database/connector.js +165 -0
  124. package/dist/infrastructure/database/index.d.ts +2 -0
  125. package/dist/infrastructure/database/index.js +2 -0
  126. package/dist/infrastructure/database/mapped.d.ts +128 -0
  127. package/dist/infrastructure/database/mapped.js +174 -0
  128. package/dist/infrastructure/database/utils.d.ts +10 -0
  129. package/dist/infrastructure/database/utils.js +35 -0
  130. package/dist/infrastructure/logger.d.ts +45 -0
  131. package/dist/infrastructure/logger.js +125 -0
  132. package/dist/infrastructure/ui/ToastHost.d.ts +1 -0
  133. package/dist/infrastructure/ui/ToastHost.js +19 -0
  134. package/dist/infrastructure/ui/UIEventBus.d.ts +12 -0
  135. package/dist/infrastructure/ui/UIEventBus.js +65 -0
  136. package/dist/infrastructure/ui/errorHandler.d.ts +1 -0
  137. package/dist/infrastructure/ui/errorHandler.js +20 -0
  138. package/dist/infrastructure/ui/events.d.ts +1 -0
  139. package/dist/infrastructure/ui/events.js +1 -0
  140. package/dist/infrastructure/workers/CronWorker.d.ts +42 -0
  141. package/dist/infrastructure/workers/CronWorker.js +143 -0
  142. package/dist/infrastructure/workers/EventBus.d.ts +67 -0
  143. package/dist/infrastructure/workers/EventBus.js +279 -0
  144. package/dist/infrastructure/workers/index.d.ts +2 -0
  145. package/dist/infrastructure/workers/index.js +2 -0
  146. package/dist/services/bluetooth.service.d.ts +14 -0
  147. package/dist/services/bluetooth.service.js +72 -0
  148. package/dist/services/database_table.service.d.ts +8 -0
  149. package/dist/services/database_table.service.js +19 -0
  150. package/dist/services/dead_letter_queue.service.d.ts +38 -0
  151. package/dist/services/dead_letter_queue.service.js +99 -0
  152. package/dist/services/event.service.d.ts +7 -0
  153. package/dist/services/event.service.js +24 -0
  154. package/dist/services/network.service.d.ts +7 -0
  155. package/dist/services/network.service.js +43 -0
  156. package/dist/services/printer.service.d.ts +25 -0
  157. package/dist/services/printer.service.js +220 -0
  158. package/dist/services/webview.service.d.ts +17 -0
  159. package/dist/services/webview.service.js +59 -0
  160. package/dist/tools/utils/Initials.d.ts +1 -0
  161. package/dist/tools/utils/Initials.js +12 -0
  162. package/dist/tools/utils/collections.d.ts +120 -0
  163. package/dist/tools/utils/collections.js +158 -0
  164. package/dist/tools/utils/date.d.ts +70 -0
  165. package/dist/tools/utils/date.js +126 -0
  166. package/dist/tools/utils/maps.d.ts +4 -0
  167. package/dist/tools/utils/maps.js +20 -0
  168. package/dist/tools/utils/monetary.d.ts +3 -0
  169. package/dist/tools/utils/monetary.js +31 -0
  170. package/dist/tools/utils/quantity.d.ts +11 -0
  171. package/dist/tools/utils/quantity.js +44 -0
  172. package/dist/tools/utils/searchTools.d.ts +39 -0
  173. package/dist/tools/utils/searchTools.js +56 -0
  174. package/dist/tools/utils/serializer.d.ts +2 -0
  175. package/dist/tools/utils/serializer.js +44 -0
  176. package/dist/ui/components/atoms/DebugBanner.d.ts +2 -0
  177. package/dist/ui/components/atoms/DebugBanner.js +15 -0
  178. package/dist/ui/components/atoms/index.d.ts +1 -0
  179. package/dist/ui/components/atoms/index.js +1 -0
  180. package/dist/ui/components/molecules/BluetoothDeviceSelectorModal.d.ts +8 -0
  181. package/dist/ui/components/molecules/BluetoothDeviceSelectorModal.js +61 -0
  182. package/dist/ui/components/molecules/DeadLetterErrorBlock.d.ts +8 -0
  183. package/dist/ui/components/molecules/DeadLetterErrorBlock.js +14 -0
  184. package/dist/ui/components/molecules/EventTimelineItem.d.ts +7 -0
  185. package/dist/ui/components/molecules/EventTimelineItem.js +65 -0
  186. package/dist/ui/components/molecules/ProcessToast.d.ts +5 -0
  187. package/dist/ui/components/molecules/ProcessToast.js +51 -0
  188. package/dist/ui/components/molecules/ProcessToastProvider.d.ts +4 -0
  189. package/dist/ui/components/molecules/ProcessToastProvider.js +5 -0
  190. package/dist/ui/components/molecules/index.d.ts +5 -0
  191. package/dist/ui/components/molecules/index.js +5 -0
  192. package/dist/ui/components/organisms/BluetoothPrinterSelector.d.ts +7 -0
  193. package/dist/ui/components/organisms/BluetoothPrinterSelector.js +92 -0
  194. package/dist/ui/components/organisms/DatabaseInfoRow.d.ts +11 -0
  195. package/dist/ui/components/organisms/DatabaseInfoRow.js +8 -0
  196. package/dist/ui/components/organisms/DeadLetterQueueRow.d.ts +7 -0
  197. package/dist/ui/components/organisms/DeadLetterQueueRow.js +72 -0
  198. package/dist/ui/components/organisms/EventRow.d.ts +7 -0
  199. package/dist/ui/components/organisms/EventRow.js +90 -0
  200. package/dist/ui/components/organisms/InjectableWebView.d.ts +35 -0
  201. package/dist/ui/components/organisms/InjectableWebView.js +169 -0
  202. package/dist/ui/components/organisms/Receipt.d.ts +11 -0
  203. package/dist/ui/components/organisms/Receipt.js +207 -0
  204. package/dist/ui/components/organisms/TableInfoInfoRow.d.ts +9 -0
  205. package/dist/ui/components/organisms/TableInfoInfoRow.js +19 -0
  206. package/dist/ui/components/organisms/index.d.ts +7 -0
  207. package/dist/ui/components/organisms/index.js +7 -0
  208. package/dist/ui/index.d.ts +4 -0
  209. package/dist/ui/index.js +4 -0
  210. package/dist/ui/layouts/router_layouts.d.ts +17 -0
  211. package/dist/ui/layouts/router_layouts.js +20 -0
  212. package/dist/ui/screens/database/database.context.d.ts +32 -0
  213. package/dist/ui/screens/database/database.context.js +158 -0
  214. package/dist/ui/screens/database/database.json_detail.d.ts +2 -0
  215. package/dist/ui/screens/database/database.json_detail.js +19 -0
  216. package/dist/ui/screens/database/database.list.d.ts +1 -0
  217. package/dist/ui/screens/database/database.list.js +41 -0
  218. package/dist/ui/screens/database/database.table_rows.d.ts +2 -0
  219. package/dist/ui/screens/database/database.table_rows.js +10 -0
  220. package/dist/ui/screens/dead_letter_queue/dead_letter_queue.context.d.ts +34 -0
  221. package/dist/ui/screens/dead_letter_queue/dead_letter_queue.context.js +166 -0
  222. package/dist/ui/screens/dead_letter_queue/dead_letter_queue.list.d.ts +2 -0
  223. package/dist/ui/screens/dead_letter_queue/dead_letter_queue.list.js +24 -0
  224. package/dist/ui/screens/events/events.context.d.ts +25 -0
  225. package/dist/ui/screens/events/events.context.js +113 -0
  226. package/dist/ui/screens/events/events.list.d.ts +1 -0
  227. package/dist/ui/screens/events/events.list.js +26 -0
  228. package/dist/ui/screens/events/index.d.ts +1 -0
  229. package/dist/ui/screens/events/index.js +1 -0
  230. package/dist/ui/screens/index.d.ts +3 -0
  231. package/dist/ui/screens/index.js +3 -0
  232. package/package.json +125 -0
@@ -0,0 +1,126 @@
1
+ import dayjs from "dayjs";
2
+ import timezone from "dayjs/plugin/timezone";
3
+ import utc from "dayjs/plugin/utc";
4
+ import { getLocales } from "expo-localization";
5
+ const DEFAULT_TIMEZONE = "America/Costa_Rica";
6
+ const DEFAULT_LOCALE = "es-CR";
7
+ dayjs.extend(utc);
8
+ dayjs.extend(timezone);
9
+ /**
10
+ * Formatea una fecha en la zona horaria indicada respetando la granularidad de la entrada.
11
+ *
12
+ * Reglas de detección:
13
+ * 1. Si `input` es un string 'YYYY-MM-DD' (solo fecha) => se interpreta como medianoche (00:00:00)
14
+ * en la zona horaria destino y se devuelve SOLO la parte de fecha (sin hora).
15
+ * 2. Si `input` incluye componente de tiempo (ISO completo o Date) => se convierte a la zona destino
16
+ * y se muestra fecha + hora (HH:MM) salvo que se fuerce lo contrario mediante `options.showTime`.
17
+ * 3. Cuando `options.showTime` es `true` o `false` se sobre‑escribe la auto‑detección.
18
+ * 4. Si `timezone` es null/undefined o inválido se retorna la cadena "Error de formateo".
19
+ *
20
+ * Localización:
21
+ * - Usa el primer locale del dispositivo (`expo-localization`) como predeterminado.
22
+ * - Puedes forzar uno diferente con `options.locale` (ej: 'es-CR', 'en-US').
23
+ *
24
+ * Seguridad de zona horaria:
25
+ * - El parse de una fecha sin hora NO se hace en la zona local del dispositivo para luego convertir,
26
+ * sino directamente en la zona destino para evitar corrimientos de día.
27
+ *
28
+ * Ejemplos:
29
+ * ```ts
30
+ * formatDate('2025-09-02', 'America/Costa_Rica');
31
+ * // => "2 de septiembre de 2025"
32
+ *
33
+ * formatDate('2025-09-02T18:30:00Z', 'America/Costa_Rica');
34
+ * // => "2 de septiembre de 2025, 12:30 p. m." (dependiendo del locale real)
35
+ *
36
+ * formatDate(new Date('2025-09-02T23:15:00Z'), 'Europe/Madrid');
37
+ * // => "3 de septiembre de 2025, 01:15" (cambio de día por zona +02)
38
+ *
39
+ * formatDate('2025-09-02', 'America/Costa_Rica', { showTime: true });
40
+ * // => "2 de septiembre de 2025, 12:00 a. m." (fuerza hora)
41
+ * ```
42
+ *
43
+ * @param input Fecha (string ISO, 'YYYY-MM-DD' o instancia Date)
44
+ * @param timezone Zona horaria IANA (ej: 'America/Costa_Rica', 'Asia/Tokyo'). Si es null/undefined usa Costa Rica
45
+ * @param options Opcional: locale forzado y/o bandera para mostrar hora
46
+ * @returns Cadena localizada o "Error de formateo" si no se puede procesar
47
+ */
48
+ export function formatDate(input, timezone, options) {
49
+ // Usar timezone por defecto si no se proporciona
50
+ const effectiveTimezone = timezone || DEFAULT_TIMEZONE;
51
+ const fallbackLocale = DEFAULT_LOCALE.split("-")[0]; // "es" from "es-CR"
52
+ const deviceLocale = getLocales()?.[0]?.languageTag ?? fallbackLocale;
53
+ const usedLocale = options?.locale ?? deviceLocale;
54
+ try {
55
+ const rawStr = typeof input === "string" ? input : input.toISOString();
56
+ const isDateOnly = /^\d{4}-\d{2}-\d{2}$/.test(rawStr);
57
+ // Auto-detect showTime si no se pasa explicitamente
58
+ const effectiveShowTime = options?.showTime !== undefined
59
+ ? options.showTime
60
+ : !isDateOnly && /T\d{2}:\d{2}/.test(rawStr); // tiene componente hora
61
+ const dateInstance = isDateOnly
62
+ ? dayjs.tz(`${rawStr}T00:00:00`, effectiveTimezone)
63
+ : dayjs.utc(rawStr).tz(effectiveTimezone);
64
+ const dateInZone = dateInstance.toDate();
65
+ const formatOptions = {
66
+ year: "numeric",
67
+ month: "long",
68
+ day: "numeric",
69
+ timeZone: effectiveTimezone,
70
+ };
71
+ if (effectiveShowTime) {
72
+ formatOptions.hour = "2-digit";
73
+ formatOptions.minute = "2-digit";
74
+ }
75
+ return new Intl.DateTimeFormat(usedLocale, formatOptions).format(dateInZone);
76
+ }
77
+ catch (error) {
78
+ console.warn("Error formateando fecha:", error);
79
+ return "Error de formateo";
80
+ }
81
+ }
82
+ /**
83
+ * Formatea una fecha usando automáticamente el timezone por defecto (Costa Rica).
84
+ * Útil para casos donde no se tiene acceso al timezone del usuario.
85
+ *
86
+ * @param input Fecha (string ISO, 'YYYY-MM-DD' o instancia Date)
87
+ * @param options Opcional: locale forzado y/o bandera para mostrar hora
88
+ * @returns Cadena localizada en timezone de Costa Rica
89
+ */
90
+ export function formatDateWithDefaultTimezone(input, options) {
91
+ return formatDate(input, DEFAULT_TIMEZONE, options);
92
+ }
93
+ /**
94
+ * Obtiene la fecha actual en formato YYYY-MM-DD en el timezone especificado.
95
+ * Útil para crear fechas de programación que respeten el timezone del usuario.
96
+ *
97
+ * @param timezone Zona horaria IANA. Si es null/undefined usa Costa Rica
98
+ * @returns Fecha actual en formato YYYY-MM-DD en el timezone especificado
99
+ */
100
+ export function getCurrentDateInTimezone(timezone) {
101
+ const effectiveTimezone = timezone || DEFAULT_TIMEZONE;
102
+ try {
103
+ return dayjs().tz(effectiveTimezone).format("YYYY-MM-DD");
104
+ }
105
+ catch (error) {
106
+ console.warn("Error obteniendo fecha actual en timezone:", error);
107
+ return dayjs().format("YYYY-MM-DD"); // Fallback to local
108
+ }
109
+ }
110
+ /**
111
+ * Obtiene la fecha y hora actual en formato ISO en el timezone especificado.
112
+ * Útil para timestamps que necesiten reflejar el timezone del usuario.
113
+ *
114
+ * @param timezone Zona horaria IANA. Si es null/undefined usa Costa Rica
115
+ * @returns Fecha actual en formato ISO en el timezone especificado
116
+ */
117
+ export function getCurrentDateTimeInTimezone(timezone) {
118
+ const effectiveTimezone = timezone || DEFAULT_TIMEZONE;
119
+ try {
120
+ return dayjs().tz(effectiveTimezone).toISOString();
121
+ }
122
+ catch (error) {
123
+ console.warn("Error obteniendo fecha/hora actual en timezone:", error);
124
+ return dayjs().toISOString(); // Fallback to local
125
+ }
126
+ }
@@ -0,0 +1,4 @@
1
+ export declare const openMapWithRoute: (destination: {
2
+ latitude: number;
3
+ longitude: number;
4
+ }) => Promise<void>;
@@ -0,0 +1,20 @@
1
+ import * as Linking from "expo-linking";
2
+ import { Platform } from "react-native";
3
+ export const openMapWithRoute = async (destination) => {
4
+ const { latitude, longitude } = destination;
5
+ const url = Platform.OS === "ios"
6
+ ? `http://maps.apple.com/?daddr=${latitude},${longitude}`
7
+ : `https://www.google.com/maps/dir/?api=1&destination=${latitude},${longitude}`;
8
+ try {
9
+ const canOpen = await Linking.canOpenURL(url);
10
+ if (canOpen) {
11
+ await Linking.openURL(url);
12
+ }
13
+ else {
14
+ console.error("No se puede abrir la URL del mapa:", url);
15
+ }
16
+ }
17
+ catch (error) {
18
+ console.error("Error al abrir la URL del mapa:", error);
19
+ }
20
+ };
@@ -0,0 +1,3 @@
1
+ export declare function parseToMonetaryNumber(input?: string | number | null): number;
2
+ export declare function formatTwoDecimals(value?: number | string | null): string;
3
+ export declare function calculateDiscountedTotal(total: number, discount: number): number;
@@ -0,0 +1,31 @@
1
+ import { Big } from "big.js";
2
+ export function parseToMonetaryNumber(input) {
3
+ if (input == null)
4
+ return 0;
5
+ const s = String(input).trim();
6
+ if (!/[0-9]/.test(s))
7
+ return 0;
8
+ const cleaned = s.replace(/[^0-9.-]+/g, "");
9
+ try {
10
+ return Number(new Big(cleaned).toString());
11
+ }
12
+ catch {
13
+ return 0;
14
+ }
15
+ }
16
+ export function formatTwoDecimals(value) {
17
+ const raw = parseToMonetaryNumber(value);
18
+ const rounded = new Big(raw).toFixed(2);
19
+ const num = Number(rounded);
20
+ return new Intl.NumberFormat("de-DE", {
21
+ minimumFractionDigits: 2,
22
+ maximumFractionDigits: 2,
23
+ }).format(num);
24
+ }
25
+ export function calculateDiscountedTotal(total, discount) {
26
+ if (discount === 0) {
27
+ return 0;
28
+ }
29
+ const result = (parseToMonetaryNumber(total) * discount) / 100;
30
+ return parseToMonetaryNumber(result);
31
+ }
@@ -0,0 +1,11 @@
1
+ /** Redondea a la precisión indicada usando round half up */
2
+ export declare function roundTo(value: number, precision: number): number;
3
+ /** Normaliza la cantidad al múltiplo más cercano del incremento mínimo */
4
+ export declare function normalizeQuantity(value: number, minIncrement: number, precision: number): number;
5
+ /** Convierte un valor a entero escalado según precisión para cálculos seguros */
6
+ export declare function toScaledInt(value: number, precision: number): number;
7
+ export declare function fromScaledInt(scaled: number, precision: number): number;
8
+ /** Multiplicación segura evitando errores binarios típicos */
9
+ export declare function safeMul(a: number, b: number, precision: number): number;
10
+ /** Valida si un valor es múltiplo del incremento mínimo dentro de la precisión */
11
+ export declare function isMultipleOfIncrement(value: number, minIncrement: number, precision: number): boolean;
@@ -0,0 +1,44 @@
1
+ import { Big } from "big.js";
2
+ /** Redondea a la precisión indicada usando round half up */
3
+ export function roundTo(value, precision) {
4
+ if (isNaN(value))
5
+ return 0;
6
+ const factor = new Big(10).pow(precision);
7
+ return Number(new Big(value).times(factor).round(0, 1).div(factor).toString());
8
+ }
9
+ /** Normaliza la cantidad al múltiplo más cercano del incremento mínimo */
10
+ export function normalizeQuantity(value, minIncrement, precision) {
11
+ if (!isFinite(value))
12
+ return 0;
13
+ if (value < 0)
14
+ value = 0;
15
+ if (minIncrement <= 0)
16
+ return roundTo(value, precision);
17
+ const steps = Math.round(value / minIncrement);
18
+ const normalized = steps * minIncrement;
19
+ return roundTo(normalized, precision);
20
+ }
21
+ /** Convierte un valor a entero escalado según precisión para cálculos seguros */
22
+ export function toScaledInt(value, precision) {
23
+ if (!isFinite(value))
24
+ return 0;
25
+ const factor = Math.pow(10, precision);
26
+ return Math.round(value * factor);
27
+ }
28
+ export function fromScaledInt(scaled, precision) {
29
+ const factor = Math.pow(10, precision);
30
+ return scaled / factor;
31
+ }
32
+ /** Multiplicación segura evitando errores binarios típicos */
33
+ export function safeMul(a, b, precision) {
34
+ const factor = Math.pow(10, precision);
35
+ return (Math.round(a * factor) * Math.round(b * factor)) / (factor * factor);
36
+ }
37
+ /** Valida si un valor es múltiplo del incremento mínimo dentro de la precisión */
38
+ export function isMultipleOfIncrement(value, minIncrement, precision) {
39
+ if (minIncrement <= 0)
40
+ return true;
41
+ const scaledValue = toScaledInt(value, precision + 3); // extra precisión para reducir error
42
+ const scaledInc = toScaledInt(minIncrement, precision + 3);
43
+ return scaledValue % scaledInc === 0;
44
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Search Tools: concurrency helpers for use-case level search orchestration.
3
+ *
4
+ * Exposes LatestDebounced to coordinate frequent, user-driven async searches
5
+ * while avoiding race conditions and backend hammering.
6
+ */
7
+ /**
8
+ * LatestDebounced
9
+ *
10
+ * What it solves (use case):
11
+ * - In interactive UIs (search bars, live filters) users type quickly.
12
+ * - Each key stroke can trigger an async search/use case request.
13
+ * - Without control, multiple in-flight requests compete and late responses can override newer results (race conditions), while also hammering the backend.
14
+ *
15
+ * Core idea:
16
+ * - Allow scheduling tasks frequently, but only execute the latest one and enforce a minimal time gap between executions (debounce at the use-case layer).
17
+ * - If an older scheduled task finishes after a newer one, its result is considered stale and can be replaced by a fallback (e.g., re-read latest local results) via the optional onStale handler.
18
+ *
19
+ * Why use this instead of UI-level debounce?
20
+ * - Keeps UI dead-simple and pushes orchestration to application logic (use cases), matching Clean Architecture.
21
+ * - Centralizes race-condition handling; UI doesn't need abort controllers or timers.
22
+ *
23
+ * Typical usage:
24
+ * const gate = new LatestDebounced(1000); // 1s min interval
25
+ * return gate.run(async () => doSearch(query), async () => getLatestLocal(query));
26
+ */
27
+ export declare class LatestDebounced {
28
+ private readonly minIntervalMs;
29
+ private token;
30
+ private lastAt;
31
+ constructor(minIntervalMs?: number);
32
+ /**
33
+ * Runs the provided async task ensuring:
34
+ * - A minimum interval between consecutive executions is respected.
35
+ * - Only the latest scheduled call's result is returned; previous ones are treated as stale.
36
+ * If a stale task completes, onStale (if provided) is invoked to produce a safe value.
37
+ */
38
+ run<T>(task: () => Promise<T>, onStale?: () => Promise<T>): Promise<T>;
39
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Search Tools: concurrency helpers for use-case level search orchestration.
3
+ *
4
+ * Exposes LatestDebounced to coordinate frequent, user-driven async searches
5
+ * while avoiding race conditions and backend hammering.
6
+ */
7
+ /**
8
+ * LatestDebounced
9
+ *
10
+ * What it solves (use case):
11
+ * - In interactive UIs (search bars, live filters) users type quickly.
12
+ * - Each key stroke can trigger an async search/use case request.
13
+ * - Without control, multiple in-flight requests compete and late responses can override newer results (race conditions), while also hammering the backend.
14
+ *
15
+ * Core idea:
16
+ * - Allow scheduling tasks frequently, but only execute the latest one and enforce a minimal time gap between executions (debounce at the use-case layer).
17
+ * - If an older scheduled task finishes after a newer one, its result is considered stale and can be replaced by a fallback (e.g., re-read latest local results) via the optional onStale handler.
18
+ *
19
+ * Why use this instead of UI-level debounce?
20
+ * - Keeps UI dead-simple and pushes orchestration to application logic (use cases), matching Clean Architecture.
21
+ * - Centralizes race-condition handling; UI doesn't need abort controllers or timers.
22
+ *
23
+ * Typical usage:
24
+ * const gate = new LatestDebounced(1000); // 1s min interval
25
+ * return gate.run(async () => doSearch(query), async () => getLatestLocal(query));
26
+ */
27
+ export class LatestDebounced {
28
+ minIntervalMs;
29
+ token = 0;
30
+ lastAt = 0;
31
+ constructor(minIntervalMs = 800) {
32
+ this.minIntervalMs = minIntervalMs;
33
+ }
34
+ /**
35
+ * Runs the provided async task ensuring:
36
+ * - A minimum interval between consecutive executions is respected.
37
+ * - Only the latest scheduled call's result is returned; previous ones are treated as stale.
38
+ * If a stale task completes, onStale (if provided) is invoked to produce a safe value.
39
+ */
40
+ async run(task, onStale) {
41
+ const current = ++this.token;
42
+ const now = Date.now();
43
+ const elapsed = now - this.lastAt;
44
+ if (elapsed < this.minIntervalMs) {
45
+ await new Promise((r) => setTimeout(r, this.minIntervalMs - elapsed));
46
+ }
47
+ this.lastAt = Date.now();
48
+ const result = await task();
49
+ if (current !== this.token) {
50
+ if (onStale) {
51
+ return onStale();
52
+ }
53
+ }
54
+ return result;
55
+ }
56
+ }
@@ -0,0 +1,2 @@
1
+ export declare function safeJsonStringify(obj: any, pretty?: boolean): string;
2
+ export declare function safeJsonParse(json: string): any;
@@ -0,0 +1,44 @@
1
+ export function safeJsonStringify(obj, pretty = false) {
2
+ const seen = new WeakSet();
3
+ if (pretty) {
4
+ return JSON.stringify(obj, (key, value) => {
5
+ if (key.startsWith("_")) {
6
+ return undefined;
7
+ }
8
+ if (value instanceof Map) {
9
+ return Object.fromEntries(value);
10
+ }
11
+ if (value instanceof Set) {
12
+ return Array.from(value);
13
+ }
14
+ if (typeof value === "object" && value !== null) {
15
+ if (seen.has(value)) {
16
+ return "[Circular]";
17
+ }
18
+ seen.add(value);
19
+ }
20
+ return value;
21
+ }, 2);
22
+ }
23
+ return JSON.stringify(obj, (key, value) => {
24
+ if (key.startsWith("_")) {
25
+ return undefined;
26
+ }
27
+ if (value instanceof Map) {
28
+ return Object.fromEntries(value);
29
+ }
30
+ if (value instanceof Set) {
31
+ return Array.from(value);
32
+ }
33
+ if (typeof value === "object" && value !== null) {
34
+ if (seen.has(value)) {
35
+ return "[Circular]";
36
+ }
37
+ seen.add(value);
38
+ }
39
+ return value;
40
+ });
41
+ }
42
+ export function safeJsonParse(json) {
43
+ return JSON.parse(json);
44
+ }
@@ -0,0 +1,2 @@
1
+ declare function DebugBanner(): import("react/jsx-runtime").JSX.Element | null;
2
+ export { DebugBanner };
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "nativewind/jsx-runtime";
2
+ import { useCommon } from "../../../entrypoints/ui/common_provider";
3
+ import { Typography } from "@sincpro/mobile-ui/Typography";
4
+ import { View } from "react-native";
5
+ function DebugBanner() {
6
+ const { debugMode } = useCommon();
7
+ function renderBanner() {
8
+ if (!debugMode) {
9
+ return null;
10
+ }
11
+ return (_jsx(View, { className: "bg-accent py-2 px-4", children: _jsx(Typography.Text, { className: "text-white font-bold text-center", semibold: true, children: "⚠️ Estás en modo Debug" }) }));
12
+ }
13
+ return renderBanner();
14
+ }
15
+ export { DebugBanner };
@@ -0,0 +1 @@
1
+ export { DebugBanner } from "./DebugBanner";
@@ -0,0 +1 @@
1
+ export { DebugBanner } from "./DebugBanner";
@@ -0,0 +1,8 @@
1
+ import { BluetoothDevice } from "../../../domain/print";
2
+ interface BluetoothDeviceSelectorModalProps {
3
+ visible: boolean;
4
+ onClose: () => void;
5
+ onSelect: (device: BluetoothDevice) => void;
6
+ }
7
+ declare function BluetoothDeviceSelectorModal({ visible, onClose, onSelect, }: BluetoothDeviceSelectorModalProps): import("react/jsx-runtime").JSX.Element;
8
+ export { BluetoothDeviceSelectorModal };
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
2
+ import { bluetoothService } from "../../../services/bluetooth.service";
3
+ import { printerService } from "../../../services/printer.service";
4
+ import { Display, Form } from "@sincpro/mobile-ui";
5
+ import { BottomSheet } from "@sincpro/mobile-ui/Dialog/BottomSheet";
6
+ import PrinterIcon from "@sincpro/mobile-ui/icons/PrinterIcon";
7
+ import { theme } from "@sincpro/mobile-ui/theme";
8
+ import { Typography } from "@sincpro/mobile-ui/Typography";
9
+ import { useCallback, useEffect, useState } from "react";
10
+ import { FlatList, RefreshControl, TouchableOpacity, View } from "react-native";
11
+ function DeviceRow({ device, onSelect, isSelected }) {
12
+ return (_jsxs(TouchableOpacity, { activeOpacity: 0.7, className: `flex-row items-center p-4 border-b border-gray-100 ${isSelected ? "bg-green-50" : "bg-white"}`, onPress: onSelect, children: [_jsx(Display.Icon, { color: device.isPrinter ? theme.success : theme.text.secondary, customIcon: PrinterIcon, size: 24, type: "custom" }), _jsxs(View, { className: "ml-3 flex-1", children: [_jsx(Typography.Text, { semibold: true, children: device.name || "Dispositivo sin nombre" }), _jsx(Typography.Text, { className: "text-gray-400 text-xs", children: device.address }), device.isPrinter && (_jsx(Typography.Text, { className: "text-green-600 text-xs", children: "Impresora detectada" }))] }), isSelected && (_jsx(View, { className: "w-6 h-6 rounded-full bg-green-500 items-center justify-center", children: _jsx(Display.Icon, { color: theme.text.inverse, name: "check", size: 16, type: "material" }) }))] }));
13
+ }
14
+ function EmptyState() {
15
+ return (_jsxs(View, { className: "p-8 items-center justify-center", style: { minHeight: 250 }, children: [_jsx(Display.Icon, { color: theme.text.tertiary, customIcon: PrinterIcon, size: 64, type: "custom" }), _jsx(Typography.Text, { className: "text-gray-500 text-center mt-4", children: "No hay dispositivos vinculados" }), _jsx(Typography.Text, { className: "text-gray-400 text-center text-sm mt-2", children: "Vincula una impresora desde configuración de Bluetooth del sistema" })] }));
16
+ }
17
+ function BluetoothDeviceSelectorModal({ visible, onClose, onSelect, }) {
18
+ const [devices, setDevices] = useState([]);
19
+ const [loading, setLoading] = useState(false);
20
+ const [selectedDevice, setSelectedDevice] = useState(null);
21
+ const [connecting, setConnecting] = useState(false);
22
+ const loadDevices = useCallback(async () => {
23
+ setLoading(true);
24
+ try {
25
+ const hasPermission = await bluetoothService.ensurePermissionsForPrinter();
26
+ if (!hasPermission)
27
+ return;
28
+ const pairedDevices = await printerService.getPairedDevices();
29
+ setDevices(pairedDevices);
30
+ }
31
+ finally {
32
+ setLoading(false);
33
+ }
34
+ }, []);
35
+ useEffect(() => {
36
+ if (visible) {
37
+ loadDevices();
38
+ setSelectedDevice(null);
39
+ }
40
+ }, [visible, loadDevices]);
41
+ async function handleConfirm() {
42
+ if (!selectedDevice)
43
+ return;
44
+ setConnecting(true);
45
+ try {
46
+ const success = await printerService.connect(selectedDevice.address, selectedDevice.name || "Impresora");
47
+ if (success) {
48
+ onSelect(selectedDevice);
49
+ onClose();
50
+ }
51
+ }
52
+ finally {
53
+ setConnecting(false);
54
+ }
55
+ }
56
+ const printers = devices.filter((d) => d.isPrinter);
57
+ const otherDevices = devices.filter((d) => !d.isPrinter);
58
+ const allDevices = [...printers, ...otherDevices];
59
+ return (_jsxs(BottomSheet.Root, { onClose: onClose, size: "large", visible: visible, children: [_jsx(BottomSheet.Header, { children: _jsxs(View, { className: "px-5 pb-3", children: [_jsx(Typography.Text, { bold: true, variant: "subtitle", children: "Seleccionar Impresora" }), _jsx(Typography.Text, { className: "text-gray-500 text-xs", children: "Dispositivos Bluetooth vinculados" })] }) }), _jsx(BottomSheet.Content, { scrollable: true, children: devices.length === 0 && !loading ? (_jsx(EmptyState, {})) : (_jsx(FlatList, { data: allDevices, keyExtractor: (item) => item.address, ListHeaderComponent: printers.length > 0 ? (_jsxs(Typography.Text, { className: "text-gray-600 px-4 py-2 bg-gray-50", semibold: true, children: ["Impresoras (", printers.length, ")"] })) : null, refreshControl: _jsx(RefreshControl, { onRefresh: loadDevices, refreshing: loading }), renderItem: ({ item, index }) => (_jsxs(_Fragment, { children: [index === printers.length && otherDevices.length > 0 && (_jsxs(Typography.Text, { className: "text-gray-600 px-4 py-2 bg-gray-50", semibold: true, children: ["Otros dispositivos (", otherDevices.length, ")"] })), _jsx(DeviceRow, { device: item, isSelected: selectedDevice?.address === item.address, onSelect: () => setSelectedDevice(item) })] })), scrollEnabled: false })) }), _jsxs(BottomSheet.Actions, { layout: "horizontal", children: [_jsx(View, { className: "flex-1", children: _jsx(Form.Button, { onPress: onClose, title: "Cancelar", variant: "outline" }) }), selectedDevice && (_jsx(View, { className: "flex-1", children: _jsx(Form.Button, { loading: connecting, onPress: handleConfirm, title: "Conectar", variant: "primary" }) }))] })] }));
60
+ }
61
+ export { BluetoothDeviceSelectorModal };
@@ -0,0 +1,8 @@
1
+ interface DeadLetterErrorBlockProps {
2
+ errorMessage?: string | null;
3
+ expanded: boolean;
4
+ onToggle: () => void;
5
+ previewChars?: number;
6
+ }
7
+ declare function DeadLetterErrorBlock({ errorMessage, expanded, onToggle, previewChars, }: DeadLetterErrorBlockProps): import("react/jsx-runtime").JSX.Element | null;
8
+ export default DeadLetterErrorBlock;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import { Display } from "@sincpro/mobile-ui/Display";
3
+ import { theme } from "@sincpro/mobile-ui/theme";
4
+ import { cn } from "@sincpro/mobile-ui/theme/tw";
5
+ import { Typography } from "@sincpro/mobile-ui/Typography";
6
+ import { TouchableOpacity, View } from "react-native";
7
+ function DeadLetterErrorBlock({ errorMessage, expanded, onToggle, previewChars = 140, }) {
8
+ if (!errorMessage)
9
+ return null;
10
+ const preview = errorMessage.substring(0, previewChars);
11
+ const truncated = errorMessage.length > previewChars;
12
+ return (_jsxs(View, { className: cn("border-l-[3px] border-red-500 bg-red-50 p-2.5 rounded-xl mb-3", expanded && "bg-red-100"), children: [_jsxs(TouchableOpacity, { accessibilityRole: "button", activeOpacity: 0.75, className: "flex-row items-center mb-1", onPress: onToggle, children: [_jsx(Display.Icon, { color: theme.danger, name: "alert-circle", size: 16, type: "feather" }), _jsx(Typography.Text, { className: "text-red-600 ml-1.5", semibold: true, variant: "bodySmall", children: "Error" })] }), !expanded && (_jsxs(Typography.Text, { className: "text-red-600", numberOfLines: 3, variant: "bodySmall", children: [preview, truncated ? "…" : ""] })), expanded && (_jsx(View, { className: "bg-white rounded-lg p-2.5 border border-red-100", children: _jsx(Typography.Text, { className: "text-red-600 text-xs leading-4", variant: "bodySmall", children: errorMessage }) })), truncated && !expanded && (_jsx(TouchableOpacity, { accessibilityRole: "button", activeOpacity: 0.7, className: "mt-1.5", onPress: onToggle, children: _jsx(Typography.Text, { className: "text-red-600 underline", semibold: true, variant: "bodySmall", children: "Ver error completo" }) }))] }));
13
+ }
14
+ export default DeadLetterErrorBlock;
@@ -0,0 +1,7 @@
1
+ import { DomainEvent } from "../../../domain/event_sourcing";
2
+ interface EventTimelineItemProps {
3
+ event: DomainEvent;
4
+ isLast?: boolean;
5
+ }
6
+ declare function EventTimelineItem({ event, isLast }: EventTimelineItemProps): import("react/jsx-runtime").JSX.Element;
7
+ export default EventTimelineItem;
@@ -0,0 +1,65 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
+ import { EEventStatus } from "../../../domain/event_sourcing";
3
+ import { Display } from "@sincpro/mobile-ui/Display";
4
+ import CopyableText from "@sincpro/mobile-ui/Display/Display.CopyableText";
5
+ import { theme } from "@sincpro/mobile-ui/theme";
6
+ import { Typography } from "@sincpro/mobile-ui/Typography";
7
+ import JsonPreview from "@sincpro/mobile-ui/widgets/JSONViewer";
8
+ import { useState } from "react";
9
+ import { TouchableOpacity, View } from "react-native";
10
+ const statusColorMap = {
11
+ [EEventStatus.ACKNOWLEDGED]: {
12
+ bg: "bg-emerald-600",
13
+ color: theme.success,
14
+ light: `${theme.success}4D`,
15
+ },
16
+ [EEventStatus.PENDING]: {
17
+ bg: "bg-amber-500",
18
+ color: theme.warning,
19
+ light: `${theme.warning}4D`,
20
+ },
21
+ [EEventStatus.PROCESSING]: {
22
+ bg: "bg-accent",
23
+ color: theme.warning,
24
+ light: `${theme.warning}4D`,
25
+ },
26
+ [EEventStatus.FAILED]: {
27
+ bg: "bg-red-500",
28
+ color: theme.danger,
29
+ light: `${theme.danger}4D`,
30
+ },
31
+ };
32
+ const defaultStatus = {
33
+ bg: "bg-gray-500",
34
+ color: theme.text.secondary,
35
+ light: `${theme.text.secondary}4D`,
36
+ };
37
+ function getStatusColor(status) {
38
+ return statusColorMap[status] ?? defaultStatus;
39
+ }
40
+ function getStatusIcon(status) {
41
+ switch (status) {
42
+ case EEventStatus.ACKNOWLEDGED:
43
+ return "check-circle";
44
+ case EEventStatus.PENDING:
45
+ return "clock";
46
+ case EEventStatus.PROCESSING:
47
+ return "loader";
48
+ case EEventStatus.FAILED:
49
+ return "x-circle";
50
+ default:
51
+ return "circle";
52
+ }
53
+ }
54
+ function formatEventName(name) {
55
+ const parts = name.split(".");
56
+ return parts[parts.length - 1]?.replace(/_/g, " ").toUpperCase() || name;
57
+ }
58
+ function EventTimelineItem({ event, isLast = false }) {
59
+ const [expanded, setExpanded] = useState(false);
60
+ const statusInfo = getStatusColor(event.status);
61
+ const statusIcon = getStatusIcon(event.status);
62
+ const friendlyName = formatEventName(event.name);
63
+ return (_jsxs(View, { className: "flex-row px-4", children: [_jsxs(View, { className: "items-center w-8 mr-3", children: [_jsx(View, { className: `w-6 h-6 rounded-full items-center justify-center ${statusInfo.bg}`, children: _jsx(Display.Icon, { color: "#ffffff", name: statusIcon, size: 12, type: "feather" }) }), !isLast && (_jsx(View, { className: "w-0.5 flex-1 mt-1", style: { backgroundColor: statusInfo.light } }))] }), _jsxs(TouchableOpacity, { activeOpacity: 0.7, className: "flex-1 bg-white rounded-xl p-3 mb-3 border border-gray-100 shadow-sm", onPress: () => setExpanded(!expanded), children: [_jsxs(View, { className: "flex-row justify-between items-center mb-2", children: [_jsx(Typography.Text, { semibold: true, variant: "body", children: friendlyName }), _jsx(Display.Icon, { color: theme.text.secondary, name: expanded ? "chevron-up" : "chevron-down", size: 16, type: "feather" })] }), _jsxs(View, { className: "flex-row items-center mb-1 gap-1.5", children: [_jsx(Display.Icon, { color: theme.text.secondary, name: "clock", size: 12, type: "feather" }), _jsx(Display.Date, { className: "text-text-tertiary", showTime: true, textVariant: "caption", value: event.createdAt })] }), _jsxs(View, { className: "flex-row items-center mb-1 gap-1.5", children: [_jsx(Display.Icon, { color: statusInfo.color, name: statusIcon, size: 12, type: "feather" }), _jsxs(Typography.Text, { style: { color: statusInfo.color }, variant: "caption", children: [event.status, " \u2022 Intentos: ", event.attempts] })] }), (event.sequence ?? 0) > 0 && (_jsxs(View, { className: "flex-row items-center mb-1 gap-1.5", children: [_jsx(Display.Icon, { color: theme.text.secondary, name: "hash", size: 12, type: "feather" }), _jsxs(Typography.Text, { className: "text-text-tertiary", variant: "caption", children: ["Secuencia: ", event.sequence] })] })), expanded && event && (_jsxs(View, { className: "mt-3 border-t border-gray-100 pt-3", children: [_jsxs(View, { className: "flex-row justify-between items-center mb-2", children: [_jsx(Typography.Text, { className: "text-text-tertiary", semibold: true, variant: "caption", children: "Payload" }), _jsx(CopyableText, { className: "text-primary text-xs", getValue: () => event.asJSON(true), label: "copy" })] }), _jsx(View, { className: "bg-gray-50 rounded-lg border border-gray-200 overflow-hidden", children: _jsx(JsonPreview, { selectedJson: event.asJSON(true) }) })] }))] })] }));
64
+ }
65
+ export default EventTimelineItem;
@@ -0,0 +1,5 @@
1
+ interface Props {
2
+ position?: "top" | "bottom";
3
+ }
4
+ declare function ProcessToast({ position }: Props): import("react/jsx-runtime").JSX.Element | null;
5
+ export default ProcessToast;