@entifix/core 0.1.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 (351) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/dist/base-entities/configuration-client/configuration-client-singleton.d.ts +39 -0
  4. package/dist/base-entities/configuration-client/configuration-client-singleton.d.ts.map +1 -0
  5. package/dist/base-entities/configuration-client/configuration-client-singleton.js +164 -0
  6. package/dist/base-entities/configuration-client/configuration-client-singleton.js.map +1 -0
  7. package/dist/base-entities/configuration-client/index.d.ts +4 -0
  8. package/dist/base-entities/configuration-client/index.d.ts.map +1 -0
  9. package/dist/base-entities/configuration-client/index.js +5 -0
  10. package/dist/base-entities/configuration-client/index.js.map +1 -0
  11. package/dist/base-entities/configuration-client/read-configuration-from-process.d.ts +11 -0
  12. package/dist/base-entities/configuration-client/read-configuration-from-process.d.ts.map +1 -0
  13. package/dist/base-entities/configuration-client/read-configuration-from-process.js +26 -0
  14. package/dist/base-entities/configuration-client/read-configuration-from-process.js.map +1 -0
  15. package/dist/base-entities/configuration-client/types.d.ts +38 -0
  16. package/dist/base-entities/configuration-client/types.d.ts.map +1 -0
  17. package/dist/base-entities/configuration-client/types.js +3 -0
  18. package/dist/base-entities/configuration-client/types.js.map +1 -0
  19. package/dist/base-entities/entifix-error/entifix-error.d.ts +31 -0
  20. package/dist/base-entities/entifix-error/entifix-error.d.ts.map +1 -0
  21. package/dist/base-entities/entifix-error/entifix-error.js +56 -0
  22. package/dist/base-entities/entifix-error/entifix-error.js.map +1 -0
  23. package/dist/base-entities/entifix-error/index.d.ts +2 -0
  24. package/dist/base-entities/entifix-error/index.d.ts.map +1 -0
  25. package/dist/base-entities/entifix-error/index.js +3 -0
  26. package/dist/base-entities/entifix-error/index.js.map +1 -0
  27. package/dist/command-palette/command-matching.d.ts +79 -0
  28. package/dist/command-palette/command-matching.d.ts.map +1 -0
  29. package/dist/command-palette/command-matching.js +116 -0
  30. package/dist/command-palette/command-matching.js.map +1 -0
  31. package/dist/command-palette/command-source.d.ts +109 -0
  32. package/dist/command-palette/command-source.d.ts.map +1 -0
  33. package/dist/command-palette/command-source.js +11 -0
  34. package/dist/command-palette/command-source.js.map +1 -0
  35. package/dist/command-palette/index.d.ts +3 -0
  36. package/dist/command-palette/index.d.ts.map +1 -0
  37. package/dist/command-palette/index.js +4 -0
  38. package/dist/command-palette/index.js.map +1 -0
  39. package/dist/entity-definition/decorators/accessor/accessor.d.ts +3 -0
  40. package/dist/entity-definition/decorators/accessor/accessor.d.ts.map +1 -0
  41. package/dist/entity-definition/decorators/accessor/accessor.js +11 -0
  42. package/dist/entity-definition/decorators/accessor/accessor.js.map +1 -0
  43. package/dist/entity-definition/decorators/accessor/index.d.ts +2 -0
  44. package/dist/entity-definition/decorators/accessor/index.d.ts.map +1 -0
  45. package/dist/entity-definition/decorators/accessor/index.js +3 -0
  46. package/dist/entity-definition/decorators/accessor/index.js.map +1 -0
  47. package/dist/entity-definition/decorators/entity/entity.d.ts +4 -0
  48. package/dist/entity-definition/decorators/entity/entity.d.ts.map +1 -0
  49. package/dist/entity-definition/decorators/entity/entity.js +9 -0
  50. package/dist/entity-definition/decorators/entity/entity.js.map +1 -0
  51. package/dist/entity-definition/decorators/entity/index.d.ts +2 -0
  52. package/dist/entity-definition/decorators/entity/index.d.ts.map +1 -0
  53. package/dist/entity-definition/decorators/entity/index.js +3 -0
  54. package/dist/entity-definition/decorators/entity/index.js.map +1 -0
  55. package/dist/entity-definition/decorators/method/index.d.ts +2 -0
  56. package/dist/entity-definition/decorators/method/index.d.ts.map +1 -0
  57. package/dist/entity-definition/decorators/method/index.js +3 -0
  58. package/dist/entity-definition/decorators/method/index.js.map +1 -0
  59. package/dist/entity-definition/decorators/method/method.d.ts +3 -0
  60. package/dist/entity-definition/decorators/method/method.d.ts.map +1 -0
  61. package/dist/entity-definition/decorators/method/method.js +10 -0
  62. package/dist/entity-definition/decorators/method/method.js.map +1 -0
  63. package/dist/entity-definition/decorators/use-case/index.d.ts +2 -0
  64. package/dist/entity-definition/decorators/use-case/index.d.ts.map +1 -0
  65. package/dist/entity-definition/decorators/use-case/index.js +3 -0
  66. package/dist/entity-definition/decorators/use-case/index.js.map +1 -0
  67. package/dist/entity-definition/decorators/use-case/use-case.d.ts +18 -0
  68. package/dist/entity-definition/decorators/use-case/use-case.d.ts.map +1 -0
  69. package/dist/entity-definition/decorators/use-case/use-case.js +26 -0
  70. package/dist/entity-definition/decorators/use-case/use-case.js.map +1 -0
  71. package/dist/entity-definition/describe/describe-child-columns.d.ts +33 -0
  72. package/dist/entity-definition/describe/describe-child-columns.d.ts.map +1 -0
  73. package/dist/entity-definition/describe/describe-child-columns.js +44 -0
  74. package/dist/entity-definition/describe/describe-child-columns.js.map +1 -0
  75. package/dist/entity-definition/describe/describe-entity-columns.d.ts +83 -0
  76. package/dist/entity-definition/describe/describe-entity-columns.d.ts.map +1 -0
  77. package/dist/entity-definition/describe/describe-entity-columns.js +112 -0
  78. package/dist/entity-definition/describe/describe-entity-columns.js.map +1 -0
  79. package/dist/entity-definition/describe/describe-entity-use-cases.d.ts +34 -0
  80. package/dist/entity-definition/describe/describe-entity-use-cases.d.ts.map +1 -0
  81. package/dist/entity-definition/describe/describe-entity-use-cases.js +24 -0
  82. package/dist/entity-definition/describe/describe-entity-use-cases.js.map +1 -0
  83. package/dist/entity-definition/describe/index.d.ts +4 -0
  84. package/dist/entity-definition/describe/index.d.ts.map +1 -0
  85. package/dist/entity-definition/describe/index.js +5 -0
  86. package/dist/entity-definition/describe/index.js.map +1 -0
  87. package/dist/entity-definition/field-path.d.ts +49 -0
  88. package/dist/entity-definition/field-path.d.ts.map +1 -0
  89. package/dist/entity-definition/field-path.js +58 -0
  90. package/dist/entity-definition/field-path.js.map +1 -0
  91. package/dist/entity-definition/helpers/entity-definition-helpers.d.ts +59 -0
  92. package/dist/entity-definition/helpers/entity-definition-helpers.d.ts.map +1 -0
  93. package/dist/entity-definition/helpers/entity-definition-helpers.js +115 -0
  94. package/dist/entity-definition/helpers/entity-definition-helpers.js.map +1 -0
  95. package/dist/entity-definition/helpers/index.d.ts +2 -0
  96. package/dist/entity-definition/helpers/index.d.ts.map +1 -0
  97. package/dist/entity-definition/helpers/index.js +3 -0
  98. package/dist/entity-definition/helpers/index.js.map +1 -0
  99. package/dist/entity-definition/links/apply-entity-links/apply-entity-links.d.ts +48 -0
  100. package/dist/entity-definition/links/apply-entity-links/apply-entity-links.d.ts.map +1 -0
  101. package/dist/entity-definition/links/apply-entity-links/apply-entity-links.js +88 -0
  102. package/dist/entity-definition/links/apply-entity-links/apply-entity-links.js.map +1 -0
  103. package/dist/entity-definition/links/apply-entity-links/index.d.ts +2 -0
  104. package/dist/entity-definition/links/apply-entity-links/index.d.ts.map +1 -0
  105. package/dist/entity-definition/links/apply-entity-links/index.js +3 -0
  106. package/dist/entity-definition/links/apply-entity-links/index.js.map +1 -0
  107. package/dist/entity-definition/links/entity-collection-link/entity-collection-link.d.ts +29 -0
  108. package/dist/entity-definition/links/entity-collection-link/entity-collection-link.d.ts.map +1 -0
  109. package/dist/entity-definition/links/entity-collection-link/entity-collection-link.js +61 -0
  110. package/dist/entity-definition/links/entity-collection-link/entity-collection-link.js.map +1 -0
  111. package/dist/entity-definition/links/entity-collection-link/index.d.ts +2 -0
  112. package/dist/entity-definition/links/entity-collection-link/index.d.ts.map +1 -0
  113. package/dist/entity-definition/links/entity-collection-link/index.js +3 -0
  114. package/dist/entity-definition/links/entity-collection-link/index.js.map +1 -0
  115. package/dist/entity-definition/links/entity-link/entity-link.d.ts +58 -0
  116. package/dist/entity-definition/links/entity-link/entity-link.d.ts.map +1 -0
  117. package/dist/entity-definition/links/entity-link/entity-link.js +79 -0
  118. package/dist/entity-definition/links/entity-link/entity-link.js.map +1 -0
  119. package/dist/entity-definition/links/entity-link/index.d.ts +2 -0
  120. package/dist/entity-definition/links/entity-link/index.d.ts.map +1 -0
  121. package/dist/entity-definition/links/entity-link/index.js +3 -0
  122. package/dist/entity-definition/links/entity-link/index.js.map +1 -0
  123. package/dist/entity-definition/links/entity-link-source/entity-link-source.d.ts +74 -0
  124. package/dist/entity-definition/links/entity-link-source/entity-link-source.d.ts.map +1 -0
  125. package/dist/entity-definition/links/entity-link-source/entity-link-source.js +11 -0
  126. package/dist/entity-definition/links/entity-link-source/entity-link-source.js.map +1 -0
  127. package/dist/entity-definition/links/entity-link-source/index.d.ts +2 -0
  128. package/dist/entity-definition/links/entity-link-source/index.d.ts.map +1 -0
  129. package/dist/entity-definition/links/entity-link-source/index.js +3 -0
  130. package/dist/entity-definition/links/entity-link-source/index.js.map +1 -0
  131. package/dist/entity-definition/meta-entities/meta-accessor/index.d.ts +2 -0
  132. package/dist/entity-definition/meta-entities/meta-accessor/index.d.ts.map +1 -0
  133. package/dist/entity-definition/meta-entities/meta-accessor/index.js +3 -0
  134. package/dist/entity-definition/meta-entities/meta-accessor/index.js.map +1 -0
  135. package/dist/entity-definition/meta-entities/meta-accessor/meta-accessor.d.ts +137 -0
  136. package/dist/entity-definition/meta-entities/meta-accessor/meta-accessor.d.ts.map +1 -0
  137. package/dist/entity-definition/meta-entities/meta-accessor/meta-accessor.js +52 -0
  138. package/dist/entity-definition/meta-entities/meta-accessor/meta-accessor.js.map +1 -0
  139. package/dist/entity-definition/meta-entities/meta-entity/index.d.ts +2 -0
  140. package/dist/entity-definition/meta-entities/meta-entity/index.d.ts.map +1 -0
  141. package/dist/entity-definition/meta-entities/meta-entity/index.js +3 -0
  142. package/dist/entity-definition/meta-entities/meta-entity/index.js.map +1 -0
  143. package/dist/entity-definition/meta-entities/meta-entity/meta-entity.d.ts +17 -0
  144. package/dist/entity-definition/meta-entities/meta-entity/meta-entity.d.ts.map +1 -0
  145. package/dist/entity-definition/meta-entities/meta-entity/meta-entity.js +13 -0
  146. package/dist/entity-definition/meta-entities/meta-entity/meta-entity.js.map +1 -0
  147. package/dist/entity-definition/meta-entities/meta-method/index.d.ts +2 -0
  148. package/dist/entity-definition/meta-entities/meta-method/index.d.ts.map +1 -0
  149. package/dist/entity-definition/meta-entities/meta-method/index.js +3 -0
  150. package/dist/entity-definition/meta-entities/meta-method/index.js.map +1 -0
  151. package/dist/entity-definition/meta-entities/meta-method/meta-method.d.ts +16 -0
  152. package/dist/entity-definition/meta-entities/meta-method/meta-method.d.ts.map +1 -0
  153. package/dist/entity-definition/meta-entities/meta-method/meta-method.js +11 -0
  154. package/dist/entity-definition/meta-entities/meta-method/meta-method.js.map +1 -0
  155. package/dist/entity-definition/meta-entities/meta-use-case/index.d.ts +2 -0
  156. package/dist/entity-definition/meta-entities/meta-use-case/index.d.ts.map +1 -0
  157. package/dist/entity-definition/meta-entities/meta-use-case/index.js +3 -0
  158. package/dist/entity-definition/meta-entities/meta-use-case/index.js.map +1 -0
  159. package/dist/entity-definition/meta-entities/meta-use-case/meta-use-case.d.ts +94 -0
  160. package/dist/entity-definition/meta-entities/meta-use-case/meta-use-case.d.ts.map +1 -0
  161. package/dist/entity-definition/meta-entities/meta-use-case/meta-use-case.js +17 -0
  162. package/dist/entity-definition/meta-entities/meta-use-case/meta-use-case.js.map +1 -0
  163. package/dist/entity-definition/metadata/entity-metadata-document.d.ts +23 -0
  164. package/dist/entity-definition/metadata/entity-metadata-document.d.ts.map +1 -0
  165. package/dist/entity-definition/metadata/entity-metadata-document.js +16 -0
  166. package/dist/entity-definition/metadata/entity-metadata-document.js.map +1 -0
  167. package/dist/entity-definition/metadata/entity-metadata-source.d.ts +19 -0
  168. package/dist/entity-definition/metadata/entity-metadata-source.d.ts.map +1 -0
  169. package/dist/entity-definition/metadata/entity-metadata-source.js +15 -0
  170. package/dist/entity-definition/metadata/entity-metadata-source.js.map +1 -0
  171. package/dist/entity-definition/metadata/index.d.ts +3 -0
  172. package/dist/entity-definition/metadata/index.d.ts.map +1 -0
  173. package/dist/entity-definition/metadata/index.js +4 -0
  174. package/dist/entity-definition/metadata/index.js.map +1 -0
  175. package/dist/entity-definition/reconstruct/clone-entity-draft.d.ts +34 -0
  176. package/dist/entity-definition/reconstruct/clone-entity-draft.d.ts.map +1 -0
  177. package/dist/entity-definition/reconstruct/clone-entity-draft.js +75 -0
  178. package/dist/entity-definition/reconstruct/clone-entity-draft.js.map +1 -0
  179. package/dist/entity-definition/reconstruct/coerce-field-value.d.ts +34 -0
  180. package/dist/entity-definition/reconstruct/coerce-field-value.d.ts.map +1 -0
  181. package/dist/entity-definition/reconstruct/coerce-field-value.js +42 -0
  182. package/dist/entity-definition/reconstruct/coerce-field-value.js.map +1 -0
  183. package/dist/entity-definition/reconstruct/index.d.ts +5 -0
  184. package/dist/entity-definition/reconstruct/index.d.ts.map +1 -0
  185. package/dist/entity-definition/reconstruct/index.js +6 -0
  186. package/dist/entity-definition/reconstruct/index.js.map +1 -0
  187. package/dist/entity-definition/reconstruct/reconstruct-child.d.ts +35 -0
  188. package/dist/entity-definition/reconstruct/reconstruct-child.d.ts.map +1 -0
  189. package/dist/entity-definition/reconstruct/reconstruct-child.js +47 -0
  190. package/dist/entity-definition/reconstruct/reconstruct-child.js.map +1 -0
  191. package/dist/entity-definition/reconstruct/reconstruct-entity.d.ts +49 -0
  192. package/dist/entity-definition/reconstruct/reconstruct-entity.d.ts.map +1 -0
  193. package/dist/entity-definition/reconstruct/reconstruct-entity.js +116 -0
  194. package/dist/entity-definition/reconstruct/reconstruct-entity.js.map +1 -0
  195. package/dist/entity-definition/serializer/deserialize.d.ts +13 -0
  196. package/dist/entity-definition/serializer/deserialize.d.ts.map +1 -0
  197. package/dist/entity-definition/serializer/deserialize.js +145 -0
  198. package/dist/entity-definition/serializer/deserialize.js.map +1 -0
  199. package/dist/entity-definition/serializer/index.d.ts +3 -0
  200. package/dist/entity-definition/serializer/index.d.ts.map +1 -0
  201. package/dist/entity-definition/serializer/index.js +4 -0
  202. package/dist/entity-definition/serializer/index.js.map +1 -0
  203. package/dist/entity-definition/serializer/serialize.d.ts +26 -0
  204. package/dist/entity-definition/serializer/serialize.d.ts.map +1 -0
  205. package/dist/entity-definition/serializer/serialize.js +64 -0
  206. package/dist/entity-definition/serializer/serialize.js.map +1 -0
  207. package/dist/envelope/event-pattern.d.ts +14 -0
  208. package/dist/envelope/event-pattern.d.ts.map +1 -0
  209. package/dist/envelope/event-pattern.js +30 -0
  210. package/dist/envelope/event-pattern.js.map +1 -0
  211. package/dist/envelope/index.d.ts +5 -0
  212. package/dist/envelope/index.d.ts.map +1 -0
  213. package/dist/envelope/index.js +6 -0
  214. package/dist/envelope/index.js.map +1 -0
  215. package/dist/envelope/make-envelope.d.ts +45 -0
  216. package/dist/envelope/make-envelope.d.ts.map +1 -0
  217. package/dist/envelope/make-envelope.js +111 -0
  218. package/dist/envelope/make-envelope.js.map +1 -0
  219. package/dist/envelope/read-envelope.d.ts +48 -0
  220. package/dist/envelope/read-envelope.d.ts.map +1 -0
  221. package/dist/envelope/read-envelope.js +138 -0
  222. package/dist/envelope/read-envelope.js.map +1 -0
  223. package/dist/envelope/types.d.ts +173 -0
  224. package/dist/envelope/types.d.ts.map +1 -0
  225. package/dist/envelope/types.js +6 -0
  226. package/dist/envelope/types.js.map +1 -0
  227. package/dist/http/session-cookies.d.ts +25 -0
  228. package/dist/http/session-cookies.d.ts.map +1 -0
  229. package/dist/http/session-cookies.js +22 -0
  230. package/dist/http/session-cookies.js.map +1 -0
  231. package/dist/i18n/format.d.ts +22 -0
  232. package/dist/i18n/format.d.ts.map +1 -0
  233. package/dist/i18n/format.js +49 -0
  234. package/dist/i18n/format.js.map +1 -0
  235. package/dist/i18n/index.d.ts +4 -0
  236. package/dist/i18n/index.d.ts.map +1 -0
  237. package/dist/i18n/index.js +5 -0
  238. package/dist/i18n/index.js.map +1 -0
  239. package/dist/i18n/locales.d.ts +23 -0
  240. package/dist/i18n/locales.d.ts.map +1 -0
  241. package/dist/i18n/locales.js +25 -0
  242. package/dist/i18n/locales.js.map +1 -0
  243. package/dist/i18n/negotiate.d.ts +39 -0
  244. package/dist/i18n/negotiate.d.ts.map +1 -0
  245. package/dist/i18n/negotiate.js +63 -0
  246. package/dist/i18n/negotiate.js.map +1 -0
  247. package/dist/index.d.ts +42 -0
  248. package/dist/index.d.ts.map +1 -0
  249. package/dist/index.js +43 -0
  250. package/dist/index.js.map +1 -0
  251. package/dist/rsql/coerce-rsql.d.ts +27 -0
  252. package/dist/rsql/coerce-rsql.d.ts.map +1 -0
  253. package/dist/rsql/coerce-rsql.js +121 -0
  254. package/dist/rsql/coerce-rsql.js.map +1 -0
  255. package/dist/rsql/index.d.ts +8 -0
  256. package/dist/rsql/index.d.ts.map +1 -0
  257. package/dist/rsql/index.js +9 -0
  258. package/dist/rsql/index.js.map +1 -0
  259. package/dist/rsql/load-request-url.d.ts +30 -0
  260. package/dist/rsql/load-request-url.d.ts.map +1 -0
  261. package/dist/rsql/load-request-url.js +67 -0
  262. package/dist/rsql/load-request-url.js.map +1 -0
  263. package/dist/rsql/parse-rsql.d.ts +35 -0
  264. package/dist/rsql/parse-rsql.d.ts.map +1 -0
  265. package/dist/rsql/parse-rsql.js +235 -0
  266. package/dist/rsql/parse-rsql.js.map +1 -0
  267. package/dist/rsql/rsql-operators.d.ts +36 -0
  268. package/dist/rsql/rsql-operators.d.ts.map +1 -0
  269. package/dist/rsql/rsql-operators.js +65 -0
  270. package/dist/rsql/rsql-operators.js.map +1 -0
  271. package/dist/rsql/rsql-values.d.ts +11 -0
  272. package/dist/rsql/rsql-values.d.ts.map +1 -0
  273. package/dist/rsql/rsql-values.js +26 -0
  274. package/dist/rsql/rsql-values.js.map +1 -0
  275. package/dist/rsql/serialize-rsql.d.ts +19 -0
  276. package/dist/rsql/serialize-rsql.d.ts.map +1 -0
  277. package/dist/rsql/serialize-rsql.js +71 -0
  278. package/dist/rsql/serialize-rsql.js.map +1 -0
  279. package/dist/rsql/sort-param.d.ts +20 -0
  280. package/dist/rsql/sort-param.d.ts.map +1 -0
  281. package/dist/rsql/sort-param.js +66 -0
  282. package/dist/rsql/sort-param.js.map +1 -0
  283. package/dist/types/BulkOutcome.d.ts +27 -0
  284. package/dist/types/BulkOutcome.d.ts.map +1 -0
  285. package/dist/types/BulkOutcome.js +8 -0
  286. package/dist/types/BulkOutcome.js.map +1 -0
  287. package/dist/types/Entity.d.ts +6 -0
  288. package/dist/types/Entity.d.ts.map +1 -0
  289. package/dist/types/Entity.js +3 -0
  290. package/dist/types/Entity.js.map +1 -0
  291. package/dist/types/EntityAction.d.ts +15 -0
  292. package/dist/types/EntityAction.d.ts.map +1 -0
  293. package/dist/types/EntityAction.js +18 -0
  294. package/dist/types/EntityAction.js.map +1 -0
  295. package/dist/types/EntityDraft.d.ts +47 -0
  296. package/dist/types/EntityDraft.d.ts.map +1 -0
  297. package/dist/types/EntityDraft.js +14 -0
  298. package/dist/types/EntityDraft.js.map +1 -0
  299. package/dist/types/EntityFiltering.d.ts +45 -0
  300. package/dist/types/EntityFiltering.d.ts.map +1 -0
  301. package/dist/types/EntityFiltering.js +30 -0
  302. package/dist/types/EntityFiltering.js.map +1 -0
  303. package/dist/types/EntityLoadRequest.d.ts +10 -0
  304. package/dist/types/EntityLoadRequest.d.ts.map +1 -0
  305. package/dist/types/EntityLoadRequest.js +3 -0
  306. package/dist/types/EntityLoadRequest.js.map +1 -0
  307. package/dist/types/EntityPage.d.ts +8 -0
  308. package/dist/types/EntityPage.d.ts.map +1 -0
  309. package/dist/types/EntityPage.js +3 -0
  310. package/dist/types/EntityPage.js.map +1 -0
  311. package/dist/types/EntityRowDraft.d.ts +79 -0
  312. package/dist/types/EntityRowDraft.d.ts.map +1 -0
  313. package/dist/types/EntityRowDraft.js +65 -0
  314. package/dist/types/EntityRowDraft.js.map +1 -0
  315. package/dist/types/EntitySelection.d.ts +117 -0
  316. package/dist/types/EntitySelection.d.ts.map +1 -0
  317. package/dist/types/EntitySelection.js +107 -0
  318. package/dist/types/EntitySelection.js.map +1 -0
  319. package/dist/types/EntitySorting.d.ts +7 -0
  320. package/dist/types/EntitySorting.d.ts.map +1 -0
  321. package/dist/types/EntitySorting.js +3 -0
  322. package/dist/types/EntitySorting.js.map +1 -0
  323. package/dist/types/Json.d.ts +37 -0
  324. package/dist/types/Json.d.ts.map +1 -0
  325. package/dist/types/Json.js +43 -0
  326. package/dist/types/Json.js.map +1 -0
  327. package/dist/types/StandardSchema.d.ts +45 -0
  328. package/dist/types/StandardSchema.d.ts.map +1 -0
  329. package/dist/types/StandardSchema.js +15 -0
  330. package/dist/types/StandardSchema.js.map +1 -0
  331. package/dist/types/UseCase.d.ts +10 -0
  332. package/dist/types/UseCase.d.ts.map +1 -0
  333. package/dist/types/UseCase.js +10 -0
  334. package/dist/types/UseCase.js.map +1 -0
  335. package/dist/wizard/index.d.ts +4 -0
  336. package/dist/wizard/index.d.ts.map +1 -0
  337. package/dist/wizard/index.js +5 -0
  338. package/dist/wizard/index.js.map +1 -0
  339. package/dist/wizard/wizard-definition.d.ts +108 -0
  340. package/dist/wizard/wizard-definition.d.ts.map +1 -0
  341. package/dist/wizard/wizard-definition.js +125 -0
  342. package/dist/wizard/wizard-definition.js.map +1 -0
  343. package/dist/wizard/wizard-navigation.d.ts +81 -0
  344. package/dist/wizard/wizard-navigation.d.ts.map +1 -0
  345. package/dist/wizard/wizard-navigation.js +139 -0
  346. package/dist/wizard/wizard-navigation.js.map +1 -0
  347. package/dist/wizard/wizard-state.d.ts +89 -0
  348. package/dist/wizard/wizard-state.d.ts.map +1 -0
  349. package/dist/wizard/wizard-state.js +103 -0
  350. package/dist/wizard/wizard-state.js.map +1 -0
  351. package/package.json +64 -0
@@ -0,0 +1,125 @@
1
+ import { EntifixBuildError } from '../base-entities/entifix-error/index.js';
2
+ /**
3
+ * What a step holds, which decides how its value is stored and edited.
4
+ *
5
+ * `form` is one `useEntityForm` instance over part of an entity; `selection` is
6
+ * a table step whose value is a set of ids; `choice` is a branch point offering
7
+ * a fixed list of options; `summary` is the read-only recap; `custom` is
8
+ * anything else the host renders and reads itself.
9
+ */ export const WizardStepKinds = [
10
+ 'form',
11
+ 'selection',
12
+ 'choice',
13
+ 'summary',
14
+ 'custom'
15
+ ];
16
+ /** The step a flow starts at: the first declared. */ export const entryStep = (definition)=>{
17
+ const [first] = definition.steps;
18
+ if (first === undefined) {
19
+ throw new EntifixBuildError(`wizard "${definition.key}" declares no steps`);
20
+ }
21
+ return first;
22
+ };
23
+ /** The step with this id, or `undefined` when the definition has none. */ export const findStep = (definition, stepId)=>definition.steps.find((step)=>step.id === stepId);
24
+ /**
25
+ * Checks a definition the moment it is declared, and throws rather than
26
+ * degrading.
27
+ *
28
+ * **Load time, not step time.** A wizard whose last step is missing, or whose
29
+ * branch names a step that does not exist, must fail on the first render of any
30
+ * surface rather than on the render of the step nobody reached — otherwise the
31
+ * failure of the longest flow in the product arrives at the end of it. That is
32
+ * the posture `assertLinkSourcesAreEditable` and `surfaceFor` already take
33
+ * ([ADR 0035](../../../../../../docs/adr/0035-entity-actions-selection-and-bulk.md)).
34
+ *
35
+ * Six faults, each of which is silent otherwise:
36
+ *
37
+ * - **no steps**, which renders an empty frame with a disabled button;
38
+ * - **a duplicate id**, which makes one step's stored value overwrite another's;
39
+ * - **an unknown `to` target**, a typo that strands the flow mid-way;
40
+ * - **several edges and no `next`**, which cannot say where the step goes;
41
+ * - **a step nothing reaches**, which is either a dead branch or a missing edge;
42
+ * - **the wrong terminal step** — the flow must end in the summary, and there
43
+ * must be exactly one of those. A wizard ending anywhere else commits without
44
+ * the operator ever seeing what they answered, which
45
+ * [#111](https://github.com/r10c-technologies/r10c/issues/111) records as not
46
+ * optional.
47
+ *
48
+ * A cycle needs no separate check: every step is reachable from the entry and
49
+ * exactly one is terminal, so a cycle would leave the steps on it unable to
50
+ * reach that terminal, which the walk below reports as unreachable-from-here.
51
+ */ export function assertWizardDefinition(definition) {
52
+ const first = entryStep(definition);
53
+ const ids = new Set();
54
+ for (const step of definition.steps){
55
+ if (ids.has(step.id)) {
56
+ throw new EntifixBuildError(`wizard "${definition.key}" declares step "${step.id}" twice`);
57
+ }
58
+ ids.add(step.id);
59
+ }
60
+ for (const step of definition.steps){
61
+ assertStepOptions(definition, step);
62
+ for (const target of step.to){
63
+ if (!ids.has(target)) {
64
+ throw new EntifixBuildError(`wizard "${definition.key}" step "${step.id}" leads to unknown step "${target}"`);
65
+ }
66
+ }
67
+ if (step.to.length > 1 && step.next === undefined) {
68
+ throw new EntifixBuildError(`wizard "${definition.key}" step "${step.id}" has ${step.to.length} edges and no next()`);
69
+ }
70
+ }
71
+ assertOneSummaryAtTheEnd(definition);
72
+ assertEveryStepIsReachable(definition, first);
73
+ }
74
+ /** `options` belongs to `choice` and to nothing else. */ function assertStepOptions(definition, step) {
75
+ if (step.kind === 'choice') {
76
+ if (step.options === undefined || step.options.length === 0) {
77
+ throw new EntifixBuildError(`wizard "${definition.key}" choice step "${step.id}" offers no options`);
78
+ }
79
+ return;
80
+ }
81
+ if (step.options !== undefined) {
82
+ throw new EntifixBuildError(`wizard "${definition.key}" step "${step.id}" is a ${step.kind} step and cannot declare options`);
83
+ }
84
+ }
85
+ /** Exactly one summary, and it is the only step the flow may end on. */ function assertOneSummaryAtTheEnd(definition) {
86
+ const summaries = definition.steps.filter((step)=>step.kind === 'summary');
87
+ if (summaries.length !== 1) {
88
+ throw new EntifixBuildError(`wizard "${definition.key}" declares ${summaries.length} summary steps, and must declare exactly one`);
89
+ }
90
+ for (const step of definition.steps){
91
+ const terminal = step.to.length === 0;
92
+ if (terminal && step.kind !== 'summary') {
93
+ throw new EntifixBuildError(`wizard "${definition.key}" ends on "${step.id}", which is not its summary`);
94
+ }
95
+ if (!terminal && step.kind === 'summary') {
96
+ throw new EntifixBuildError(`wizard "${definition.key}" summary step "${step.id}" leads onward, and must end the flow`);
97
+ }
98
+ }
99
+ }
100
+ /** Every declared step is on some path out of the entry step. */ function assertEveryStepIsReachable(definition, first) {
101
+ const seen = new Set([
102
+ first.id
103
+ ]);
104
+ // A fixpoint over `seen` rather than a queue of resolved steps: every target
105
+ // has already been checked to name a declared step, so a walk that looked one
106
+ // up would carry an `undefined` arm nothing can reach — and an unreachable
107
+ // arm is indistinguishable from an untested one.
108
+ for(let grew = true; grew;){
109
+ grew = false;
110
+ for (const step of definition.steps){
111
+ if (!seen.has(step.id)) continue;
112
+ for (const target of step.to){
113
+ if (seen.has(target)) continue;
114
+ seen.add(target);
115
+ grew = true;
116
+ }
117
+ }
118
+ }
119
+ const stranded = definition.steps.filter((step)=>!seen.has(step.id)).map((step)=>step.id);
120
+ if (stranded.length > 0) {
121
+ throw new EntifixBuildError(`wizard "${definition.key}" cannot reach ${stranded.map((id)=>`"${id}"`).join(', ')} from "${first.id}"`);
122
+ }
123
+ }
124
+
125
+ //# sourceMappingURL=wizard-definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/wizard/wizard-definition.ts"],"sourcesContent":["import { EntifixBuildError } from '../base-entities/entifix-error/index.js';\n\n/**\n * What a step holds, which decides how its value is stored and edited.\n *\n * `form` is one `useEntityForm` instance over part of an entity; `selection` is\n * a table step whose value is a set of ids; `choice` is a branch point offering\n * a fixed list of options; `summary` is the read-only recap; `custom` is\n * anything else the host renders and reads itself.\n */\nexport const WizardStepKinds = [\n 'form',\n 'selection',\n 'choice',\n 'summary',\n 'custom',\n] as const;\nexport type WizardStepKind = (typeof WizardStepKinds)[number];\n\n/**\n * One step, and the edges out of it.\n *\n * **The graph is data; `next` only chooses along it.** `to` lists the steps this\n * one may lead to, so reachability, unknown targets, cycles and terminality are\n * decidable by reading the definition — no probing, no enumeration of the state\n * space, and no rule that \"only appears to hold\" because a `next` reading a form\n * value could never be enumerated. It is the move\n * [ADR 0039](../../../../../../docs/adr/0039-multi-step-sagas-are-orchestrated.md)\n * made for saga steps, for the same reason: a walkable definition is checkable\n * at load, and a function is not.\n *\n * A step with an empty `to` is **terminal**, and\n * {@link assertWizardDefinition} requires that to be the summary.\n */\nexport interface WizardStep {\n readonly id: string;\n readonly kind: WizardStepKind;\n /** Catalog key for the stepper's label. Resolved by the renderer, never here. */\n readonly labelKey: string;\n /**\n * The options a `choice` step offers, as stable identifiers.\n *\n * Required on `choice` and forbidden elsewhere: the value of a choice step is\n * one of these strings, so a choice with no options can never be answered and\n * options on a form step describe nothing.\n */\n readonly options?: readonly string[];\n /** Every step this one may lead to. Empty means the flow ends here. */\n readonly to: readonly string[];\n /**\n * Which of {@link WizardStep.to} comes next, given everything answered so far.\n *\n * Optional, and omitting it is the ordinary case: a step with exactly one edge\n * needs no function to pick it. A step with several **must** declare one, or\n * the definition cannot say where it goes.\n *\n * It returns a step id and never `undefined`: **the end of the flow is an\n * empty `to`, not a `next` that declines**. Two ways of saying the same thing\n * would let a step be terminal in one of them and not the other, and it is\n * `to` that {@link assertWizardDefinition} can read.\n */\n next?(state: WizardStateLike): string;\n}\n\n/**\n * The part of the state a `next` may read.\n *\n * Declared structurally rather than importing `WizardState`, so the definition\n * module stays below the state module and neither has to import the other.\n */\nexport interface WizardStateLike {\n readonly activeStep: string;\n readonly steps: { readonly [stepId: string]: unknown };\n}\n\n/**\n * A whole wizard: its key — which is also its screen key in a workspace address\n * — and its steps, the first of which is where the flow begins.\n */\nexport interface WizardDefinition {\n readonly key: string;\n readonly steps: readonly WizardStep[];\n}\n\n/** The step a flow starts at: the first declared. */\nexport const entryStep = (definition: WizardDefinition): WizardStep => {\n const [first] = definition.steps;\n if (first === undefined) {\n throw new EntifixBuildError(`wizard \"${definition.key}\" declares no steps`);\n }\n return first;\n};\n\n/** The step with this id, or `undefined` when the definition has none. */\nexport const findStep = (\n definition: WizardDefinition,\n stepId: string,\n): WizardStep | undefined => definition.steps.find(step => step.id === stepId);\n\n/**\n * Checks a definition the moment it is declared, and throws rather than\n * degrading.\n *\n * **Load time, not step time.** A wizard whose last step is missing, or whose\n * branch names a step that does not exist, must fail on the first render of any\n * surface rather than on the render of the step nobody reached — otherwise the\n * failure of the longest flow in the product arrives at the end of it. That is\n * the posture `assertLinkSourcesAreEditable` and `surfaceFor` already take\n * ([ADR 0035](../../../../../../docs/adr/0035-entity-actions-selection-and-bulk.md)).\n *\n * Six faults, each of which is silent otherwise:\n *\n * - **no steps**, which renders an empty frame with a disabled button;\n * - **a duplicate id**, which makes one step's stored value overwrite another's;\n * - **an unknown `to` target**, a typo that strands the flow mid-way;\n * - **several edges and no `next`**, which cannot say where the step goes;\n * - **a step nothing reaches**, which is either a dead branch or a missing edge;\n * - **the wrong terminal step** — the flow must end in the summary, and there\n * must be exactly one of those. A wizard ending anywhere else commits without\n * the operator ever seeing what they answered, which\n * [#111](https://github.com/r10c-technologies/r10c/issues/111) records as not\n * optional.\n *\n * A cycle needs no separate check: every step is reachable from the entry and\n * exactly one is terminal, so a cycle would leave the steps on it unable to\n * reach that terminal, which the walk below reports as unreachable-from-here.\n */\nexport function assertWizardDefinition(definition: WizardDefinition): void {\n const first = entryStep(definition);\n const ids = new Set<string>();\n\n for (const step of definition.steps) {\n if (ids.has(step.id)) {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" declares step \"${step.id}\" twice`,\n );\n }\n ids.add(step.id);\n }\n\n for (const step of definition.steps) {\n assertStepOptions(definition, step);\n\n for (const target of step.to) {\n if (!ids.has(target)) {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" step \"${step.id}\" leads to unknown step \"${target}\"`,\n );\n }\n }\n\n if (step.to.length > 1 && step.next === undefined) {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" step \"${step.id}\" has ${step.to.length} edges and no next()`,\n );\n }\n }\n\n assertOneSummaryAtTheEnd(definition);\n assertEveryStepIsReachable(definition, first);\n}\n\n/** `options` belongs to `choice` and to nothing else. */\nfunction assertStepOptions(\n definition: WizardDefinition,\n step: WizardStep,\n): void {\n if (step.kind === 'choice') {\n if (step.options === undefined || step.options.length === 0) {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" choice step \"${step.id}\" offers no options`,\n );\n }\n return;\n }\n if (step.options !== undefined) {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" step \"${step.id}\" is a ${step.kind} step and cannot declare options`,\n );\n }\n}\n\n/** Exactly one summary, and it is the only step the flow may end on. */\nfunction assertOneSummaryAtTheEnd(definition: WizardDefinition): void {\n const summaries = definition.steps.filter(step => step.kind === 'summary');\n if (summaries.length !== 1) {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" declares ${summaries.length} summary steps, and must declare exactly one`,\n );\n }\n\n for (const step of definition.steps) {\n const terminal = step.to.length === 0;\n if (terminal && step.kind !== 'summary') {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" ends on \"${step.id}\", which is not its summary`,\n );\n }\n if (!terminal && step.kind === 'summary') {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" summary step \"${step.id}\" leads onward, and must end the flow`,\n );\n }\n }\n}\n\n/** Every declared step is on some path out of the entry step. */\nfunction assertEveryStepIsReachable(\n definition: WizardDefinition,\n first: WizardStep,\n): void {\n const seen = new Set<string>([first.id]);\n\n // A fixpoint over `seen` rather than a queue of resolved steps: every target\n // has already been checked to name a declared step, so a walk that looked one\n // up would carry an `undefined` arm nothing can reach — and an unreachable\n // arm is indistinguishable from an untested one.\n for (let grew = true; grew;) {\n grew = false;\n for (const step of definition.steps) {\n if (!seen.has(step.id)) continue;\n for (const target of step.to) {\n if (seen.has(target)) continue;\n seen.add(target);\n grew = true;\n }\n }\n }\n\n const stranded = definition.steps\n .filter(step => !seen.has(step.id))\n .map(step => step.id);\n\n if (stranded.length > 0) {\n throw new EntifixBuildError(\n `wizard \"${definition.key}\" cannot reach ${stranded.map(id => `\"${id}\"`).join(', ')} from \"${first.id}\"`,\n );\n }\n}\n"],"names":["EntifixBuildError","WizardStepKinds","entryStep","definition","first","steps","undefined","key","findStep","stepId","find","step","id","assertWizardDefinition","ids","Set","has","add","assertStepOptions","target","to","length","next","assertOneSummaryAtTheEnd","assertEveryStepIsReachable","kind","options","summaries","filter","terminal","seen","grew","stranded","map","join"],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import { type WizardDefinition } from './wizard-definition.js';
2
+ import type { WizardState } from './wizard-state.js';
3
+ /** How a step reads in the stepper. */
4
+ export declare const WizardStepStatuses: readonly ["pending", "active", "complete", "error"];
5
+ export type WizardStepStatus = (typeof WizardStepStatuses)[number];
6
+ /**
7
+ * Where the active step leads, or `undefined` when it ends the flow.
8
+ *
9
+ * A step with one edge needs no `next`; a step with several declares one, and
10
+ * what it returns **must** be an edge the step declared. That check is an
11
+ * {@link EntifixLogicError} rather than a silent fallback because the two ways
12
+ * of being wrong are both invisible otherwise: returning an id from another
13
+ * branch strands the operator on a step whose earlier answers were never given,
14
+ * and returning a typo would read as "this wizard has ended" one step early.
15
+ */
16
+ export declare function nextStepId(definition: WizardDefinition, state: WizardState): string | undefined;
17
+ /**
18
+ * The state one step further on, or the same state when there is nowhere to go.
19
+ *
20
+ * Unchanged rather than throwing on a terminal step: the button that calls this
21
+ * is the one {@link canFinish} turns into Finalizar, so reaching here means the
22
+ * caller asked twice, not that the definition is wrong.
23
+ */
24
+ export declare function advanceWizard(definition: WizardDefinition, state: WizardState): WizardState;
25
+ /**
26
+ * The state one step back, or the same state at the entry step.
27
+ *
28
+ * It pops {@link WizardState.history} rather than inverting `next`, which is the
29
+ * whole reason that history is stored: a branch's inverse is ambiguous the
30
+ * moment an earlier answer changes, so a computed one walks the operator back
31
+ * through a path they were never on.
32
+ */
33
+ export declare function goBackWizard(state: WizardState): WizardState;
34
+ /**
35
+ * Jump to a step already visited.
36
+ *
37
+ * Backwards only, and to a step **on the current path** — a stepper may make a
38
+ * completed step clickable, and nothing else. Jumping forward would skip the
39
+ * per-step submit that validates the steps in between, which is the one thing
40
+ * gating advancement at all; jumping to a step on an abandoned branch would put
41
+ * the operator somewhere their current answers do not lead.
42
+ *
43
+ * The history truncates to before the target, exactly as arriving there by
44
+ * pressing Back repeatedly would leave it.
45
+ */
46
+ export declare function goToWizardStep(state: WizardState, stepId: string): WizardState;
47
+ /** Whether the active step ends the flow, so its button reads Finalizar. */
48
+ export declare const canFinish: (definition: WizardDefinition, state: WizardState) => boolean;
49
+ /**
50
+ * The steps this flow runs through, given what has been answered — the ones
51
+ * already visited, the active one, and the ones ahead.
52
+ *
53
+ * **Projected, not the declared list.** A graph's step list contains branches
54
+ * not taken, so rendering `definition.steps` would show a stepper promising a
55
+ * "duplicate" step to an operator who chose to start blank. Walking forward from
56
+ * the active step with the current answers is what makes the stepper honest:
57
+ * it re-shapes as a branch point is answered, which is the visible half of the
58
+ * step graph being a graph.
59
+ *
60
+ * The walk stops on a step it has already placed, which is what makes it
61
+ * terminate: every pass either adds a step to a finite set or stops. A
62
+ * definition that cycles therefore produces a finite path rather than hanging
63
+ * the render — `assertWizardDefinition` has already refused such a definition at
64
+ * load, and this exists because a render loop is a worse way to find out.
65
+ */
66
+ export declare function wizardPath(definition: WizardDefinition, state: WizardState): readonly string[];
67
+ /**
68
+ * Each step on the projected path, with how it reads.
69
+ *
70
+ * `errored` is supplied by the caller rather than derived, because validity is
71
+ * the step's own knowledge: a form step's errors live in its `useEntityForm`
72
+ * instance, and this module is framework-free and holds none of them.
73
+ *
74
+ * An error wins over `complete` — a step the operator has been through and left
75
+ * invalid is exactly the one the stepper has to point at.
76
+ */
77
+ export declare function stepStatuses(definition: WizardDefinition, state: WizardState, errored?: readonly string[]): ReadonlyArray<{
78
+ readonly id: string;
79
+ readonly status: WizardStepStatus;
80
+ }>;
81
+ //# sourceMappingURL=wizard-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard-navigation.d.ts","sourceRoot":"","sources":["../../src/wizard/wizard-navigation.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,uCAAuC;AACvC,eAAO,MAAM,kBAAkB,qDAKrB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,WAAW,GACjB,MAAM,GAAG,SAAS,CAcpB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,WAAW,GACjB,WAAW,CASb;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAS5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,GACb,WAAW,CASb;AAED,4EAA4E;AAC5E,eAAO,MAAM,SAAS,GACpB,YAAY,gBAAgB,EAC5B,OAAO,WAAW,KACjB,OAAsD,CAAC;AAE1D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,WAAW,GACjB,SAAS,MAAM,EAAE,CAcnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,SAAS,MAAM,EAAO,GAC9B,aAAa,CAAC;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC,CAO3E"}
@@ -0,0 +1,139 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { EntifixLogicError } from '../base-entities/entifix-error/index.js';
3
+ import { findStep } from './wizard-definition.js';
4
+ /** How a step reads in the stepper. */ export const WizardStepStatuses = [
5
+ 'pending',
6
+ 'active',
7
+ 'complete',
8
+ 'error'
9
+ ];
10
+ /**
11
+ * Where the active step leads, or `undefined` when it ends the flow.
12
+ *
13
+ * A step with one edge needs no `next`; a step with several declares one, and
14
+ * what it returns **must** be an edge the step declared. That check is an
15
+ * {@link EntifixLogicError} rather than a silent fallback because the two ways
16
+ * of being wrong are both invisible otherwise: returning an id from another
17
+ * branch strands the operator on a step whose earlier answers were never given,
18
+ * and returning a typo would read as "this wizard has ended" one step early.
19
+ */ export function nextStepId(definition, state) {
20
+ var _ref;
21
+ const step = findStep(definition, state.activeStep);
22
+ if (step === undefined || step.to.length === 0) return undefined;
23
+ // `to` is non-empty here, so the fallback always resolves — which is why a
24
+ // step ends a flow by declaring no edges rather than by returning nothing.
25
+ const chosen = (_ref = step.next == null ? void 0 : step.next.call(step, state)) != null ? _ref : step.to[0];
26
+ if (!step.to.includes(chosen)) {
27
+ throw new EntifixLogicError(`wizard "${definition.key}" step "${step.id}" chose "${chosen}", which is not one of its edges`);
28
+ }
29
+ return chosen;
30
+ }
31
+ /**
32
+ * The state one step further on, or the same state when there is nowhere to go.
33
+ *
34
+ * Unchanged rather than throwing on a terminal step: the button that calls this
35
+ * is the one {@link canFinish} turns into Finalizar, so reaching here means the
36
+ * caller asked twice, not that the definition is wrong.
37
+ */ export function advanceWizard(definition, state) {
38
+ const next = nextStepId(definition, state);
39
+ if (next === undefined) return state;
40
+ return _extends({}, state, {
41
+ activeStep: next,
42
+ history: [
43
+ ...state.history,
44
+ state.activeStep
45
+ ]
46
+ });
47
+ }
48
+ /**
49
+ * The state one step back, or the same state at the entry step.
50
+ *
51
+ * It pops {@link WizardState.history} rather than inverting `next`, which is the
52
+ * whole reason that history is stored: a branch's inverse is ambiguous the
53
+ * moment an earlier answer changes, so a computed one walks the operator back
54
+ * through a path they were never on.
55
+ */ export function goBackWizard(state) {
56
+ const previous = state.history.at(-1);
57
+ if (previous === undefined) return state;
58
+ return _extends({}, state, {
59
+ activeStep: previous,
60
+ history: state.history.slice(0, -1)
61
+ });
62
+ }
63
+ /**
64
+ * Jump to a step already visited.
65
+ *
66
+ * Backwards only, and to a step **on the current path** — a stepper may make a
67
+ * completed step clickable, and nothing else. Jumping forward would skip the
68
+ * per-step submit that validates the steps in between, which is the one thing
69
+ * gating advancement at all; jumping to a step on an abandoned branch would put
70
+ * the operator somewhere their current answers do not lead.
71
+ *
72
+ * The history truncates to before the target, exactly as arriving there by
73
+ * pressing Back repeatedly would leave it.
74
+ */ export function goToWizardStep(state, stepId) {
75
+ const index = state.history.indexOf(stepId);
76
+ if (index === -1) return state;
77
+ return _extends({}, state, {
78
+ activeStep: stepId,
79
+ history: state.history.slice(0, index)
80
+ });
81
+ }
82
+ /** Whether the active step ends the flow, so its button reads Finalizar. */ export const canFinish = (definition, state)=>nextStepId(definition, state) === undefined;
83
+ /**
84
+ * The steps this flow runs through, given what has been answered — the ones
85
+ * already visited, the active one, and the ones ahead.
86
+ *
87
+ * **Projected, not the declared list.** A graph's step list contains branches
88
+ * not taken, so rendering `definition.steps` would show a stepper promising a
89
+ * "duplicate" step to an operator who chose to start blank. Walking forward from
90
+ * the active step with the current answers is what makes the stepper honest:
91
+ * it re-shapes as a branch point is answered, which is the visible half of the
92
+ * step graph being a graph.
93
+ *
94
+ * The walk stops on a step it has already placed, which is what makes it
95
+ * terminate: every pass either adds a step to a finite set or stops. A
96
+ * definition that cycles therefore produces a finite path rather than hanging
97
+ * the render — `assertWizardDefinition` has already refused such a definition at
98
+ * load, and this exists because a render loop is a worse way to find out.
99
+ */ export function wizardPath(definition, state) {
100
+ const path = [
101
+ ...state.history,
102
+ state.activeStep
103
+ ];
104
+ const seen = new Set(path);
105
+ let cursor = state.activeStep;
106
+ for(;;){
107
+ const next = nextStepId(definition, _extends({}, state, {
108
+ activeStep: cursor
109
+ }));
110
+ if (next === undefined || seen.has(next)) break;
111
+ path.push(next);
112
+ seen.add(next);
113
+ cursor = next;
114
+ }
115
+ return path;
116
+ }
117
+ /**
118
+ * Each step on the projected path, with how it reads.
119
+ *
120
+ * `errored` is supplied by the caller rather than derived, because validity is
121
+ * the step's own knowledge: a form step's errors live in its `useEntityForm`
122
+ * instance, and this module is framework-free and holds none of them.
123
+ *
124
+ * An error wins over `complete` — a step the operator has been through and left
125
+ * invalid is exactly the one the stepper has to point at.
126
+ */ export function stepStatuses(definition, state, errored = []) {
127
+ const visited = new Set(state.history);
128
+ return wizardPath(definition, state).map((id)=>({
129
+ id,
130
+ status: statusOf(id, state.activeStep, visited, errored)
131
+ }));
132
+ }
133
+ function statusOf(id, activeStep, visited, errored) {
134
+ if (errored.includes(id)) return 'error';
135
+ if (id === activeStep) return 'active';
136
+ return visited.has(id) ? 'complete' : 'pending';
137
+ }
138
+
139
+ //# sourceMappingURL=wizard-navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/wizard/wizard-navigation.ts"],"sourcesContent":["import { EntifixLogicError } from '../base-entities/entifix-error/index.js';\nimport { findStep, type WizardDefinition } from './wizard-definition.js';\nimport type { WizardState } from './wizard-state.js';\n\n/** How a step reads in the stepper. */\nexport const WizardStepStatuses = [\n 'pending',\n 'active',\n 'complete',\n 'error',\n] as const;\nexport type WizardStepStatus = (typeof WizardStepStatuses)[number];\n\n/**\n * Where the active step leads, or `undefined` when it ends the flow.\n *\n * A step with one edge needs no `next`; a step with several declares one, and\n * what it returns **must** be an edge the step declared. That check is an\n * {@link EntifixLogicError} rather than a silent fallback because the two ways\n * of being wrong are both invisible otherwise: returning an id from another\n * branch strands the operator on a step whose earlier answers were never given,\n * and returning a typo would read as \"this wizard has ended\" one step early.\n */\nexport function nextStepId(\n definition: WizardDefinition,\n state: WizardState,\n): string | undefined {\n const step = findStep(definition, state.activeStep);\n if (step === undefined || step.to.length === 0) return undefined;\n\n // `to` is non-empty here, so the fallback always resolves — which is why a\n // step ends a flow by declaring no edges rather than by returning nothing.\n const chosen = step.next?.(state) ?? step.to[0];\n\n if (!step.to.includes(chosen)) {\n throw new EntifixLogicError(\n `wizard \"${definition.key}\" step \"${step.id}\" chose \"${chosen}\", which is not one of its edges`,\n );\n }\n return chosen;\n}\n\n/**\n * The state one step further on, or the same state when there is nowhere to go.\n *\n * Unchanged rather than throwing on a terminal step: the button that calls this\n * is the one {@link canFinish} turns into Finalizar, so reaching here means the\n * caller asked twice, not that the definition is wrong.\n */\nexport function advanceWizard(\n definition: WizardDefinition,\n state: WizardState,\n): WizardState {\n const next = nextStepId(definition, state);\n if (next === undefined) return state;\n\n return {\n ...state,\n activeStep: next,\n history: [...state.history, state.activeStep],\n };\n}\n\n/**\n * The state one step back, or the same state at the entry step.\n *\n * It pops {@link WizardState.history} rather than inverting `next`, which is the\n * whole reason that history is stored: a branch's inverse is ambiguous the\n * moment an earlier answer changes, so a computed one walks the operator back\n * through a path they were never on.\n */\nexport function goBackWizard(state: WizardState): WizardState {\n const previous = state.history.at(-1);\n if (previous === undefined) return state;\n\n return {\n ...state,\n activeStep: previous,\n history: state.history.slice(0, -1),\n };\n}\n\n/**\n * Jump to a step already visited.\n *\n * Backwards only, and to a step **on the current path** — a stepper may make a\n * completed step clickable, and nothing else. Jumping forward would skip the\n * per-step submit that validates the steps in between, which is the one thing\n * gating advancement at all; jumping to a step on an abandoned branch would put\n * the operator somewhere their current answers do not lead.\n *\n * The history truncates to before the target, exactly as arriving there by\n * pressing Back repeatedly would leave it.\n */\nexport function goToWizardStep(\n state: WizardState,\n stepId: string,\n): WizardState {\n const index = state.history.indexOf(stepId);\n if (index === -1) return state;\n\n return {\n ...state,\n activeStep: stepId,\n history: state.history.slice(0, index),\n };\n}\n\n/** Whether the active step ends the flow, so its button reads Finalizar. */\nexport const canFinish = (\n definition: WizardDefinition,\n state: WizardState,\n): boolean => nextStepId(definition, state) === undefined;\n\n/**\n * The steps this flow runs through, given what has been answered — the ones\n * already visited, the active one, and the ones ahead.\n *\n * **Projected, not the declared list.** A graph's step list contains branches\n * not taken, so rendering `definition.steps` would show a stepper promising a\n * \"duplicate\" step to an operator who chose to start blank. Walking forward from\n * the active step with the current answers is what makes the stepper honest:\n * it re-shapes as a branch point is answered, which is the visible half of the\n * step graph being a graph.\n *\n * The walk stops on a step it has already placed, which is what makes it\n * terminate: every pass either adds a step to a finite set or stops. A\n * definition that cycles therefore produces a finite path rather than hanging\n * the render — `assertWizardDefinition` has already refused such a definition at\n * load, and this exists because a render loop is a worse way to find out.\n */\nexport function wizardPath(\n definition: WizardDefinition,\n state: WizardState,\n): readonly string[] {\n const path = [...state.history, state.activeStep];\n const seen = new Set(path);\n\n let cursor = state.activeStep;\n for (;;) {\n const next = nextStepId(definition, { ...state, activeStep: cursor });\n if (next === undefined || seen.has(next)) break;\n path.push(next);\n seen.add(next);\n cursor = next;\n }\n\n return path;\n}\n\n/**\n * Each step on the projected path, with how it reads.\n *\n * `errored` is supplied by the caller rather than derived, because validity is\n * the step's own knowledge: a form step's errors live in its `useEntityForm`\n * instance, and this module is framework-free and holds none of them.\n *\n * An error wins over `complete` — a step the operator has been through and left\n * invalid is exactly the one the stepper has to point at.\n */\nexport function stepStatuses(\n definition: WizardDefinition,\n state: WizardState,\n errored: readonly string[] = [],\n): ReadonlyArray<{ readonly id: string; readonly status: WizardStepStatus }> {\n const visited = new Set(state.history);\n\n return wizardPath(definition, state).map(id => ({\n id,\n status: statusOf(id, state.activeStep, visited, errored),\n }));\n}\n\nfunction statusOf(\n id: string,\n activeStep: string,\n visited: ReadonlySet<string>,\n errored: readonly string[],\n): WizardStepStatus {\n if (errored.includes(id)) return 'error';\n if (id === activeStep) return 'active';\n return visited.has(id) ? 'complete' : 'pending';\n}\n"],"names":["EntifixLogicError","findStep","WizardStepStatuses","nextStepId","definition","state","step","activeStep","undefined","to","length","chosen","next","includes","key","id","advanceWizard","history","goBackWizard","previous","at","slice","goToWizardStep","stepId","index","indexOf","canFinish","wizardPath","path","seen","Set","cursor","has","push","add","stepStatuses","errored","visited","map","status","statusOf"],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import type { EntityDraft } from '../types/EntityDraft.js';
2
+ /**
3
+ * What one step holds.
4
+ *
5
+ * A wizard's state is **heterogeneous by construction** — a form step drafts
6
+ * strings, a table step holds a set of ids, a branch point holds the option
7
+ * taken — so this is a discriminated union rather than one shape with optional
8
+ * members, which would let a form step carry ids nothing would ever read.
9
+ *
10
+ * ⚠️ A selection holds `readonly string[]`, **never a `ReadonlySet`**. A `Set`
11
+ * serializes to `{}` and does it silently, which is the fault
12
+ * [ADR 0035](../../../../../../docs/adr/0035-entity-actions-selection-and-bulk.md)
13
+ * named for the wire — and a wizard's state goes through `createJSONStorage` on
14
+ * every keystroke, so it would be met far more often here than there.
15
+ */
16
+ export type WizardStepValue = {
17
+ readonly kind: 'form';
18
+ readonly values: EntityDraft;
19
+ } | {
20
+ readonly kind: 'selection';
21
+ readonly ids: readonly string[];
22
+ } | {
23
+ readonly kind: 'choice';
24
+ readonly option: string;
25
+ } | {
26
+ readonly kind: 'none';
27
+ };
28
+ /**
29
+ * A wizard in progress: where the operator is, how they got there, and what
30
+ * they have answered.
31
+ *
32
+ * **A `type`, never an `interface`.** This is persisted through
33
+ * `createJSONStorage` and therefore has to satisfy `JsonValue`, and TypeScript
34
+ * gives an interface no implicit index signature — the resulting "Index
35
+ * signature for type 'string' is missing" explains nothing about the real cause
36
+ * ([ADR 0032](../../../../../../docs/adr/0032-what-may-live-in-an-autosaved-draft.md)).
37
+ *
38
+ * `history` is **the path actually taken**, and it is what Back pops. A branch's
39
+ * inverse is ambiguous once an earlier answer changes, so a computed `previous`
40
+ * would walk the operator back through a path they were never on
41
+ * ([ADR 0045](../../../../../../docs/adr/0045-the-wizard-a-step-graph-and-a-submit-that-hands-off.md)).
42
+ *
43
+ * `steps` is deliberately **not** pruned when a branch is abandoned. It is the
44
+ * record of what was typed, and {@link wizardPath} decides what counts — so
45
+ * flipping back to an earlier answer restores the work instead of discarding it,
46
+ * while the summary and the submit still read only the steps on the live path.
47
+ */
48
+ export type WizardState = {
49
+ readonly activeStep: string;
50
+ readonly history: readonly string[];
51
+ readonly steps: {
52
+ readonly [stepId: string]: WizardStepValue;
53
+ };
54
+ };
55
+ /** A wizard that has been opened and not yet answered. */
56
+ export declare const emptyWizardState: (entryStepId: string) => WizardState;
57
+ /** The value stored for a step, or `undefined` when it has none. */
58
+ export declare const readStepValue: (state: WizardState, stepId: string) => WizardStepValue | undefined;
59
+ /**
60
+ * The draft a form step holds, or an empty one.
61
+ *
62
+ * The fallback is `{}` rather than `undefined` for the reason every draft read
63
+ * in this repo has one: a form handed `undefined` flips its inputs from
64
+ * controlled to uncontrolled mid-render.
65
+ */
66
+ export declare const readStepDraft: (state: WizardState, stepId: string) => EntityDraft;
67
+ /** The ids a selection step holds, or none. */
68
+ export declare const readStepIds: (state: WizardState, stepId: string) => readonly string[];
69
+ /** The option a choice step holds, or `undefined` while it is unanswered. */
70
+ export declare const readStepChoice: (state: WizardState, stepId: string) => string | undefined;
71
+ /** The state with one step's value replaced. */
72
+ export declare const withStepValue: (state: WizardState, stepId: string, value: WizardStepValue) => WizardState;
73
+ /**
74
+ * Narrows a restored value to a usable state.
75
+ *
76
+ * A persisted wizard comes back as `JsonValue`, so it can be anything — written
77
+ * by a build before a step existed, `null`, or the right shape with the wrong
78
+ * contents. Every caller must ask before reading, and the answer for a value
79
+ * that fails is a **fresh** wizard rather than a crash: an unreadable draft is
80
+ * an unfinished edit, and `restoreEntityDraft` already discards those per entry
81
+ * rather than losing the whole form.
82
+ *
83
+ * A step value of an unknown `kind` fails the whole state rather than being
84
+ * dropped, deliberately. Dropping it would resume the operator on a step whose
85
+ * answer had silently vanished, which reads as the wizard having forgotten one
86
+ * page of a flow it otherwise restored perfectly.
87
+ */
88
+ export declare function readWizardState(value: unknown): WizardState | undefined;
89
+ //# sourceMappingURL=wizard-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard-state.d.ts","sourceRoot":"","sources":["../../src/wizard/wizard-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC/D;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAAA;KAAE,CAAC;CAChE,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,KAAG,WAIrD,CAAC;AAEH,oEAAoE;AACpE,eAAO,MAAM,aAAa,GACxB,OAAO,WAAW,EAClB,QAAQ,MAAM,KACb,eAAe,GAAG,SAAgC,CAAC;AAEtD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GACxB,OAAO,WAAW,EAClB,QAAQ,MAAM,KACb,WAGF,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,WAAW,GACtB,OAAO,WAAW,EAClB,QAAQ,MAAM,KACb,SAAS,MAAM,EAGjB,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,cAAc,GACzB,OAAO,WAAW,EAClB,QAAQ,MAAM,KACb,MAAM,GAAG,SAGX,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,aAAa,GACxB,OAAO,WAAW,EAClB,QAAQ,MAAM,EACd,OAAO,eAAe,KACrB,WAGD,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAiBvE"}
@@ -0,0 +1,103 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /** A wizard that has been opened and not yet answered. */ export const emptyWizardState = (entryStepId)=>({
3
+ activeStep: entryStepId,
4
+ history: [],
5
+ steps: {}
6
+ });
7
+ /** The value stored for a step, or `undefined` when it has none. */ export const readStepValue = (state, stepId)=>state.steps[stepId];
8
+ /**
9
+ * The draft a form step holds, or an empty one.
10
+ *
11
+ * The fallback is `{}` rather than `undefined` for the reason every draft read
12
+ * in this repo has one: a form handed `undefined` flips its inputs from
13
+ * controlled to uncontrolled mid-render.
14
+ */ export const readStepDraft = (state, stepId)=>{
15
+ const value = state.steps[stepId];
16
+ return (value == null ? void 0 : value.kind) === 'form' ? value.values : {};
17
+ };
18
+ /** The ids a selection step holds, or none. */ export const readStepIds = (state, stepId)=>{
19
+ const value = state.steps[stepId];
20
+ return (value == null ? void 0 : value.kind) === 'selection' ? value.ids : [];
21
+ };
22
+ /** The option a choice step holds, or `undefined` while it is unanswered. */ export const readStepChoice = (state, stepId)=>{
23
+ const value = state.steps[stepId];
24
+ return (value == null ? void 0 : value.kind) === 'choice' ? value.option : undefined;
25
+ };
26
+ /** The state with one step's value replaced. */ export const withStepValue = (state, stepId, value)=>_extends({}, state, {
27
+ steps: _extends({}, state.steps, {
28
+ [stepId]: value
29
+ })
30
+ });
31
+ /**
32
+ * Narrows a restored value to a usable state.
33
+ *
34
+ * A persisted wizard comes back as `JsonValue`, so it can be anything — written
35
+ * by a build before a step existed, `null`, or the right shape with the wrong
36
+ * contents. Every caller must ask before reading, and the answer for a value
37
+ * that fails is a **fresh** wizard rather than a crash: an unreadable draft is
38
+ * an unfinished edit, and `restoreEntityDraft` already discards those per entry
39
+ * rather than losing the whole form.
40
+ *
41
+ * A step value of an unknown `kind` fails the whole state rather than being
42
+ * dropped, deliberately. Dropping it would resume the operator on a step whose
43
+ * answer had silently vanished, which reads as the wizard having forgotten one
44
+ * page of a flow it otherwise restored perfectly.
45
+ */ export function readWizardState(value) {
46
+ if (!isRecord(value)) return undefined;
47
+ const { activeStep, history, steps } = value;
48
+ if (typeof activeStep !== 'string' || activeStep === '') return undefined;
49
+ if (!Array.isArray(history)) return undefined;
50
+ if (!history.every((entry)=>typeof entry === 'string')) return undefined;
51
+ if (!isRecord(steps)) return undefined;
52
+ const readSteps = {};
53
+ for (const [stepId, stepValue] of Object.entries(steps)){
54
+ const read = readStepValueOf(stepValue);
55
+ if (read === undefined) return undefined;
56
+ readSteps[stepId] = read;
57
+ }
58
+ return {
59
+ activeStep,
60
+ history,
61
+ steps: readSteps
62
+ };
63
+ }
64
+ function readStepValueOf(value) {
65
+ if (!isRecord(value)) return undefined;
66
+ switch(value.kind){
67
+ case 'none':
68
+ return {
69
+ kind: 'none'
70
+ };
71
+ case 'choice':
72
+ return typeof value.option === 'string' ? {
73
+ kind: 'choice',
74
+ option: value.option
75
+ } : undefined;
76
+ case 'selection':
77
+ return Array.isArray(value.ids) && value.ids.every((id)=>typeof id === 'string') ? {
78
+ kind: 'selection',
79
+ ids: value.ids
80
+ } : undefined;
81
+ case 'form':
82
+ return isDraft(value.values) ? {
83
+ kind: 'form',
84
+ values: value.values
85
+ } : undefined;
86
+ default:
87
+ return undefined;
88
+ }
89
+ }
90
+ /**
91
+ * Whether a restored value is a usable {@link EntityDraft}.
92
+ *
93
+ * The same two shapes `EntityDraft` allows, checked the way `isRowDraftArray`
94
+ * checks its half — a scalar is a string and a composition is a list of row
95
+ * drafts, and anything else means the entry was written by something that does
96
+ * not know the contract.
97
+ */ function isDraft(value) {
98
+ return isRecord(value) && Object.values(value).every((member)=>typeof member === 'string' || Array.isArray(member) && member.every(isRowOfStrings));
99
+ }
100
+ const isRowOfStrings = (row)=>isRecord(row) && Object.values(row).every((cell)=>typeof cell === 'string');
101
+ const isRecord = (value)=>typeof value === 'object' && value !== null && !Array.isArray(value);
102
+
103
+ //# sourceMappingURL=wizard-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/wizard/wizard-state.ts"],"sourcesContent":["import type { EntityDraft } from '../types/EntityDraft.js';\n\n/**\n * What one step holds.\n *\n * A wizard's state is **heterogeneous by construction** — a form step drafts\n * strings, a table step holds a set of ids, a branch point holds the option\n * taken — so this is a discriminated union rather than one shape with optional\n * members, which would let a form step carry ids nothing would ever read.\n *\n * ⚠️ A selection holds `readonly string[]`, **never a `ReadonlySet`**. A `Set`\n * serializes to `{}` and does it silently, which is the fault\n * [ADR 0035](../../../../../../docs/adr/0035-entity-actions-selection-and-bulk.md)\n * named for the wire — and a wizard's state goes through `createJSONStorage` on\n * every keystroke, so it would be met far more often here than there.\n */\nexport type WizardStepValue =\n | { readonly kind: 'form'; readonly values: EntityDraft }\n | { readonly kind: 'selection'; readonly ids: readonly string[] }\n | { readonly kind: 'choice'; readonly option: string }\n | { readonly kind: 'none' };\n\n/**\n * A wizard in progress: where the operator is, how they got there, and what\n * they have answered.\n *\n * **A `type`, never an `interface`.** This is persisted through\n * `createJSONStorage` and therefore has to satisfy `JsonValue`, and TypeScript\n * gives an interface no implicit index signature — the resulting \"Index\n * signature for type 'string' is missing\" explains nothing about the real cause\n * ([ADR 0032](../../../../../../docs/adr/0032-what-may-live-in-an-autosaved-draft.md)).\n *\n * `history` is **the path actually taken**, and it is what Back pops. A branch's\n * inverse is ambiguous once an earlier answer changes, so a computed `previous`\n * would walk the operator back through a path they were never on\n * ([ADR 0045](../../../../../../docs/adr/0045-the-wizard-a-step-graph-and-a-submit-that-hands-off.md)).\n *\n * `steps` is deliberately **not** pruned when a branch is abandoned. It is the\n * record of what was typed, and {@link wizardPath} decides what counts — so\n * flipping back to an earlier answer restores the work instead of discarding it,\n * while the summary and the submit still read only the steps on the live path.\n */\nexport type WizardState = {\n readonly activeStep: string;\n readonly history: readonly string[];\n readonly steps: { readonly [stepId: string]: WizardStepValue };\n};\n\n/** A wizard that has been opened and not yet answered. */\nexport const emptyWizardState = (entryStepId: string): WizardState => ({\n activeStep: entryStepId,\n history: [],\n steps: {},\n});\n\n/** The value stored for a step, or `undefined` when it has none. */\nexport const readStepValue = (\n state: WizardState,\n stepId: string,\n): WizardStepValue | undefined => state.steps[stepId];\n\n/**\n * The draft a form step holds, or an empty one.\n *\n * The fallback is `{}` rather than `undefined` for the reason every draft read\n * in this repo has one: a form handed `undefined` flips its inputs from\n * controlled to uncontrolled mid-render.\n */\nexport const readStepDraft = (\n state: WizardState,\n stepId: string,\n): EntityDraft => {\n const value = state.steps[stepId];\n return value?.kind === 'form' ? value.values : {};\n};\n\n/** The ids a selection step holds, or none. */\nexport const readStepIds = (\n state: WizardState,\n stepId: string,\n): readonly string[] => {\n const value = state.steps[stepId];\n return value?.kind === 'selection' ? value.ids : [];\n};\n\n/** The option a choice step holds, or `undefined` while it is unanswered. */\nexport const readStepChoice = (\n state: WizardState,\n stepId: string,\n): string | undefined => {\n const value = state.steps[stepId];\n return value?.kind === 'choice' ? value.option : undefined;\n};\n\n/** The state with one step's value replaced. */\nexport const withStepValue = (\n state: WizardState,\n stepId: string,\n value: WizardStepValue,\n): WizardState => ({\n ...state,\n steps: { ...state.steps, [stepId]: value },\n});\n\n/**\n * Narrows a restored value to a usable state.\n *\n * A persisted wizard comes back as `JsonValue`, so it can be anything — written\n * by a build before a step existed, `null`, or the right shape with the wrong\n * contents. Every caller must ask before reading, and the answer for a value\n * that fails is a **fresh** wizard rather than a crash: an unreadable draft is\n * an unfinished edit, and `restoreEntityDraft` already discards those per entry\n * rather than losing the whole form.\n *\n * A step value of an unknown `kind` fails the whole state rather than being\n * dropped, deliberately. Dropping it would resume the operator on a step whose\n * answer had silently vanished, which reads as the wizard having forgotten one\n * page of a flow it otherwise restored perfectly.\n */\nexport function readWizardState(value: unknown): WizardState | undefined {\n if (!isRecord(value)) return undefined;\n\n const { activeStep, history, steps } = value;\n if (typeof activeStep !== 'string' || activeStep === '') return undefined;\n if (!Array.isArray(history)) return undefined;\n if (!history.every(entry => typeof entry === 'string')) return undefined;\n if (!isRecord(steps)) return undefined;\n\n const readSteps: Record<string, WizardStepValue> = {};\n for (const [stepId, stepValue] of Object.entries(steps)) {\n const read = readStepValueOf(stepValue);\n if (read === undefined) return undefined;\n readSteps[stepId] = read;\n }\n\n return { activeStep, history, steps: readSteps };\n}\n\nfunction readStepValueOf(value: unknown): WizardStepValue | undefined {\n if (!isRecord(value)) return undefined;\n\n switch (value.kind) {\n case 'none':\n return { kind: 'none' };\n case 'choice':\n return typeof value.option === 'string'\n ? { kind: 'choice', option: value.option }\n : undefined;\n case 'selection':\n return Array.isArray(value.ids) &&\n value.ids.every(id => typeof id === 'string')\n ? { kind: 'selection', ids: value.ids }\n : undefined;\n case 'form':\n return isDraft(value.values)\n ? { kind: 'form', values: value.values }\n : undefined;\n default:\n return undefined;\n }\n}\n\n/**\n * Whether a restored value is a usable {@link EntityDraft}.\n *\n * The same two shapes `EntityDraft` allows, checked the way `isRowDraftArray`\n * checks its half — a scalar is a string and a composition is a list of row\n * drafts, and anything else means the entry was written by something that does\n * not know the contract.\n */\nfunction isDraft(value: unknown): value is EntityDraft {\n return (\n isRecord(value) &&\n Object.values(value).every(\n member =>\n typeof member === 'string' ||\n (Array.isArray(member) && member.every(isRowOfStrings)),\n )\n );\n}\n\nconst isRowOfStrings = (row: unknown): boolean =>\n isRecord(row) && Object.values(row).every(cell => typeof cell === 'string');\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n"],"names":["emptyWizardState","entryStepId","activeStep","history","steps","readStepValue","state","stepId","readStepDraft","value","kind","values","readStepIds","ids","readStepChoice","option","undefined","withStepValue","readWizardState","isRecord","Array","isArray","every","entry","readSteps","stepValue","Object","entries","read","readStepValueOf","id","isDraft","member","isRowOfStrings","row","cell"],"mappings":";AAgDA,wDAAwD,GACxD,OAAO,MAAMA,mBAAmB,CAACC,cAAsC,CAAA;QACrEC,YAAYD;QACZE,SAAS,EAAE;QACXC,OAAO,CAAC;IACV,CAAA,EAAG;AAEH,kEAAkE,GAClE,OAAO,MAAMC,gBAAgB,CAC3BC,OACAC,SACgCD,MAAMF,KAAK,CAACG,OAAO,CAAC;AAEtD;;;;;;CAMC,GACD,OAAO,MAAMC,gBAAgB,CAC3BF,OACAC;IAEA,MAAME,QAAQH,MAAMF,KAAK,CAACG,OAAO;IACjC,OAAOE,CAAAA,yBAAAA,MAAOC,IAAI,MAAK,SAASD,MAAME,MAAM,GAAG,CAAC;AAClD,EAAE;AAEF,6CAA6C,GAC7C,OAAO,MAAMC,cAAc,CACzBN,OACAC;IAEA,MAAME,QAAQH,MAAMF,KAAK,CAACG,OAAO;IACjC,OAAOE,CAAAA,yBAAAA,MAAOC,IAAI,MAAK,cAAcD,MAAMI,GAAG,GAAG,EAAE;AACrD,EAAE;AAEF,2EAA2E,GAC3E,OAAO,MAAMC,iBAAiB,CAC5BR,OACAC;IAEA,MAAME,QAAQH,MAAMF,KAAK,CAACG,OAAO;IACjC,OAAOE,CAAAA,yBAAAA,MAAOC,IAAI,MAAK,WAAWD,MAAMM,MAAM,GAAGC;AACnD,EAAE;AAEF,8CAA8C,GAC9C,OAAO,MAAMC,gBAAgB,CAC3BX,OACAC,QACAE,QACiB,aACdH;QACHF,OAAO,aAAKE,MAAMF,KAAK;YAAE,CAACG,OAAO,EAAEE;;OAClC;AAEH;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASS,gBAAgBT,KAAc;IAC5C,IAAI,CAACU,SAASV,QAAQ,OAAOO;IAE7B,MAAM,EAAEd,UAAU,EAAEC,OAAO,EAAEC,KAAK,EAAE,GAAGK;IACvC,IAAI,OAAOP,eAAe,YAAYA,eAAe,IAAI,OAAOc;IAChE,IAAI,CAACI,MAAMC,OAAO,CAAClB,UAAU,OAAOa;IACpC,IAAI,CAACb,QAAQmB,KAAK,CAACC,CAAAA,QAAS,OAAOA,UAAU,WAAW,OAAOP;IAC/D,IAAI,CAACG,SAASf,QAAQ,OAAOY;IAE7B,MAAMQ,YAA6C,CAAC;IACpD,KAAK,MAAM,CAACjB,QAAQkB,UAAU,IAAIC,OAAOC,OAAO,CAACvB,OAAQ;QACvD,MAAMwB,OAAOC,gBAAgBJ;QAC7B,IAAIG,SAASZ,WAAW,OAAOA;QAC/BQ,SAAS,CAACjB,OAAO,GAAGqB;IACtB;IAEA,OAAO;QAAE1B;QAAYC;QAASC,OAAOoB;IAAU;AACjD;AAEA,SAASK,gBAAgBpB,KAAc;IACrC,IAAI,CAACU,SAASV,QAAQ,OAAOO;IAE7B,OAAQP,MAAMC,IAAI;QAChB,KAAK;YACH,OAAO;gBAAEA,MAAM;YAAO;QACxB,KAAK;YACH,OAAO,OAAOD,MAAMM,MAAM,KAAK,WAC3B;gBAAEL,MAAM;gBAAUK,QAAQN,MAAMM,MAAM;YAAC,IACvCC;QACN,KAAK;YACH,OAAOI,MAAMC,OAAO,CAACZ,MAAMI,GAAG,KAC5BJ,MAAMI,GAAG,CAACS,KAAK,CAACQ,CAAAA,KAAM,OAAOA,OAAO,YAClC;gBAAEpB,MAAM;gBAAaG,KAAKJ,MAAMI,GAAG;YAAC,IACpCG;QACN,KAAK;YACH,OAAOe,QAAQtB,MAAME,MAAM,IACvB;gBAAED,MAAM;gBAAQC,QAAQF,MAAME,MAAM;YAAC,IACrCK;QACN;YACE,OAAOA;IACX;AACF;AAEA;;;;;;;CAOC,GACD,SAASe,QAAQtB,KAAc;IAC7B,OACEU,SAASV,UACTiB,OAAOf,MAAM,CAACF,OAAOa,KAAK,CACxBU,CAAAA,SACE,OAAOA,WAAW,YACjBZ,MAAMC,OAAO,CAACW,WAAWA,OAAOV,KAAK,CAACW;AAG/C;AAEA,MAAMA,iBAAiB,CAACC,MACtBf,SAASe,QAAQR,OAAOf,MAAM,CAACuB,KAAKZ,KAAK,CAACa,CAAAA,OAAQ,OAAOA,SAAS;AAEpE,MAAMhB,WAAW,CAACV,QAChB,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACW,MAAMC,OAAO,CAACZ"}