@kosdev-code/kos-dispense-sdk 2.1.38 → 3.0.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 (301) hide show
  1. package/dispense-registration-manager-BH0mkCQx.cjs +2672 -0
  2. package/dispense-registration-manager-BH0mkCQx.cjs.map +1 -0
  3. package/dispense-registration-manager-BSKa5Oi9.js +2674 -0
  4. package/dispense-registration-manager-BSKa5Oi9.js.map +1 -0
  5. package/extension-utils-FKfiDSbi.cjs +489 -0
  6. package/extension-utils-FKfiDSbi.cjs.map +1 -0
  7. package/{extension-utils-DrsPfQWC.js → extension-utils-jntF0-vN.js} +185 -159
  8. package/extension-utils-jntF0-vN.js.map +1 -0
  9. package/extensions/control-pour-extension.d.ts +8 -9
  10. package/extensions/control-pour-extension.d.ts.map +1 -1
  11. package/extensions/index.d.ts.map +1 -1
  12. package/index.cjs +139 -1
  13. package/index.cjs.map +1 -1
  14. package/index.d.ts.map +1 -1
  15. package/index.js +124 -124
  16. package/index.js.map +1 -1
  17. package/models/constants/constants.d.ts.map +1 -1
  18. package/models/constants/index.d.ts.map +1 -1
  19. package/models/index.d.ts.map +1 -1
  20. package/models/models/assembly/assembly-model.d.ts +4 -5
  21. package/models/models/assembly/assembly-model.d.ts.map +1 -1
  22. package/models/models/assembly/assembly-registration.d.ts +1 -2
  23. package/models/models/assembly/assembly-registration.d.ts.map +1 -1
  24. package/models/models/assembly/board-utils.d.ts +1 -2
  25. package/models/models/assembly/board-utils.d.ts.map +1 -1
  26. package/models/models/assembly/holder-utils.d.ts +1 -2
  27. package/models/models/assembly/holder-utils.d.ts.map +1 -1
  28. package/models/models/assembly/index.d.ts.map +1 -1
  29. package/models/models/assembly/nozzle-utils.d.ts +1 -2
  30. package/models/models/assembly/nozzle-utils.d.ts.map +1 -1
  31. package/models/models/assembly/pump-utils.d.ts +2 -3
  32. package/models/models/assembly/pump-utils.d.ts.map +1 -1
  33. package/models/models/assembly/services/assembly-services.d.ts +0 -1
  34. package/models/models/assembly/services/assembly-services.d.ts.map +1 -1
  35. package/models/models/assembly/services/index.d.ts.map +1 -1
  36. package/models/models/assembly/types/index.d.ts +2 -3
  37. package/models/models/availability/availability-model.d.ts +1 -2
  38. package/models/models/availability/availability-model.d.ts.map +1 -1
  39. package/models/models/availability/index.d.ts.map +1 -1
  40. package/models/models/availability/types/index.d.ts +0 -1
  41. package/models/models/board/board-container-model.d.ts +2 -3
  42. package/models/models/board/board-container-model.d.ts.map +1 -1
  43. package/models/models/board/board-container-registration.d.ts +2 -3
  44. package/models/models/board/board-container-registration.d.ts.map +1 -1
  45. package/models/models/board/board-model.d.ts +1 -2
  46. package/models/models/board/board-model.d.ts.map +1 -1
  47. package/models/models/board/board-registration.d.ts +1 -2
  48. package/models/models/board/board-registration.d.ts.map +1 -1
  49. package/models/models/board/index.d.ts.map +1 -1
  50. package/models/models/board/types/index.d.ts +0 -2
  51. package/models/models/board/types/services.d.ts.map +1 -1
  52. package/models/models/board/utils/board-trouble-data-mapper.d.ts +1 -2
  53. package/models/models/board/utils/board-trouble-data-mapper.d.ts.map +1 -1
  54. package/models/models/board/utils/board-trouble-resolver.d.ts +0 -1
  55. package/models/models/board/utils/board-trouble-resolver.d.ts.map +1 -1
  56. package/models/models/device-assembly/device-assembly-model.d.ts +2 -3
  57. package/models/models/device-assembly/device-assembly-model.d.ts.map +1 -1
  58. package/models/models/device-assembly/device-assembly-registration.d.ts +2 -3
  59. package/models/models/device-assembly/device-assembly-registration.d.ts.map +1 -1
  60. package/models/models/device-assembly/index.d.ts.map +1 -1
  61. package/models/models/generic-pour/generic-pour-model.d.ts +3 -4
  62. package/models/models/generic-pour/generic-pour-model.d.ts.map +1 -1
  63. package/models/models/generic-pour/generic-pour-registration.d.ts +2 -3
  64. package/models/models/generic-pour/generic-pour-registration.d.ts.map +1 -1
  65. package/models/models/generic-pour/index.d.ts.map +1 -1
  66. package/models/models/generic-pour/services/generic-pour-services.d.ts.map +1 -1
  67. package/models/models/generic-pour/services/index.d.ts.map +1 -1
  68. package/models/models/holder/holder-model.d.ts +1 -2
  69. package/models/models/holder/holder-model.d.ts.map +1 -1
  70. package/models/models/holder/index.d.ts.map +1 -1
  71. package/models/models/holder/services/assignment-services.d.ts.map +1 -1
  72. package/models/models/holder/services/holder-services.d.ts.map +1 -1
  73. package/models/models/holder/services/index.d.ts.map +1 -1
  74. package/models/models/holder/types/index.d.ts +7 -7
  75. package/models/models/holder/utils/holder-utils.d.ts +0 -1
  76. package/models/models/holder/utils/holder-utils.d.ts.map +1 -1
  77. package/models/models/holder-container/holder-container-model.d.ts +1 -2
  78. package/models/models/holder-container/holder-container-model.d.ts.map +1 -1
  79. package/models/models/holder-container/index.d.ts.map +1 -1
  80. package/models/models/holder-container/types/index.d.ts +1 -3
  81. package/models/models/index.d.ts.map +1 -1
  82. package/models/models/ingredient/index.d.ts.map +1 -1
  83. package/models/models/ingredient/ingredient-model.d.ts +1 -2
  84. package/models/models/ingredient/ingredient-model.d.ts.map +1 -1
  85. package/models/models/ingredient/services/index.d.ts.map +1 -1
  86. package/models/models/ingredient/services/ingredient-services.d.ts.map +1 -1
  87. package/models/models/ingredient/types/index.d.ts +0 -2
  88. package/models/models/ingredient-container/index.d.ts.map +1 -1
  89. package/models/models/ingredient-container/ingredient-container-model.d.ts +1 -2
  90. package/models/models/ingredient-container/ingredient-container-model.d.ts.map +1 -1
  91. package/models/models/ingredient-container/types/index.d.ts +1 -3
  92. package/models/models/nozzle/index.d.ts.map +1 -1
  93. package/models/models/nozzle/nozzle-model.d.ts +7 -7
  94. package/models/models/nozzle/nozzle-model.d.ts.map +1 -1
  95. package/models/models/nozzle/services/index.d.ts.map +1 -1
  96. package/models/models/nozzle/services/nozzle-services.d.ts.map +1 -1
  97. package/models/models/nozzle/types/index.d.ts +1 -3
  98. package/models/models/pump/index.d.ts.map +1 -1
  99. package/models/models/pump/pump-model.d.ts +1 -2
  100. package/models/models/pump/pump-model.d.ts.map +1 -1
  101. package/models/models/pump/services/index.d.ts.map +1 -1
  102. package/models/models/pump/services/pump-services.d.ts +3 -5
  103. package/models/models/pump/services/pump-services.d.ts.map +1 -1
  104. package/models/models/pump/types/index.d.ts +1 -3
  105. package/models/models/pump/utils/pump-trouble-resolver.d.ts +0 -1
  106. package/models/models/pump/utils/pump-trouble-resolver.d.ts.map +1 -1
  107. package/models/models/pump-container/index.d.ts.map +1 -1
  108. package/models/models/pump-container/pump-container-model.d.ts +1 -2
  109. package/models/models/pump-container/pump-container-model.d.ts.map +1 -1
  110. package/models/models/pump-container/types/index.d.ts +1 -3
  111. package/models/models/types/assembly.d.ts +1 -0
  112. package/models/models/types/assembly.d.ts.map +1 -1
  113. package/models/models/types/index.d.ts.map +1 -1
  114. package/models/models/types/intent.d.ts +0 -1
  115. package/models/models/types/intent.d.ts.map +1 -1
  116. package/models/models/types/pouring.d.ts.map +1 -1
  117. package/models/utils/dispense-registration-manager.d.ts +5 -6
  118. package/models/utils/dispense-registration-manager.d.ts.map +1 -1
  119. package/models/utils/extension-utils.d.ts +6 -7
  120. package/models/utils/extension-utils.d.ts.map +1 -1
  121. package/models/utils/openapi-index.d.ts.map +1 -1
  122. package/models/utils/registration.d.ts +0 -1
  123. package/models/utils/registration.d.ts.map +1 -1
  124. package/models/utils/service.d.ts +34 -35
  125. package/models/utils/service.d.ts.map +1 -1
  126. package/models/utils/services/dispense/1.6.5/service.d.ts +34 -35
  127. package/models/utils/services/dispense/1.6.5/service.d.ts.map +1 -1
  128. package/models/utils/services/dispense/1.8.1/service.d.ts +34 -35
  129. package/models/utils/services/dispense/1.8.1/service.d.ts.map +1 -1
  130. package/models/utils/services/dispense/daily/service.d.ts +34 -35
  131. package/models/utils/services/dispense/daily/service.d.ts.map +1 -1
  132. package/models/utils/services-index.d.ts.map +1 -1
  133. package/models.cjs +45 -1
  134. package/models.cjs.map +1 -1
  135. package/models.d.ts +1 -0
  136. package/models.js +40 -42
  137. package/models.js.map +1 -1
  138. package/package.json +22 -11
  139. package/pump-provider-D4iVLU-o.cjs +1803 -0
  140. package/pump-provider-D4iVLU-o.cjs.map +1 -0
  141. package/pump-provider-ntLT8vr7.js +1804 -0
  142. package/pump-provider-ntLT8vr7.js.map +1 -0
  143. package/ui/contexts/assembly/assembly-provider.d.ts +1 -2
  144. package/ui/contexts/assembly/assembly-provider.d.ts.map +1 -1
  145. package/ui/contexts/assembly/index.d.ts.map +1 -1
  146. package/ui/contexts/availability/availability-provider.d.ts +1 -2
  147. package/ui/contexts/availability/availability-provider.d.ts.map +1 -1
  148. package/ui/contexts/availability/index.d.ts.map +1 -1
  149. package/ui/contexts/board/board-provider.d.ts +1 -2
  150. package/ui/contexts/board/board-provider.d.ts.map +1 -1
  151. package/ui/contexts/board/index.d.ts.map +1 -1
  152. package/ui/contexts/board-container/board-container-provider.d.ts +1 -2
  153. package/ui/contexts/board-container/board-container-provider.d.ts.map +1 -1
  154. package/ui/contexts/board-container/index.d.ts.map +1 -1
  155. package/ui/contexts/cui-kit/cui-kit.d.ts +1 -2
  156. package/ui/contexts/cui-kit/cui-kit.d.ts.map +1 -1
  157. package/ui/contexts/cui-kit/index.d.ts.map +1 -1
  158. package/ui/contexts/device-assembly/device-assembly-provider.d.ts +1 -2
  159. package/ui/contexts/device-assembly/device-assembly-provider.d.ts.map +1 -1
  160. package/ui/contexts/device-assembly/index.d.ts.map +1 -1
  161. package/ui/contexts/holder/holder-provider.d.ts +1 -2
  162. package/ui/contexts/holder/holder-provider.d.ts.map +1 -1
  163. package/ui/contexts/holder/index.d.ts.map +1 -1
  164. package/ui/contexts/holder-container/holder-container-provider.d.ts +1 -2
  165. package/ui/contexts/holder-container/holder-container-provider.d.ts.map +1 -1
  166. package/ui/contexts/holder-container/index.d.ts.map +1 -1
  167. package/ui/contexts/index.d.ts.map +1 -1
  168. package/ui/contexts/ingredient/index.d.ts.map +1 -1
  169. package/ui/contexts/ingredient/ingredient-provider.d.ts +1 -2
  170. package/ui/contexts/ingredient/ingredient-provider.d.ts.map +1 -1
  171. package/ui/contexts/ingredient-container/index.d.ts.map +1 -1
  172. package/ui/contexts/ingredient-container/ingredient-container-provider.d.ts +1 -2
  173. package/ui/contexts/ingredient-container/ingredient-container-provider.d.ts.map +1 -1
  174. package/ui/contexts/nozzle/index.d.ts.map +1 -1
  175. package/ui/contexts/nozzle/nozzle-provider.d.ts +1 -2
  176. package/ui/contexts/nozzle/nozzle-provider.d.ts.map +1 -1
  177. package/ui/contexts/pump/index.d.ts.map +1 -1
  178. package/ui/contexts/pump/pump-provider.d.ts +1 -2
  179. package/ui/contexts/pump/pump-provider.d.ts.map +1 -1
  180. package/ui/hooks/assembly/index.d.ts.map +1 -1
  181. package/ui/hooks/assembly/use-assembly.d.ts +1 -2
  182. package/ui/hooks/assembly/use-assembly.d.ts.map +1 -1
  183. package/ui/hooks/assembly/with-assembly.d.ts +0 -1
  184. package/ui/hooks/assembly/with-assembly.d.ts.map +1 -1
  185. package/ui/hooks/availability/index.d.ts.map +1 -1
  186. package/ui/hooks/availability/use-availability.d.ts +1 -2
  187. package/ui/hooks/availability/use-availability.d.ts.map +1 -1
  188. package/ui/hooks/availability/with-availability.d.ts +0 -1
  189. package/ui/hooks/availability/with-availability.d.ts.map +1 -1
  190. package/ui/hooks/board/index.d.ts.map +1 -1
  191. package/ui/hooks/board/use-board.d.ts +1 -2
  192. package/ui/hooks/board/use-board.d.ts.map +1 -1
  193. package/ui/hooks/board/with-board.d.ts +0 -1
  194. package/ui/hooks/board/with-board.d.ts.map +1 -1
  195. package/ui/hooks/board-container/index.d.ts.map +1 -1
  196. package/ui/hooks/board-container/use-board-container.d.ts +1 -2
  197. package/ui/hooks/board-container/use-board-container.d.ts.map +1 -1
  198. package/ui/hooks/board-container/with-board-container.d.ts +0 -1
  199. package/ui/hooks/board-container/with-board-container.d.ts.map +1 -1
  200. package/ui/hooks/cui-kit/dispense-topics.d.ts +0 -1
  201. package/ui/hooks/cui-kit/dispense-topics.d.ts.map +1 -1
  202. package/ui/hooks/cui-kit/index.d.ts.map +1 -1
  203. package/ui/hooks/cui-kit/use-ambient-attract-timers.d.ts +0 -1
  204. package/ui/hooks/cui-kit/use-ambient-attract-timers.d.ts.map +1 -1
  205. package/ui/hooks/cui-kit/use-beverages.d.ts +1 -2
  206. package/ui/hooks/cui-kit/use-beverages.d.ts.map +1 -1
  207. package/ui/hooks/cui-kit/use-brands.d.ts +1 -2
  208. package/ui/hooks/cui-kit/use-brands.d.ts.map +1 -1
  209. package/ui/hooks/cui-kit/use-cui-kit.d.ts +3 -4
  210. package/ui/hooks/cui-kit/use-cui-kit.d.ts.map +1 -1
  211. package/ui/hooks/cui-kit/use-default-cui-kit-lifecycle.d.ts +0 -1
  212. package/ui/hooks/cui-kit/use-default-cui-kit-lifecycle.d.ts.map +1 -1
  213. package/ui/hooks/cui-kit/use-dispense-lifecycle.d.ts +0 -1
  214. package/ui/hooks/cui-kit/use-dispense-lifecycle.d.ts.map +1 -1
  215. package/ui/hooks/cui-kit/use-dispense-timers.d.ts +0 -1
  216. package/ui/hooks/cui-kit/use-dispense-timers.d.ts.map +1 -1
  217. package/ui/hooks/cui-kit/use-flavors.d.ts +1 -2
  218. package/ui/hooks/cui-kit/use-flavors.d.ts.map +1 -1
  219. package/ui/hooks/device-assembly/index.d.ts.map +1 -1
  220. package/ui/hooks/device-assembly/use-device-assembly.d.ts +1 -2
  221. package/ui/hooks/device-assembly/use-device-assembly.d.ts.map +1 -1
  222. package/ui/hooks/device-assembly/with-device-assembly.d.ts +0 -1
  223. package/ui/hooks/device-assembly/with-device-assembly.d.ts.map +1 -1
  224. package/ui/hooks/generic-pour/index.d.ts.map +1 -1
  225. package/ui/hooks/generic-pour/use-generic-pour.d.ts +2 -3
  226. package/ui/hooks/generic-pour/use-generic-pour.d.ts.map +1 -1
  227. package/ui/hooks/generic-pour/with-generic-pour.d.ts +0 -1
  228. package/ui/hooks/generic-pour/with-generic-pour.d.ts.map +1 -1
  229. package/ui/hooks/holder/index.d.ts.map +1 -1
  230. package/ui/hooks/holder/use-holder.d.ts +1 -2
  231. package/ui/hooks/holder/use-holder.d.ts.map +1 -1
  232. package/ui/hooks/holder/with-holder.d.ts +0 -1
  233. package/ui/hooks/holder/with-holder.d.ts.map +1 -1
  234. package/ui/hooks/holder-container/index.d.ts.map +1 -1
  235. package/ui/hooks/holder-container/use-holder-container.d.ts +1 -2
  236. package/ui/hooks/holder-container/use-holder-container.d.ts.map +1 -1
  237. package/ui/hooks/holder-container/with-holder-container.d.ts +0 -1
  238. package/ui/hooks/holder-container/with-holder-container.d.ts.map +1 -1
  239. package/ui/hooks/index.d.ts.map +1 -1
  240. package/ui/hooks/ingredient/index.d.ts.map +1 -1
  241. package/ui/hooks/ingredient/use-ingredient-pour.d.ts +2 -3
  242. package/ui/hooks/ingredient/use-ingredient-pour.d.ts.map +1 -1
  243. package/ui/hooks/ingredient/use-ingredient.d.ts +1 -2
  244. package/ui/hooks/ingredient/use-ingredient.d.ts.map +1 -1
  245. package/ui/hooks/ingredient/with-ingredient.d.ts +0 -1
  246. package/ui/hooks/ingredient/with-ingredient.d.ts.map +1 -1
  247. package/ui/hooks/ingredient-container/index.d.ts.map +1 -1
  248. package/ui/hooks/ingredient-container/use-ingredient-container.d.ts +1 -2
  249. package/ui/hooks/ingredient-container/use-ingredient-container.d.ts.map +1 -1
  250. package/ui/hooks/ingredient-container/with-ingredient-container.d.ts +0 -1
  251. package/ui/hooks/ingredient-container/with-ingredient-container.d.ts.map +1 -1
  252. package/ui/hooks/nozzle/index.d.ts.map +1 -1
  253. package/ui/hooks/nozzle/use-dispense-kit.d.ts +0 -1
  254. package/ui/hooks/nozzle/use-dispense-kit.d.ts.map +1 -1
  255. package/ui/hooks/nozzle/use-nozzle.d.ts +1 -2
  256. package/ui/hooks/nozzle/use-nozzle.d.ts.map +1 -1
  257. package/ui/hooks/nozzle/with-nozzle.d.ts +0 -1
  258. package/ui/hooks/nozzle/with-nozzle.d.ts.map +1 -1
  259. package/ui/hooks/nozzle-pour/index.d.ts.map +1 -1
  260. package/ui/hooks/nozzle-pour/use-nozzle-pour.d.ts +3 -4
  261. package/ui/hooks/nozzle-pour/use-nozzle-pour.d.ts.map +1 -1
  262. package/ui/hooks/pour/index.d.ts.map +1 -1
  263. package/ui/hooks/pour/use-pour.d.ts +4 -5
  264. package/ui/hooks/pour/use-pour.d.ts.map +1 -1
  265. package/ui/hooks/pump/index.d.ts.map +1 -1
  266. package/ui/hooks/pump/use-pump.d.ts +1 -2
  267. package/ui/hooks/pump/use-pump.d.ts.map +1 -1
  268. package/ui/hooks/pump/with-pump.d.ts +0 -1
  269. package/ui/hooks/pump/with-pump.d.ts.map +1 -1
  270. package/ui/hooks/utils/pour-strategy/hold-to-pour-intent-strategy.d.ts +1 -2
  271. package/ui/hooks/utils/pour-strategy/hold-to-pour-intent-strategy.d.ts.map +1 -1
  272. package/ui/hooks/utils/pour-strategy/hold-to-pour-strategy.d.ts +0 -1
  273. package/ui/hooks/utils/pour-strategy/hold-to-pour-strategy.d.ts.map +1 -1
  274. package/ui/hooks/utils/pour-strategy/index.d.ts.map +1 -1
  275. package/ui/hooks/utils/pour-strategy/pour-strategy.d.ts +1 -2
  276. package/ui/hooks/utils/pour-strategy/pour-strategy.d.ts.map +1 -1
  277. package/ui/hooks/utils/pour-strategy/tap-or-hold-to-pour-intent-strategy.d.ts +1 -2
  278. package/ui/hooks/utils/pour-strategy/tap-or-hold-to-pour-intent-strategy.d.ts.map +1 -1
  279. package/ui/hooks/utils/pour-strategy/tap-to-pour-intent-strategy.d.ts +1 -2
  280. package/ui/hooks/utils/pour-strategy/tap-to-pour-intent-strategy.d.ts.map +1 -1
  281. package/ui/hooks/utils/pour-strategy/tap-to-pour-strategy.d.ts +0 -1
  282. package/ui/hooks/utils/pour-strategy/tap-to-pour-strategy.d.ts.map +1 -1
  283. package/ui/index.d.ts.map +1 -1
  284. package/ui/utils/pour-context.d.ts.map +1 -1
  285. package/ui.cjs +69 -1
  286. package/ui.cjs.map +1 -1
  287. package/ui.d.ts +1 -0
  288. package/ui.js +66 -70
  289. package/ui.js.map +1 -1
  290. package/dispense-registration-manager-Cj0565Ze.cjs +0 -2
  291. package/dispense-registration-manager-Cj0565Ze.cjs.map +0 -1
  292. package/dispense-registration-manager-CzAqcL8D.js +0 -2044
  293. package/dispense-registration-manager-CzAqcL8D.js.map +0 -1
  294. package/extension-utils-BDyaRwRN.cjs +0 -2
  295. package/extension-utils-BDyaRwRN.cjs.map +0 -1
  296. package/extension-utils-DrsPfQWC.js.map +0 -1
  297. package/kos-models.json +0 -180
  298. package/pump-provider-Bytd6qXc.js +0 -1308
  299. package/pump-provider-Bytd6qXc.js.map +0 -1
  300. package/pump-provider-CTELJBW5.cjs +0 -2
  301. package/pump-provider-CTELJBW5.cjs.map +0 -1
@@ -0,0 +1,1804 @@
1
+ import { jsx } from "@emotion/react/jsx-runtime";
2
+ import { useKosModel, getKosCompanionModel, kosAutoEffect, KosLog, usePressGesture, EventBus, TimerManager } from "@kosdev-code/kos-ui-sdk";
3
+ import { A as Assembly$1, a as Availability$1, B as Board$1, b as BoardContainer$1, N as Nozzle$1, D as DeviceAssembly, H as Holder$1, f as HolderContainer$1, I as Ingredient$1, g as IngredientContainer$1, G as GenericPour, h as Pump$1 } from "./dispense-registration-manager-BSKa5Oi9.js";
4
+ import React, { createContext, useMemo, useContext, useState, useCallback, useEffect, useRef } from "react";
5
+ const useAssembly = () => {
6
+ const modelId = Assembly$1.type;
7
+ const result = useKosModel({
8
+ modelId,
9
+ modelType: Assembly$1.type,
10
+ options: {}
11
+ });
12
+ return result;
13
+ };
14
+ function withAssembly(WrappedComponent) {
15
+ return (props) => {
16
+ const { model, status, KosModelLoader } = useAssembly();
17
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, assembly: model }) });
18
+ };
19
+ }
20
+ const useAvailability = () => {
21
+ const modelId = Availability$1.type;
22
+ const result = useKosModel({
23
+ modelId,
24
+ modelType: Availability$1.type,
25
+ options: {}
26
+ });
27
+ return result;
28
+ };
29
+ function withBeverage(WrappedComponent) {
30
+ return (props) => {
31
+ const { model, status, KosModelLoader } = useAvailability();
32
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, beverage: model }) });
33
+ };
34
+ }
35
+ const useBoard = (id) => {
36
+ const modelId = id;
37
+ const result = useKosModel({
38
+ modelId,
39
+ modelType: Board$1.type,
40
+ options: {}
41
+ });
42
+ return result;
43
+ };
44
+ function withBoard(WrappedComponent) {
45
+ return (id) => (props) => {
46
+ const { model, status, KosModelLoader } = useBoard(id);
47
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, board: model }) });
48
+ };
49
+ }
50
+ const useBoardContainer = () => {
51
+ const modelId = BoardContainer$1.type;
52
+ const result = useKosModel({
53
+ modelId,
54
+ modelType: BoardContainer$1.type,
55
+ options: {}
56
+ });
57
+ return result;
58
+ };
59
+ function withBoardContainer(WrappedComponent) {
60
+ return (props) => {
61
+ const { model, status, KosModelLoader } = useBoardContainer();
62
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, boardContainer: model }) });
63
+ };
64
+ }
65
+ const useNozzle = (path) => {
66
+ const modelId = path;
67
+ const result = useKosModel({
68
+ modelId,
69
+ modelType: Nozzle$1.type,
70
+ options: {
71
+ path
72
+ }
73
+ });
74
+ return result;
75
+ };
76
+ const Nozzle = createContext(void 0);
77
+ const NozzleProvider = ({ children, path }) => {
78
+ const { model, ready } = useNozzle(path);
79
+ const value = useMemo(() => {
80
+ if (ready && model) {
81
+ return { model };
82
+ }
83
+ return {};
84
+ }, [ready, model]);
85
+ return /* @__PURE__ */ jsx(Nozzle.Provider, { value, children });
86
+ };
87
+ const useNozzleContext = () => {
88
+ const context = useContext(Nozzle);
89
+ if (!context) {
90
+ throw new Error("useNozzleContext must be used within a NozzleProvider");
91
+ }
92
+ return context;
93
+ };
94
+ const useBeverages = ({
95
+ onBeverageSelected,
96
+ onBeverageListUpdated,
97
+ onClearBeverage,
98
+ companionType
99
+ }) => {
100
+ const { model: nozzle } = useNozzleContext();
101
+ const [beverages, setBeverages] = useState([]);
102
+ const [selectedBeverage, setSelectedBeverage] = useState(null);
103
+ const companions = useMemo(() => {
104
+ if (!companionType) return [];
105
+ return beverages.map(
106
+ (brand) => getKosCompanionModel(brand, companionType)
107
+ );
108
+ }, [beverages, companionType]);
109
+ const selectBeverage = useCallback(
110
+ async (beverage, context, forceUpdate) => {
111
+ setSelectedBeverage(beverage);
112
+ await nozzle?.setSelectedPourable({ beverage, context }, forceUpdate);
113
+ onBeverageSelected?.(beverage);
114
+ },
115
+ [nozzle, onBeverageSelected]
116
+ );
117
+ const clearBeverage = useCallback(async () => {
118
+ setSelectedBeverage(null);
119
+ await nozzle?.setSelectedPourable({ beverage: void 0 });
120
+ onClearBeverage?.();
121
+ }, [nozzle, onClearBeverage]);
122
+ useEffect(() => {
123
+ const disposer = kosAutoEffect(() => {
124
+ if (!nozzle) return;
125
+ const selectedBrand = nozzle.selectedBrand;
126
+ if (!selectedBrand) {
127
+ const allBeverages = nozzle.getGroupAvailabilityItems("beverages").filter((beverage) => beverage.visible);
128
+ setBeverages(allBeverages ?? []);
129
+ onBeverageListUpdated?.(allBeverages);
130
+ return;
131
+ }
132
+ const beverages2 = nozzle.getAvailabilityByParent(selectedBrand.id).filter((b) => b.visible);
133
+ setBeverages(beverages2 ?? []);
134
+ onBeverageListUpdated?.(beverages2);
135
+ });
136
+ return () => {
137
+ disposer();
138
+ };
139
+ }, [nozzle]);
140
+ return {
141
+ beverages,
142
+ beverageCompanions: companions,
143
+ selectBeverage,
144
+ selectedBeverage,
145
+ clearBeverage
146
+ };
147
+ };
148
+ const useBrands = ({
149
+ onBrandSelected,
150
+ onBrandCleared,
151
+ companionType
152
+ }) => {
153
+ const { model: nozzle } = useNozzleContext();
154
+ const [selectedBrand, setSelectedBrand] = useState(null);
155
+ const [brands, setBrands] = useState([]);
156
+ const companions = useMemo(() => {
157
+ if (!companionType) return [];
158
+ return brands.map((brand) => getKosCompanionModel(brand, companionType));
159
+ }, [brands, companionType]);
160
+ const selectBrand = useCallback(
161
+ async (brand, context, forceUpdate) => {
162
+ setSelectedBrand(brand);
163
+ if (forceUpdate) {
164
+ KosLog.warn(
165
+ `forceUpdate is not currently supported when setting brand`
166
+ );
167
+ }
168
+ nozzle?.setSelectedBrand(brand, context);
169
+ onBrandSelected?.(brand);
170
+ },
171
+ [nozzle, onBrandSelected]
172
+ );
173
+ const clearBrand = useCallback(() => {
174
+ setSelectedBrand(null);
175
+ nozzle?.setSelectedBrand(void 0);
176
+ onBrandCleared?.();
177
+ }, [nozzle, onBrandCleared]);
178
+ useEffect(() => {
179
+ const disposer = kosAutoEffect(() => {
180
+ if (!nozzle) return;
181
+ setBrands(nozzle.visibleBrands);
182
+ });
183
+ return () => {
184
+ disposer();
185
+ };
186
+ }, [nozzle]);
187
+ return {
188
+ brands,
189
+ brandCompanions: companions,
190
+ selectedBrand,
191
+ selectBrand,
192
+ clearBrand
193
+ };
194
+ };
195
+ class PourContext {
196
+ _data = /* @__PURE__ */ new Map();
197
+ get(key) {
198
+ return this._data.get(key);
199
+ }
200
+ set(key, value) {
201
+ this._data.set(key, value);
202
+ }
203
+ remove(key) {
204
+ this._data.delete(key);
205
+ }
206
+ has(key) {
207
+ return this._data.has(key);
208
+ }
209
+ }
210
+ const logger$7 = KosLog.createLogger({
211
+ name: "HoldToPourStrategy",
212
+ group: "kos-hooks"
213
+ });
214
+ const HoldToPourStrategy = {
215
+ name: "HoldToPourStrategy",
216
+ async initiate(nozzle) {
217
+ if (!nozzle?.canPour) {
218
+ logger$7.debug(`Nozzle ${nozzle?.id} cannot pour. Returning early.`);
219
+ return;
220
+ }
221
+ await nozzle?.pour();
222
+ },
223
+ async initiateEnded(nozzle) {
224
+ await nozzle?.cancelPour();
225
+ }
226
+ };
227
+ const logger$6 = KosLog.createLogger({
228
+ name: "useNozzlePour",
229
+ group: "kos-hooks"
230
+ });
231
+ const useNozzlePour = ({
232
+ onPour,
233
+ onPourCancel,
234
+ onBeforePour,
235
+ onBeforePourRejected,
236
+ pourContext,
237
+ strategy = HoldToPourStrategy
238
+ }) => {
239
+ const { model: nozzle } = useNozzleContext();
240
+ const [context, _setContext] = useState(
241
+ pourContext || new PourContext()
242
+ );
243
+ const handlePour = useCallback(async () => {
244
+ const canPour = onBeforePour ? await onBeforePour?.(context) : true;
245
+ if (canPour) {
246
+ logger$6.debug(
247
+ `[${strategy?.name}] - Pour initiated for nozzle ${nozzle?.id}.`
248
+ );
249
+ strategy?.initiate(nozzle);
250
+ onPour?.();
251
+ } else {
252
+ logger$6.debug(
253
+ `[${strategy?.name}] - Did not pass onBeforePour gate for nozzle ${nozzle?.id}. Cancelling pour.`
254
+ );
255
+ onBeforePourRejected?.();
256
+ }
257
+ }, [
258
+ onPour,
259
+ nozzle,
260
+ strategy,
261
+ onBeforePour,
262
+ onPourCancel,
263
+ context,
264
+ onBeforePourRejected
265
+ ]);
266
+ const handleCancelPour = useCallback(() => {
267
+ logger$6.debug(
268
+ `[${strategy?.name}] - Pour initiate ended called for nozzle ${nozzle?.id}.`
269
+ );
270
+ strategy?.initiateEnded?.(nozzle);
271
+ onPourCancel?.();
272
+ }, [onPourCancel, nozzle, strategy]);
273
+ const forceCancelPour = useCallback(() => {
274
+ logger$6.debug(`Force cancelling pour for nozzle ${nozzle?.id}.`);
275
+ nozzle?.cancelPour();
276
+ onPourCancel?.();
277
+ }, [onPourCancel, nozzle]);
278
+ const handleUpdateContext = useCallback(
279
+ (key, value) => {
280
+ context.set(key, value);
281
+ },
282
+ [context]
283
+ );
284
+ const handleRemoveFromContext = useCallback(
285
+ (key) => {
286
+ context.remove(key);
287
+ },
288
+ [context]
289
+ );
290
+ const handlers = usePressGesture({
291
+ onPressed: handlePour,
292
+ onRelease: handleCancelPour
293
+ });
294
+ return {
295
+ handlers: handlers.dom,
296
+ cancel: forceCancelPour,
297
+ updatePourContext: handleUpdateContext,
298
+ removeFromPourContext: handleRemoveFromContext,
299
+ status: nozzle
300
+ };
301
+ };
302
+ const useFlavors = ({
303
+ onFlavorSelected,
304
+ onFlavorCleared,
305
+ companionType
306
+ }) => {
307
+ const { model: nozzle } = useNozzleContext();
308
+ const flavors = useMemo(
309
+ () => nozzle?.getGroupAvailabilityItems("flavors").filter((f) => f.visible) ?? [],
310
+ [nozzle]
311
+ );
312
+ const companions = useMemo(() => {
313
+ if (!companionType) return [];
314
+ return flavors.map(
315
+ (flavor) => getKosCompanionModel(flavor, companionType)
316
+ );
317
+ }, [flavors, companionType]);
318
+ const [selectedFlavors, setSelectedFlavors] = useState([]);
319
+ const selectFlavor = useCallback(
320
+ async (flavor, context, forceUpdate) => {
321
+ setSelectedFlavors(
322
+ (previous) => previous?.includes(flavor) ? [...previous.filter((p) => p !== flavor)] : [...previous ?? [], flavor]
323
+ );
324
+ if (nozzle?.selectedPourable) {
325
+ const { beverage } = nozzle.selectedPourable;
326
+ await nozzle.setSelectedPourable(
327
+ {
328
+ beverage,
329
+ additional: selectedFlavors ?? [],
330
+ context
331
+ },
332
+ forceUpdate
333
+ );
334
+ }
335
+ onFlavorSelected?.(flavor, selectedFlavors ?? []);
336
+ },
337
+ [nozzle, onFlavorSelected, selectedFlavors]
338
+ );
339
+ const clear = useCallback(async () => {
340
+ setSelectedFlavors([]);
341
+ if (nozzle?.selectedPourable) {
342
+ const { beverage } = nozzle.selectedPourable;
343
+ nozzle.setSelectedPourable({ beverage });
344
+ onFlavorCleared?.();
345
+ }
346
+ }, [nozzle, onFlavorCleared]);
347
+ return {
348
+ flavors,
349
+ flavorCompanions: companions,
350
+ selectFlavor,
351
+ selectedFlavors,
352
+ clearFlavors: clear
353
+ };
354
+ };
355
+ const DISPENSE_GROUP_BRAND = "brands";
356
+ const DISPENSE_GROUP_BEVERAGE = "beverages";
357
+ const DISPENSE_GROUP_FLAVOR = "flavors";
358
+ const log$2 = KosLog.createLogger({ name: "use-cui-kit" });
359
+ const useCuiKit = ({
360
+ initialGroup = DISPENSE_GROUP_BRAND,
361
+ options = {}
362
+ }) => {
363
+ const [currentGroup, setCurrentGroup] = useState(initialGroup);
364
+ const { model: nozzle } = useNozzleContext();
365
+ const timersRef = useRef([]);
366
+ const updatePourContext = useRef();
367
+ const removeFromPourContext = useRef();
368
+ const onBrandSelected = useCallback(
369
+ (model) => {
370
+ setCurrentGroup(DISPENSE_GROUP_BEVERAGE);
371
+ const topic = `/kos/dispense/${nozzle?.path}/brand/selected/`;
372
+ EventBus.publish(topic, model);
373
+ },
374
+ [nozzle?.path]
375
+ );
376
+ const onBrandCleared = useCallback(() => {
377
+ const topic = `/kos/dispense/${nozzle?.path}/brand/cleared/`;
378
+ EventBus.publish(topic, {});
379
+ }, [nozzle?.path]);
380
+ const onBeverageListUpdated = useCallback(
381
+ (beverages2) => {
382
+ const topic = `/kos/dispense/${nozzle?.path}/beverage/list/updated/`;
383
+ EventBus.publish(topic, beverages2);
384
+ },
385
+ [nozzle?.path]
386
+ );
387
+ const onBeverageSelected = useCallback(
388
+ (model) => {
389
+ setCurrentGroup(DISPENSE_GROUP_FLAVOR);
390
+ updatePourContext.current?.("selectedBeverage", model);
391
+ const topic = `/kos/dispense/${nozzle?.path}/beverage/selected/`;
392
+ EventBus.publish(topic, model);
393
+ },
394
+ [nozzle?.path]
395
+ );
396
+ const onBeverageCleared = useCallback(() => {
397
+ const topic = `/kos/dispense/${nozzle?.path}/beverage/cleared/`;
398
+ removeFromPourContext.current?.("selectedBeverage");
399
+ EventBus.publish(topic, {});
400
+ }, [nozzle?.path]);
401
+ const onFlavorSelected = useCallback(
402
+ (model) => {
403
+ const topic = `/kos/dispense/${nozzle?.path}/flavor/selected/`;
404
+ EventBus.publish(topic, model);
405
+ },
406
+ [nozzle?.path]
407
+ );
408
+ const onFlavorCleared = useCallback(() => {
409
+ const topic = `/kos/dispense/${nozzle?.path}/flavor/cleared/`;
410
+ EventBus.publish(topic, {});
411
+ }, [nozzle?.path]);
412
+ const onPour = useCallback(() => {
413
+ const topic = `/kos/dispense/${nozzle?.path}/pour/`;
414
+ EventBus.publish(topic, {});
415
+ }, [nozzle?.path]);
416
+ const handleBeforePour = useCallback(
417
+ async (context) => {
418
+ const topic = `/kos/dispense/${nozzle?.path}/pre/pour/`;
419
+ EventBus.publish(topic, {});
420
+ return await onBeforePour?.(context) || true;
421
+ },
422
+ [nozzle?.path]
423
+ );
424
+ const handleBeforePourRejected = useCallback(async () => {
425
+ const topic = `/kos/dispense/${nozzle?.path}/pre/pour/rejected/`;
426
+ EventBus.publish(topic, {});
427
+ }, [nozzle?.path]);
428
+ const onPourCancel = useCallback(() => {
429
+ const topic = `/kos/dispense/${nozzle?.path}/pour/cancel/`;
430
+ EventBus.publish(topic, {});
431
+ }, [nozzle?.path]);
432
+ const { brands, selectBrand, selectedBrand, clearBrand, brandCompanions } = useBrands({
433
+ companionType: options.companionTypes?.brand,
434
+ onBrandSelected,
435
+ onBrandCleared
436
+ });
437
+ const {
438
+ beverages,
439
+ selectBeverage,
440
+ selectedBeverage,
441
+ clearBeverage,
442
+ beverageCompanions
443
+ } = useBeverages({
444
+ companionType: options.companionTypes?.beverage,
445
+ onBeverageSelected,
446
+ onClearBeverage: onBeverageCleared,
447
+ onBeverageListUpdated
448
+ });
449
+ const {
450
+ clearFlavors,
451
+ flavors,
452
+ selectFlavor,
453
+ selectedFlavors,
454
+ flavorCompanions
455
+ } = useFlavors({
456
+ companionType: options.companionTypes?.flavor,
457
+ onFlavorSelected,
458
+ onFlavorCleared
459
+ });
460
+ const [onBeforePour, setOnBeforePour] = useState();
461
+ const updateOnBeforePour = useCallback((callback) => {
462
+ setOnBeforePour(() => callback);
463
+ }, []);
464
+ const pour = useNozzlePour({
465
+ onPour,
466
+ onPourCancel,
467
+ onBeforePour: handleBeforePour,
468
+ onBeforePourRejected: handleBeforePourRejected
469
+ });
470
+ updatePourContext.current = pour.updatePourContext;
471
+ removeFromPourContext.current = pour.removeFromPourContext;
472
+ const back = useCallback(() => {
473
+ log$2.debug(`Navigating back from group: ${currentGroup}`);
474
+ switch (currentGroup) {
475
+ case DISPENSE_GROUP_BRAND:
476
+ clearBeverage();
477
+ clearBrand();
478
+ break;
479
+ case DISPENSE_GROUP_BEVERAGE:
480
+ case DISPENSE_GROUP_FLAVOR:
481
+ setCurrentGroup(initialGroup);
482
+ clearBeverage();
483
+ clearBrand();
484
+ break;
485
+ }
486
+ }, [clearBeverage, clearBrand, currentGroup, initialGroup]);
487
+ const home = useCallback(() => {
488
+ const topic = `/kos/dispense/${nozzle?.path}/home/`;
489
+ EventBus.publish(topic, {});
490
+ setCurrentGroup(initialGroup);
491
+ if (initialGroup === DISPENSE_GROUP_BRAND) {
492
+ clearBeverage();
493
+ clearBrand();
494
+ }
495
+ if (initialGroup === DISPENSE_GROUP_BEVERAGE) {
496
+ clearBeverage();
497
+ }
498
+ }, [clearBeverage, clearBrand, initialGroup]);
499
+ const pauseTimers = useCallback(() => {
500
+ if (timersRef.current.length === 0) {
501
+ log$2.debug("No timers to pause.");
502
+ return;
503
+ }
504
+ log$2.debug(`Pausing ${timersRef.current.length} timers.`);
505
+ timersRef.current.forEach((timer) => {
506
+ log$2.debug(`Pausing timer with id ${timer.id}.`);
507
+ timer.pause();
508
+ });
509
+ }, []);
510
+ const restartTimers = useCallback(() => {
511
+ if (timersRef.current.length === 0) {
512
+ log$2.debug("No timers to restart.");
513
+ return;
514
+ }
515
+ log$2.debug(`Restarting ${timersRef.current.length} timers.`);
516
+ timersRef.current.forEach((timer) => {
517
+ log$2.debug(`Restarting timer with id ${timer.id}.`);
518
+ timer.restart();
519
+ });
520
+ }, []);
521
+ const addTimer = useCallback((timer) => {
522
+ if (!timer) {
523
+ return;
524
+ }
525
+ if (timersRef.current.some((t) => t.id === timer.id)) {
526
+ log$2.debug(`Timer with id ${timer.id} already exists.`);
527
+ return;
528
+ }
529
+ timersRef.current.push(timer);
530
+ }, []);
531
+ return {
532
+ timers: {
533
+ add: addTimer,
534
+ pause: pauseTimers,
535
+ restart: restartTimers
536
+ },
537
+ nav: {
538
+ currentGroup,
539
+ back,
540
+ home
541
+ },
542
+ pour,
543
+ updateOnBeforePour,
544
+ selections: {
545
+ [DISPENSE_GROUP_BRAND]: selectedBrand,
546
+ [DISPENSE_GROUP_BEVERAGE]: selectedBeverage,
547
+ [DISPENSE_GROUP_FLAVOR]: selectedFlavors
548
+ },
549
+ [DISPENSE_GROUP_BRAND]: {
550
+ models: brands,
551
+ companions: brandCompanions,
552
+ clear: clearBrand,
553
+ handlers: {
554
+ onSelected: selectBrand
555
+ }
556
+ },
557
+ [DISPENSE_GROUP_BEVERAGE]: {
558
+ models: beverages,
559
+ companions: beverageCompanions,
560
+ clear: clearBeverage,
561
+ handlers: {
562
+ onSelected: selectBeverage
563
+ }
564
+ },
565
+ [DISPENSE_GROUP_FLAVOR]: {
566
+ models: flavors,
567
+ companions: flavorCompanions,
568
+ clear: clearFlavors,
569
+ handlers: {
570
+ onSelected: selectFlavor
571
+ }
572
+ }
573
+ };
574
+ };
575
+ const useAmbientAttractTimers = (props) => {
576
+ const { model: nozzle } = useNozzleContext();
577
+ const [attractTimer, setAttractTimer] = useState(null);
578
+ const {
579
+ onAmbientTimer,
580
+ onAttractTimer,
581
+ onResetAttractTimer,
582
+ onResumeAttractTimer,
583
+ defaultAttractTime,
584
+ defaultAmbientTime
585
+ } = props;
586
+ const handleAmbientTimer = useCallback(() => {
587
+ if (onAmbientTimer) {
588
+ KosLog.info("Ambient timer expired. Calling callback");
589
+ onAmbientTimer?.();
590
+ }
591
+ }, [onAmbientTimer]);
592
+ const handleAttractTimer = useCallback(() => {
593
+ if (onAttractTimer) {
594
+ KosLog.info("Attract timer expired. Calling callback");
595
+ onAttractTimer?.();
596
+ }
597
+ }, [onAttractTimer]);
598
+ const handleResetAttractTimer = useCallback(() => {
599
+ if (attractTimer) {
600
+ attractTimer.restart();
601
+ onResetAttractTimer?.();
602
+ }
603
+ }, [attractTimer, onResetAttractTimer]);
604
+ const handlePauseAttractTimer = useCallback(() => {
605
+ if (attractTimer) {
606
+ attractTimer.reset();
607
+ onResetAttractTimer?.();
608
+ }
609
+ }, [attractTimer, onResetAttractTimer]);
610
+ const handleResume = useCallback(() => {
611
+ if (attractTimer) {
612
+ attractTimer.pause();
613
+ onResumeAttractTimer?.();
614
+ }
615
+ }, [attractTimer, onResumeAttractTimer]);
616
+ useEffect(() => {
617
+ if (nozzle && defaultAttractTime) {
618
+ KosLog.info("Nozzle is available. Creating timers");
619
+ const timer = TimerManager.createTimer(
620
+ "attract-timer-" + nozzle.path,
621
+ defaultAttractTime
622
+ );
623
+ if (defaultAttractTime) {
624
+ timer?.addTimeoutAction({
625
+ name: "attract-timer",
626
+ remainingTime: 0,
627
+ action: handleAttractTimer
628
+ });
629
+ }
630
+ if (defaultAmbientTime) {
631
+ timer?.addTimeoutAction({
632
+ name: "ambient-timer",
633
+ remainingTime: defaultAmbientTime,
634
+ action: handleAmbientTimer
635
+ });
636
+ }
637
+ if (defaultAttractTime) {
638
+ timer?.start();
639
+ }
640
+ setAttractTimer(timer ?? null);
641
+ return () => {
642
+ timer?.reset();
643
+ setAttractTimer(null);
644
+ };
645
+ }
646
+ return () => {
647
+ KosLog.info("Nozzle is not available. No timers to clear");
648
+ };
649
+ }, [
650
+ defaultAmbientTime,
651
+ defaultAttractTime,
652
+ handleAmbientTimer,
653
+ handleAttractTimer,
654
+ nozzle
655
+ ]);
656
+ return {
657
+ attractTimer,
658
+ restart: handleResetAttractTimer,
659
+ pause: handlePauseAttractTimer,
660
+ resume: handleResume
661
+ };
662
+ };
663
+ const DISPENSE_EVENT_CONFIGS = [
664
+ { path: "brand/selected", callbackKey: "onBrandSelected" },
665
+ { path: "brand/cleared", callbackKey: "onBrandCleared" },
666
+ { path: "beverage/list/updated", callbackKey: "onBeverageListUpdated" },
667
+ { path: "beverage/selected", callbackKey: "onBeverageSelected" },
668
+ { path: "beverage/cleared", callbackKey: "onBeverageCleared" },
669
+ { path: "flavor/selected", callbackKey: "onFlavorSelected" },
670
+ { path: "flavor/cleared", callbackKey: "onFlavorCleared" },
671
+ { path: "pour", callbackKey: "onPour" },
672
+ { path: "pour/cancel", callbackKey: "onPourCancel" },
673
+ { path: "pre/pour/rejected", callbackKey: "onBeforePourRejected" },
674
+ { path: "ambient/start", callbackKey: "onAmbientTimer" },
675
+ { path: "attract/start", callbackKey: "onAttractTimer" },
676
+ { path: "attract/resume", callbackKey: "onResumeAttractTimer" },
677
+ { path: "idle/timeout", callbackKey: "onIdleTimeout" },
678
+ { path: "are-you-there/timeout", callbackKey: "onAreYouThereTimeout" },
679
+ { path: "init", callbackKey: "onInit" },
680
+ { path: "home", callbackKey: "onReturnToHome" }
681
+ ];
682
+ function buildDispenseTopics(nozzlePath, callbacks) {
683
+ if (!nozzlePath) {
684
+ return [];
685
+ }
686
+ return DISPENSE_EVENT_CONFIGS.filter(
687
+ (config) => callbacks[config.callbackKey] !== void 0
688
+ ).map((config) => {
689
+ return {
690
+ topic: `/kos/dispense/${nozzlePath}/${config.path}/`,
691
+ callback: callbacks[config.callbackKey]
692
+ };
693
+ });
694
+ }
695
+ const subscribe = (topic, callback) => {
696
+ if (callback) {
697
+ const callbackWrapper = (args) => {
698
+ if (args && args.body) {
699
+ callback(args.body);
700
+ }
701
+ };
702
+ const result = EventBus.subscribe(topic, callbackWrapper);
703
+ return result.unsubscribe;
704
+ }
705
+ return void 0;
706
+ };
707
+ const useDispenseLifecycle = ({
708
+ onInit,
709
+ onBrandSelected,
710
+ onBrandCleared,
711
+ onBeverageCleared,
712
+ onBeverageSelected,
713
+ onBeverageListUpdated,
714
+ onFlavorCleared,
715
+ onFlavorSelected,
716
+ onReturnToHome,
717
+ onPour,
718
+ onPourCancel,
719
+ onBeforePourRejected,
720
+ onAmbientTimer,
721
+ onAttractTimer,
722
+ onResumeAttractTimer,
723
+ onIdleTimeout,
724
+ onAreYouThereTimeout
725
+ }) => {
726
+ const { model: nozzle } = useNozzleContext();
727
+ useEffect(() => {
728
+ const topics = buildDispenseTopics(nozzle?.path, {
729
+ onBrandSelected,
730
+ onBrandCleared,
731
+ onBeverageListUpdated,
732
+ onBeverageSelected,
733
+ onBeverageCleared,
734
+ onFlavorSelected,
735
+ onFlavorCleared,
736
+ onPour,
737
+ onPourCancel,
738
+ onBeforePourRejected,
739
+ onAmbientTimer,
740
+ onAttractTimer,
741
+ onResumeAttractTimer,
742
+ onIdleTimeout,
743
+ onAreYouThereTimeout,
744
+ onInit,
745
+ onReturnToHome
746
+ });
747
+ const disposers = topics.map(
748
+ ({ topic, callback }) => subscribe(topic, callback)
749
+ );
750
+ return () => {
751
+ disposers.forEach((disposer) => disposer?.());
752
+ };
753
+ }, [
754
+ nozzle?.path,
755
+ onAmbientTimer,
756
+ onAttractTimer,
757
+ onBeverageCleared,
758
+ onBeverageSelected,
759
+ onBeverageListUpdated,
760
+ onBrandCleared,
761
+ onBrandSelected,
762
+ onFlavorCleared,
763
+ onFlavorSelected,
764
+ onPour,
765
+ onPourCancel,
766
+ onBeforePourRejected,
767
+ onResumeAttractTimer,
768
+ onIdleTimeout,
769
+ onAreYouThereTimeout,
770
+ onInit,
771
+ onReturnToHome
772
+ ]);
773
+ };
774
+ const log$1 = KosLog.createLogger({ name: "useCuiKitTimers" });
775
+ const useCuiKitTimers = (props) => {
776
+ const { model: nozzle } = useNozzleContext();
777
+ const [idleTimer, setIdleTimer] = useState(null);
778
+ const {
779
+ onAreYouThereTimer,
780
+ onIdleTimer,
781
+ onResetIdleTimer,
782
+ defaultAreYouThereTime = 10,
783
+ defaultIdleTime = 20
784
+ } = props;
785
+ const hasAreYouThereFiredRef = useRef(false);
786
+ const handleAreYouThereTimer = useCallback(() => {
787
+ if (!hasAreYouThereFiredRef.current && onAreYouThereTimer) {
788
+ KosLog.info("Are you there timer expired. Calling callback");
789
+ hasAreYouThereFiredRef.current = true;
790
+ onAreYouThereTimer?.();
791
+ }
792
+ }, [onAreYouThereTimer]);
793
+ const handleIdleTimer = useCallback(() => {
794
+ log$1.debug(
795
+ "handleIdleTimer called in useCuiKitTimers, onIdleTimer exists:",
796
+ !!onIdleTimer
797
+ );
798
+ if (onIdleTimer) {
799
+ log$1.debug("Idle timer expired. Calling callback");
800
+ onIdleTimer?.();
801
+ } else {
802
+ log$1.debug("No onIdleTimer callback provided!");
803
+ }
804
+ }, [onIdleTimer]);
805
+ const handleRestartIdleTimer = useCallback(() => {
806
+ log$1.debug(`TIMER RESTART called for ${props.prefix ?? ""}timer`);
807
+ if (idleTimer) {
808
+ idleTimer.restart();
809
+ hasAreYouThereFiredRef.current = false;
810
+ onResetIdleTimer?.();
811
+ }
812
+ }, [idleTimer, onResetIdleTimer, props.prefix]);
813
+ const handlePauseIdleTimer = useCallback(() => {
814
+ log$1.debug(`TIMER PAUSE/RESET called for ${props.prefix ?? ""}timer`);
815
+ if (idleTimer) {
816
+ idleTimer.reset();
817
+ hasAreYouThereFiredRef.current = false;
818
+ onResetIdleTimer?.();
819
+ }
820
+ }, [idleTimer, onResetIdleTimer, props.prefix]);
821
+ useEffect(() => {
822
+ log$1.debug(
823
+ `useCuiKitTimers effect triggered - nozzle: ${!!nozzle}, path: ${nozzle?.path}, callbacks: handleIdle=${!!handleIdleTimer}, handleAreYouThere=${!!handleAreYouThereTimer}`
824
+ );
825
+ if (nozzle) {
826
+ log$1.info("Nozzle is available. Creating timers");
827
+ const timer = TimerManager.createTimer(
828
+ `${props.prefix ?? ""}idle-timer-${nozzle.path}`,
829
+ defaultIdleTime
830
+ );
831
+ log$1.debug(
832
+ `Adding idle timer action for ${props.prefix ?? ""}idle-timer-${nozzle.path} with callback:`,
833
+ !!handleIdleTimer
834
+ );
835
+ timer?.addTimeoutAction({
836
+ name: "idle-timer",
837
+ remainingTime: 0,
838
+ action: handleIdleTimer
839
+ });
840
+ timer?.addTimeoutAction({
841
+ name: "are-you-there-timer",
842
+ remainingTime: defaultAreYouThereTime,
843
+ action: handleAreYouThereTimer
844
+ });
845
+ setIdleTimer(timer ?? null);
846
+ return () => {
847
+ timer?.reset();
848
+ setIdleTimer(null);
849
+ };
850
+ }
851
+ return () => {
852
+ log$1.info("Nozzle is not available. No timers to clear");
853
+ };
854
+ }, [
855
+ defaultAreYouThereTime,
856
+ defaultIdleTime,
857
+ handleAreYouThereTimer,
858
+ handleIdleTimer,
859
+ nozzle,
860
+ props.prefix
861
+ ]);
862
+ return {
863
+ idleTimer,
864
+ restart: handleRestartIdleTimer,
865
+ pause: handlePauseIdleTimer
866
+ };
867
+ };
868
+ const log = KosLog.createLogger({ name: "useDefaultCuiKitLifecycle" });
869
+ const useDefaultCuiKitLifecycle = ({
870
+ kit,
871
+ inactivity,
872
+ pour,
873
+ screens,
874
+ onBeforeAreYouThereTimer,
875
+ areYouThereRejectionPolicy = "pause"
876
+ }) => {
877
+ const [showAmbientScreen, setShowAmbientScreen] = useState(false);
878
+ const [showAttractScreen, setShowAttractScreen] = useState(false);
879
+ const { model: nozzle } = useNozzleContext();
880
+ const [hasPoured, setHasPoured] = useState(false);
881
+ const idleTimeout = inactivity?.idleTimeout ?? 15;
882
+ const areYouThereTimeout = inactivity?.areYouThereTimeoutOffset ?? 10;
883
+ const idlePourTimeout = pour?.idleTimeout ?? inactivity?.idleTimeout ?? 10;
884
+ const areYouTherePourTimeout = pour?.areYouThereTimeoutOffset ?? inactivity?.areYouThereTimeoutOffset ?? 5;
885
+ const ambientTimeout = screens?.ambientTimeoutOffset;
886
+ const attractTimeout = screens?.attractTimeout;
887
+ const handleIdleTimeout = useCallback(() => {
888
+ log.info("handleIdleTimeout called - navigating home and publishing event");
889
+ setShowAreYouThere(false);
890
+ kit?.nav.home();
891
+ if (nozzle) {
892
+ const topic = `/kos/dispense/${nozzle.path}/idle/timeout/`;
893
+ EventBus.publish(topic, {});
894
+ }
895
+ }, [kit?.nav?.home, nozzle]);
896
+ const handleResetIdleTimer = useCallback(() => {
897
+ log.info("handleResetIdleTimer called - resetting idle timer");
898
+ setShowAreYouThere(false);
899
+ }, []);
900
+ const handleAmbientTimer = useCallback(() => {
901
+ if (ambientTimeout) {
902
+ setShowAmbientScreen(true);
903
+ setShowAttractScreen(false);
904
+ if (nozzle) {
905
+ const topic = `/kos/dispense/${nozzle.path}/ambient/start/`;
906
+ EventBus.publish(topic, {});
907
+ }
908
+ }
909
+ }, [ambientTimeout, nozzle]);
910
+ const handleAttractTimer = useCallback(() => {
911
+ if (attractTimeout) {
912
+ setShowAttractScreen(true);
913
+ setShowAmbientScreen(false);
914
+ if (nozzle) {
915
+ const topic = `/kos/dispense/${nozzle.path}/attract/start/`;
916
+ EventBus.publish(topic, {});
917
+ }
918
+ }
919
+ }, [attractTimeout, nozzle]);
920
+ const handleAttractResume = useCallback(() => {
921
+ if (attractTimeout) {
922
+ setShowAttractScreen(false);
923
+ setShowAmbientScreen(false);
924
+ kit?.nav.home();
925
+ if (nozzle) {
926
+ const topic = `/kos/dispense/${nozzle.path}/attract/resume/`;
927
+ EventBus.publish(topic, {});
928
+ }
929
+ }
930
+ }, [kit?.nav, attractTimeout, nozzle]);
931
+ const {
932
+ pause: ambientPause,
933
+ restart: ambientRestart,
934
+ attractTimer
935
+ } = useAmbientAttractTimers({
936
+ defaultAmbientTime: ambientTimeout,
937
+ defaultAttractTime: attractTimeout,
938
+ onAmbientTimer: handleAmbientTimer,
939
+ onAttractTimer: handleAttractTimer,
940
+ onResumeAttractTimer: handleAttractResume
941
+ });
942
+ kit?.timers?.add(attractTimer);
943
+ const [showAreYouThere, setShowAreYouThere] = useState(false);
944
+ log.info(
945
+ "Creating idle timer with timeout:",
946
+ idleTimeout,
947
+ "seconds and callback:",
948
+ !!handleIdleTimeout
949
+ );
950
+ const { pause, restart, idleTimer } = useCuiKitTimers({
951
+ defaultAreYouThereTime: areYouThereTimeout,
952
+ defaultIdleTime: idleTimeout,
953
+ onIdleTimer: handleIdleTimeout,
954
+ onResetIdleTimer: handleResetIdleTimer
955
+ });
956
+ log.info(
957
+ `Creating pour timer with timeout: ${idlePourTimeout} seconds and callback: ${!!handleIdleTimeout}`
958
+ );
959
+ const {
960
+ pause: pausePourTimer,
961
+ restart: restartPourTimer,
962
+ idleTimer: pourIdleTimer
963
+ } = useCuiKitTimers({
964
+ defaultAreYouThereTime: areYouTherePourTimeout,
965
+ defaultIdleTime: idlePourTimeout,
966
+ onIdleTimer: handleIdleTimeout,
967
+ prefix: "pour-"
968
+ });
969
+ const handleAreYouThereTimer = useCallback(async () => {
970
+ let shouldShowAreYouThere = true;
971
+ if (onBeforeAreYouThereTimer) {
972
+ try {
973
+ shouldShowAreYouThere = await onBeforeAreYouThereTimer();
974
+ } catch (error) {
975
+ log.error(`onBeforeAreYouThereTimer callback failed: ${error}`);
976
+ shouldShowAreYouThere = false;
977
+ }
978
+ }
979
+ if (shouldShowAreYouThere) {
980
+ if (nozzle) {
981
+ const topic = `/kos/dispense/${nozzle.path}/are-you-there/timeout/`;
982
+ EventBus.publish(topic, {});
983
+ }
984
+ setShowAreYouThere(true);
985
+ if (hasPoured) {
986
+ pausePourTimer();
987
+ } else {
988
+ pause();
989
+ }
990
+ } else {
991
+ switch (areYouThereRejectionPolicy) {
992
+ case "pause":
993
+ if (hasPoured) {
994
+ pausePourTimer();
995
+ } else {
996
+ pause();
997
+ }
998
+ break;
999
+ case "restart":
1000
+ if (hasPoured) {
1001
+ restartPourTimer();
1002
+ } else {
1003
+ restart();
1004
+ }
1005
+ break;
1006
+ }
1007
+ }
1008
+ }, [onBeforeAreYouThereTimer, nozzle, areYouThereRejectionPolicy, hasPoured]);
1009
+ const clearAreYouThere = useCallback(() => {
1010
+ setShowAreYouThere(false);
1011
+ ambientPause();
1012
+ if (hasPoured) {
1013
+ restartPourTimer();
1014
+ pause();
1015
+ } else {
1016
+ restart();
1017
+ pausePourTimer();
1018
+ }
1019
+ }, [hasPoured, pause, pausePourTimer, restart, restartPourTimer]);
1020
+ useEffect(() => {
1021
+ if (idleTimer) {
1022
+ idleTimer.addTimeoutAction({
1023
+ name: "are-you-there-timer",
1024
+ remainingTime: areYouThereTimeout,
1025
+ action: handleAreYouThereTimer
1026
+ });
1027
+ }
1028
+ }, [idleTimer, areYouThereTimeout, handleAreYouThereTimer]);
1029
+ useEffect(() => {
1030
+ if (pourIdleTimer) {
1031
+ pourIdleTimer.addTimeoutAction({
1032
+ name: "pour-are-you-there-timer",
1033
+ remainingTime: areYouTherePourTimeout,
1034
+ action: handleAreYouThereTimer
1035
+ });
1036
+ }
1037
+ }, [pourIdleTimer, areYouTherePourTimeout, handleAreYouThereTimer]);
1038
+ kit?.timers?.add(idleTimer);
1039
+ kit?.timers?.add(pourIdleTimer);
1040
+ const handlePour = useCallback(() => {
1041
+ setHasPoured(false);
1042
+ pausePourTimer();
1043
+ pause();
1044
+ ambientPause();
1045
+ }, [pause, pausePourTimer]);
1046
+ const handlePourCancel = useCallback(() => {
1047
+ setHasPoured(true);
1048
+ log.info("restarting pour timer");
1049
+ restartPourTimer();
1050
+ ambientPause();
1051
+ pause();
1052
+ }, [pause, restartPourTimer]);
1053
+ const handleBeforePourRejected = useCallback(() => {
1054
+ setHasPoured(false);
1055
+ log.info("restarting pour timer on before pour rejected");
1056
+ pausePourTimer();
1057
+ restart();
1058
+ }, []);
1059
+ const handleBrandSelected = useCallback(() => {
1060
+ ambientPause();
1061
+ setShowAttractScreen(false);
1062
+ setShowAmbientScreen(false);
1063
+ restart();
1064
+ }, [ambientPause, restart]);
1065
+ const handleBrandCleared = useCallback(() => {
1066
+ setShowAttractScreen(false);
1067
+ setShowAmbientScreen(false);
1068
+ setHasPoured(false);
1069
+ pausePourTimer();
1070
+ ambientRestart();
1071
+ }, [ambientRestart, pausePourTimer]);
1072
+ const handleBeverageSelected = useCallback(() => {
1073
+ setShowAttractScreen(false);
1074
+ setShowAmbientScreen(false);
1075
+ setHasPoured(false);
1076
+ ambientPause();
1077
+ restart();
1078
+ }, [ambientPause, restart]);
1079
+ const handleBeverageCleared = useCallback(() => {
1080
+ setShowAttractScreen(false);
1081
+ setShowAmbientScreen(false);
1082
+ setHasPoured(false);
1083
+ ambientRestart();
1084
+ pause();
1085
+ pausePourTimer();
1086
+ }, [ambientRestart, pause, pausePourTimer]);
1087
+ const handleInit = useCallback(() => {
1088
+ setShowAttractScreen(false);
1089
+ setShowAmbientScreen(false);
1090
+ ambientRestart();
1091
+ pause();
1092
+ }, [ambientRestart, pause]);
1093
+ useDispenseLifecycle({
1094
+ onBrandSelected: handleBrandSelected,
1095
+ onBrandCleared: handleBrandCleared,
1096
+ onBeverageSelected: handleBeverageSelected,
1097
+ onBeverageCleared: handleBeverageCleared,
1098
+ onPour: handlePour,
1099
+ onPourCancel: handlePourCancel,
1100
+ onBeforePourRejected: handleBeforePourRejected,
1101
+ onInit: handleInit
1102
+ // Note: Timer-related handlers (onIdleTimeout, onAmbientTimer, onAttractTimer,
1103
+ // onResumeAttractTimer, onAreYouThereTimeout) are NOT included here since this
1104
+ // component's own timer hooks call those handlers directly. Including them would
1105
+ // create circular event loops.
1106
+ });
1107
+ const areYouThereCountdown = hasPoured ? areYouTherePourTimeout : areYouThereTimeout;
1108
+ useEffect(() => {
1109
+ if (nozzle && attractTimer) {
1110
+ const topic = `/kos/dispense/${nozzle?.path}/init/`;
1111
+ EventBus.publish(topic, {});
1112
+ }
1113
+ }, [nozzle, attractTimer]);
1114
+ return {
1115
+ showAreYouThere,
1116
+ clearAreYouThere,
1117
+ pauseIdleTimer: pause,
1118
+ restartIdleTimer: restart,
1119
+ areYouThereCountdown,
1120
+ showAmbientScreen,
1121
+ showAttractScreen,
1122
+ pauseScreenTimer: ambientPause,
1123
+ restartScreenTimer: ambientRestart
1124
+ };
1125
+ };
1126
+ const useDeviceAssembly = () => {
1127
+ const modelId = DeviceAssembly.type;
1128
+ const result = useKosModel({
1129
+ modelId,
1130
+ modelType: DeviceAssembly.type,
1131
+ options: {}
1132
+ });
1133
+ return result;
1134
+ };
1135
+ function withDeviceAssembly(WrappedComponent) {
1136
+ return (props) => {
1137
+ const { model, status, KosModelLoader } = useDeviceAssembly();
1138
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, deviceAssembly: model }) });
1139
+ };
1140
+ }
1141
+ const useHolder = (id) => {
1142
+ const modelId = id;
1143
+ const result = useKosModel({
1144
+ modelId,
1145
+ modelType: Holder$1.type,
1146
+ options: {}
1147
+ });
1148
+ return result;
1149
+ };
1150
+ function withHolder(id, WrappedComponent) {
1151
+ return (props) => {
1152
+ const { model, status, KosModelLoader } = useHolder(id);
1153
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, holder: model }) });
1154
+ };
1155
+ }
1156
+ const useHolderContainer = () => {
1157
+ const modelId = HolderContainer$1.type;
1158
+ const result = useKosModel({
1159
+ modelId,
1160
+ modelType: HolderContainer$1.type,
1161
+ options: {}
1162
+ });
1163
+ return result;
1164
+ };
1165
+ function withHolderContainer(WrappedComponent) {
1166
+ return (props) => {
1167
+ const { model, status, KosModelLoader } = useHolderContainer();
1168
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, holderContainer: model }) });
1169
+ };
1170
+ }
1171
+ const useIngredient = () => {
1172
+ const modelId = Ingredient$1.type;
1173
+ const result = useKosModel({
1174
+ modelId,
1175
+ modelType: Ingredient$1.type,
1176
+ options: {}
1177
+ });
1178
+ return result;
1179
+ };
1180
+ const logger$5 = KosLog.createLogger({
1181
+ name: "HoldToPourIntentStrategy",
1182
+ group: "kos-hooks"
1183
+ });
1184
+ const HoldToPourIntentStrategy = {
1185
+ name: "HoldToPourIntentStrategy",
1186
+ async initiate(model, intent) {
1187
+ if (!model?.canPour) {
1188
+ logger$5.debug(`${model?.id} cannot pour. Returning early.`);
1189
+ return;
1190
+ }
1191
+ if (intent) {
1192
+ logger$5.debug(`performing intent: ${intent}`);
1193
+ await model?.performIntent(intent);
1194
+ } else {
1195
+ logger$5.debug("no intent provided. Returning early.");
1196
+ }
1197
+ },
1198
+ async initiateEnded(nozzle) {
1199
+ await nozzle?.cancelPour();
1200
+ }
1201
+ };
1202
+ const logger$4 = KosLog.createLogger({
1203
+ name: "useNozzlePour",
1204
+ group: "kos-hooks"
1205
+ });
1206
+ const useIngredientPour = ({
1207
+ onPour,
1208
+ onPourCancel,
1209
+ intentContainer,
1210
+ strategy = HoldToPourIntentStrategy
1211
+ }) => {
1212
+ const handlePour = useCallback(() => {
1213
+ logger$4.debug(
1214
+ `[${strategy?.name}] - Pour initiated for model ${intentContainer?.id}.`
1215
+ );
1216
+ strategy?.initiate(intentContainer);
1217
+ onPour?.();
1218
+ }, [onPour, intentContainer, strategy]);
1219
+ const handleCancelPour = useCallback(() => {
1220
+ logger$4.debug(
1221
+ `[${strategy?.name}] - Pour initiate ended called for nozzle ${intentContainer?.id}.`
1222
+ );
1223
+ strategy?.initiateEnded?.(intentContainer);
1224
+ onPourCancel?.();
1225
+ }, [onPourCancel, intentContainer, strategy]);
1226
+ const forceCancelPour = useCallback(() => {
1227
+ logger$4.debug(`Force cancelling pour for nozzle ${intentContainer?.id}.`);
1228
+ intentContainer?.cancelPour();
1229
+ onPourCancel?.();
1230
+ }, [onPourCancel, intentContainer]);
1231
+ const handlers = usePressGesture({
1232
+ onPressed: handlePour,
1233
+ onRelease: handleCancelPour
1234
+ });
1235
+ return {
1236
+ handlers: handlers.dom,
1237
+ cancel: forceCancelPour,
1238
+ status: intentContainer
1239
+ };
1240
+ };
1241
+ function withIngredient(WrappedComponent) {
1242
+ return (props) => {
1243
+ const { model, status, KosModelLoader } = useIngredient();
1244
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, ingredient: model }) });
1245
+ };
1246
+ }
1247
+ const useIngredientContainer = () => {
1248
+ const modelId = IngredientContainer$1.type;
1249
+ const result = useKosModel({
1250
+ modelId,
1251
+ modelType: IngredientContainer$1.type,
1252
+ options: {}
1253
+ });
1254
+ return result;
1255
+ };
1256
+ function withIngredientContainer(WrappedComponent) {
1257
+ return (props) => {
1258
+ const { model, status, KosModelLoader } = useIngredientContainer();
1259
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, ingredientContainer: model }) });
1260
+ };
1261
+ }
1262
+ function withNozzle(path, WrappedComponent) {
1263
+ return (props) => {
1264
+ const { model, status, KosModelLoader } = useNozzle(path);
1265
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, nozzle: model }) });
1266
+ };
1267
+ }
1268
+ const logger$3 = KosLog.createLogger({
1269
+ name: "usePour",
1270
+ group: "kos-hooks"
1271
+ });
1272
+ const usePourTarget = ({
1273
+ onBeforePour,
1274
+ onPour,
1275
+ onPourCancel,
1276
+ onPourAbort,
1277
+ pourTarget,
1278
+ pourContext,
1279
+ strategy = HoldToPourStrategy
1280
+ }) => {
1281
+ const [context, _setContext] = useState(
1282
+ pourContext || new PourContext()
1283
+ );
1284
+ const handlePour = useCallback(async () => {
1285
+ logger$3.debug(
1286
+ `[${strategy?.name}] - calling before pour for pour target ${pourTarget?.id}.`
1287
+ );
1288
+ const canPour = onBeforePour ? await onBeforePour?.(context) : true;
1289
+ if (canPour) {
1290
+ logger$3.debug(
1291
+ `[${strategy?.name}] - Pour initiated for pour target ${pourTarget?.id}.`
1292
+ );
1293
+ await strategy?.initiate(pourTarget);
1294
+ onPour?.();
1295
+ if (!pourTarget?.isPouring) {
1296
+ onPourAbort?.();
1297
+ }
1298
+ } else {
1299
+ logger$3.debug(
1300
+ `[${strategy?.name}] - Pour cancelled for pour target ${pourTarget?.id}.`
1301
+ );
1302
+ onPourCancel?.();
1303
+ }
1304
+ }, [onPour, onBeforePour, onPourAbort, pourTarget, strategy, context]);
1305
+ const handleCancelPour = useCallback(async () => {
1306
+ logger$3.debug(
1307
+ `[${strategy?.name}] - Pour initiate ended called for pour target ${pourTarget?.id}.`
1308
+ );
1309
+ const ignore = await strategy?.initiateEnded?.(pourTarget);
1310
+ if (!ignore) {
1311
+ onPourCancel?.();
1312
+ }
1313
+ }, [onPourCancel, pourTarget, strategy]);
1314
+ const forceCancelPour = useCallback(async () => {
1315
+ logger$3.debug(`Force cancelling pour for pour target ${pourTarget?.id}.`);
1316
+ await pourTarget?.cancelPour();
1317
+ onPourCancel?.();
1318
+ }, [onPourCancel, pourTarget]);
1319
+ const handleUpdateContext = useCallback(
1320
+ (key, value) => {
1321
+ context.set(key, value);
1322
+ },
1323
+ [context]
1324
+ );
1325
+ const handleRemoveFromContext = useCallback(
1326
+ (key) => {
1327
+ context.remove(key);
1328
+ },
1329
+ [context]
1330
+ );
1331
+ const handlers = usePressGesture({
1332
+ onPressed: handlePour,
1333
+ onRelease: handleCancelPour
1334
+ });
1335
+ return {
1336
+ handlers: handlers.dom,
1337
+ cancel: forceCancelPour,
1338
+ updatePourContext: handleUpdateContext,
1339
+ removeFromPourContext: handleRemoveFromContext,
1340
+ status: pourTarget
1341
+ };
1342
+ };
1343
+ const logger$2 = KosLog.createLogger({
1344
+ name: "TapOrHoldIntentStrategy",
1345
+ group: "kos-hooks"
1346
+ });
1347
+ class TapOrHoldIntentStrategy {
1348
+ intent;
1349
+ name = "TapOrHoldIntentStrategy";
1350
+ isHold = false;
1351
+ disposer = null;
1352
+ constructor(intent) {
1353
+ this.intent = intent;
1354
+ }
1355
+ async initiate(model, intent) {
1356
+ this.disposer = setTimeout(() => {
1357
+ this.isHold = true;
1358
+ }, 250);
1359
+ if (model?.isPouring && !this.isHold) {
1360
+ logger$2.debug(`additional tap detected. cancelling pour`);
1361
+ await model.cancelPour();
1362
+ return;
1363
+ }
1364
+ if (!model?.canPour) {
1365
+ logger$2.debug(`${model?.id} cannot pour. Returning early.`);
1366
+ return;
1367
+ }
1368
+ if (intent) {
1369
+ logger$2.debug(`performing intent: ${intent}`);
1370
+ await model?.performIntent(intent);
1371
+ } else {
1372
+ logger$2.debug("no intent provided. Returning early.");
1373
+ }
1374
+ }
1375
+ async initiateEnded(nozzle) {
1376
+ if (this.disposer) clearTimeout(this.disposer);
1377
+ this.disposer = null;
1378
+ if (!this.isHold) {
1379
+ logger$2.debug("Tap detected. don't cancel and return.");
1380
+ return true;
1381
+ }
1382
+ await nozzle?.cancelPour();
1383
+ return false;
1384
+ }
1385
+ }
1386
+ const logger$1 = KosLog.createLogger({
1387
+ name: "TapToPourIntentStrategy",
1388
+ group: "kos-hooks"
1389
+ });
1390
+ const TapToPourIntentStrategy = {
1391
+ name: "TapToPourIntentStrategy",
1392
+ async initiate(model, intent) {
1393
+ if (model?.isPouring) {
1394
+ logger$1.debug(`Nozzle ${model?.id} is already pouring. cancelling pour`);
1395
+ await model.cancelPour();
1396
+ return;
1397
+ }
1398
+ if (!model?.canPour) {
1399
+ logger$1.debug(`Nozzle ${model?.id} cannot pour. Returning early.`);
1400
+ return;
1401
+ }
1402
+ if (intent) {
1403
+ logger$1.debug(`performing intent: ${intent}`);
1404
+ await model?.performIntent(intent);
1405
+ } else {
1406
+ logger$1.debug("no intent provided. Returning early.");
1407
+ }
1408
+ },
1409
+ async initiateEnded(_nozzle) {
1410
+ return true;
1411
+ }
1412
+ };
1413
+ const logger = KosLog.createLogger({
1414
+ name: "HoldToPourStrategy",
1415
+ group: "kos-hooks"
1416
+ });
1417
+ const TapToPourStrategy = {
1418
+ name: "TapToPourStrategy",
1419
+ async initiate(nozzle) {
1420
+ if (nozzle?.isPouring) {
1421
+ logger.debug(`Nozzle ${nozzle?.id} is already pouring. cancelling pour`);
1422
+ await nozzle.cancelPour();
1423
+ return;
1424
+ }
1425
+ if (!nozzle?.canPour) {
1426
+ logger.debug(`Nozzle ${nozzle?.id} cannot pour. Returning early.`);
1427
+ return;
1428
+ }
1429
+ await nozzle?.pour();
1430
+ },
1431
+ async initiateEnded(_nozzle) {
1432
+ return true;
1433
+ }
1434
+ };
1435
+ const useGenericPour = (id, servicePathFactory, itemId, data) => {
1436
+ const modelId = id;
1437
+ const result = useKosModel({
1438
+ modelId,
1439
+ modelType: GenericPour.type,
1440
+ forceUpdate: true,
1441
+ options: {
1442
+ servicePathFactory,
1443
+ selectedId: itemId,
1444
+ initialData: data
1445
+ }
1446
+ });
1447
+ return result;
1448
+ };
1449
+ function withGenericPour(WrappedComponent) {
1450
+ return (props) => {
1451
+ const { model, status, KosModelLoader } = useGenericPour(
1452
+ props.id,
1453
+ props.servicePathFactory,
1454
+ props.itemId
1455
+ );
1456
+ return /* @__PURE__ */ jsx(KosModelLoader, { ...status, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props, genericPour: model }) });
1457
+ };
1458
+ }
1459
+ const Assembly = createContext(void 0);
1460
+ const AssemblyProvider = ({ children }) => {
1461
+ const { model, ready } = useAssembly();
1462
+ const value = useMemo(() => {
1463
+ if (ready && model) {
1464
+ return { model };
1465
+ }
1466
+ return {};
1467
+ }, [ready, model]);
1468
+ return /* @__PURE__ */ jsx(Assembly.Provider, { value, children });
1469
+ };
1470
+ const useAssemblyContext = () => {
1471
+ const context = useContext(
1472
+ Assembly
1473
+ );
1474
+ if (!context) {
1475
+ throw new Error(
1476
+ "useAssemblyContext must be used within a AssemblyProvider"
1477
+ );
1478
+ }
1479
+ return context;
1480
+ };
1481
+ const Availability = createContext(void 0);
1482
+ const AvailabilityProvider = ({ children }) => {
1483
+ const { model, ready } = useAvailability();
1484
+ const value = useMemo(() => {
1485
+ if (ready && model) {
1486
+ return { model };
1487
+ }
1488
+ return {};
1489
+ }, [ready, model]);
1490
+ return /* @__PURE__ */ jsx(Availability.Provider, { value, children });
1491
+ };
1492
+ const useAvailabilityContext = () => {
1493
+ const context = useContext(Availability);
1494
+ if (!context) {
1495
+ throw new Error(
1496
+ "useAvailabilityContext must be used within a AvailabilityProvider"
1497
+ );
1498
+ }
1499
+ return context;
1500
+ };
1501
+ const Board = createContext(void 0);
1502
+ const BoardProvider = ({ children, id }) => {
1503
+ const { model, ready } = useBoard(id);
1504
+ const value = useMemo(() => {
1505
+ if (ready && model) {
1506
+ return { model };
1507
+ }
1508
+ return {};
1509
+ }, [ready, model]);
1510
+ return /* @__PURE__ */ jsx(Board.Provider, { value, children });
1511
+ };
1512
+ const useBoardContext = () => {
1513
+ const context = useContext(Board);
1514
+ if (!context) {
1515
+ throw new Error("useBoardContext must be used within a BoardProvider");
1516
+ }
1517
+ return context;
1518
+ };
1519
+ const BoardContainer = createContext(void 0);
1520
+ const BoardContainerProvider = ({ children }) => {
1521
+ const { model, ready } = useBoardContainer();
1522
+ const value = useMemo(() => {
1523
+ if (ready && model) {
1524
+ return { model };
1525
+ }
1526
+ return {};
1527
+ }, [ready, model]);
1528
+ return /* @__PURE__ */ jsx(BoardContainer.Provider, { value, children });
1529
+ };
1530
+ const useBoardContainerContext = () => {
1531
+ const context = useContext(BoardContainer);
1532
+ if (!context) {
1533
+ throw new Error(
1534
+ "useBoardContainerContext must be used within a BoardContainerProvider"
1535
+ );
1536
+ }
1537
+ return context;
1538
+ };
1539
+ const DeviceAssemblyContext = createContext(
1540
+ void 0
1541
+ );
1542
+ const DeviceAssemblyProvider = ({ children }) => {
1543
+ const { model, ready } = useDeviceAssembly();
1544
+ const value = useMemo(() => {
1545
+ if (ready && model) {
1546
+ const nozzlePaths = model.nozzlePaths;
1547
+ return { model, nozzlePaths };
1548
+ }
1549
+ return {};
1550
+ }, [ready, model]);
1551
+ const content = ready && model ? children : null;
1552
+ return /* @__PURE__ */ jsx(DeviceAssemblyContext.Provider, { value, children: content });
1553
+ };
1554
+ const useDeviceAssemblyContext = () => {
1555
+ const context = useContext(DeviceAssemblyContext);
1556
+ if (!context) {
1557
+ throw new Error(
1558
+ "useDeviceAssemblyContext must be used within a DeviceAssemblyProvider"
1559
+ );
1560
+ }
1561
+ return context;
1562
+ };
1563
+ function createDispenseKitContext() {
1564
+ const CuiKitContext = React.createContext(null);
1565
+ const useCuiKitContext = () => {
1566
+ const ctx = useContext(CuiKitContext);
1567
+ if (ctx === void 0) {
1568
+ throw new Error("useDispenseKitContext must be used within a Provider");
1569
+ }
1570
+ return ctx;
1571
+ };
1572
+ return [useCuiKitContext, CuiKitContext.Provider];
1573
+ }
1574
+ function CuiKitWrapper({
1575
+ children,
1576
+ provider: CuiKitProvider,
1577
+ props,
1578
+ nozzleProps
1579
+ }) {
1580
+ const result = useCuiKit(props);
1581
+ return /* @__PURE__ */ jsx(CuiKitProvider, { value: result, children: children(nozzleProps || {}) });
1582
+ }
1583
+ function DispenseView({
1584
+ children,
1585
+ provider,
1586
+ props
1587
+ }) {
1588
+ const { nozzlePaths } = useDeviceAssemblyContext();
1589
+ const totalNozzles = nozzlePaths?.length || 0;
1590
+ const nozzles = nozzlePaths?.map((path, index) => /* @__PURE__ */ jsx(NozzleProvider, { path, children: /* @__PURE__ */ jsx(
1591
+ CuiKitWrapper,
1592
+ {
1593
+ provider,
1594
+ props,
1595
+ nozzleProps: {
1596
+ nozzleIndex: index,
1597
+ nozzlePath: path,
1598
+ totalNozzles,
1599
+ isFirstNozzle: index === 0,
1600
+ isLastNozzle: index === totalNozzles - 1
1601
+ },
1602
+ children
1603
+ }
1604
+ ) }, path)) || [];
1605
+ return nozzles;
1606
+ }
1607
+ function CuiKit({
1608
+ provider,
1609
+ props
1610
+ }) {
1611
+ return ({ children }) => provider ? /* @__PURE__ */ jsx(DeviceAssemblyProvider, { children: /* @__PURE__ */ jsx(
1612
+ DispenseView,
1613
+ {
1614
+ provider,
1615
+ props,
1616
+ children
1617
+ }
1618
+ ) }) : null;
1619
+ }
1620
+ function initializeCuiKit(props) {
1621
+ const [useCuiKitContext, DispenseKitProvider] = createDispenseKitContext();
1622
+ return [
1623
+ useCuiKitContext,
1624
+ CuiKit({ provider: DispenseKitProvider, props })
1625
+ ];
1626
+ }
1627
+ const Holder = createContext(void 0);
1628
+ const HolderProvider = ({ children, id }) => {
1629
+ const { model, ready } = useHolder(id || "");
1630
+ const value = useMemo(() => {
1631
+ if (ready && model) {
1632
+ return { model };
1633
+ }
1634
+ return {};
1635
+ }, [ready, model]);
1636
+ return /* @__PURE__ */ jsx(Holder.Provider, { value, children });
1637
+ };
1638
+ const useHolderContext = () => {
1639
+ const context = useContext(Holder);
1640
+ if (!context) {
1641
+ throw new Error("useHolderContext must be used within a HolderProvider");
1642
+ }
1643
+ return context;
1644
+ };
1645
+ const HolderContainer = createContext(
1646
+ void 0
1647
+ );
1648
+ const HolderContainerProvider = ({ children }) => {
1649
+ const { model, ready } = useHolderContainer();
1650
+ const value = useMemo(() => {
1651
+ if (ready && model) {
1652
+ return { model };
1653
+ }
1654
+ return {};
1655
+ }, [ready, model]);
1656
+ return /* @__PURE__ */ jsx(HolderContainer.Provider, { value, children });
1657
+ };
1658
+ const useHolderContainerContext = () => {
1659
+ const context = useContext(HolderContainer);
1660
+ if (!context) {
1661
+ throw new Error(
1662
+ "useHolderContainerContext must be used within a HolderContainerProvider"
1663
+ );
1664
+ }
1665
+ return context;
1666
+ };
1667
+ const Ingredient = createContext(void 0);
1668
+ const IngredientProvider = ({ children }) => {
1669
+ const { model, ready } = useIngredient();
1670
+ const value = useMemo(() => {
1671
+ if (ready && model) {
1672
+ return { model };
1673
+ }
1674
+ return {};
1675
+ }, [ready, model]);
1676
+ return /* @__PURE__ */ jsx(Ingredient.Provider, { value, children });
1677
+ };
1678
+ const useIngredientContext = () => {
1679
+ const context = useContext(Ingredient);
1680
+ if (!context) {
1681
+ throw new Error(
1682
+ "useIngredientContext must be used within a IngredientProvider"
1683
+ );
1684
+ }
1685
+ return context;
1686
+ };
1687
+ const IngredientContainer = createContext(
1688
+ void 0
1689
+ );
1690
+ const IngredientContainerProvider = ({ children }) => {
1691
+ const { model, ready } = useIngredientContainer();
1692
+ const value = useMemo(() => {
1693
+ if (ready && model) {
1694
+ return { model };
1695
+ }
1696
+ return {};
1697
+ }, [ready, model]);
1698
+ return /* @__PURE__ */ jsx(IngredientContainer.Provider, { value, children });
1699
+ };
1700
+ const useIngredientContainerContext = () => {
1701
+ const context = useContext(IngredientContainer);
1702
+ if (!context) {
1703
+ throw new Error(
1704
+ "useIngredientContainerContext must be used within a IngredientContainerProvider"
1705
+ );
1706
+ }
1707
+ return context;
1708
+ };
1709
+ const usePump = () => {
1710
+ const modelId = Pump$1.type;
1711
+ const result = useKosModel({
1712
+ modelId,
1713
+ modelType: Pump$1.type,
1714
+ options: {}
1715
+ });
1716
+ return result;
1717
+ };
1718
+ const Pump = createContext(void 0);
1719
+ const PumpProvider = ({ children }) => {
1720
+ const { model, ready } = usePump();
1721
+ const value = useMemo(() => {
1722
+ if (ready && model) {
1723
+ return { model };
1724
+ }
1725
+ return {};
1726
+ }, [ready, model]);
1727
+ return /* @__PURE__ */ jsx(Pump.Provider, { value, children });
1728
+ };
1729
+ const usePumpContext = () => {
1730
+ const context = useContext(Pump);
1731
+ if (!context) {
1732
+ throw new Error("usePumpContext must be used within a PumpProvider");
1733
+ }
1734
+ return context;
1735
+ };
1736
+ export {
1737
+ usePourTarget as $,
1738
+ AssemblyProvider as A,
1739
+ BoardContainerProvider as B,
1740
+ CuiKit as C,
1741
+ DISPENSE_GROUP_BEVERAGE as D,
1742
+ useDefaultCuiKitLifecycle as E,
1743
+ useDeviceAssembly as F,
1744
+ useDeviceAssemblyContext as G,
1745
+ HoldToPourIntentStrategy as H,
1746
+ IngredientContainerProvider as I,
1747
+ useDispenseLifecycle as J,
1748
+ useFlavors as K,
1749
+ useGenericPour as L,
1750
+ useHolder as M,
1751
+ NozzleProvider as N,
1752
+ useHolderContainer as O,
1753
+ PourContext as P,
1754
+ useHolderContainerContext as Q,
1755
+ useHolderContext as R,
1756
+ useIngredient as S,
1757
+ TapOrHoldIntentStrategy as T,
1758
+ useIngredientContainer as U,
1759
+ useIngredientContainerContext as V,
1760
+ useIngredientContext as W,
1761
+ useIngredientPour as X,
1762
+ useNozzle as Y,
1763
+ useNozzleContext as Z,
1764
+ useNozzlePour as _,
1765
+ AvailabilityProvider as a,
1766
+ usePumpContext as a0,
1767
+ withAssembly as a1,
1768
+ withBeverage as a2,
1769
+ withBoard as a3,
1770
+ withBoardContainer as a4,
1771
+ withDeviceAssembly as a5,
1772
+ withGenericPour as a6,
1773
+ withHolder as a7,
1774
+ withHolderContainer as a8,
1775
+ withIngredient as a9,
1776
+ withIngredientContainer as aa,
1777
+ withNozzle as ab,
1778
+ BoardProvider as b,
1779
+ CuiKitWrapper as c,
1780
+ DISPENSE_GROUP_BRAND as d,
1781
+ DISPENSE_GROUP_FLAVOR as e,
1782
+ DeviceAssemblyProvider as f,
1783
+ HoldToPourStrategy as g,
1784
+ HolderContainerProvider as h,
1785
+ HolderProvider as i,
1786
+ IngredientProvider as j,
1787
+ PumpProvider as k,
1788
+ TapToPourIntentStrategy as l,
1789
+ TapToPourStrategy as m,
1790
+ initializeCuiKit as n,
1791
+ useAssemblyContext as o,
1792
+ useAvailability as p,
1793
+ useAvailabilityContext as q,
1794
+ useBeverages as r,
1795
+ useBoard as s,
1796
+ useBoardContainer as t,
1797
+ useAssembly as u,
1798
+ useBoardContainerContext as v,
1799
+ useBoardContext as w,
1800
+ useBrands as x,
1801
+ useCuiKit as y,
1802
+ useCuiKitTimers as z
1803
+ };
1804
+ //# sourceMappingURL=pump-provider-ntLT8vr7.js.map