@livenetworks/ashlar 1.6.1 → 2.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 (559) hide show
  1. package/LICENSE +641 -0
  2. package/README.md +202 -86
  3. package/{js → components}/COMPONENTS.md +1116 -1108
  4. package/{js → components}/index.js +81 -58
  5. package/{js → components}/ln-accordion/README.md +7 -6
  6. package/components/ln-accordion/ln-accordion-dev.scss +8 -0
  7. package/components/ln-accordion/ln-accordion.js +1 -0
  8. package/components/ln-accordion/ln-accordion.schema.json +30 -0
  9. package/components/ln-accordion/ln-accordion.scss +8 -0
  10. package/{js → components}/ln-accordion/src/ln-accordion.js +8 -2
  11. package/{js → components}/ln-ajax/README.md +171 -160
  12. package/components/ln-ajax/ln-ajax-dev.scss +8 -0
  13. package/components/ln-ajax/ln-ajax.js +1 -0
  14. package/components/ln-ajax/ln-ajax.schema.json +30 -0
  15. package/{js → components}/ln-ajax/src/ln-ajax.js +65 -30
  16. package/{js → components}/ln-api-connector/README.md +27 -5
  17. package/components/ln-api-connector/ln-api-connector.js +1 -0
  18. package/components/ln-api-connector/ln-api-connector.schema.json +96 -0
  19. package/components/ln-api-connector/src/connector-core.js +97 -0
  20. package/components/ln-api-connector/src/ln-api-connector.js +447 -0
  21. package/{js → components}/ln-api-queue/README.md +12 -9
  22. package/components/ln-api-queue/ln-api-queue.js +1 -0
  23. package/components/ln-api-queue/ln-api-queue.schema.json +34 -0
  24. package/{js → components}/ln-api-queue/src/ln-api-queue.js +33 -14
  25. package/{js → components}/ln-api-queue/src/queue-storage.js +7 -3
  26. package/{js → components}/ln-autoresize/README.md +129 -127
  27. package/components/ln-autoresize/ln-autoresize-dev.scss +8 -0
  28. package/components/ln-autoresize/ln-autoresize.js +1 -0
  29. package/components/ln-autoresize/ln-autoresize.schema.json +22 -0
  30. package/{js → components}/ln-autoresize/src/ln-autoresize.js +8 -1
  31. package/{js → components}/ln-autosave/README.md +127 -124
  32. package/components/ln-autosave/ln-autosave-dev.scss +13 -0
  33. package/components/ln-autosave/ln-autosave.js +1 -0
  34. package/components/ln-autosave/ln-autosave.schema.json +48 -0
  35. package/components/ln-autosave/src/autosave-model.js +34 -0
  36. package/{js → components}/ln-autosave/src/ln-autosave.js +65 -58
  37. package/components/ln-chart/README.md +145 -0
  38. package/components/ln-chart/ln-chart-dev.scss +20 -0
  39. package/components/ln-chart/ln-chart.js +1 -0
  40. package/components/ln-chart/ln-chart.schema.json +146 -0
  41. package/components/ln-chart/ln-chart.scss +8 -0
  42. package/components/ln-chart/src/chart-model.js +154 -0
  43. package/components/ln-chart/src/ln-chart.js +176 -0
  44. package/{js → components}/ln-circular-progress/README.md +15 -14
  45. package/components/ln-circular-progress/ln-circular-progress-dev.scss +8 -0
  46. package/components/ln-circular-progress/ln-circular-progress.js +1 -0
  47. package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -0
  48. package/{js → components}/ln-circular-progress/src/ln-circular-progress.js +32 -50
  49. package/{js → components}/ln-confirm/README.md +69 -18
  50. package/components/ln-confirm/ln-confirm-dev.scss +24 -0
  51. package/components/ln-confirm/ln-confirm.js +1 -0
  52. package/components/ln-confirm/ln-confirm.schema.json +66 -0
  53. package/components/ln-confirm/ln-confirm.scss +24 -0
  54. package/{js → components}/ln-confirm/src/ln-confirm.js +180 -171
  55. package/{js → components}/ln-core/README.md +374 -149
  56. package/components/ln-core/attrs.js +273 -0
  57. package/components/ln-core/compare.js +40 -0
  58. package/components/ln-core/crypto.js +265 -0
  59. package/components/ln-core/date.js +50 -0
  60. package/components/ln-core/dom.js +115 -0
  61. package/components/ln-core/events.js +122 -0
  62. package/components/ln-core/form.js +136 -0
  63. package/{js → components}/ln-core/hash.js +149 -92
  64. package/components/ln-core/helpers.js +33 -0
  65. package/components/ln-core/http.js +48 -0
  66. package/components/ln-core/index.js +11 -0
  67. package/components/ln-core/lifecycle.js +403 -0
  68. package/components/ln-core/ln-core.schema.json +109 -0
  69. package/components/ln-core/locale.js +55 -0
  70. package/components/ln-core/matching.js +78 -0
  71. package/components/ln-core/number.js +125 -0
  72. package/components/ln-core/progress.js +30 -0
  73. package/components/ln-core/template.js +206 -0
  74. package/{js → components}/ln-core/window-cache.js +247 -213
  75. package/{js → components}/ln-couchdb-connector/README.md +7 -5
  76. package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -0
  77. package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -0
  78. package/{js → components}/ln-couchdb-connector/src/ln-couchdb-connector.js +29 -43
  79. package/{js → components}/ln-data-coordinator/README.md +109 -73
  80. package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -0
  81. package/components/ln-data-coordinator/ln-data-coordinator.js +1 -0
  82. package/components/ln-data-coordinator/ln-data-coordinator.schema.json +196 -0
  83. package/components/ln-data-coordinator/src/data-read-policy.js +41 -0
  84. package/{js → components}/ln-data-coordinator/src/ln-data-coordinator.js +411 -154
  85. package/{js → components}/ln-data-coordinator/src/mutation-receipts.js +0 -5
  86. package/{js → components}/ln-data-store/README.md +42 -17
  87. package/components/ln-data-store/ln-data-store-dev.scss +13 -0
  88. package/components/ln-data-store/ln-data-store.js +1 -0
  89. package/components/ln-data-store/ln-data-store.schema.json +84 -0
  90. package/components/ln-data-store/src/data-store-model.js +155 -0
  91. package/{js → components}/ln-data-store/src/ln-data-store.js +407 -105
  92. package/components/ln-data-store/src/window-index.js +119 -0
  93. package/{js → components}/ln-date/README.md +17 -7
  94. package/{js → components}/ln-date/ln-date-dev.scss +14 -14
  95. package/components/ln-date/ln-date.js +1 -0
  96. package/components/ln-date/ln-date.schema.json +92 -0
  97. package/components/ln-date/src/date-model.js +186 -0
  98. package/components/ln-date/src/ln-date.js +486 -0
  99. package/components/ln-debug/README.md +132 -0
  100. package/components/ln-debug/ln-debug.js +1 -0
  101. package/components/ln-debug/ln-debug.schema.json +28 -0
  102. package/components/ln-debug/src/console-sink.js +19 -0
  103. package/components/ln-debug/src/debug-verifier.js +331 -0
  104. package/components/ln-debug/src/gate.js +95 -0
  105. package/components/ln-debug/src/generated-attributes.js +299 -0
  106. package/components/ln-debug/src/ln-debug.js +60 -0
  107. package/{js → components}/ln-dropdown/README.md +150 -140
  108. package/components/ln-dropdown/ln-dropdown-dev.scss +13 -0
  109. package/components/ln-dropdown/ln-dropdown.js +1 -0
  110. package/components/ln-dropdown/ln-dropdown.schema.json +90 -0
  111. package/components/ln-dropdown/ln-dropdown.scss +18 -0
  112. package/{js → components}/ln-dropdown/src/ln-dropdown.js +114 -11
  113. package/{js → components}/ln-editor/README.md +11 -9
  114. package/components/ln-editor/ln-editor-dev.scss +18 -0
  115. package/components/ln-editor/ln-editor.js +1 -0
  116. package/components/ln-editor/ln-editor.schema.json +58 -0
  117. package/components/ln-editor/ln-editor.scss +13 -0
  118. package/{js → components}/ln-editor/src/ln-editor.js +59 -11
  119. package/{js → components}/ln-external-links/README.md +10 -8
  120. package/components/ln-external-links/ln-external-links.js +1 -0
  121. package/components/ln-external-links/ln-external-links.schema.json +18 -0
  122. package/{js → components}/ln-external-links/src/ln-external-links.js +13 -11
  123. package/{js → components}/ln-fill/README.md +6 -8
  124. package/components/ln-fill/ln-fill.js +1 -0
  125. package/components/ln-fill/ln-fill.schema.json +23 -0
  126. package/{js → components}/ln-fill/src/ln-fill.js +7 -1
  127. package/components/ln-filter/README.md +131 -0
  128. package/components/ln-filter/ln-filter-dev.scss +13 -0
  129. package/components/ln-filter/ln-filter.js +1 -0
  130. package/components/ln-filter/ln-filter.schema.json +153 -0
  131. package/components/ln-filter/src/filter-model.js +185 -0
  132. package/components/ln-filter/src/ln-filter.js +435 -0
  133. package/{js → components}/ln-form/README.md +260 -264
  134. package/components/ln-form/ln-form-dev.scss +8 -0
  135. package/components/ln-form/ln-form.js +1 -0
  136. package/components/ln-form/ln-form.schema.json +45 -0
  137. package/{js → components}/ln-form/src/ln-form.js +107 -99
  138. package/{js → components}/ln-http/README.md +11 -6
  139. package/components/ln-http/ln-http.js +1 -0
  140. package/components/ln-http/ln-http.schema.json +6 -0
  141. package/components/ln-http/src/http-core.js +51 -0
  142. package/{js → components}/ln-http/src/ln-http.js +28 -33
  143. package/{js → components}/ln-icon/README.md +16 -9
  144. package/components/ln-icon/ln-icon.schema.json +6 -0
  145. package/components/ln-include/README.md +75 -0
  146. package/components/ln-include/ln-include-dev.scss +13 -0
  147. package/components/ln-include/ln-include.js +1 -0
  148. package/components/ln-include/ln-include.schema.json +23 -0
  149. package/components/ln-include/src/ln-include.js +111 -0
  150. package/components/ln-key/README.md +130 -0
  151. package/components/ln-key/ln-key-dev.scss +18 -0
  152. package/components/ln-key/ln-key.js +1 -0
  153. package/components/ln-key/ln-key.schema.json +56 -0
  154. package/components/ln-key/src/key-model.js +146 -0
  155. package/components/ln-key/src/ln-key.js +201 -0
  156. package/{js → components}/ln-link/README.md +7 -9
  157. package/components/ln-link/ln-link-dev.scss +8 -0
  158. package/components/ln-link/ln-link.js +1 -0
  159. package/components/ln-link/ln-link.schema.json +22 -0
  160. package/{js → components}/ln-link/src/ln-link.js +16 -11
  161. package/components/ln-list/README.md +152 -0
  162. package/components/ln-list/ln-list-dev.scss +8 -0
  163. package/components/ln-list/ln-list.js +1 -0
  164. package/components/ln-list/ln-list.schema.json +166 -0
  165. package/components/ln-list/ln-list.scss +25 -0
  166. package/{js → components}/ln-list/src/ln-list.js +1301 -1216
  167. package/{js → components}/ln-modal/README.md +13 -10
  168. package/components/ln-modal/ln-modal-dev.scss +18 -0
  169. package/components/ln-modal/ln-modal.js +1 -0
  170. package/components/ln-modal/ln-modal.schema.json +54 -0
  171. package/components/ln-modal/ln-modal.scss +51 -0
  172. package/{js → components}/ln-modal/src/ln-modal.js +164 -137
  173. package/{js → components}/ln-nav/README.md +11 -11
  174. package/components/ln-nav/ln-nav.js +1 -0
  175. package/components/ln-nav/ln-nav.schema.json +25 -0
  176. package/{js → components}/ln-nav/src/ln-nav.js +25 -14
  177. package/components/ln-number/README.md +205 -0
  178. package/{js → components}/ln-number/ln-number-dev.scss +13 -13
  179. package/components/ln-number/ln-number.js +1 -0
  180. package/components/ln-number/ln-number.schema.json +63 -0
  181. package/components/ln-number/src/ln-number.js +400 -0
  182. package/components/ln-number/src/number-model.js +31 -0
  183. package/components/ln-obfuscator/README.md +60 -0
  184. package/components/ln-obfuscator/ln-obfuscator.js +1 -0
  185. package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -0
  186. package/components/ln-obfuscator/src/ln-obfuscator.js +159 -0
  187. package/components/ln-obfuscator/src/obfuscator-model.js +250 -0
  188. package/{js → components}/ln-options/README.md +3 -1
  189. package/components/ln-options/ln-options-dev.scss +13 -0
  190. package/components/ln-options/ln-options.js +1 -0
  191. package/components/ln-options/ln-options.schema.json +41 -0
  192. package/{js → components}/ln-options/src/ln-options.js +13 -5
  193. package/components/ln-persist/README.md +151 -0
  194. package/components/ln-persist/ln-persist.js +1 -0
  195. package/components/ln-persist/ln-persist.schema.json +28 -0
  196. package/components/ln-persist/src/ln-persist.js +83 -0
  197. package/components/ln-picklist/README.md +230 -0
  198. package/components/ln-picklist/ln-picklist-dev.scss +22 -0
  199. package/components/ln-picklist/ln-picklist.js +1 -0
  200. package/components/ln-picklist/ln-picklist.schema.json +49 -0
  201. package/components/ln-picklist/src/ln-picklist.js +228 -0
  202. package/{js → components}/ln-popover/README.md +164 -162
  203. package/components/ln-popover/ln-popover-dev.scss +13 -0
  204. package/components/ln-popover/ln-popover.js +1 -0
  205. package/components/ln-popover/ln-popover.schema.json +82 -0
  206. package/components/ln-popover/ln-popover.scss +18 -0
  207. package/{js → components}/ln-popover/src/ln-popover.js +42 -36
  208. package/{js → components}/ln-progress/README.md +410 -413
  209. package/components/ln-progress/ln-progress-dev.scss +8 -0
  210. package/components/ln-progress/ln-progress.js +1 -0
  211. package/components/ln-progress/ln-progress.schema.json +40 -0
  212. package/components/ln-progress/src/ln-progress.js +91 -0
  213. package/components/ln-progress/src/progress-model.js +20 -0
  214. package/{js → components}/ln-router/README.md +443 -432
  215. package/components/ln-router/ln-router-dev.scss +13 -0
  216. package/components/ln-router/ln-router.js +1 -0
  217. package/components/ln-router/ln-router.schema.json +68 -0
  218. package/{js → components}/ln-router/src/ln-router.js +585 -539
  219. package/components/ln-router/src/router-model.js +50 -0
  220. package/components/ln-scroll/README.md +45 -0
  221. package/components/ln-scroll/ln-scroll.js +1 -0
  222. package/components/ln-scroll/ln-scroll.schema.json +85 -0
  223. package/components/ln-scroll/src/ln-scroll.js +150 -0
  224. package/components/ln-search/README.md +188 -0
  225. package/components/ln-search/ln-search-dev.scss +13 -0
  226. package/components/ln-search/ln-search.js +1 -0
  227. package/components/ln-search/ln-search.schema.json +103 -0
  228. package/components/ln-search/src/ln-search.js +330 -0
  229. package/{js → components}/ln-slug/README.md +6 -3
  230. package/components/ln-slug/ln-slug-dev.scss +18 -0
  231. package/components/ln-slug/ln-slug.js +1 -0
  232. package/components/ln-slug/ln-slug.schema.json +23 -0
  233. package/{js → components}/ln-slug/src/ln-slug.js +20 -13
  234. package/components/ln-slug/src/slug-model.js +21 -0
  235. package/{js → components}/ln-sort/README.md +178 -170
  236. package/{js → components}/ln-sort/ln-sort-dev.scss +8 -8
  237. package/components/ln-sort/ln-sort.js +1 -0
  238. package/components/ln-sort/ln-sort.schema.json +104 -0
  239. package/components/ln-sort/src/ln-sort.js +321 -0
  240. package/components/ln-sort/src/sort-model.js +117 -0
  241. package/{js → components}/ln-sortable/README.md +7 -11
  242. package/components/ln-sortable/ln-sortable-dev.scss +13 -0
  243. package/components/ln-sortable/ln-sortable.js +1 -0
  244. package/components/ln-sortable/ln-sortable.schema.json +36 -0
  245. package/{js → components}/ln-sortable/src/ln-sortable.js +8 -13
  246. package/{js → components}/ln-stat/README.md +3 -1
  247. package/components/ln-stat/ln-stat-dev.scss +8 -0
  248. package/components/ln-stat/ln-stat.js +1 -0
  249. package/components/ln-stat/ln-stat.schema.json +32 -0
  250. package/{js → components}/ln-stat/src/ln-stat.js +14 -18
  251. package/components/ln-stat/src/stat-model.js +28 -0
  252. package/{js → components}/ln-table/README.md +37 -24
  253. package/{js → components}/ln-table/ln-table-dev.scss +17 -17
  254. package/components/ln-table/ln-table.js +1 -0
  255. package/components/ln-table/ln-table.schema.json +211 -0
  256. package/components/ln-table/ln-table.scss +15 -0
  257. package/{js → components}/ln-table/src/ln-table.js +1365 -1493
  258. package/components/ln-table/src/table-model.js +98 -0
  259. package/components/ln-table-coordinator/README.md +61 -0
  260. package/components/ln-table-coordinator/ln-table-coordinator.js +1 -0
  261. package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -0
  262. package/components/ln-table-coordinator/src/ln-table-coordinator.js +193 -0
  263. package/{js → components}/ln-tabs/README.md +32 -14
  264. package/components/ln-tabs/ln-tabs-dev.scss +24 -0
  265. package/components/ln-tabs/ln-tabs.js +1 -0
  266. package/components/ln-tabs/ln-tabs.schema.json +75 -0
  267. package/components/ln-tabs/ln-tabs.scss +8 -0
  268. package/components/ln-tabs/src/ln-tabs.js +207 -0
  269. package/components/ln-tabs/src/tabs-model.js +82 -0
  270. package/{js → components}/ln-time/README.md +96 -95
  271. package/components/ln-time/ln-time-dev.scss +13 -0
  272. package/components/ln-time/ln-time.js +1 -0
  273. package/components/ln-time/ln-time.schema.json +38 -0
  274. package/{js → components}/ln-time/src/ln-time.js +206 -223
  275. package/components/ln-time/src/time-model.js +64 -0
  276. package/{js → components}/ln-toast/README.md +23 -5
  277. package/components/ln-toast/ln-toast-dev.scss +8 -0
  278. package/components/ln-toast/ln-toast.js +1 -0
  279. package/components/ln-toast/ln-toast.schema.json +65 -0
  280. package/components/ln-toast/ln-toast.scss +59 -0
  281. package/{js → components}/ln-toast/src/ln-toast.js +233 -232
  282. package/{js → components}/ln-toggle/README.md +198 -196
  283. package/{js → components}/ln-toggle/ln-toggle-dev.scss +13 -13
  284. package/components/ln-toggle/ln-toggle.js +1 -0
  285. package/components/ln-toggle/ln-toggle.schema.json +52 -0
  286. package/components/ln-toggle/ln-toggle.scss +37 -0
  287. package/{js → components}/ln-toggle/src/ln-toggle.js +61 -46
  288. package/{js → components}/ln-tooltip/README.md +6 -6
  289. package/{js → components}/ln-tooltip/ln-tooltip-dev.scss +9 -9
  290. package/components/ln-tooltip/ln-tooltip.js +1 -0
  291. package/components/ln-tooltip/ln-tooltip.schema.json +86 -0
  292. package/components/ln-tooltip/ln-tooltip.scss +9 -0
  293. package/{js → components}/ln-tooltip/src/ln-tooltip.js +14 -3
  294. package/{js → components}/ln-translations/README.md +3 -1
  295. package/components/ln-translations/ln-translations-dev.scss +13 -0
  296. package/components/ln-translations/ln-translations.js +1 -0
  297. package/components/ln-translations/ln-translations.schema.json +120 -0
  298. package/{js → components}/ln-translations/src/ln-translations.js +25 -10
  299. package/components/ln-ui-coordinator/README.md +101 -0
  300. package/components/ln-ui-coordinator/ln-ui-coordinator-dev.scss +8 -0
  301. package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -0
  302. package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +60 -0
  303. package/{js/ln-modal-coordinator/src/ln-modal-coordinator.js → components/ln-ui-coordinator/src/ln-ui-coordinator.js} +403 -345
  304. package/components/ln-upload/README.md +133 -0
  305. package/components/ln-upload/ln-upload-dev.scss +18 -0
  306. package/components/ln-upload/ln-upload.js +1 -0
  307. package/components/ln-upload/ln-upload.schema.json +193 -0
  308. package/components/ln-upload/ln-upload.scss +20 -0
  309. package/components/ln-upload/src/ln-upload.js +652 -0
  310. package/components/ln-upload/src/upload-model.js +78 -0
  311. package/{js → components}/ln-validate/README.md +182 -180
  312. package/{js → components}/ln-validate/ln-validate-dev.scss +15 -15
  313. package/components/ln-validate/ln-validate.js +1 -0
  314. package/components/ln-validate/ln-validate.schema.json +50 -0
  315. package/components/ln-validate/ln-validate.scss +7 -0
  316. package/{js → components}/ln-validate/src/ln-validate.js +23 -45
  317. package/components/ln-validate/src/validate-model.js +64 -0
  318. package/components/ln-websocket-connector/README.md +166 -0
  319. package/components/ln-websocket-connector/ln-websocket-connector.js +1 -0
  320. package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -0
  321. package/components/ln-websocket-connector/src/ln-websocket-connector.js +279 -0
  322. package/ln-ashlar.html-data.json +1796 -0
  323. package/package.json +84 -61
  324. package/{scss → theme}/base/_global.scss +1 -2
  325. package/{scss → theme}/base/_reset.scss +1 -1
  326. package/{scss → theme}/base/_typography.scss +2 -0
  327. package/theme/brand.css +73 -0
  328. package/{scss → theme}/components/_app-shell.scss +8 -0
  329. package/theme/components/_button.scss +24 -0
  330. package/theme/components/_chart.scss +5 -0
  331. package/theme/components/_confirm.scss +6 -0
  332. package/{scss → theme}/components/_date.scss +30 -22
  333. package/{scss → theme}/components/_dropdown.scss +6 -1
  334. package/theme/components/_form.scss +140 -0
  335. package/{scss → theme}/components/_layout.scss +6 -0
  336. package/{scss → theme}/components/_ln-table.scss +1 -6
  337. package/theme/components/_picklist.scss +3 -0
  338. package/{scss → theme}/components/_sort.scss +10 -10
  339. package/theme/components/_status-badge.scss +6 -0
  340. package/{scss → theme}/components/_table.scss +16 -0
  341. package/{scss → theme}/components/_tabs.scss +0 -4
  342. package/theme/components/_toast.scss +48 -0
  343. package/{scss → theme}/components/_toggle.scss +1 -1
  344. package/theme/components/_upload.scss +45 -0
  345. package/{scss → theme}/config/_breakpoints.scss +1 -1
  346. package/theme/config/_contrast.scss +128 -0
  347. package/{scss → theme}/config/_density.scss +191 -205
  348. package/theme/config/_palette.scss +274 -0
  349. package/theme/config/_theme.scss +293 -0
  350. package/{scss → theme}/config/_tokens.scss +285 -441
  351. package/{scss → theme}/config/mixins/_accordion.scss +1 -1
  352. package/{scss → theme}/config/mixins/_alert.scss +1 -0
  353. package/{scss → theme}/config/mixins/_app-shell.scss +4 -2
  354. package/{scss → theme}/config/mixins/_borders.scss +2 -0
  355. package/theme/config/mixins/_btn.scss +175 -0
  356. package/{scss → theme}/config/mixins/_card.scss +55 -46
  357. package/theme/config/mixins/_chart.scss +82 -0
  358. package/{scss → theme}/config/mixins/_collapsible.scss +2 -1
  359. package/{scss → theme}/config/mixins/_colors.scss +8 -14
  360. package/{scss → theme}/config/mixins/_diagnostics.scss +48 -48
  361. package/theme/config/mixins/_dropdown.scss +169 -0
  362. package/{scss → theme}/config/mixins/_editor.scss +0 -7
  363. package/{scss → theme}/config/mixins/_filter.scss +47 -47
  364. package/{scss → theme}/config/mixins/_footer.scss +1 -1
  365. package/{scss → theme}/config/mixins/_form.scss +49 -18
  366. package/{scss → theme}/config/mixins/_index.scss +62 -61
  367. package/{scss → theme}/config/mixins/_layout.scss +6 -2
  368. package/{scss → theme}/config/mixins/_ln-table.scss +31 -10
  369. package/{scss → theme}/config/mixins/_loader.scss +1 -1
  370. package/{scss → theme}/config/mixins/_modal.scss +145 -149
  371. package/{scss → theme}/config/mixins/_motion.scss +13 -0
  372. package/{scss → theme}/config/mixins/_nav.scss +7 -7
  373. package/theme/config/mixins/_picklist.scss +66 -0
  374. package/theme/config/mixins/_popover.scss +96 -0
  375. package/{scss → theme}/config/mixins/_sidebar.scss +7 -4
  376. package/{scss → theme}/config/mixins/_sort.scss +43 -42
  377. package/{scss → theme}/config/mixins/_status-badge.scss +15 -2
  378. package/{scss → theme}/config/mixins/_table.scss +25 -14
  379. package/{scss → theme}/config/mixins/_tabs.scss +1 -1
  380. package/{scss → theme}/config/mixins/_toast.scss +174 -179
  381. package/{scss → theme}/config/mixins/_tooltip.scss +2 -2
  382. package/{scss → theme}/config/mixins/_typography.scss +16 -5
  383. package/{scss → theme}/config/mixins/_upload.scss +8 -6
  384. package/theme/ln-ashlar-core.scss +24 -0
  385. package/theme/ln-ashlar-dev.scss +66 -0
  386. package/theme/ln-ashlar-landing.scss +56 -0
  387. package/{scss/ln-ashlar.scss → theme/ln-ashlar-theme.scss} +63 -69
  388. package/theme/ln-ashlar.scss +8 -0
  389. package/theme/presentation/_bento.scss +151 -0
  390. package/theme/presentation/_cta.scss +111 -0
  391. package/theme/presentation/_effects.scss +216 -0
  392. package/theme/presentation/_features.scss +108 -0
  393. package/theme/presentation/_footer.scss +129 -0
  394. package/theme/presentation/_hero.scss +158 -0
  395. package/theme/presentation/_layout.scss +170 -0
  396. package/theme/presentation/_navbar.scss +140 -0
  397. package/theme/presentation/_pricing.scss +262 -0
  398. package/theme/presentation/_stats.scss +87 -0
  399. package/theme/presentation/_testimonials.scss +124 -0
  400. package/theme/presentation/_tokens.scss +39 -0
  401. package/theme/presentation/_typography.scss +163 -0
  402. package/{scss → theme}/utilities/_animations.scss +38 -0
  403. package/{scss → theme}/utilities/_utilities.scss +6 -0
  404. package/web-types.json +2312 -0
  405. package/js/ln-accordion/ln-accordion.js +0 -1
  406. package/js/ln-ajax/ln-ajax.js +0 -1
  407. package/js/ln-api-connector/ln-api-connector.js +0 -1
  408. package/js/ln-api-connector/src/ln-api-connector.js +0 -368
  409. package/js/ln-api-queue/ln-api-queue.js +0 -1
  410. package/js/ln-autoresize/ln-autoresize.js +0 -1
  411. package/js/ln-autosave/ln-autosave.js +0 -1
  412. package/js/ln-circular-progress/ln-circular-progress.js +0 -1
  413. package/js/ln-confirm/_ln-confirm.scss +0 -24
  414. package/js/ln-confirm/ln-confirm.js +0 -1
  415. package/js/ln-core/crypto.js +0 -83
  416. package/js/ln-core/helpers.js +0 -788
  417. package/js/ln-core/index.js +0 -7
  418. package/js/ln-core/persist.js +0 -97
  419. package/js/ln-couchdb-connector/ln-couchdb-connector.js +0 -1
  420. package/js/ln-data-coordinator/ln-data-coordinator.js +0 -1
  421. package/js/ln-data-coordinator/src/data-read-policy.js +0 -18
  422. package/js/ln-data-store/ln-data-store.js +0 -1
  423. package/js/ln-date/ln-date.js +0 -1
  424. package/js/ln-date/src/ln-date.js +0 -603
  425. package/js/ln-debug/README.md +0 -58
  426. package/js/ln-debug/ln-debug.js +0 -1
  427. package/js/ln-debug/src/ln-debug.js +0 -19
  428. package/js/ln-dropdown/ln-dropdown.js +0 -1
  429. package/js/ln-dropdown/ln-dropdown.scss +0 -15
  430. package/js/ln-editor/ln-editor.js +0 -1
  431. package/js/ln-editor/ln-editor.scss +0 -43
  432. package/js/ln-external-links/ln-external-links.js +0 -1
  433. package/js/ln-fill/ln-fill.js +0 -1
  434. package/js/ln-filter/README.md +0 -189
  435. package/js/ln-filter/ln-filter-dev.scss +0 -8
  436. package/js/ln-filter/ln-filter.js +0 -1
  437. package/js/ln-filter/src/ln-filter.js +0 -419
  438. package/js/ln-form/ln-form.js +0 -1
  439. package/js/ln-http/ln-http.js +0 -1
  440. package/js/ln-link/ln-link.js +0 -1
  441. package/js/ln-list/README.md +0 -129
  442. package/js/ln-list/ln-list.js +0 -1
  443. package/js/ln-list/ln-list.scss +0 -28
  444. package/js/ln-modal/ln-modal-dev.scss +0 -13
  445. package/js/ln-modal/ln-modal.js +0 -1
  446. package/js/ln-modal/ln-modal.scss +0 -35
  447. package/js/ln-modal-coordinator/README.md +0 -99
  448. package/js/ln-modal-coordinator/ln-modal-coordinator-dev.scss +0 -8
  449. package/js/ln-modal-coordinator/ln-modal-coordinator.js +0 -1
  450. package/js/ln-nav/ln-nav.js +0 -1
  451. package/js/ln-number/README.md +0 -149
  452. package/js/ln-number/ln-number.js +0 -1
  453. package/js/ln-number/src/ln-number.js +0 -443
  454. package/js/ln-options/ln-options.js +0 -1
  455. package/js/ln-popover/ln-popover.js +0 -1
  456. package/js/ln-progress/ln-progress.js +0 -1
  457. package/js/ln-progress/src/ln-progress.js +0 -98
  458. package/js/ln-router/ln-router.js +0 -1
  459. package/js/ln-search/README.md +0 -158
  460. package/js/ln-search/ln-search-dev.scss +0 -8
  461. package/js/ln-search/ln-search.js +0 -1
  462. package/js/ln-search/src/ln-search.js +0 -117
  463. package/js/ln-slug/ln-slug.js +0 -1
  464. package/js/ln-sort/ln-sort.js +0 -1
  465. package/js/ln-sort/src/ln-sort.js +0 -178
  466. package/js/ln-sortable/ln-sortable.js +0 -1
  467. package/js/ln-stat/ln-stat.js +0 -1
  468. package/js/ln-table/ln-table.js +0 -1
  469. package/js/ln-table/ln-table.scss +0 -11
  470. package/js/ln-table-coordinator/README.md +0 -73
  471. package/js/ln-table-coordinator/ln-table-coordinator.js +0 -1
  472. package/js/ln-table-coordinator/src/ln-table-coordinator.js +0 -160
  473. package/js/ln-tabs/ln-tabs-dev.scss +0 -18
  474. package/js/ln-tabs/ln-tabs.js +0 -1
  475. package/js/ln-tabs/src/ln-tabs.js +0 -188
  476. package/js/ln-time/ln-time.js +0 -1
  477. package/js/ln-toast/ln-toast.js +0 -1
  478. package/js/ln-toggle/ln-toggle.js +0 -1
  479. package/js/ln-tooltip/ln-tooltip.js +0 -1
  480. package/js/ln-tooltip/ln-tooltip.scss +0 -9
  481. package/js/ln-translations/ln-translations.js +0 -1
  482. package/js/ln-upload/README.md +0 -255
  483. package/js/ln-upload/ln-upload.js +0 -1
  484. package/js/ln-upload/ln-upload.scss +0 -20
  485. package/js/ln-upload/src/ln-upload.js +0 -423
  486. package/js/ln-validate/ln-validate.js +0 -1
  487. package/scss/components/_button.scss +0 -20
  488. package/scss/components/_confirm.scss +0 -5
  489. package/scss/components/_form.scss +0 -107
  490. package/scss/components/_status-badge.scss +0 -4
  491. package/scss/components/_toast.scss +0 -68
  492. package/scss/components/_upload.scss +0 -51
  493. package/scss/config/_theme.scss +0 -216
  494. package/scss/config/mixins/_btn.scss +0 -179
  495. package/scss/config/mixins/_confirm.scss +0 -31
  496. package/scss/config/mixins/_dropdown.scss +0 -141
  497. package/scss/config/mixins/_popover.scss +0 -64
  498. package/scss/ln-ashlar-dev.scss +0 -39
  499. /package/{js → components}/ln-core/positioning.js +0 -0
  500. /package/{js → components}/ln-core/reactive.js +0 -0
  501. /package/{js → components}/ln-filter/ln-filter.scss +0 -0
  502. /package/{js → components}/ln-icon/ln-icon.js +0 -0
  503. /package/{js → components}/ln-icon/src/ln-icon.js +0 -0
  504. /package/{js → components}/ln-search/ln-search.scss +0 -0
  505. /package/{js → components}/ln-toast/template.html +0 -0
  506. /package/{scss → theme}/components/_accordion.scss +0 -0
  507. /package/{scss → theme}/components/_ajax.scss +0 -0
  508. /package/{scss → theme}/components/_alert.scss +0 -0
  509. /package/{scss → theme}/components/_avatar.scss +0 -0
  510. /package/{scss → theme}/components/_breadcrumbs.scss +0 -0
  511. /package/{scss → theme}/components/_card.scss +0 -0
  512. /package/{scss → theme}/components/_chip.scss +0 -0
  513. /package/{scss → theme}/components/_circular-progress.scss +0 -0
  514. /package/{scss → theme}/components/_editor.scss +0 -0
  515. /package/{scss → theme}/components/_empty-state.scss +0 -0
  516. /package/{scss → theme}/components/_filter.scss +0 -0
  517. /package/{scss → theme}/components/_link.scss +0 -0
  518. /package/{scss → theme}/components/_loader.scss +0 -0
  519. /package/{scss → theme}/components/_modal.scss +0 -0
  520. /package/{scss → theme}/components/_nav.scss +0 -0
  521. /package/{scss → theme}/components/_page-header.scss +0 -0
  522. /package/{scss → theme}/components/_popover.scss +0 -0
  523. /package/{scss → theme}/components/_progress.scss +0 -0
  524. /package/{scss → theme}/components/_prose.scss +0 -0
  525. /package/{scss → theme}/components/_scrollbar.scss +0 -0
  526. /package/{scss → theme}/components/_sections.scss +0 -0
  527. /package/{scss → theme}/components/_sidebar.scss +0 -0
  528. /package/{scss → theme}/components/_stat-card.scss +0 -0
  529. /package/{scss → theme}/components/_stepper.scss +0 -0
  530. /package/{scss → theme}/components/_timeline.scss +0 -0
  531. /package/{scss → theme}/components/_tooltip.scss +0 -0
  532. /package/{scss → theme}/components/_translations.scss +0 -0
  533. /package/{scss → theme}/config/_icons.scss +0 -0
  534. /package/{scss → theme}/config/_mixins.scss +0 -0
  535. /package/{scss → theme}/config/mixins/_ajax.scss +0 -0
  536. /package/{scss → theme}/config/mixins/_avatar.scss +0 -0
  537. /package/{scss → theme}/config/mixins/_breadcrumbs.scss +0 -0
  538. /package/{scss → theme}/config/mixins/_breakpoints.scss +0 -0
  539. /package/{scss → theme}/config/mixins/_chip.scss +0 -0
  540. /package/{scss → theme}/config/mixins/_circular-progress.scss +0 -0
  541. /package/{scss → theme}/config/mixins/_display.scss +0 -0
  542. /package/{scss → theme}/config/mixins/_empty-state.scss +0 -0
  543. /package/{scss → theme}/config/mixins/_focus.scss +0 -0
  544. /package/{scss → theme}/config/mixins/_interaction.scss +0 -0
  545. /package/{scss → theme}/config/mixins/_kbd.scss +0 -0
  546. /package/{scss → theme}/config/mixins/_link.scss +0 -0
  547. /package/{scss → theme}/config/mixins/_page-header.scss +0 -0
  548. /package/{scss → theme}/config/mixins/_position.scss +0 -0
  549. /package/{scss → theme}/config/mixins/_progress.scss +0 -0
  550. /package/{scss → theme}/config/mixins/_prose.scss +0 -0
  551. /package/{scss → theme}/config/mixins/_shadows.scss +0 -0
  552. /package/{scss → theme}/config/mixins/_sizing.scss +0 -0
  553. /package/{scss → theme}/config/mixins/_spacing.scss +0 -0
  554. /package/{scss → theme}/config/mixins/_stat-card.scss +0 -0
  555. /package/{scss → theme}/config/mixins/_stepper.scss +0 -0
  556. /package/{scss → theme}/config/mixins/_timeline.scss +0 -0
  557. /package/{scss → theme}/config/mixins/_transitions.scss +0 -0
  558. /package/{scss → theme}/config/mixins/_translations.scss +0 -0
  559. /package/{scss → theme}/tabler-icons.txt +0 -0
@@ -0,0 +1,447 @@
1
+ import { registerComponent, dispatch, getHeaders, parseHeaders, defineAttrs, attrSpec, attrStr } from '../../ln-core';
2
+ import { buildQueryParams, buildQueryUrl, joinUrl, unwrapEnvelope } from './connector-core';
3
+
4
+ (function () {
5
+ const DOM_SELECTOR = 'data-ln-api-connector';
6
+ const DOM_ATTRIBUTE = 'lnApiConnector';
7
+ const DOM_ALIAS = 'lnConnector';
8
+ if (window[DOM_ATTRIBUTE] !== undefined) return;
9
+
10
+ // ─── Attribute Contract (SSOT) ──────────────────────────
11
+ function _syncAttribute(el) {
12
+ const instance = el[DOM_ATTRIBUTE];
13
+ if (!instance) return;
14
+ instance.refreshConfig();
15
+ }
16
+
17
+ const ATTRIBUTES = {
18
+ 'data-ln-api-connector': { type: 'marker', description: 'Mounts API connector bridging REST backend and ln-ashlar data coordinators' },
19
+ 'data-ln-api-base-url': { prop: 'baseUrl', read: attrStr, type: 'string', fallback: '', effect: _syncAttribute, description: 'Base URL endpoint for API requests' },
20
+ 'data-ln-api-path': { prop: 'path', read: attrStr, type: 'string', fallback: '', effect: _syncAttribute, description: 'Resource path appended to base URL' },
21
+ 'data-ln-api-headers': { prop: 'rawHeaders', read: attrStr, type: 'json', fallback: null, effect: _syncAttribute, description: 'Custom HTTP headers in JSON format or semicolon-separated pairs' },
22
+ 'data-ln-api-param-offset': { effect: _syncAttribute, type: 'string', fallback: 'offset', description: 'Query parameter name for pagination offset' },
23
+ 'data-ln-api-param-limit': { effect: _syncAttribute, type: 'string', fallback: 'limit', description: 'Query parameter name for pagination page size' },
24
+ 'data-ln-api-param-search': { effect: _syncAttribute, type: 'string', fallback: 'search', description: 'Query parameter name for text search filter' },
25
+ 'data-ln-api-param-sort-field': { effect: _syncAttribute, type: 'string', fallback: 'sort_by', description: 'Query parameter name for sort field' },
26
+ 'data-ln-api-param-sort-dir': { effect: _syncAttribute, type: 'string', fallback: 'sort_dir', description: 'Query parameter name for sort direction' },
27
+ 'data-ln-api-connector-query-debounce': { effect: _syncAttribute, type: 'integer', fallback: 200, min: 0, description: 'Debounce delay in milliseconds before dispatching query requests' }
28
+ };
29
+ const ATTR_SPEC = attrSpec(ATTRIBUTES);
30
+
31
+ // ─── Response Resolver ──────────────────────────────────
32
+
33
+ function _resolve(res) {
34
+ if (res.ok) return res.status === 204 ? null : res.json();
35
+ return res.json().catch(() => null).then(body => {
36
+ const err = new Error('HTTP ' + res.status + ': ' + res.statusText);
37
+ err.status = res.status;
38
+ err.data = body;
39
+ throw err;
40
+ });
41
+ }
42
+
43
+ // ─── Component Constructor ─────────────────────────────
44
+
45
+ function _component(dom) {
46
+ this.dom = dom;
47
+ defineAttrs(this, dom, ATTR_SPEC);
48
+ dom[DOM_ATTRIBUTE] = this;
49
+ dom[DOM_ALIAS] = this; // Set alias for compatibility
50
+
51
+ this._inflight = new Map();
52
+ this._queryTimers = new Map(); // per-key: { timer, pendingDetail, pendingParams, pendingTarget }
53
+ this.refreshConfig();
54
+ this._handlers = null;
55
+ _bindEvents(this);
56
+
57
+ return this;
58
+ }
59
+
60
+ // ─── Refresh Config from DOM Attributes ─────────────────
61
+
62
+ _component.prototype.refreshConfig = function () {
63
+ const dom = this.dom;
64
+
65
+ this.credentials = 'same-origin';
66
+ this.headers = parseHeaders(this.rawHeaders);
67
+
68
+ const paramKeys = {};
69
+ const offset = dom.getAttribute('data-ln-api-param-offset');
70
+ if (offset) paramKeys.offset = offset;
71
+ const limit = dom.getAttribute('data-ln-api-param-limit');
72
+ if (limit) paramKeys.limit = limit;
73
+ const search = dom.getAttribute('data-ln-api-param-search');
74
+ if (search) paramKeys.search = search;
75
+ const sortField = dom.getAttribute('data-ln-api-param-sort-field');
76
+ if (sortField) paramKeys.sortField = sortField;
77
+ const sortDir = dom.getAttribute('data-ln-api-param-sort-dir');
78
+ if (sortDir) paramKeys.sortDir = sortDir;
79
+ this.paramKeys = paramKeys;
80
+
81
+ const qd = dom.getAttribute('data-ln-api-connector-query-debounce');
82
+ this.queryDebounce = qd !== null ? +qd : 300;
83
+
84
+ dispatch(this.dom, 'ln-api-connector:config-changed', {
85
+ baseUrl: this.baseUrl,
86
+ path: this.path,
87
+ headers: this.headers,
88
+ paramKeys: this.paramKeys
89
+ });
90
+ };
91
+
92
+ // ─── Request Headers (forces X-LN-Response) ─────────────
93
+
94
+ _component.prototype._reqHeaders = function (idempotencyKey) {
95
+ const headers = Object.assign({}, this.headers);
96
+ if (!headers['Accept'] && !headers['accept']) {
97
+ headers['Accept'] = 'application/json';
98
+ }
99
+ if (!headers['Content-Type'] && !headers['content-type']) {
100
+ headers['Content-Type'] = 'application/json';
101
+ }
102
+ if (idempotencyKey) {
103
+ headers['X-Idempotency-Key'] = idempotencyKey;
104
+ }
105
+ return headers;
106
+ };
107
+
108
+ // ─── Cancellation API ────────────────────────────────────
109
+
110
+ _component.prototype.cancel = function (key) {
111
+ if (!key) return false;
112
+ if (this._inflight.has(key)) {
113
+ this._inflight.get(key).abort();
114
+ this._inflight.delete(key);
115
+ return true;
116
+ }
117
+ return false;
118
+ };
119
+
120
+ // ─── JS API Methods (Promises) ──────────────────────────
121
+
122
+ _component.prototype.fetchDelta = function (since, targetEl) {
123
+ const self = this;
124
+ let url = joinUrl(self.baseUrl, self.path);
125
+
126
+ if (since !== undefined && since !== null && since !== '') {
127
+ url += (url.indexOf('?') !== -1 ? '&' : '?') + 'since=' + encodeURIComponent(since);
128
+ }
129
+
130
+ const key = targetEl || 'sync';
131
+ if (self._inflight.has(key)) {
132
+ self._inflight.get(key).abort();
133
+ }
134
+ const controller = new AbortController();
135
+ self._inflight.set(key, controller);
136
+
137
+ return window.fetch(url, {
138
+ method: 'GET',
139
+ headers: self._reqHeaders(),
140
+ credentials: self.credentials,
141
+ signal: controller.signal
142
+ })
143
+ .then(_resolve)
144
+ .finally(function () {
145
+ if (self._inflight.get(key) === controller) {
146
+ self._inflight.delete(key);
147
+ }
148
+ });
149
+ };
150
+
151
+ _component.prototype.query = function (queryParams, targetEl) {
152
+ const self = this;
153
+ const qs = buildQueryParams(queryParams, self.paramKeys);
154
+ const url = buildQueryUrl(self.baseUrl, self.path, qs);
155
+
156
+ const key = targetEl || 'query';
157
+ if (self._inflight.has(key)) {
158
+ self._inflight.get(key).abort();
159
+ }
160
+ const controller = new AbortController();
161
+ self._inflight.set(key, controller);
162
+
163
+ return window.fetch(url, {
164
+ method: 'GET',
165
+ headers: self._reqHeaders(),
166
+ credentials: self.credentials,
167
+ signal: controller.signal
168
+ })
169
+ .then(_resolve)
170
+ .finally(function () {
171
+ if (self._inflight.get(key) === controller) {
172
+ self._inflight.delete(key);
173
+ }
174
+ });
175
+ };
176
+
177
+ _component.prototype.create = function (payload, url, idempotencyKey) {
178
+ const self = this;
179
+ return window.fetch(joinUrl(self.baseUrl, url || self.path), {
180
+ method: 'POST',
181
+ headers: self._reqHeaders(idempotencyKey),
182
+ credentials: self.credentials,
183
+ body: JSON.stringify(payload)
184
+ })
185
+ .then(_resolve);
186
+ };
187
+
188
+ _component.prototype.update = function (id, payload, expectedVersion, url, idempotencyKey) {
189
+ const self = this;
190
+ if (expectedVersion !== undefined && expectedVersion !== null) {
191
+ payload = Object.assign({}, payload, { expected_version: expectedVersion });
192
+ }
193
+ // An explicit `url` is the COMPLETE resource URL — it already carries the
194
+ // id (e.g. the form's resolved action `/documents/42`). Do NOT re-append
195
+ // id, symmetric with create(). Only the path fallback needs id appended.
196
+ const target = url ? joinUrl(self.baseUrl, url) : joinUrl(self.baseUrl, self.path, id);
197
+ return window.fetch(target, {
198
+ method: 'PUT',
199
+ headers: self._reqHeaders(idempotencyKey),
200
+ credentials: self.credentials,
201
+ body: JSON.stringify(payload)
202
+ })
203
+ .then(_resolve);
204
+ };
205
+
206
+ _component.prototype.delete = function (id, url, idempotencyKey) {
207
+ const self = this;
208
+ return window.fetch(joinUrl(self.baseUrl, url || self.path, id), {
209
+ method: 'DELETE',
210
+ headers: self._reqHeaders(idempotencyKey),
211
+ credentials: self.credentials
212
+ })
213
+ .then(_resolve);
214
+ };
215
+
216
+ _component.prototype.bulkDelete = function (ids, url, idempotencyKey) {
217
+ const self = this;
218
+ return window.fetch(joinUrl(self.baseUrl, url || self.path, 'bulk-delete'), {
219
+ method: 'DELETE',
220
+ headers: self._reqHeaders(idempotencyKey),
221
+ credentials: self.credentials,
222
+ body: JSON.stringify({ ids: ids })
223
+ })
224
+ .then(_resolve);
225
+ };
226
+
227
+ // ─── DOM Event Routing ────────────────────────────────────
228
+
229
+ function _bindEvents(self) {
230
+ self._handlers = {
231
+ sync: function (e) {
232
+ const detail = e.detail || {};
233
+ const targetEl = (detail.meta && detail.meta.targetEl) ? detail.meta.targetEl : null;
234
+ self.fetchDelta(detail.since, targetEl)
235
+ .then(function (data) {
236
+ dispatch(self.dom, 'ln-api-connector:fetched', { data: data, since: detail.since, meta: detail.meta || null });
237
+ })
238
+ .catch(function (err) {
239
+ if (err && err.name === 'AbortError') return;
240
+ dispatch(self.dom, 'ln-api-connector:error', {
241
+ action: 'sync',
242
+ error: err.message,
243
+ status: err.status || 0,
244
+ data: err.data || null,
245
+ since: detail.since,
246
+ meta: detail.meta || null
247
+ });
248
+ });
249
+ },
250
+ query: function (e) {
251
+ const detail = e.detail || {};
252
+ const queryParams = detail.query || detail;
253
+ const targetEl = (detail.meta && detail.meta.targetEl) ? detail.meta.targetEl : null;
254
+ const key = targetEl || 'query';
255
+ const delay = self.queryDebounce;
256
+
257
+ function _doQuery(d, qp, tel) {
258
+ self.query(qp, tel)
259
+ .then(function (res) {
260
+ const payload = res || {};
261
+ dispatch(self.dom, 'ln-api-connector:fetched', {
262
+ data: payload.data || (Array.isArray(payload) ? payload : []),
263
+ total: payload.total,
264
+ filtered: payload.filtered,
265
+ offset: qp.offset,
266
+ queryGen: qp.queryGen,
267
+ meta: d.meta || null
268
+ });
269
+ })
270
+ .catch(function (err) {
271
+ if (err && err.name === 'AbortError') return;
272
+ dispatch(self.dom, 'ln-api-connector:error', {
273
+ action: 'query',
274
+ error: err.message,
275
+ status: err.status || 0,
276
+ data: err.data || null,
277
+ meta: d.meta || null
278
+ });
279
+ });
280
+ }
281
+
282
+ if (delay === 0) {
283
+ _doQuery(detail, queryParams, targetEl);
284
+ return;
285
+ }
286
+
287
+ if (self._queryTimers.has(key)) {
288
+ clearTimeout(self._queryTimers.get(key));
289
+ }
290
+
291
+ const timer = setTimeout(function () {
292
+ self._queryTimers.delete(key);
293
+ _doQuery(detail, queryParams, targetEl);
294
+ }, delay);
295
+
296
+ self._queryTimers.set(key, timer);
297
+ },
298
+ cancel: function (e) {
299
+ const detail = e.detail || {};
300
+ const targetKey = (detail.meta && detail.meta.targetEl) ? detail.meta.targetEl : (detail.targetEl || detail.key);
301
+ if (targetKey) self.cancel(targetKey);
302
+ },
303
+ create: function (e) {
304
+ const detail = e.detail || {};
305
+ self.create(detail.data, detail.url, detail.idempotencyKey)
306
+ .then(function (body) {
307
+ const unwrapped = unwrapEnvelope(body);
308
+ dispatch(self.dom, 'ln-api-connector:created', {
309
+ record: unwrapped.record,
310
+ tempId: detail.tempId,
311
+ message: unwrapped.message,
312
+ meta: detail.meta || null
313
+ });
314
+ })
315
+ .catch(function (err) {
316
+ if (err && err.name === 'AbortError') return;
317
+ dispatch(self.dom, 'ln-api-connector:error', {
318
+ action: 'create',
319
+ error: err.message,
320
+ status: err.status || 0,
321
+ data: err.data || null,
322
+ tempId: detail.tempId,
323
+ meta: detail.meta || null
324
+ });
325
+ });
326
+ },
327
+ update: function (e) {
328
+ const detail = e.detail || {};
329
+ self.update(detail.id, detail.data, detail.expected_version, detail.url, detail.idempotencyKey)
330
+ .then(function (body) {
331
+ const unwrapped = unwrapEnvelope(body);
332
+ dispatch(self.dom, 'ln-api-connector:updated', {
333
+ record: unwrapped.record,
334
+ id: detail.id,
335
+ message: unwrapped.message,
336
+ meta: detail.meta || null
337
+ });
338
+ })
339
+ .catch(function (err) {
340
+ if (err && err.name === 'AbortError') return;
341
+ dispatch(self.dom, 'ln-api-connector:error', {
342
+ action: 'update',
343
+ error: err.message,
344
+ status: err.status || 0,
345
+ data: err.data || null,
346
+ id: detail.id,
347
+ conflictData: err.status === 409 ? err.data : null,
348
+ meta: detail.meta || null
349
+ });
350
+ });
351
+ },
352
+ delete: function (e) {
353
+ const detail = e.detail || {};
354
+ self.delete(detail.id, detail.url, detail.idempotencyKey)
355
+ .then(function (body) {
356
+ const message = (body && body.message) ? body.message : null;
357
+ dispatch(self.dom, 'ln-api-connector:deleted', {
358
+ response: body,
359
+ id: detail.id,
360
+ message: message,
361
+ meta: detail.meta || null
362
+ });
363
+ })
364
+ .catch(function (err) {
365
+ if (err && err.name === 'AbortError') return;
366
+ dispatch(self.dom, 'ln-api-connector:error', {
367
+ action: 'delete',
368
+ error: err.message,
369
+ status: err.status || 0,
370
+ data: err.data || null,
371
+ id: detail.id,
372
+ meta: detail.meta || null
373
+ });
374
+ });
375
+ },
376
+ bulkDelete: function (e) {
377
+ const detail = e.detail || {};
378
+ self.bulkDelete(detail.ids, detail.url, detail.idempotencyKey)
379
+ .then(function (body) {
380
+ const message = (body && body.message) ? body.message : null;
381
+ dispatch(self.dom, 'ln-api-connector:bulk-deleted', {
382
+ response: body,
383
+ ids: detail.ids,
384
+ message: message,
385
+ meta: detail.meta || null
386
+ });
387
+ })
388
+ .catch(function (err) {
389
+ if (err && err.name === 'AbortError') return;
390
+ dispatch(self.dom, 'ln-api-connector:error', {
391
+ action: 'bulk-delete',
392
+ error: err.message,
393
+ status: err.status || 0,
394
+ data: err.data || null,
395
+ ids: detail.ids,
396
+ meta: detail.meta || null
397
+ });
398
+ });
399
+ }
400
+ };
401
+
402
+ self.dom.addEventListener('ln-api-connector:request-sync', self._handlers.sync);
403
+ self.dom.addEventListener('ln-api-connector:request-query', self._handlers.query);
404
+ self.dom.addEventListener('ln-api-connector:request-cancel', self._handlers.cancel);
405
+ self.dom.addEventListener('ln-api-connector:request-create', self._handlers.create);
406
+ self.dom.addEventListener('ln-api-connector:request-update', self._handlers.update);
407
+ self.dom.addEventListener('ln-api-connector:request-delete', self._handlers.delete);
408
+ self.dom.addEventListener('ln-api-connector:request-bulk-delete', self._handlers.bulkDelete);
409
+ }
410
+
411
+ _component.prototype.destroy = function () {
412
+ if (!this.dom[DOM_ATTRIBUTE]) return;
413
+
414
+ const self = this;
415
+ if (self._inflight) {
416
+ self._inflight.forEach(function (controller) {
417
+ controller.abort();
418
+ });
419
+ self._inflight.clear();
420
+ }
421
+
422
+ if (this._queryTimers) {
423
+ this._queryTimers.forEach(function (timer) {
424
+ if (timer) clearTimeout(timer);
425
+ });
426
+ this._queryTimers.clear();
427
+ }
428
+
429
+ if (this._handlers) {
430
+ self.dom.removeEventListener('ln-api-connector:request-sync', self._handlers.sync);
431
+ self.dom.removeEventListener('ln-api-connector:request-query', self._handlers.query);
432
+ self.dom.removeEventListener('ln-api-connector:request-cancel', self._handlers.cancel);
433
+ self.dom.removeEventListener('ln-api-connector:request-create', self._handlers.create);
434
+ self.dom.removeEventListener('ln-api-connector:request-update', self._handlers.update);
435
+ self.dom.removeEventListener('ln-api-connector:request-delete', self._handlers.delete);
436
+ self.dom.removeEventListener('ln-api-connector:request-bulk-delete', self._handlers.bulkDelete);
437
+ self._handlers = null;
438
+ }
439
+
440
+ delete this.dom[DOM_ATTRIBUTE];
441
+ delete this.dom[DOM_ALIAS];
442
+ };
443
+
444
+ registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-api-connector', {
445
+ attributes: ATTRIBUTES
446
+ });
447
+ })();
@@ -1,5 +1,7 @@
1
1
  # `data-ln-api-queue`
2
2
 
3
+ > Applied to an outbox element (`<li data-ln-api-queue>`) nested inside `data-ln-data-coordinator`. It listens for `ln-api-queue:request-enqueue` from the coordinator, persists mutations to an internal `IndexedDB` outbox (`ln_api_queue`) with monotonic per-scope sequence counters, and emits `ln-api-queue:send` CustomEvents for FIFO dispatch. It never initiates network requests directly, updating retry attempts with exponential backoff until acknowledged via `ack`/`nack`.
4
+
3
5
  A zero-dependency, Local-First **offline write outbox** component that implements the persistent-queue tier of `ln-ashlar`'s 3-tier data layer.
4
6
 
5
7
  This component persists pending mutations to its own `IndexedDB` database and replays them, FIFO per chain, once the coordinator can execute transport for them. It is **connector-blind and id-blind** — it never calls the network itself, never knows about REST paths, and never interprets `entryId`/`targetId`/`chainKey` beyond bookkeeping. The parent `ln-data-coordinator` executes the actual transport call on the queue's `ln-api-queue:send` command and reports the outcome back via `ack` / `nack`.
@@ -11,9 +13,9 @@ This component persists pending mutations to its own `IndexedDB` database and re
11
13
  Place the queue inside your parent coordinator element alongside your store and connector — it is an **optional** third child:
12
14
 
13
15
  ```html
14
- <ul data-ln-data-coordinator="documents" hidden>
16
+ <ul id="documents-module" data-ln-data-coordinator hidden>
15
17
  <!-- Storage Layer Cache (Blind to networking) -->
16
- <li data-ln-data-store
18
+ <li id="documents" data-ln-data-store
17
19
  data-ln-data-store-indexes="status,updated_at">
18
20
  </li>
19
21
 
@@ -24,7 +26,7 @@ Place the queue inside your parent coordinator element alongside your store and
24
26
  </li>
25
27
 
26
28
  <!-- Offline Outbox (optional Child 3) -->
27
- <li data-ln-api-queue></li>
29
+ <li id="documents-queue" data-ln-api-queue></li>
28
30
  </ul>
29
31
  ```
30
32
 
@@ -36,8 +38,9 @@ When this child is absent, the coordinator's write handlers call the connector d
36
38
 
37
39
  | Attribute | Category | Description |
38
40
  |-----------|----------|-------------|
39
- | `data-ln-api-queue` | Selector | Creates the component instance. Optional value serves as a scope/name (defaults to the coordinator's scope). |
40
- | `data-ln-api-queue-online` | Status (read-only, reflected) | Set by the component itself — `"true"` when the scope is draining/idle normally, `"false"` while paused (e.g. auth pause). Useful for CSS hooks on a connectivity indicator; not meant to be written by consumers. |
41
+ | `id="name"` | Identity | Unique identifier of the queue (the scope name). Defaults to the coordinator's `id` if nested, else `'default'`. |
42
+ | `data-ln-api-queue` | Selector | Marker attribute to declare the component. |
43
+ | `data-ln-api-queue-online` | Connectivity Override | Consumer override attribute (e.g. `"false"` to simulate offline state during testing/manual debugging). Checked via `_isOnline()`. |
41
44
 
42
45
  ---
43
46
 
@@ -48,7 +51,7 @@ The queue owns its **own** IndexedDB database, `ln_api_queue` — entirely separ
48
51
  | Object store | Key path | Indexes | Purpose |
49
52
  |---|---|---|---|
50
53
  | `outbox` | `entryId` | `by_scope_chain` (`[scope, chainKey]`), `by_scope_seq` (`[scope, seq]`) | One row per pending mutation. `seq` is a monotonically increasing per-scope counter used to preserve global FIFO ordering within a scope; `by_scope_chain` is used to find the head entry per chain. |
51
- | `_queue_meta` | `key` | — | Holds `seq:<scope>` counters and `paused:<scope>` auth-pause state. |
54
+ | `_queue_meta` | `key` | — | Holds `seq:<scope>` counters and `paused:<scope>` state (`'auth'`, `'manual'`, or `false`). |
52
55
 
53
56
  Each `outbox` entry carries: `entryId`, `scope`, `chainKey`, `seq`, `op`, `targetId`, `payload`, `expectedVersion`, `meta`, `attempts`, `status` (`pending` / `inflight` / `failed`), `leaseOwner`, `leaseUntil`, and timestamps. The queue never inspects `payload` — it passes it through untouched to whatever the coordinator sends on `ln-api-queue:send`.
54
57
 
@@ -86,6 +89,7 @@ const queue = queueEl.lnApiQueue;
86
89
  | `ln-api-queue:request-remap` | `{ oldKey, newId }` | For pending entries whose chain is `oldKey`: any entry with `targetId === oldKey` gets `targetId = newId`; the chain itself is re-keyed from `oldKey` to `newId`; if `meta.action` contains `oldKey` as a substring, it is string-replaced with `newId` too (keeps a persisted per-record URL in sync after a create resolves). |
87
90
  | `ln-api-queue:resolve-create` | `{ entryId, oldKey, newId }` | Atomically deletes the acknowledged create and remaps every queued sibling from the temp key to the authoritative id in one transaction, then advances the chain. |
88
91
  | `ln-api-queue:request-resume` | `{}` | Clears the pause on this scope and resumes draining. |
92
+ | `ln-api-queue:request-pause` | `{}` | Manually pauses draining for this scope. |
89
93
  | `ln-api-queue:request-drain` | `{}` | Manually triggers a drain attempt (e.g. to retry `failed` entries). |
90
94
  | `ln-api-queue:request-clear` | `{}` | Deletes all entries for this scope (e.g. on logout). |
91
95
 
@@ -97,12 +101,11 @@ const queue = queueEl.lnApiQueue;
97
101
  | `ln-api-queue:enqueued` | `{ entryId, chainKey, count }` | An entry was persisted. |
98
102
  | `ln-api-queue:pending-count` | `{ count, scope }` | Live outbox depth for the scope — the primary UI-facing signal (badge, banner). |
99
103
  | `ln-api-queue:auth-required` | `{ entryId, chainKey }` | The scope paused after a `401`/`419` nack. The consumer drives re-authentication, then dispatches `request-resume`. |
100
- | `ln-api-queue:paused` | `{ reason }` | Draining paused for this scope. |
104
+ | `ln-api-queue:paused` | `{ reason: "auth" \| "manual", restored?: Boolean }` | Draining paused for this scope. `restored: true` when re-emitted upon component boot from persisted state. |
101
105
  | `ln-api-queue:resumed` | `{}` | Draining resumed for this scope. |
102
106
  | `ln-api-queue:failed` | `{ entryId, chainKey, attempts }` | Retries exhausted (see backoff below); the entry is retained (not deleted) for a manual `request-drain`. |
103
107
  | `ln-api-queue:drained` | `{ scope }` | The outbox for this scope is empty. |
104
108
  | `ln-api-queue:error` | `{ operation, entryId?, error }` | IndexedDB or queue orchestration failed without silently discarding the entry. |
105
- | `ln-api-queue:destroyed` | `{ scope }` | The instance was torn down. |
106
109
 
107
110
  ---
108
111
 
@@ -174,7 +177,7 @@ The queue never imports or references a connector, never constructs a URL, and n
174
177
 
175
178
  ```javascript
176
179
  (function () {
177
- const parent = document.querySelector('[data-ln-data-coordinator="documents"]');
180
+ const parent = document.getElementById('documents-module');
178
181
  const queueEl = parent.querySelector('[data-ln-api-queue]');
179
182
  const connectorEl = parent.querySelector('[data-ln-api-connector]');
180
183
 
@@ -0,0 +1 @@
1
+ (function(){"use strict";function R(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function k(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let o=null;for(let u=1;u<t.length;u++)if(t[u]&&t[u].nodeType===1){o=t[u];break}if(!k(o))return}e.apply(console,t)}}function w(e,t,r){const o=r||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,o),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:o}))}function A(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){A(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}const P={};function z(e,t){P[e]=t}function X(e){return P[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=z,window.lnCore.getDataMapper=X);function G(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,A(function(){new MutationObserver(function(){w(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const Q={};function J(e,t){if(!e||typeof t!="object")return;const r=e.toLowerCase().split("-")[0];Q[r]=t}function Y(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return Q[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=J,window.lnCore.getLocaleFallback=Y,window.lnCore.ensureLocaleObserver=G);const E={};function Z(e,t){E[e]||(E[e]=document.querySelector('[data-ln-template="'+e+'"]'));const r=E[e];return r?r.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function B(e,t){if(!e||!t)return e;const r=e.querySelectorAll("[data-ln-field]");for(let i=0;i<r.length;i++){const l=r[i],c=l.getAttribute("data-ln-field");t[c]!=null&&(l.textContent=t[c])}const o=e.querySelectorAll("[data-ln-attr]");for(let i=0;i<o.length;i++){const l=o[i],c=l.getAttribute("data-ln-attr").split(",");for(let d=0;d<c.length;d++){const n=c[d].trim().split(":");if(n.length!==2)continue;const s=n[0].trim(),f=n[1].trim();t[f]!=null&&l.setAttribute(s,t[f])}}const u=e.querySelectorAll("[data-ln-show]");for(let i=0;i<u.length;i++){const l=u[i],c=l.getAttribute("data-ln-show");c in t&&l.classList.toggle("hidden",!t[c])}const a=e.querySelectorAll("[data-ln-class]");for(let i=0;i<a.length;i++){const l=a[i],c=l.getAttribute("data-ln-class").split(",");for(let d=0;d<c.length;d++){const n=c[d].trim().split(":");if(n.length!==2)continue;const s=n[0].trim(),f=n[1].trim();f in t&&l.classList.toggle(s,!!t[f])}}return e}function ee(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const r=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let o=0;o<r.length;o++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",r[o],t??null),r[o].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)B(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let r=0;r<t.length;r++)t[r].textContent=""}})));function M(e,t){if(!e||!t)return e;const r=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;r.nextNode();){const a=r.currentNode;a.textContent.indexOf("{{")!==-1&&(a.textContent=a.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(i,l){return t[l]!==void 0?t[l]:""}))}const o=function(a,i){return t[i]!==void 0?t[i]:""},u=Array.from(e.querySelectorAll("*"));e.nodeType===1&&u.push(e);for(let a=0;a<u.length;a++){const i=u[a],l=i.attributes;for(let c=0;c<l.length;c++){const d=l[c];d.value.indexOf("{{")!==-1&&i.setAttribute(d.name,d.value.replace(/\{\{\s*(\w+)\s*\}\}/g,o))}}return e}function te(e,t,r,o,u,a){const i={};for(let c=0;c<e.children.length;c++){const d=e.children[c],n=d.getAttribute("data-ln-render-key");n&&(i[n]=d)}const l=document.createDocumentFragment();for(let c=0;c<t.length;c++){const d=t[c],n=String(o(d));let s=i[n];if(s)u(s,d,c);else{const f=Z(r,a);if(!f||(M(f,d),s=f.firstElementChild,!s))continue;s.setAttribute("data-ln-render-key",n),u(s,d,c)}l.appendChild(s)}e.textContent="",e.appendChild(l)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=M,window.lnCore.fill=B,window.lnCore.lnFill=ee,window.lnCore.renderList=te);function $(e,t,r,o,u){if(!e||t===null)return!0;const a=o||"ln-component",i=e.type;if(i==="trigger"||i==="marker"||i==="string"||i==="list"||!i||t===""&&e.fallback!==void 0)return!0;const l=c=>{u?console.warn(c,u):console.warn(c)};if(i==="boolean"){const c=t.trim().toLowerCase();return c!==""&&c!=="true"&&c!=="false"&&c!=="1"&&c!=="0"?(l(`[${a}] Invalid value "${t}" for boolean attribute "${r}". Allowed: "true", "false", or presence-only.`),!1):!0}if(i==="enum"){const c=e.values||[];return c.includes(t)?!0:(l(`[${a}] Invalid value "${t}" for attribute "${r}". Allowed: ${c.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(i==="integer"){if(!/^-?\d+$/.test(t))return l(`[${a}] Invalid integer "${t}" for attribute "${r}". Fallback: ${e.fallback}.`),!1;const c=parseInt(t,10);return e.min!==void 0&&c<e.min?(l(`[${a}] Value ${c} for attribute "${r}" is less than min (${e.min}).`),!1):e.max!==void 0&&c>e.max?(l(`[${a}] Value ${c} for attribute "${r}" is greater than max (${e.max}).`),!1):!0}if(i==="float")return isNaN(Number(t))?(l(`[${a}] Invalid float "${t}" for attribute "${r}". Fallback: ${e.fallback}.`),!1):!0;if(i==="json")try{return JSON.parse(t),!0}catch(c){return l(`[${a}] Invalid JSON for attribute "${r}": ${c.message}. Fallback: ${e.fallback}.`),!1}return!0}function ne(e){const t={};for(const r in e){const o=e[r];o&&o.effect&&(t[r]=o.effect)}return Object.keys(t).length?t:null}function re(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const r in e.effects)t.add(r);if(e.onAttrChange&&e.declared)for(const r of e.declared)t.add(r);return t}function S(e,t,r,o){if(e.nodeType!==1)return;const a=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",i=Array.from(e.querySelectorAll(a));e.matches&&e.matches(a)&&i.push(e);for(const l of i)if(!l[r]){window.lnCore._persistSink&&l.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(l,t);try{l[r]=new o(l)}catch(c){console.error("["+r+"] init failed",l,c)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function oe(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function ie(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function N(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function se(e){const t=N(),r=e.observed||[];for(let o=0;o<r.length;o++){const u=r[o];t.byAttr.has(u)||t.byAttr.set(u,[]),t.byAttr.get(u).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const o in e.attributes){t.byDeclaredAttr.has(o)||t.byDeclaredAttr.set(o,[]);const u=t.byDeclaredAttr.get(o);u.some(a=>a.componentTag===e.componentTag)||u.push({spec:e.attributes[o],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const o=re(e);if(o===null)t.reactiveWildcard.push(e);else for(const u of o)t.byReactive.has(u)||t.byReactive.set(u,[]),t.byReactive.get(u).push(e)}e.persist&&t.persist.push(e)}function F(e,t,r,o){for(let u=0;u<e.length;u++){const a=e[u];if(!t[a.attribute])continue;const i=a.effects&&a.effects[r];i?i(t,r,o):a.onAttrChange&&(!a.declared||a.declared.has(r))&&a.onAttrChange(t,r,o)}}function ae(e){const t=e.target,r=e.attributeName;if(e.oldValue===t.getAttribute(r))return;const o=N(),u=o.byAttr.get(r);if(R()&&o.byDeclaredAttr&&o.byDeclaredAttr.has(r)&&k(t)){const a=o.byDeclaredAttr.get(r),i=t.getAttribute(r);for(let l=0;l<a.length;l++)$(a[l].spec,i,r,a[l].componentTag,t)}if(window.lnCore._debugSink&&(r.indexOf("data-ln-")===0||u)&&window.lnCore._debugSink("attr",r,t,{oldValue:e.oldValue,newValue:t.getAttribute(r)}),r.indexOf("data-ln-")===0){const a=o.byReactive.get(r);a&&F(a,t,r,e.oldValue),o.reactiveWildcard.length&&F(o.reactiveWildcard,t,r,e.oldValue)}if(u)for(let a=0;a<u.length;a++){const i=u[a];if(i.handler){i.handler(t,r,e.oldValue);continue}i.onAttributeChange&&t[i.attribute]?i.onAttributeChange(t,r):(S(t,i.selector,i.attribute,i.ComponentFn),i.onInit&&i.onInit(t))}}function ue(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,A(function(){new MutationObserver(function(t){for(let r=0;r<t.length;r++)try{ae(t[r])}catch(o){console.error("[ln-core] mutation handler failed",t[r].target,o)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function K(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function le(e){const t=K();if(t.length){if(e.target)for(let r=0;r<t.length;r++){const o=t[r];if(o.onSubtreeChange){const u=o.query,a=e.target.nodeType===1?e.target.matches(u)?e.target:e.target.closest(u):e.target.parentElement?e.target.parentElement.closest(u):null;a&&o.onSubtreeChange(a,e)}}for(let r=0;r<e.addedNodes.length;r++){const o=e.addedNodes[r];if(o.nodeType===1)for(let u=0;u<t.length;u++){const a=t[u];S(o,a.selector,a.attribute,a.ComponentFn),a.onInit&&a.onInit(o)}}for(let r=0;r<e.removedNodes.length;r++){const o=e.removedNodes[r];if(o.nodeType===1)for(let u=0;u<t.length;u++){const a=t[u],i=a.query,l=Array.from(o.querySelectorAll(i));o.matches&&o.matches(i)&&l.push(o);for(let c=0;c<l.length;c++){const d=l[c];if(!document.contains(d)){const n=d[a.attribute];if(n&&typeof n.destroy=="function")try{n.destroy()}catch(s){console.error("["+a.attribute+"] destroy failed",d,s)}delete d[a.attribute]}}}}}}function ce(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,A(function(){new MutationObserver(function(t){for(let r=0;r<t.length;r++){const o=t[r];if(o.type==="childList")try{le(o)}catch(u){console.error("[ln-core] lifecycle handler failed",o.target,u)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function de(e,t,r,o,u={}){const a=u.extraAttributes||[],i=u.onAttributeChange||null,l=u.onSubtreeChange||null,c=u.onInit||null,d=u.onAttrChange||null,n=u.effects||null,s=u.attributes||null,f=s?ne(s):n,p=s?new Set(Object.keys(s)):null,m=u.persist||null;function h(D){const _=D||document.body;if(S(_,e,t,r),s&&R())for(const x in s){const Ee=s[x],L=Array.from(_.querySelectorAll("["+x+"]"));_.matches&&_.matches("["+x+"]")&&L.push(_);for(let O=0;O<L.length;O++){const T=L[O];k(T)&&$(Ee,T.getAttribute(x),x,o,T)}}c&&c(_)}const C=[];if(e.indexOf("[")!==-1){const D=/\[([\w-]+)/g;let _;for(;(_=D.exec(e))!==null;)C.push(_[1])}else C.push(e);se({selector:e,attribute:t,componentTag:o,attributes:s,ComponentFn:r,onInit:c,observed:C.concat(a),onAttributeChange:i,onAttrChange:d,effects:f,declared:p,persist:m}),ue();const ke=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]";K().push({selector:e,attribute:t,ComponentFn:r,onInit:c,onSubtreeChange:l,query:ke}),ce(),window[t]=h;function H(){oe()>0?ie(function(){h(document.body)}):h(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",H):H(),h}function U(e){return(e||"").replace(/^#/,"")}function I(e){const t=e===void 0?location.hash:e,r={},o=U(t);if(!o)return r;const u=o.split("&");for(let a=0;a<u.length;a++){const i=u[a];if(!i)continue;const l=i.indexOf(":"),c=l>-1?i.slice(0,l):i,d=l>-1?i.slice(l+1):"";if(c)try{r[c]=decodeURIComponent(d)}catch{r[c]=d}}return r}function fe(e){if(!e)return null;const t=I();return e in t?t[e]:null}function pe(e,t){if(!e)return;const r=I();t==null?delete r[e]:r[e]=String(t);const u=Object.keys(r).map(function(a){const i=r[a];return i===""?a:a+":"+encodeURIComponent(i)}).join("&");U(location.hash)!==u&&(location.hash=u)}function he(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function we(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const r=e.getAttribute("data-ln-hash");if(r&&r.trim()!=="")return r.trim();const o=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return o?t?o+"-"+t:o:t||null}function me(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function be(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function ye(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function ge(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const r=e.slice(0,t),o=e.slice(t+1),u=o?o.split(",").map(function(a){try{return decodeURIComponent(a)}catch{return a}}).filter(Boolean):[];return{key:r,values:u}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=I,window.lnCore.hashGet=fe,window.lnCore.hashSet=pe,window.lnCore.hashLinkClick=he,window.lnCore.resolveHashNamespace=we,window.lnCore.hashSortEncode=me,window.lnCore.hashSortDecode=be,window.lnCore.hashFilterEncode=ye,window.lnCore.hashFilterDecode=ge);const _e="ln_api_queue",Ce=2,b="outbox",y="_queue_meta";function g(e,t){return e.error||new Error(t)}function q(e,t){return e.bound([t,-1/0],[t,1/0])}function V(e){return"seq:"+e}function v(e){return"paused:"+e}function j(e){e.leaseOwner=null,e.leaseUntil=0}function qe(e,t,r){return typeof e!="string"||e.indexOf(t)===-1?e:e.split(t).join(r)}function xe(e,t,r,o){const u=new Map,a=[],i=[];for(const l of e||[])u.has(l.chainKey)||u.set(l.chainKey,[]),u.get(l.chainKey).push(l);return u.forEach((l,c)=>{l.sort((n,s)=>n.seq-s.seq);const d=l[0];if(!(!d||d.status==="failed")){if(d.status==="inflight"&&(d.leaseUntil||0)>o){i.push({chainKey:c,at:d.leaseUntil});return}if((d.nextAttemptAt||0)>o){i.push({chainKey:c,at:d.nextAttemptAt});return}d.status="inflight",d.leaseOwner=t,d.leaseUntil=o+r,d.updatedAt=o,a.push(d)}}),{entries:a,wakeups:i}}function Ae(e,t,r,o,u){const a=[],i=[];for(const l of e||[]){if(l.entryId===t){i.push(l.entryId);continue}l.chainKey===r&&(l.chainKey=o,l.targetId===r&&(l.targetId=o),l.meta&&l.meta.id===r&&(l.meta.id=o),l.meta&&typeof l.meta.action=="string"&&(l.meta.action=qe(l.meta.action,r,o)),l.updatedAt=u,a.push(l))}return{changed:a,deleted:i}}class ve{constructor(t){t=t||{},this.indexedDB=t.indexedDB||globalThis.indexedDB,this.keyRange=t.IDBKeyRange||globalThis.IDBKeyRange,this.dbName=t.dbName||_e,this.now=t.now||(()=>Date.now()),this.uuid=t.uuid||(()=>crypto.randomUUID()),this._db=null,this._ready=null}open(){return this._ready?this._ready:!this.indexedDB||!this.keyRange?Promise.resolve(null):(this._ready=new Promise((t,r)=>{const o=this.indexedDB.open(this.dbName,Ce);o.onupgradeneeded=u=>{const a=u.target.result;let i;a.objectStoreNames.contains(b)?i=u.target.transaction.objectStore(b):i=a.createObjectStore(b,{keyPath:"entryId"}),i.indexNames.contains("by_scope_chain")||i.createIndex("by_scope_chain",["scope","chainKey"],{unique:!1}),i.indexNames.contains("by_scope_seq")||i.createIndex("by_scope_seq",["scope","seq"],{unique:!1}),a.objectStoreNames.contains(y)||a.createObjectStore(y,{keyPath:"key"})},o.onerror=()=>r(g(o,"Queue database open failed")),o.onsuccess=u=>{this._db=u.target.result,this._db.onversionchange=()=>this.close(),t(this._db)}}),this._ready)}close(){this._db&&this._db.close(),this._db=null,this._ready=null}deleteDatabase(){return this.close(),this.indexedDB?new Promise((t,r)=>{const o=this.indexedDB.deleteDatabase(this.dbName);o.onsuccess=()=>t(),o.onerror=()=>r(g(o,"Queue database delete failed")),o.onblocked=()=>r(new Error("Queue database delete blocked"))}):Promise.resolve()}allForScope(t){return this.open().then(r=>r?new Promise((o,u)=>{const i=r.transaction(b,"readonly").objectStore(b).index("by_scope_seq").getAll(q(this.keyRange,t));i.onsuccess=()=>o(i.result||[]),i.onerror=()=>u(g(i,"Queue scope read failed"))}):[])}enqueue(t,r){return r=r||{},this.open().then(o=>o?new Promise((u,a)=>{const i=o.transaction([y,b],"readwrite"),l=i.objectStore(y),c=i.objectStore(b),d=V(t);let n=null;const s=p=>{const m=p+1;n={entryId:this.uuid(),scope:t,chainKey:r.chainKey,seq:m,op:r.op,targetId:r.targetId!==void 0?r.targetId:null,payload:r.payload,expectedVersion:r.expectedVersion!==void 0?r.expectedVersion:null,meta:r.meta||{},attempts:0,nextAttemptAt:0,status:"pending",leaseOwner:null,leaseUntil:0,createdAt:this.now(),updatedAt:this.now()},l.put({key:d,value:m}),c.put(n)},f=l.get(d);f.onerror=()=>a(g(f,"Queue sequence read failed")),f.onsuccess=()=>{const p=f.result;if(p&&typeof p.value=="number"){s(p.value);return}const m=c.index("by_scope_seq").getAll(q(this.keyRange,t));m.onerror=()=>a(g(m,"Queue sequence migration failed")),m.onsuccess=()=>{const h=(m.result||[]).reduce((C,W)=>Math.max(C,W.seq||0),0);s(h)}},i.oncomplete=()=>u(n),i.onerror=()=>a(i.error||new Error("Queue enqueue transaction failed")),i.onabort=()=>a(i.error||new Error("Queue enqueue transaction aborted"))}):null)}claimReady(t,r,o){return this.open().then(u=>u?new Promise((a,i)=>{const l=u.transaction(b,"readwrite"),c=l.objectStore(b),d=c.index("by_scope_seq").getAll(q(this.keyRange,t)),n=this.now();let s={entries:[],wakeups:[]};d.onerror=()=>i(g(d,"Queue claim read failed")),d.onsuccess=()=>{s=xe(d.result||[],r,o,n);for(const f of s.entries)c.put(f)},l.oncomplete=()=>a(s),l.onerror=()=>i(l.error||new Error("Queue claim transaction failed")),l.onabort=()=>i(l.error||new Error("Queue claim transaction aborted"))}):{entries:[],wakeups:[]})}ack(t,r){return this._updateEntry(t,r,(o,u)=>(u.delete(o.entryId),{status:"acked",entry:o}))}nack(t,r,o,u){u=u||{};const a=u.maxAttempts||8,i=u.backoff||[2e3,5e3,15e3,6e4,3e5];return this.open().then(l=>l?new Promise((c,d)=>{const n=l.transaction([b,y],"readwrite"),s=n.objectStore(b),f=n.objectStore(y),p=s.get(r);let m=null;p.onerror=()=>d(g(p,"Queue nack read failed")),p.onsuccess=()=>{const h=p.result;if(!(!h||h.scope!==t)){if(o==="drop"){s.delete(h.entryId),m={status:"dropped",entry:h};return}if(j(h),h.updatedAt=this.now(),o==="auth"){h.status="pending",s.put(h),f.put({key:v(t),value:"auth"}),m={status:"auth",entry:h};return}if(o==="retry"){if(h.attempts=(h.attempts||0)+1,h.attempts>=a){h.status="failed",h.nextAttemptAt=0,s.put(h),m={status:"failed",entry:h};return}const C=i[Math.min(h.attempts-1,i.length-1)];h.status="pending",h.nextAttemptAt=this.now()+C,s.put(h),m={status:"retry",entry:h,delay:C}}}},n.oncomplete=()=>c(m),n.onerror=()=>d(n.error||new Error("Queue nack transaction failed")),n.onabort=()=>d(n.error||new Error("Queue nack transaction aborted"))}):null)}remap(t,r,o){return this._remapTransaction(t,null,r,o)}resolveCreate(t,r,o,u){return this._remapTransaction(t,r,o,u)}_remapTransaction(t,r,o,u){return this.open().then(a=>a?new Promise((i,l)=>{const c=a.transaction(b,"readwrite"),d=c.objectStore(b),n=d.index("by_scope_seq").getAll(q(this.keyRange,t));let s={changed:[],deleted:[]};n.onerror=()=>l(g(n,"Queue remap read failed")),n.onsuccess=()=>{s=Ae(n.result||[],r,o,u,this.now());for(const f of s.deleted)d.delete(f);for(const f of s.changed)d.put(f)},c.oncomplete=()=>i(s.changed),c.onerror=()=>l(c.error||new Error("Queue remap transaction failed")),c.onabort=()=>l(c.error||new Error("Queue remap transaction aborted"))}):[])}resetFailed(t){return this.open().then(r=>r?new Promise((o,u)=>{const a=r.transaction(b,"readwrite"),i=a.objectStore(b),l=i.index("by_scope_seq").getAll(q(this.keyRange,t));let c=0;l.onerror=()=>u(g(l,"Queue failed-entry read failed")),l.onsuccess=()=>{for(const d of l.result||[])d.status==="failed"&&(d.status="pending",d.attempts=0,d.nextAttemptAt=0,d.updatedAt=this.now(),j(d),i.put(d),c++)},a.oncomplete=()=>o(c),a.onerror=()=>u(a.error||new Error("Queue failed-entry reset failed")),a.onabort=()=>u(a.error||new Error("Queue failed-entry reset aborted"))}):0)}getPaused(t){return this.open().then(r=>r?new Promise((o,u)=>{const i=r.transaction(y,"readonly").objectStore(y).get(v(t));i.onsuccess=()=>{const l=i.result?i.result.value:!1;o(l||!1)},i.onerror=()=>u(g(i,"Queue pause-state read failed"))}):!1)}setPaused(t,r){return this.open().then(o=>{if(o)return new Promise((u,a)=>{const i=o.transaction(y,"readwrite"),l=typeof r=="string"?r:r?"manual":!1;i.objectStore(y).put({key:v(t),value:l}),i.oncomplete=()=>u(),i.onerror=()=>a(i.error||new Error("Queue pause-state write failed")),i.onabort=()=>a(i.error||new Error("Queue pause-state write aborted"))})})}clear(t){return this.open().then(r=>{if(r)return new Promise((o,u)=>{const a=r.transaction([b,y],"readwrite"),l=a.objectStore(b).index("by_scope_seq").openCursor(q(this.keyRange,t));l.onsuccess=c=>{const d=c.target.result;d&&(d.delete(),d.continue())},l.onerror=()=>u(g(l,"Queue clear failed")),a.objectStore(y).delete(V(t)),a.objectStore(y).delete(v(t)),a.oncomplete=()=>o(),a.onerror=()=>u(a.error||new Error("Queue clear transaction failed")),a.onabort=()=>u(a.error||new Error("Queue clear transaction aborted"))})})}_updateEntry(t,r,o){return this.open().then(u=>u?new Promise((a,i)=>{const l=u.transaction(b,"readwrite"),c=l.objectStore(b),d=c.get(r);let n=null;d.onerror=()=>i(g(d,"Queue entry read failed")),d.onsuccess=()=>{const s=d.result;!s||s.scope!==t||(n=o(s,c))},l.oncomplete=()=>a(n),l.onerror=()=>i(l.error||new Error("Queue entry transaction failed")),l.onabort=()=>i(l.error||new Error("Queue entry transaction aborted"))}):null)}}(function(){const e="data-ln-api-queue",t="lnApiQueue",r=[2e3,5e3,15e3,6e4,3e5],o=8,u=6e4;if(window[t]!==void 0)return;function a(n){const s=n[t];s&&s._drain()}const i={"data-ln-api-queue":{type:"marker",description:"Mounts offline API synchronization queue backed by IndexedDB"},"data-ln-api-queue-online":{effect:a,type:"enum",values:["true","false"],fallback:"auto",description:"Network connectivity override (true/false, or auto-detect from navigator.onLine)"}};function l(){try{return crypto.randomUUID()}catch{return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,s=>{const f=Math.random()*16|0;return(s==="x"?f:f&3|8).toString(16)})}}const c=new ve({indexedDB:window.indexedDB,IDBKeyRange:window.IDBKeyRange,uuid:l});function d(n){this.dom=n,n[t]=this;const s=n.closest("[data-ln-data-coordinator]");this.scope=n.id||(s?s.id:null)||"default",this._paused=!1,this._timers=new Map,this._workerId=l(),this._drainPromise=null,this._onlineHandler=()=>this._drain(),this._bindEvents(),window.addEventListener("online",this._onlineHandler);const f=this;return c.open().then(p=>p?c.getPaused(f.scope):(console.warn("[ln-api-queue] IndexedDB not available — queue disabled"),!1)).then(p=>{if(f._paused=!!p,f._paused){const m=typeof p=="string"?p:"auth";w(f.dom,"ln-api-queue:paused",{reason:m,restored:!0})}return f._emitPendingCount()}).then(()=>f._drain()).catch(p=>{console.error("[ln-api-queue] Initialization failed:",p),w(f.dom,"ln-api-queue:error",{operation:"initialize",error:p})}),this}d.prototype._isOnline=function(){const n=this.dom.getAttribute("data-ln-api-queue-online");return n==="true"?!0:n==="false"?!1:navigator.onLine},d.prototype._emitPendingCount=function(){const n=this;return c.allForScope(n.scope).then(s=>(w(n.dom,"ln-api-queue:pending-count",{count:s.length,scope:n.scope}),s.length===0&&w(n.dom,"ln-api-queue:drained",{scope:n.scope}),s))},d.prototype._clearTimer=function(n){const s=this._timers.get(n);s&&(clearTimeout(s),this._timers.delete(n))},d.prototype._scheduleTimer=function(n,s){const f=Math.max(0,s),p=this._timers.get(n);p&&clearTimeout(p);const m=this,h=setTimeout(()=>{m._timers.delete(n),m._drain()},f);this._timers.set(n,h)},d.prototype._drain=function(){const n=this;return n._paused||!n._isOnline()?Promise.resolve():(n._drainPromise||(n._drainPromise=c.claimReady(n.scope,n._workerId,u).then(s=>{for(const f of s.wakeups)n._scheduleTimer(f.chainKey,f.at-Date.now());for(const f of s.entries)n._clearTimer(f.chainKey),w(n.dom,"ln-api-queue:send",{entryId:f.entryId,chainKey:f.chainKey,op:f.op,targetId:f.targetId,payload:f.payload,expectedVersion:f.expectedVersion,idempotencyKey:f.entryId,meta:f.meta})}).catch(s=>{console.error("[ln-api-queue] Drain failed:",s),w(n.dom,"ln-api-queue:error",{operation:"drain",error:s})}).finally(()=>{n._drainPromise=null})),n._drainPromise)},d.prototype._onEnqueue=function(n){const s=this;return c.enqueue(s.scope,n.detail||{}).then(f=>{if(f)return s._emitPendingCount().then(p=>(w(s.dom,"ln-api-queue:enqueued",{entryId:f.entryId,chainKey:f.chainKey,count:p.length}),s._drain()))}).catch(f=>{w(s.dom,"ln-api-queue:error",{operation:"enqueue",error:f})})},d.prototype._onAck=function(n){const s=this,f=n.detail||{};return c.ack(s.scope,f.entryId).then(()=>s._emitPendingCount()).then(()=>s._drain()).catch(p=>{w(s.dom,"ln-api-queue:error",{operation:"ack",entryId:f.entryId,error:p})})},d.prototype._onNack=function(n){const s=this,f=n.detail||{};return c.nack(s.scope,f.entryId,f.reason,{maxAttempts:o,backoff:r}).then(p=>{if(p)return p.status==="failed"?w(s.dom,"ln-api-queue:failed",{entryId:p.entry.entryId,chainKey:p.entry.chainKey,attempts:p.entry.attempts}):p.status==="retry"?s._scheduleTimer(p.entry.chainKey,p.delay):p.status==="auth"&&(s._paused=!0,w(s.dom,"ln-api-queue:paused",{reason:"auth"}),w(s.dom,"ln-api-queue:auth-required",{entryId:p.entry.entryId,chainKey:p.entry.chainKey})),s._emitPendingCount().then(()=>{if(p.status==="dropped")return s._drain()})}).catch(p=>{w(s.dom,"ln-api-queue:error",{operation:"nack",entryId:f.entryId,error:p})})},d.prototype._onRemap=function(n){const s=this,f=n.detail||{};return c.remap(s.scope,f.oldKey,f.newId).catch(p=>{w(s.dom,"ln-api-queue:error",{operation:"remap",error:p})})},d.prototype._onResolveCreate=function(n){const s=this,f=n.detail||{};return c.resolveCreate(s.scope,f.entryId,f.oldKey,f.newId).then(()=>s._emitPendingCount()).then(()=>s._drain()).catch(p=>{w(s.dom,"ln-api-queue:error",{operation:"resolve-create",entryId:f.entryId,error:p})})},d.prototype._onResume=function(){const n=this;return c.setPaused(n.scope,!1).then(()=>(n._paused=!1,w(n.dom,"ln-api-queue:resumed",{}),n._drain())).catch(s=>{w(n.dom,"ln-api-queue:error",{operation:"resume",error:s})})},d.prototype._onPause=function(){const n=this;return c.setPaused(n.scope,"manual").then(()=>{n._paused=!0,w(n.dom,"ln-api-queue:paused",{reason:"manual"})}).catch(s=>{w(n.dom,"ln-api-queue:error",{operation:"pause",error:s})})},d.prototype._onDrain=function(){const n=this;return c.resetFailed(n.scope).then(()=>{const s=n._drainPromise;return s?s.then(()=>n._drain()):n._drain()}).catch(s=>{w(n.dom,"ln-api-queue:error",{operation:"manual-drain",error:s})})},d.prototype._onClear=function(){const n=this;return n._timers.forEach(s=>clearTimeout(s)),n._timers.clear(),c.clear(n.scope).then(()=>{n._paused=!1,w(n.dom,"ln-api-queue:pending-count",{count:0,scope:n.scope}),w(n.dom,"ln-api-queue:drained",{scope:n.scope})}).catch(s=>{w(n.dom,"ln-api-queue:error",{operation:"clear",error:s})})},d.prototype._bindEvents=function(){const n=this;n._handlers={enqueue:s=>n._onEnqueue(s),ack:s=>n._onAck(s),nack:s=>n._onNack(s),remap:s=>n._onRemap(s),resolveCreate:s=>n._onResolveCreate(s),resume:()=>n._onResume(),pause:()=>n._onPause(),drain:()=>n._onDrain(),clear:()=>n._onClear()},n.dom.addEventListener("ln-api-queue:request-enqueue",n._handlers.enqueue),n.dom.addEventListener("ln-api-queue:ack",n._handlers.ack),n.dom.addEventListener("ln-api-queue:nack",n._handlers.nack),n.dom.addEventListener("ln-api-queue:request-remap",n._handlers.remap),n.dom.addEventListener("ln-api-queue:resolve-create",n._handlers.resolveCreate),n.dom.addEventListener("ln-api-queue:request-resume",n._handlers.resume),n.dom.addEventListener("ln-api-queue:request-pause",n._handlers.pause),n.dom.addEventListener("ln-api-queue:request-drain",n._handlers.drain),n.dom.addEventListener("ln-api-queue:request-clear",n._handlers.clear)},d.prototype.destroy=function(){if(!this.dom[t])return;const n=this;n.dom.removeEventListener("ln-api-queue:request-enqueue",n._handlers.enqueue),n.dom.removeEventListener("ln-api-queue:ack",n._handlers.ack),n.dom.removeEventListener("ln-api-queue:nack",n._handlers.nack),n.dom.removeEventListener("ln-api-queue:request-remap",n._handlers.remap),n.dom.removeEventListener("ln-api-queue:resolve-create",n._handlers.resolveCreate),n.dom.removeEventListener("ln-api-queue:request-resume",n._handlers.resume),n.dom.removeEventListener("ln-api-queue:request-pause",n._handlers.pause),n.dom.removeEventListener("ln-api-queue:request-drain",n._handlers.drain),n.dom.removeEventListener("ln-api-queue:request-clear",n._handlers.clear),window.removeEventListener("online",n._onlineHandler),n._timers.forEach(s=>clearTimeout(s)),n._timers.clear(),delete n.dom[t]},de(e,t,d,"ln-api-queue",{attributes:i})})()})();
@@ -0,0 +1,34 @@
1
+ {
2
+ "$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
3
+ "component": "ln-api-queue",
4
+ "generator": "scripts/sync-ln-schemas.mjs",
5
+ "attributes": {
6
+ "data-ln-api-queue": {
7
+ "direction": null,
8
+ "sources": [
9
+ "src/ln-api-queue.js"
10
+ ],
11
+ "type": "marker",
12
+ "description": "Mounts offline API synchronization queue backed by IndexedDB"
13
+ },
14
+ "data-ln-api-queue-online": {
15
+ "direction": "author",
16
+ "sources": [
17
+ "src/ln-api-queue.js"
18
+ ],
19
+ "type": "enum",
20
+ "values": [
21
+ "true",
22
+ "false"
23
+ ],
24
+ "fallback": "auto",
25
+ "description": "Network connectivity override (true/false, or auto-detect from navigator.onLine)"
26
+ },
27
+ "data-ln-data-coordinator": {
28
+ "direction": "author",
29
+ "sources": [
30
+ "src/ln-api-queue.js"
31
+ ]
32
+ }
33
+ }
34
+ }