@wix/himalaya-cli 0.1391.0 → 0.1393.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 (284) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/bookings-v2/src/extensions.d.ts +7 -5
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-bookings.mjs +4 -4
  3. package/dist/cli.mjs +31 -23
  4. package/dist/preview-assets.generated.bin +0 -0
  5. package/guides/sdk-reference.json +4 -4
  6. package/package.json +2 -2
  7. package/templates/beauty-salon/tier5-src/_shared/owner-load-error.ts +115 -12
  8. package/templates/beauty-salon/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  9. package/templates/beauty-salon-owner/dev/index.ts +545 -100
  10. package/templates/beauty-salon-owner/himalaya.content.json +6 -0
  11. package/templates/beauty-salon-owner/tier5-src/_shared/owner-account.ts +6 -2
  12. package/templates/beauty-salon-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  13. package/templates/beauty-salon-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  14. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  15. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  16. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  17. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  18. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  19. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  20. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  21. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  22. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  23. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  24. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  25. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  26. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  27. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  28. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  29. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  30. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  31. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  32. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  33. package/templates/branded-lite/tier5-src/_shared/owner-load-error.ts +115 -12
  34. package/templates/branded-lite/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  35. package/templates/branded-lite/tier5-src/himi-branded-lite-group/index.ts +24 -24
  36. package/templates/community-club/tier5-src/_shared/owner-load-error.ts +115 -12
  37. package/templates/community-club/tier5-src/himi-branded-lite-group/index.ts +24 -24
  38. package/templates/community-club-owner/dev/index.ts +317 -100
  39. package/templates/community-club-owner/himalaya.content.json +6 -0
  40. package/templates/community-club-owner/tier5-src/_shared/owner-account.ts +6 -2
  41. package/templates/community-club-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  42. package/templates/community-club-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  43. package/templates/community-club-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  44. package/templates/community-club-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  45. package/templates/community-club-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  46. package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  47. package/templates/community-club-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  48. package/templates/community-club-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  49. package/templates/community-club-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  50. package/templates/community-club-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  51. package/templates/community-club-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  52. package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  53. package/templates/community-club-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  54. package/templates/community-club-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  55. package/templates/community-club-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  56. package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  57. package/templates/community-club-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  58. package/templates/community-club-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  59. package/templates/community-club-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  60. package/templates/community-club-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  61. package/templates/events-meetups/tier5-src/_shared/owner-load-error.ts +115 -12
  62. package/templates/events-meetups/tier5-src/himi-branded-lite-group/index.ts +24 -24
  63. package/templates/events-meetups-owner/dev/index.ts +275 -100
  64. package/templates/events-meetups-owner/himalaya.content.json +6 -0
  65. package/templates/events-meetups-owner/tier5-src/_shared/owner-account.ts +6 -2
  66. package/templates/events-meetups-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  67. package/templates/events-meetups-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  68. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  69. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  70. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  71. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  72. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  73. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  74. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  75. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  76. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  77. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  78. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  79. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  80. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  81. package/templates/gym-fitness/tier5-src/_shared/owner-load-error.ts +115 -12
  82. package/templates/gym-fitness/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  83. package/templates/gym-fitness-owner/dev/index.ts +545 -100
  84. package/templates/gym-fitness-owner/himalaya.content.json +6 -0
  85. package/templates/gym-fitness-owner/tier5-src/_shared/owner-account.ts +6 -2
  86. package/templates/gym-fitness-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  87. package/templates/gym-fitness-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  88. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  89. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  90. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  91. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  92. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  93. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  94. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  95. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  96. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  97. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  98. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  99. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  100. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  101. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  102. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  103. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  104. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  105. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  106. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  107. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  108. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  109. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  110. package/templates/himi-chat/tier5-src/_shared/owner-load-error.ts +115 -12
  111. package/templates/nonprofit-cause/tier5-src/_shared/owner-load-error.ts +115 -12
  112. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-group/index.ts +24 -24
  113. package/templates/nonprofit-cause-owner/dev/index.ts +503 -100
  114. package/templates/nonprofit-cause-owner/himalaya.content.json +6 -0
  115. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-account.ts +6 -2
  116. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  117. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  118. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  119. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  120. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  121. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  122. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  123. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  124. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  125. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  126. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  127. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  128. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  129. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  130. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  131. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  132. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  133. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  134. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  135. package/templates/owner-lite/dev/index.ts +545 -100
  136. package/templates/owner-lite/himalaya.content.json +6 -0
  137. package/templates/owner-lite/tier5-src/_shared/owner-account.ts +6 -2
  138. package/templates/owner-lite/tier5-src/_shared/owner-booking-respond.ts +82 -0
  139. package/templates/owner-lite/tier5-src/_shared/owner-load-error.ts +115 -12
  140. package/templates/owner-lite/tier5-src/himi-owner-lite-account/index.ts +7 -4
  141. package/templates/owner-lite/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  142. package/templates/owner-lite/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  143. package/templates/owner-lite/tier5-src/himi-owner-lite-event/index.ts +18 -20
  144. package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  145. package/templates/owner-lite/tier5-src/himi-owner-lite-events/index.ts +2 -2
  146. package/templates/owner-lite/tier5-src/himi-owner-lite-home/index.ts +2 -2
  147. package/templates/owner-lite/tier5-src/himi-owner-lite-order/index.ts +3 -3
  148. package/templates/owner-lite/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  149. package/templates/owner-lite/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  150. package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +60 -43
  151. package/templates/owner-lite/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  152. package/templates/owner-lite/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  153. package/templates/owner-lite/tier5-src/himi-owner-lite-product/index.ts +31 -32
  154. package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  155. package/templates/owner-lite/tier5-src/himi-owner-lite-products/index.ts +2 -2
  156. package/templates/owner-lite/tier5-src/himi-owner-lite-service/index.ts +18 -20
  157. package/templates/owner-lite/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  158. package/templates/owner-lite/tier5-src/himi-owner-lite-services/index.ts +2 -2
  159. package/templates/owner-lite/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  160. package/templates/owner-lite/tier5-src/himi-owner-lite-today/index.ts +315 -0
  161. package/templates/owner-lite/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  162. package/templates/podcast-creator/tier5-src/_shared/owner-load-error.ts +115 -12
  163. package/templates/podcast-creator-owner/dev/index.ts +317 -100
  164. package/templates/podcast-creator-owner/himalaya.content.json +6 -0
  165. package/templates/podcast-creator-owner/tier5-src/_shared/owner-account.ts +6 -2
  166. package/templates/podcast-creator-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  167. package/templates/podcast-creator-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  168. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  169. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  170. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  171. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  172. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  173. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  174. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  175. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  176. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  177. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  178. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  179. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  180. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  181. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  182. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  183. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  184. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  185. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  186. package/templates/portfolio-creative/tier5-src/_shared/owner-load-error.ts +115 -12
  187. package/templates/portfolio-creative/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  188. package/templates/portfolio-creative-owner/dev/index.ts +545 -100
  189. package/templates/portfolio-creative-owner/himalaya.content.json +6 -0
  190. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-account.ts +6 -2
  191. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  192. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  193. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  194. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  195. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  196. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  197. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  198. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  199. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  200. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  201. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  202. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  203. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  204. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  205. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  206. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  207. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  208. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  209. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  210. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  211. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  212. package/templates/restaurant/tier5-src/_shared/owner-load-error.ts +115 -12
  213. package/templates/restaurant-owner/dev/index.ts +545 -100
  214. package/templates/restaurant-owner/himalaya.content.json +6 -0
  215. package/templates/restaurant-owner/tier5-src/_shared/owner-account.ts +6 -2
  216. package/templates/restaurant-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  217. package/templates/restaurant-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  218. package/templates/restaurant-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  219. package/templates/restaurant-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  220. package/templates/restaurant-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  221. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  222. package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  223. package/templates/restaurant-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  224. package/templates/restaurant-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  225. package/templates/restaurant-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  226. package/templates/restaurant-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  227. package/templates/restaurant-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  228. package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  229. package/templates/restaurant-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  230. package/templates/restaurant-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  231. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  232. package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  233. package/templates/restaurant-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  234. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  235. package/templates/restaurant-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  236. package/templates/restaurant-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  237. package/templates/restaurant-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  238. package/templates/restaurant-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  239. package/templates/restaurant-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  240. package/templates/retail-store/tier5-src/_shared/owner-load-error.ts +115 -12
  241. package/templates/retail-store/tier5-src/himi-branded-lite-cart/index.ts +52 -28
  242. package/templates/retail-store-owner/dev/index.ts +317 -100
  243. package/templates/retail-store-owner/himalaya.content.json +6 -0
  244. package/templates/retail-store-owner/tier5-src/_shared/owner-account.ts +6 -2
  245. package/templates/retail-store-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  246. package/templates/retail-store-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  247. package/templates/retail-store-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  248. package/templates/retail-store-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  249. package/templates/retail-store-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  250. package/templates/retail-store-owner/tier5-src/himi-owner-lite-order/index.ts +3 -3
  251. package/templates/retail-store-owner/tier5-src/himi-owner-lite-orders/index.ts +2 -2
  252. package/templates/retail-store-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  253. package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  254. package/templates/retail-store-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  255. package/templates/retail-store-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  256. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product/index.ts +31 -32
  257. package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +23 -43
  258. package/templates/retail-store-owner/tier5-src/himi-owner-lite-products/index.ts +2 -2
  259. package/templates/retail-store-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  260. package/templates/retail-store-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  261. package/templates/retail-store-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
  262. package/templates/yoga-studio/tier5-src/_shared/owner-load-error.ts +115 -12
  263. package/templates/yoga-studio-owner/dev/index.ts +503 -100
  264. package/templates/yoga-studio-owner/himalaya.content.json +6 -0
  265. package/templates/yoga-studio-owner/tier5-src/_shared/owner-account.ts +6 -2
  266. package/templates/yoga-studio-owner/tier5-src/_shared/owner-booking-respond.ts +82 -0
  267. package/templates/yoga-studio-owner/tier5-src/_shared/owner-load-error.ts +115 -12
  268. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-account/index.ts +7 -4
  269. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-appointments/index.ts +2 -2
  270. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-ask/live.ts +3 -3
  271. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event/index.ts +18 -20
  272. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +20 -28
  273. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-events/index.ts +2 -2
  274. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-home/index.ts +2 -2
  275. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-overview/index.ts +2 -2
  276. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +60 -43
  277. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post-form/index.ts +10 -23
  278. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-posts/index.ts +2 -2
  279. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service/index.ts +18 -20
  280. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service-form/index.ts +16 -29
  281. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-services/index.ts +2 -2
  282. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-sites/index.ts +2 -2
  283. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-today/index.ts +315 -0
  284. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-wrist/index.ts +42 -15
@@ -10,21 +10,20 @@ import { wixCall } from "@himalaya/wix-site-media";
10
10
  import { wixMediaUrl, WIX_DETAIL_IMAGE } from "../_shared/himi-store.js";
11
11
  import { defineService } from "@himalaya/state";
12
12
  import { getDraftPost, createDraftPost, updateDraftPost, type WixDraftPostWrite, type WixRichContent } from "@himalaya/wix-blog";
13
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo, shouldQueueOwnerWrite } from "../_shared/owner-load-error.js";
13
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError } from "../_shared/owner-load-error.js";
14
14
  import { DEMO_POSTS, DEMO_NOTE, DEMO_SAVE_NOTE, demoRefusalPatch } from "../_shared/owner-preview-demo.js";
15
15
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
16
- import { get as dbGet, upsert as dbUpsert, remove as dbRemove, enqueue as dbEnqueue, type DbEntity } from "../_shared/owner-local-db.js";
16
+ import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
17
17
 
18
18
  // Offline-first (data-offline): owner CRUD is WRITE-BEHIND against the encrypted
19
- // `owner_posts` entity — cache confirmed writes, or enqueue offline edits for
20
- // replay on reconnect. Failed cover imports must not appear as saved drafts.
19
+ // `owner_posts` entity — cache confirmed writes only; a failed save says nothing was
20
+ // saved (no host replays a queue). Failed cover imports must not appear as saved drafts.
21
21
  // Every local-db call is wrapped (try/catch) so a build that ships without the
22
22
  // `local_database` grant behaves exactly as before (online-only, no cache/queue).
23
23
  const ENTITY = "owner_posts";
24
24
  async function cachePut(row: DbEntity): Promise<void> { try { await dbUpsert(ENTITY, row); } catch { /* capability not granted */ } }
25
25
  async function cacheDrop(id: string): Promise<void> { try { await dbRemove(ENTITY, id); } catch { /* capability not granted */ } }
26
26
  async function cacheGet(id: string): Promise<DbEntity | null> { try { return await dbGet(ENTITY, id); } catch { return null; } }
27
- async function queueWrite(actionId: string, params: Record<string, string>): Promise<void> { try { await dbEnqueue(actionId, params); } catch { /* capability not granted */ } }
28
27
 
29
28
  type Mode = "create" | "edit";
30
29
 
@@ -223,7 +222,7 @@ const svc = defineService<PostFormState, {
223
222
  status: "idle", error: "", savedMessage: "",
224
223
  });
225
224
  }
226
- if (isBridgeUnavailable(e)) {
225
+ if (ownerDemoFallback(e)) {
227
226
  const d = DEMO_POSTS.find((x) => x.id === id);
228
227
  if (d) {
229
228
  return shape({
@@ -342,23 +341,11 @@ const svc = defineService<PostFormState, {
342
341
  await cachePut(localRow(id));
343
342
  return savedState(id, editing ? copyParam("ownerPostForm.updatedMessage", "Post updated.") : copyParam("ownerPostForm.createdMessage", "Draft created."));
344
343
  } catch (e) {
345
- if (shouldQueueOwnerWrite(e)) {
346
- // Demo / web-preview (no owner bridge; the record came from demo sample
347
- // data, marked by demoNote): a queued write could never replay, so answer
348
- // with the demo save note instead of the real-offline write-behind.
349
- if (s.demoNote) return demoRefusal(s);
350
- // Real device offline: cache and queue the edit for reconnect. `preserveBody` stays
351
- // "true" even for a body edit, so a bundle rolled back past this change keeps the stored
352
- // body rather than flattening it to text. This bundle replays `richContentJson`.
353
- await cachePut(localRow(localId));
354
- await queueWrite("tier5.himiOwnerLitePostForm.submit", {
355
- id: targetId, title, excerpt, coverUrl, coverChanged: String(coverChanged), preserveBody: "true",
356
- body: postBodyText(kept), ...(bodyEdited ? { richContentJson: bodyRaw } : {}),
357
- isFeatured: String(isFeatured), mode: editing ? "edit" : "create",
358
- });
359
- return savedState(localId, copyParam("ownerPostForm.savedOffline", "Saved offline — will sync when you reconnect."));
360
- }
361
- return shape({ ...s, status: "error", error: ownerLoadError(e), savedMessage: "" });
344
+ // Demo / web-preview: the record came from demo sample data (marked by demoNote).
345
+ if (s.demoNote) return demoRefusal(s);
346
+ // Never "saved offline": nothing replays a queued write on any platform. The
347
+ // typed values stay in the form (the body in its editor), so a retry is one tap.
348
+ return shape({ ...s, title, excerpt, coverUrl, isFeatured: isFeatured ? "true" : "false", status: "error", error: ownerWriteError(e), savedMessage: "" });
362
349
  }
363
350
  })()),
364
351
  },
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { defineService } from "../_shared/collection-service.js";
6
6
  import { queryPosts, queryDraftPosts } from "@himalaya/wix-blog";
7
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
7
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
8
8
  import { DEMO_POSTS, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
9
9
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
10
10
  import { getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
@@ -227,7 +227,7 @@ async function loadList(s: PostsState): Promise<PostsState> {
227
227
  } catch (e) {
228
228
  // Offline / fetch failure: keep the last-synced cache BEFORE the demo/error fallbacks.
229
229
  if (cached.length) return base;
230
- if (isBridgeUnavailable(e)) return demoList(s);
230
+ if (ownerDemoFallback(e)) return demoList(s);
231
231
  return shape({ ...s, status: "error", allPosts: [], posts: [], error: ownerLoadError(e) });
232
232
  }
233
233
  }
@@ -7,24 +7,22 @@
7
7
  import { defineService } from "@himalaya/state";
8
8
  import { getProduct, updateProduct, deleteProduct, type WixProduct } from "@himalaya/wix-stores";
9
9
  import { plainText, productImage, wixMediaUrl, WIX_DETAIL_IMAGE, type StoreProduct } from "../_shared/himi-store.js";
10
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo, shouldQueueOwnerWrite } from "../_shared/owner-load-error.js";
10
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError, isNotFound } from "../_shared/owner-load-error.js";
11
11
  import { DEMO_PRODUCTS, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
12
12
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
13
- import { get as dbGet, upsert as dbUpsert, remove as dbRemove, enqueue as dbEnqueue, type DbEntity } from "../_shared/owner-local-db.js";
13
+ import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
14
14
  import { blankFlags } from "../_shared/detail-facts.js";
15
15
 
16
- // Offline-first (data-offline): owner CRUD is WRITE-BEHIND against the encrypted
17
- // `owner_products` entity — the local store is updated OPTIMISTICALLY so the
18
- // detail/list repaint from cache immediately, then the Wix write is attempted; if
19
- // it can't reach the bridge/network the mutation is ENQUEUED for replay on
20
- // reconnect, and detail reads fall back to the last-synced local row. Every
21
- // local-db call is wrapped (try/catch) so a build that ships without the
22
- // `local_database` grant behaves exactly as before (online-only, no cache/queue).
16
+ // Offline-first (data-offline): detail reads fall back to the last-synced local row
17
+ // of the encrypted `owner_products` entity. Writes are SERVER-CONFIRMED: the local
18
+ // row changes only after Wix accepts the write; a failed one leaves it alone and
19
+ // tells the owner why. No host replays a queued write, so nothing is queued.
20
+ // Every local-db call is wrapped (try/catch) so a build that ships without the
21
+ // `local_database` grant behaves exactly as before (online-only, no cache).
23
22
  const ENTITY = "owner_products";
24
23
  async function cachePut(row: DbEntity): Promise<void> { try { await dbUpsert(ENTITY, row); } catch { /* capability not granted */ } }
25
24
  async function cacheDrop(id: string): Promise<void> { try { await dbRemove(ENTITY, id); } catch { /* capability not granted */ } }
26
25
  async function cacheGet(id: string): Promise<DbEntity | null> { try { return await dbGet(ENTITY, id); } catch { return null; } }
27
- async function queueWrite(actionId: string, params: Record<string, string>): Promise<void> { try { await dbEnqueue(actionId, params); } catch { /* capability not granted */ } }
28
26
 
29
27
  interface ProductState {
30
28
  id: string;
@@ -265,19 +263,21 @@ async function setVisibility(s: ProductState, visible: boolean, msg: string): Pr
265
263
  : copyParam("ownerProduct.alreadyHidden", "Already hidden."),
266
264
  });
267
265
  }
268
- // Optimistic local write — the detail/list repaint from cache immediately.
269
- const optimistic = shape({ ...s, visibleRaw: visible, statusLabel: visible ? "Visible in store" : "Hidden", subtitle: visible ? "Visible in store" : "Hidden from store", actionMessage: msg });
270
- await cachePut(cacheRow(optimistic));
271
266
  try {
272
267
  await updateProduct(s.id, { visible });
273
- return refresh(s, s.id, msg);
274
268
  } catch (e) {
275
- if (shouldQueueOwnerWrite(e)) {
276
- // Offline / no bridge: queue the visibility write to replay on reconnect.
277
- await queueWrite("tier5.himiOwnerLiteProduct." + (visible ? "show" : "hide"), { id: s.id });
278
- return shape({ ...optimistic, actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
279
- }
280
- return shape({ ...s, actionMessage: ownerLoadError(e) });
269
+ // Nothing replays a queued write: the record is as it was, and the owner is told why.
270
+ return shape({ ...s, actionMessage: ownerWriteError(e) });
271
+ }
272
+ // Wix confirmed it: the list repaints from cache at once, and a re-read that fails
273
+ // afterwards still shows the confirmed change rather than undoing it on screen.
274
+ const confirmed = shape({ ...s, visibleRaw: visible, statusLabel: visible ? "Visible in store" : "Hidden", subtitle: visible ? "Visible in store" : "Hidden from store", actionMessage: msg });
275
+ await cachePut(cacheRow(confirmed));
276
+ try {
277
+ const next = await refresh(s, s.id, msg);
278
+ return next.status === "error" ? confirmed : next;
279
+ } catch {
280
+ return confirmed;
281
281
  }
282
282
  }
283
283
 
@@ -321,9 +321,10 @@ const svc = defineService<ProductState, {
321
321
  return await refresh(shape({ ...s, id, status: "loading" }), id);
322
322
  } catch (e) {
323
323
  // Offline: fall back to the last-synced local row before the demo/error paths.
324
- const cached = await cacheGet(id);
324
+ // Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
325
+ const cached = isNotFound(e) ? (await cacheDrop(id), null) : await cacheGet(id);
325
326
  if (cached) return cachedDetail(s, cached);
326
- if (isBridgeUnavailable(e)) {
327
+ if (ownerDemoFallback(e)) {
327
328
  const demo = demoDetail(s, id);
328
329
  if (demo) return demo;
329
330
  }
@@ -342,9 +343,10 @@ const svc = defineService<ProductState, {
342
343
  try {
343
344
  return await refresh(shape({ ...s, status: "loading" }), s.id);
344
345
  } catch (e) {
345
- const cached = await cacheGet(s.id);
346
+ // Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
347
+ const cached = isNotFound(e) ? (await cacheDrop(s.id), null) : await cacheGet(s.id);
346
348
  if (cached) return cachedDetail(s, cached);
347
- if (isBridgeUnavailable(e)) {
349
+ if (ownerDemoFallback(e)) {
348
350
  const demo = demoDetail(s, s.id);
349
351
  if (demo) return demo;
350
352
  }
@@ -368,18 +370,15 @@ const svc = defineService<ProductState, {
368
370
  const s = disarm(s0);
369
371
  if (isOwnerPreviewDemo() || s.demoNote) return shape({ ...s, actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
370
372
  if (!s.id) return shape({ ...s, actionMessage: copyParam("ownerProduct.noIdMessage", "No product id.") });
371
- // Optimistic local delete — the list drops the row immediately.
372
- await cacheDrop(s.id);
373
373
  try {
374
374
  await deleteProduct(s.id);
375
- return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerProduct.deletedEmpty", "Product deleted."), actionMessage: "" });
376
375
  } catch (e) {
377
- if (shouldQueueOwnerWrite(e)) {
378
- await queueWrite("tier5.himiOwnerLiteProduct.delete", { id: s.id });
379
- return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerProduct.deletedEmpty", "Product deleted."), actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
380
- }
381
- return shape({ ...s, actionMessage: ownerLoadError(e) });
376
+ // Nothing replays a queued write: the record stays, and the owner is told why.
377
+ return shape({ ...s, actionMessage: ownerWriteError(e) });
382
378
  }
379
+ // Only a delete Wix confirmed leaves the local list.
380
+ await cacheDrop(s.id);
381
+ return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerProduct.deletedEmpty", "Product deleted."), actionMessage: "" });
383
382
  } finally {
384
383
  deleteInFlight = false;
385
384
  }
@@ -15,29 +15,28 @@ import {
15
15
  type WixProduct,
16
16
  type WixProductWrite,
17
17
  } from "@himalaya/wix-stores";
18
- import { get as dbGet, upsert as dbUpsert, remove as dbRemove, enqueue as dbEnqueue, type DbEntity } from "../_shared/owner-local-db.js";
18
+ import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
19
19
  import { htmlIsTrivial, htmlPreviewText } from "../_shared/owner-rich-guard.js";
20
20
  import { postBodyText, plainPostBody } from "../_shared/owner-post-content.js";
21
21
  import { editorSubmitValue, queuedDocument, editorChanged, cachedRichVerdict, editorRunKeys, resetHydratedEditorOnOlderRuntime, editorAfterSave, liveState, settleOverLive } from "../_shared/owner-editor-value.js";
22
22
  import { parseRicosJson } from "@himalaya/wix-rich-content";
23
23
  import { ricosUploadService } from "@himalaya/wix-rich-content-editor";
24
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo, shouldQueueOwnerWrite } from "../_shared/owner-load-error.js";
24
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError } from "../_shared/owner-load-error.js";
25
25
  import { DEMO_PRODUCTS, DEMO_NOTE, DEMO_SAVE_NOTE, demoRefusalPatch, editablePrice } from "../_shared/owner-preview-demo.js";
26
26
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
27
27
 
28
28
  type Mode = "create" | "edit";
29
29
 
30
- // Offline-first (data-offline): owner CRUD is WRITE-BEHIND against the encrypted
31
- // `owner_products` entity — the local store is updated OPTIMISTICALLY so the list
32
- // repaints from cache immediately, then the Wix write is attempted; if it can't
33
- // reach the bridge/network the mutation is ENQUEUED for replay on reconnect. Every
34
- // local-db call is wrapped (try/catch) so a build that ships without the
35
- // `local_database` grant behaves exactly as before (online-only, no cache/queue).
30
+ // Offline-first (data-offline): writes to the encrypted `owner_products` entity are
31
+ // SERVER-CONFIRMED — the list's local row changes only after Wix accepts the save;
32
+ // a failed one leaves it alone, keeps the form, and tells the owner why. No host
33
+ // replays a queued write, so nothing is queued.
34
+ // Every local-db call is wrapped (try/catch) so a build that ships without the
35
+ // `local_database` grant behaves exactly as before (online-only, no cache).
36
36
  const ENTITY = "owner_products";
37
37
  async function cachePut(row: DbEntity): Promise<void> { try { await dbUpsert(ENTITY, row); } catch { /* capability not granted */ } }
38
38
  async function cacheDrop(id: string): Promise<void> { try { await dbRemove(ENTITY, id); } catch { /* capability not granted */ } }
39
39
  async function cacheGet(id: string): Promise<DbEntity | null> { try { return await dbGet(ENTITY, id); } catch { return null; } }
40
- async function queueWrite(actionId: string, params: Record<string, string>): Promise<void> { try { await dbEnqueue(actionId, params); } catch { /* capability not granted */ } }
41
40
 
42
41
  // The store's currency — the Apptestersite detail view shows € prices.
43
42
  const CURRENCY = "EUR";
@@ -268,7 +267,7 @@ const svc = defineService<ProductFormState, {
268
267
  status: "idle", error: "", savedMessage: "",
269
268
  });
270
269
  }
271
- if (isBridgeUnavailable(e)) {
270
+ if (ownerDemoFallback(e)) {
272
271
  const d = DEMO_PRODUCTS.find((p) => p.id === id);
273
272
  if (d) {
274
273
  return shape({
@@ -356,7 +355,7 @@ const svc = defineService<ProductFormState, {
356
355
  const knownPlain = s.descriptionMode === "plain" || (s.descriptionMode === "editor" && !s.descriptionPending && s.descriptionJson === "");
357
356
  const descriptionProtected = cachedRichVerdict(heldDoc as never, knownPlain);
358
357
 
359
- // Optimistic local write — the list repaints from cache immediately (offline or not).
358
+ // The row the cache gets once Wix accepts the save.
360
359
  // Replay starts with default worker state. An untouched description was omitted from the
361
360
  // queued PATCH, so retain its cached mirror/document/verdict when replacing the local row.
362
361
  const cached = replay && targetId ? await cacheGet(targetId) : null;
@@ -380,7 +379,6 @@ const svc = defineService<ProductFormState, {
380
379
  return { descriptionDirty: a.dirty, descriptionEdits: a.edits, ...(a.editedDuringSave ? { status: "idle" as const, savedMessage: "" } : {}) };
381
380
  };
382
381
  const localId = mode === "edit" && targetId ? targetId : `local-${Date.now()}`;
383
- await cachePut(localRow(localId));
384
382
  try {
385
383
  let id = targetId;
386
384
  if (mode === "edit" && targetId) {
@@ -388,9 +386,9 @@ const svc = defineService<ProductFormState, {
388
386
  } else {
389
387
  const r = await createProduct(write);
390
388
  id = r.product?.id || localId;
391
- // Reconcile the optimistic local id with the server-assigned id.
392
- if (id !== localId) { await cacheDrop(localId); await cachePut(localRow(id)); }
393
389
  }
390
+ // The local row follows only what Wix confirmed, under the id Wix assigned.
391
+ await cachePut(localRow(id));
394
392
  return shape({
395
393
  ...s,
396
394
  mode: "edit",
@@ -407,44 +405,26 @@ const svc = defineService<ProductFormState, {
407
405
  ...afterSaved(),
408
406
  });
409
407
  } catch (e) {
410
- if (shouldQueueOwnerWrite(e)) {
411
- // Demo / web-preview (no owner bridge; the record came from DEMO_PRODUCTS,
412
- // marked by demoNote): a queued write could never replay, so answer with
413
- // the demo save note instead of the real-offline write-behind.
414
- if (s.demoNote) return demoRefusal(s);
415
- // Real device offline: the optimistic cache row already shows; queue the
416
- // write to replay (WriteQueue, idempotent) when connectivity returns.
417
- // A document rides as `descriptionJson` with descriptionEdited "false", so a bundle rolled back
418
- // past this change leaves the description rather than flattening it to text.
419
- await queueWrite("tier5.himiOwnerLiteProductForm.submit", { id: targetId, name, price, sku, description, visible: String(visible), mode,
420
- ...(docRaw ? { descriptionJson: docRaw, descriptionEdited: "false" } : { descriptionEdited: String(descriptionEdited) }) });
421
- return shape({
422
- ...s, mode: "edit", id: localId, name, price, sku, ...savedDescription,
423
- visible: visible ? "true" : "false", status: "saved",
424
- savedMessage: copyParam("ownerProductForm.savedOffline", "Saved offline — will sync when you reconnect."),
425
- savedId: localId,
426
- ...afterSaved(),
427
- });
428
- }
429
- return shape({ ...s, status: "error", error: ownerLoadError(e), savedMessage: "" });
408
+ // Never "saved offline": nothing replays a queued write on any platform. The cache was
409
+ // not touched, and the typed values stay in the form (the description in its editor) so
410
+ // a retry is one tap.
411
+ // Demo / web-preview: the record came from DEMO_PRODUCTS (marked by demoNote).
412
+ if (s.demoNote) return demoRefusal(s);
413
+ return shape({ ...s, name, price, sku, ...(s.descriptionMode === "editor" ? {} : { description }), visible: visible ? "true" : "false", status: "error", error: ownerWriteError(e), savedMessage: "" });
430
414
  }
431
415
  })()),
432
416
  remove: async (s) => {
433
417
  if (isOwnerPreviewDemo() || s.demoNote) return demoRefusal(s);
434
418
  if (!s.id) return shape({ ...s, status: "error", error: copyParam("ownerProductForm.errorNoDelete", "No product to delete."), savedMessage: "" });
435
- // Optimistic local delete — the list drops the row immediately.
436
- await cacheDrop(s.id);
437
419
  try {
438
420
  await deleteProduct(s.id);
439
- return shape({ ...s, id: "", status: "saved", error: "", savedMessage: copyParam("ownerProductForm.deletedMessage", "Product deleted."), savedId: "" });
440
421
  } catch (e) {
441
- if (shouldQueueOwnerWrite(e)) {
442
- if (s.demoNote) return demoRefusal(s);
443
- await queueWrite("tier5.himiOwnerLiteProductForm.remove", { id: s.id });
444
- return shape({ ...s, id: "", status: "saved", error: "", savedMessage: copyParam("ownerProductForm.deletedOffline", "Deleted offline — will sync when you reconnect."), savedId: "" });
445
- }
446
- return shape({ ...s, status: "error", error: ownerLoadError(e), savedMessage: "" });
422
+ // Nothing replays a queued delete: the row stays, and the owner is told why.
423
+ return shape({ ...s, status: "error", error: ownerWriteError(e), savedMessage: "" });
447
424
  }
425
+ // Only a delete Wix confirmed leaves the local list.
426
+ await cacheDrop(s.id);
427
+ return shape({ ...s, id: "", status: "saved", error: "", savedMessage: copyParam("ownerProductForm.deletedMessage", "Product deleted."), savedId: "" });
448
428
  },
449
429
  },
450
430
  });
@@ -7,7 +7,7 @@
7
7
  import { compareText } from "../_shared/engine-intl.js";
8
8
  import { defineBackendCollection } from "../_shared/collection-service.js";
9
9
  import { searchStoreProducts, productImage, productPrice, plainText, type StoreProduct } from "../_shared/himi-store.js";
10
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
10
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
11
11
  import { DEMO_PRODUCTS, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
12
12
  import { copyParam } from "../_shared/himi-copy.js";
13
13
  import { getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
@@ -191,7 +191,7 @@ const svc = defineBackendCollection("himiOwnerLiteProducts", {
191
191
  const items = (await readCachedRows()).filter(item => !!item.id);
192
192
  if (items.length) return { items, nextCursor: "", complete: false, metadata: { fromCache: true, demoNote: "" } };
193
193
  }
194
- if (!cursor && isBridgeUnavailable(error)) return demoPage();
194
+ if (!cursor && ownerDemoFallback(error)) return demoPage();
195
195
  throw error;
196
196
  }
197
197
  },
@@ -7,25 +7,24 @@
7
7
 
8
8
  import { defineService } from "@himalaya/state";
9
9
  import { getService, deleteService, type WixService } from "@himalaya/wix-bookings";
10
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo, shouldQueueOwnerWrite } from "../_shared/owner-load-error.js";
10
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError, isNotFound } from "../_shared/owner-load-error.js";
11
11
  import { DEMO_SERVICES, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
12
12
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
13
- import { get as dbGet, remove as dbRemove, enqueue as dbEnqueue, type DbEntity } from "../_shared/owner-local-db.js";
13
+ import { get as dbGet, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
14
14
  import { wixMediaUrl, WIX_DETAIL_IMAGE } from "@himalaya/wix-media";
15
15
  import { blankFlags } from "../_shared/detail-facts.js";
16
16
 
17
17
  // Offline-first (data-offline): the service DETAIL falls back to the last-synced
18
- // local `owner_services` row (put by the service form's write-behind) on a failed
19
- // fetch, and its delete is WRITE-BEHIND — the local row is dropped OPTIMISTICALLY,
20
- // then deleteService is attempted; if the bridge/network is unreachable the delete
21
- // is ENQUEUED for replay on reconnect. Every local-db call is wrapped so a build
22
- // without the `local_database` grant behaves exactly as before (online-only).
18
+ // local `owner_services` row on a failed fetch. Its delete is SERVER-CONFIRMED: the
19
+ // local row is dropped only after Wix deletes the service; a failed delete leaves it
20
+ // and tells the owner why. No host replays a queued write, so nothing is queued.
21
+ // Every local-db call is wrapped so a build without the `local_database` grant
22
+ // behaves exactly as before (online-only).
23
23
  const ENTITY = "owner_services";
24
24
 
25
25
 
26
26
  async function cacheDrop(id: string): Promise<void> { try { await dbRemove(ENTITY, id); } catch { /* capability not granted */ } }
27
27
  async function cacheGet(id: string): Promise<DbEntity | null> { try { return await dbGet(ENTITY, id); } catch { return null; } }
28
- async function queueWrite(actionId: string, params: Record<string, string>): Promise<void> { try { await dbEnqueue(actionId, params); } catch { /* capability not granted */ } }
29
28
 
30
29
  interface ServiceState {
31
30
  id: string;
@@ -238,9 +237,10 @@ const svc = defineService<ServiceState, {
238
237
  return await refresh(shape({ ...s, id, status: "loading" }), id);
239
238
  } catch (e) {
240
239
  // Offline: fall back to the last-synced local row before the demo/error paths.
241
- const cached = await cacheGet(id);
240
+ // Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
241
+ const cached = isNotFound(e) ? (await cacheDrop(id), null) : await cacheGet(id);
242
242
  if (cached) return cachedDetail(s, cached);
243
- if (isBridgeUnavailable(e)) {
243
+ if (ownerDemoFallback(e)) {
244
244
  const demo = demoDetail(s, id);
245
245
  if (demo) return demo;
246
246
  }
@@ -258,9 +258,10 @@ const svc = defineService<ServiceState, {
258
258
  try {
259
259
  return await refresh(shape({ ...s, status: "loading" }), s.id);
260
260
  } catch (e) {
261
- const cached = await cacheGet(s.id);
261
+ // Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
262
+ const cached = isNotFound(e) ? (await cacheDrop(s.id), null) : await cacheGet(s.id);
262
263
  if (cached) return cachedDetail(s, cached);
263
- if (isBridgeUnavailable(e)) {
264
+ if (ownerDemoFallback(e)) {
264
265
  const demo = demoDetail(s, s.id);
265
266
  if (demo) return demo;
266
267
  }
@@ -270,18 +271,15 @@ const svc = defineService<ServiceState, {
270
271
  delete: async (s) => {
271
272
  if (isOwnerPreviewDemo() || s.demoNote) return shape({ ...s, actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
272
273
  if (!s.id) return shape({ ...s, actionMessage: copyParam("ownerService.noIdMessage", "No service id.") });
273
- // Optimistic local delete — the list drops the row immediately.
274
- await cacheDrop(s.id);
275
274
  try {
276
275
  await deleteService(s.id);
277
- return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerService.deletedEmpty", "Service deleted."), actionMessage: "" });
278
276
  } catch (e) {
279
- if (shouldQueueOwnerWrite(e)) {
280
- await queueWrite("tier5.himiOwnerLiteService.delete", { id: s.id });
281
- return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerService.deletedEmpty", "Service deleted."), actionMessage: copyParam("ownerCommon.demoSaveNote", DEMO_SAVE_NOTE) });
282
- }
283
- return shape({ ...s, actionMessage: ownerLoadError(e) });
277
+ // Nothing replays a queued write: the record stays, and the owner is told why.
278
+ return shape({ ...s, actionMessage: ownerWriteError(e) });
284
279
  }
280
+ // Only a delete Wix confirmed leaves the local list.
281
+ await cacheDrop(s.id);
282
+ return shape({ ...s, status: "deleted", title: "", emptyText: copyParam("ownerService.deletedEmpty", "Service deleted."), actionMessage: "" });
285
283
  },
286
284
  },
287
285
  });
@@ -6,22 +6,20 @@
6
6
 
7
7
  import { defineService } from "@himalaya/state";
8
8
  import { getService, updateService, type WixService } from "@himalaya/wix-bookings";
9
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo, shouldQueueOwnerWrite } from "../_shared/owner-load-error.js";
9
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError } from "../_shared/owner-load-error.js";
10
10
  import { DEMO_SERVICES, DEMO_NOTE, DEMO_SAVE_NOTE, demoRefusalPatch } from "../_shared/owner-preview-demo.js";
11
11
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
12
- import { get as dbGet, upsert as dbUpsert, enqueue as dbEnqueue, type DbEntity } from "../_shared/owner-local-db.js";
12
+ import { get as dbGet, upsert as dbUpsert, type DbEntity } from "../_shared/owner-local-db.js";
13
13
 
14
- // Offline-first (data-offline): the service edit is WRITE-BEHIND against the
15
- // encrypted `owner_services` entity — the local store is updated OPTIMISTICALLY so
16
- // the detail/list repaint from cache immediately, then updateService is attempted;
17
- // if it can't reach the bridge/network the write is ENQUEUED for replay on
18
- // reconnect, and load prefills from the last-synced local row when offline. Every
19
- // local-db call is wrapped (try/catch) so a build that ships without the
20
- // `local_database` grant behaves exactly as before (online-only, no cache/queue).
14
+ // Offline-first (data-offline): load prefills from the last-synced local
15
+ // `owner_services` row when offline, and the edit is SERVER-CONFIRMED — the local
16
+ // row changes only after Wix accepts it; a failed save leaves it alone, keeps the
17
+ // form, and tells the owner why. No host replays a queued write, so nothing is queued.
18
+ // Every local-db call is wrapped (try/catch) so a build that ships without the
19
+ // `local_database` grant behaves exactly as before (online-only, no cache).
21
20
  const ENTITY = "owner_services";
22
21
  async function cachePut(row: DbEntity): Promise<void> { try { await dbUpsert(ENTITY, row); } catch { /* capability not granted */ } }
23
22
  async function cacheGet(id: string): Promise<DbEntity | null> { try { return await dbGet(ENTITY, id); } catch { return null; } }
24
- async function queueWrite(actionId: string, params: Record<string, string>): Promise<void> { try { await dbEnqueue(actionId, params); } catch { /* capability not granted */ } }
25
23
 
26
24
  interface ServiceFormState {
27
25
  mode: "edit";
@@ -156,7 +154,7 @@ const svc = defineService<ServiceFormState, {
156
154
  status: "idle", error: "", savedMessage: "",
157
155
  });
158
156
  }
159
- if (isBridgeUnavailable(e)) {
157
+ if (ownerDemoFallback(e)) {
160
158
  const d = DEMO_SERVICES.find((x) => x.id === id);
161
159
  if (d) {
162
160
  return shape({
@@ -178,10 +176,8 @@ const svc = defineService<ServiceFormState, {
178
176
  if (!name) return shape({ ...s, status: "error", error: copyParam("ownerServiceForm.nameRequired", "Name is required"), savedMessage: "" });
179
177
  if (!targetId) return shape({ ...s, status: "error", error: copyParam("ownerServiceForm.errorNoService", "No service to edit."), savedMessage: "" });
180
178
 
181
- // Optimistic local write — the detail/list repaint from cache immediately (offline or not).
182
179
  const cached = !s.id ? await cacheGet(targetId) : null;
183
180
  const localRow: DbEntity = { ...(cached ?? {}), id: targetId, name, title: name, description, category: s.category || String(cached?.category ?? "") };
184
- await cachePut(localRow);
185
181
  try {
186
182
  // v2 PATCH is a masked update requiring the current `revision` (optimistic
187
183
  // concurrency), captured from the getService on load. The response wraps
@@ -190,6 +186,8 @@ const svc = defineService<ServiceFormState, {
190
186
  // load-time revision and reject.
191
187
  const res = await updateService(targetId, { name, ...(description ? { description } : {}), ...(s.revision ? { revision: s.revision } : {}) });
192
188
  const bumped = String((res?.service as { revision?: unknown } | undefined)?.revision ?? "");
189
+ // The local row follows only what Wix confirmed.
190
+ await cachePut(localRow);
193
191
  return shape({
194
192
  ...s, id: targetId, name, description,
195
193
  revision: bumped || s.revision,
@@ -197,22 +195,11 @@ const svc = defineService<ServiceFormState, {
197
195
  savedId: targetId,
198
196
  });
199
197
  } catch (e) {
200
- if (shouldQueueOwnerWrite(e)) {
201
- // Demo / web-preview (no owner bridge; the record came from demo sample
202
- // data, marked by demoNote): a queued write could never replay, so answer
203
- // with the demo save note instead of the real-offline write-behind.
204
- if (s.demoNote) return demoRefusal(s);
205
- // Real device offline: the optimistic cache row already shows; queue the
206
- // write to replay (WriteQueue, idempotent) when connectivity returns.
207
- await queueWrite("tier5.himiOwnerLiteServiceForm.submit", { id: targetId, name, description });
208
- return shape({
209
- ...s, id: targetId, name, description,
210
- status: "saved", error: "",
211
- savedMessage: copyParam("ownerServiceForm.savedOffline", "Saved offline — will sync when you reconnect."),
212
- savedId: targetId,
213
- });
214
- }
215
- return shape({ ...s, status: "error", error: ownerLoadError(e), savedMessage: "" });
198
+ // Never "saved offline": nothing replays a queued write on any platform. The cache was
199
+ // not touched, and the typed values stay in the form so a retry is one tap.
200
+ // Demo / web-preview: the record came from demo sample data (marked by demoNote).
201
+ if (s.demoNote) return demoRefusal(s);
202
+ return shape({ ...s, name, description, status: "error", error: ownerWriteError(e), savedMessage: "" });
216
203
  }
217
204
  },
218
205
  },
@@ -5,7 +5,7 @@
5
5
  import { defineBackendCollection } from "../_shared/collection-service.js";
6
6
  import { offsetPage } from "../_shared/offset-page.js";
7
7
  import { queryServices, type WixService } from "@himalaya/wix-bookings";
8
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
8
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
9
9
  import { DEMO_SERVICES, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
10
10
  import { copyParam } from "../_shared/himi-copy.js";
11
11
  import { getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
@@ -171,7 +171,7 @@ const svc = defineBackendCollection("himiOwnerLiteServices", {
171
171
  const cached = await readCachedRows();
172
172
  if (cached.length) return { items: cached, nextCursor: "", complete: false, metadata: { fromCache: true } };
173
173
  }
174
- if (!cursor && isBridgeUnavailable(error)) return demo();
174
+ if (!cursor && ownerDemoFallback(error)) return demo();
175
175
  throw error;
176
176
  }
177
177
  },
@@ -8,7 +8,7 @@
8
8
 
9
9
  import { defineService } from "@himalaya/state";
10
10
  import { querySites, type WixSite } from "@himalaya/wix-site-list";
11
- import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
11
+ import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
12
12
  import { DEMO_SITES, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
13
13
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
14
14
  import { getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
@@ -165,7 +165,7 @@ async function loadList(s: SitesState): Promise<SitesState> {
165
165
  } catch (e) {
166
166
  // Offline / fetch failure: keep the last-synced cache BEFORE the demo/error fallbacks.
167
167
  if (repairedCache.length) return base;
168
- if (isBridgeUnavailable(e)) return demoList(s);
168
+ if (ownerDemoFallback(e)) return demoList(s);
169
169
  return shape({ ...s, status: "error", allSites: [], sites: [], error: ownerLoadError(e) });
170
170
  }
171
171
  }