@aglyn/aglyn 1.0.0-beta.218 → 1.0.0-beta.220

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 (455) hide show
  1. package/package.json +12 -12
  2. package/src/lib/app-utils/actions.d.ts +26 -433
  3. package/src/lib/app-utils/actions.js +108 -633
  4. package/src/lib/app-utils/actions.js.map +1 -1
  5. package/src/lib/app-utils/activity-presenter.d.ts +3 -3
  6. package/src/lib/app-utils/activity-presenter.js +36 -52
  7. package/src/lib/app-utils/activity-presenter.js.map +1 -1
  8. package/src/lib/app-utils/analytics-events.d.ts +1 -1
  9. package/src/lib/app-utils/analytics-events.js.map +1 -1
  10. package/src/lib/app-utils/analytics-provider.d.ts +182 -0
  11. package/src/lib/app-utils/analytics-provider.js +133 -0
  12. package/src/lib/app-utils/analytics-provider.js.map +1 -0
  13. package/src/lib/app-utils/api-plugins.d.ts +46 -0
  14. package/src/lib/app-utils/api-plugins.js +19 -0
  15. package/src/lib/app-utils/api-plugins.js.map +1 -1
  16. package/src/lib/app-utils/{marketplace-overrides.d.ts → artifact-overrides.d.ts} +9 -6
  17. package/src/lib/app-utils/{marketplace-overrides.js → artifact-overrides.js} +10 -7
  18. package/src/lib/app-utils/artifact-overrides.js.map +1 -0
  19. package/src/lib/app-utils/{marketplace-provenance.d.ts → artifact-provenance.d.ts} +12 -10
  20. package/src/lib/app-utils/{marketplace-provenance.js → artifact-provenance.js} +9 -7
  21. package/src/lib/app-utils/artifact-provenance.js.map +1 -0
  22. package/src/lib/app-utils/binding-token-catalog.d.ts +5 -13
  23. package/src/lib/app-utils/binding-token-catalog.js +17 -41
  24. package/src/lib/app-utils/binding-token-catalog.js.map +1 -1
  25. package/src/lib/app-utils/brand-support-line.d.ts +36 -0
  26. package/src/lib/app-utils/brand-support-line.js +38 -0
  27. package/src/lib/app-utils/brand-support-line.js.map +1 -0
  28. package/src/lib/app-utils/collection-entries.d.ts +2 -2
  29. package/src/lib/app-utils/collection-entries.js.map +1 -1
  30. package/src/lib/app-utils/consent-group-change.d.ts +4 -0
  31. package/src/lib/app-utils/consent-group-change.js.map +1 -1
  32. package/src/lib/app-utils/consent-groups.d.ts +1 -1
  33. package/src/lib/app-utils/consent-groups.js.map +1 -1
  34. package/src/lib/app-utils/console-routes.d.ts +15 -42
  35. package/src/lib/app-utils/console-routes.js +10 -39
  36. package/src/lib/app-utils/console-routes.js.map +1 -1
  37. package/src/lib/app-utils/contacts.d.ts +24 -2
  38. package/src/lib/app-utils/contacts.js +21 -5
  39. package/src/lib/app-utils/contacts.js.map +1 -1
  40. package/src/lib/app-utils/container-membership.d.ts +93 -0
  41. package/src/lib/app-utils/container-membership.js +165 -0
  42. package/src/lib/app-utils/container-membership.js.map +1 -0
  43. package/src/lib/app-utils/crm-task-reminders.d.ts +23 -6
  44. package/src/lib/app-utils/crm-task-reminders.js +32 -11
  45. package/src/lib/app-utils/crm-task-reminders.js.map +1 -1
  46. package/src/lib/app-utils/crm.d.ts +24 -4
  47. package/src/lib/app-utils/crm.js +23 -0
  48. package/src/lib/app-utils/crm.js.map +1 -1
  49. package/src/lib/app-utils/cross-pool-desync.d.ts +39 -0
  50. package/src/lib/app-utils/cross-pool-desync.js +47 -0
  51. package/src/lib/app-utils/cross-pool-desync.js.map +1 -0
  52. package/src/lib/app-utils/csv-upload.d.ts +29 -0
  53. package/src/lib/app-utils/csv-upload.js +29 -0
  54. package/src/lib/app-utils/csv-upload.js.map +1 -0
  55. package/src/lib/app-utils/{dataset-csv.d.ts → csv.d.ts} +10 -43
  56. package/src/lib/app-utils/{dataset-csv.js → csv.js} +10 -81
  57. package/src/lib/app-utils/csv.js.map +1 -0
  58. package/src/lib/app-utils/dataset-models.d.ts +5 -5
  59. package/src/lib/app-utils/dataset-models.js +19 -2
  60. package/src/lib/app-utils/dataset-models.js.map +1 -1
  61. package/src/lib/app-utils/datasets.d.ts +65 -30
  62. package/src/lib/app-utils/datasets.js +74 -24
  63. package/src/lib/app-utils/datasets.js.map +1 -1
  64. package/src/lib/app-utils/docs-deflection.d.ts +6 -6
  65. package/src/lib/app-utils/docs-deflection.js.map +1 -1
  66. package/src/lib/app-utils/docs-help.generated.d.ts +14 -8
  67. package/src/lib/app-utils/docs-help.generated.js +23 -6
  68. package/src/lib/app-utils/docs-help.generated.js.map +1 -1
  69. package/src/lib/app-utils/docs-index.generated.d.ts +2 -2
  70. package/src/lib/app-utils/docs-index.generated.js +570 -346
  71. package/src/lib/app-utils/docs-index.generated.js.map +1 -1
  72. package/src/lib/app-utils/docs-retrieval.d.ts +3 -3
  73. package/src/lib/app-utils/docs-retrieval.js +14 -10
  74. package/src/lib/app-utils/docs-retrieval.js.map +1 -1
  75. package/src/lib/app-utils/duplicate-resource.d.ts +4 -1
  76. package/src/lib/app-utils/duplicate-resource.js +7 -4
  77. package/src/lib/app-utils/duplicate-resource.js.map +1 -1
  78. package/src/lib/app-utils/dynamic-list-rule.d.ts +1 -1
  79. package/src/lib/app-utils/dynamic-list-rule.js +3 -3
  80. package/src/lib/app-utils/dynamic-list-rule.js.map +1 -1
  81. package/src/lib/app-utils/element-ui.d.ts +1 -1
  82. package/src/lib/app-utils/element-ui.js +1 -1
  83. package/src/lib/app-utils/element-ui.js.map +1 -1
  84. package/src/lib/app-utils/email-starter-policy.js +3 -3
  85. package/src/lib/app-utils/email-starter-policy.js.map +1 -1
  86. package/src/lib/app-utils/email-text.d.ts +80 -0
  87. package/src/lib/app-utils/email-text.js +189 -0
  88. package/src/lib/app-utils/email-text.js.map +1 -0
  89. package/src/lib/app-utils/{list-assignment-policy.d.ts → enrollment-basis.d.ts} +4 -0
  90. package/src/lib/app-utils/{list-assignment-policy.js → enrollment-basis.js} +5 -1
  91. package/src/lib/app-utils/enrollment-basis.js.map +1 -0
  92. package/src/lib/app-utils/entity-picker-context.d.ts +10 -5
  93. package/src/lib/app-utils/entity-picker-context.js.map +1 -1
  94. package/src/lib/app-utils/error-beacon.d.ts +75 -6
  95. package/src/lib/app-utils/error-beacon.js +160 -21
  96. package/src/lib/app-utils/error-beacon.js.map +1 -1
  97. package/src/lib/app-utils/expand-repeatables.d.ts +10 -10
  98. package/src/lib/app-utils/expand-repeatables.js +14 -14
  99. package/src/lib/app-utils/expand-repeatables.js.map +1 -1
  100. package/src/lib/app-utils/forms.js +2 -2
  101. package/src/lib/app-utils/forms.js.map +1 -1
  102. package/src/lib/app-utils/health-report.d.ts +2 -3
  103. package/src/lib/app-utils/health-report.js +8 -6
  104. package/src/lib/app-utils/health-report.js.map +1 -1
  105. package/src/lib/app-utils/host-events.d.ts +82 -0
  106. package/src/lib/app-utils/host-events.js +62 -0
  107. package/src/lib/app-utils/host-events.js.map +1 -0
  108. package/src/lib/app-utils/inbound-mail-domain.d.ts +27 -0
  109. package/src/lib/app-utils/inbound-mail-domain.js +31 -0
  110. package/src/lib/app-utils/inbound-mail-domain.js.map +1 -0
  111. package/src/lib/app-utils/lockdown.d.ts +11 -0
  112. package/src/lib/app-utils/lockdown.js +33 -3
  113. package/src/lib/app-utils/lockdown.js.map +1 -1
  114. package/src/lib/app-utils/margin-utilization.d.ts +4 -69
  115. package/src/lib/app-utils/margin-utilization.js +82 -69
  116. package/src/lib/app-utils/margin-utilization.js.map +1 -1
  117. package/src/lib/app-utils/member-email-aliases.d.ts +25 -0
  118. package/src/lib/app-utils/member-email-aliases.js +29 -0
  119. package/src/lib/app-utils/member-email-aliases.js.map +1 -1
  120. package/src/lib/app-utils/node-definition-sanitizer.d.ts +16 -16
  121. package/src/lib/app-utils/node-definition-sanitizer.js +24 -20
  122. package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -1
  123. package/src/lib/app-utils/node-interactions.d.ts +7 -7
  124. package/src/lib/app-utils/node-interactions.js.map +1 -1
  125. package/src/lib/app-utils/notifications.d.ts +147 -47
  126. package/src/lib/app-utils/notifications.js +182 -44
  127. package/src/lib/app-utils/notifications.js.map +1 -1
  128. package/src/lib/app-utils/operator-alerts.d.ts +15 -1
  129. package/src/lib/app-utils/operator-alerts.js +47 -10
  130. package/src/lib/app-utils/operator-alerts.js.map +1 -1
  131. package/src/lib/app-utils/payments-configured.d.ts +8 -21
  132. package/src/lib/app-utils/payments-configured.js +8 -23
  133. package/src/lib/app-utils/payments-configured.js.map +1 -1
  134. package/src/lib/app-utils/plan-entitlements.d.ts +207 -306
  135. package/src/lib/app-utils/plan-entitlements.js +345 -528
  136. package/src/lib/app-utils/plan-entitlements.js.map +1 -1
  137. package/src/lib/app-utils/platform-brand.d.ts +10 -0
  138. package/src/lib/app-utils/platform-brand.js +14 -3
  139. package/src/lib/app-utils/platform-brand.js.map +1 -1
  140. package/src/lib/app-utils/platform-marketing-consent.d.ts +56 -2
  141. package/src/lib/app-utils/platform-marketing-consent.js +6 -5
  142. package/src/lib/app-utils/platform-marketing-consent.js.map +1 -1
  143. package/src/lib/app-utils/plugin-api-rate-limit.d.ts +7 -1
  144. package/src/lib/app-utils/plugin-api-rate-limit.js +11 -3
  145. package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -1
  146. package/src/lib/app-utils/plugin-bundle-checks.js +2 -2
  147. package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -1
  148. package/src/lib/app-utils/plugin-host-events.generated.d.ts +12 -0
  149. package/src/lib/app-utils/plugin-host-events.generated.js +169 -0
  150. package/src/lib/app-utils/plugin-host-events.generated.js.map +1 -0
  151. package/src/lib/app-utils/plugin-release-flags.generated.d.ts +12 -0
  152. package/src/lib/app-utils/plugin-release-flags.generated.js +106 -0
  153. package/src/lib/app-utils/plugin-release-flags.generated.js.map +1 -0
  154. package/src/lib/app-utils/plugin-starter-templates.generated.d.ts +12 -0
  155. package/src/lib/app-utils/plugin-starter-templates.generated.js +711 -0
  156. package/src/lib/app-utils/plugin-starter-templates.generated.js.map +1 -0
  157. package/src/lib/app-utils/realm-host-surface.generated.js +2 -0
  158. package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
  159. package/src/lib/app-utils/release-flags.d.ts +14 -5
  160. package/src/lib/app-utils/release-flags.js +21 -125
  161. package/src/lib/app-utils/release-flags.js.map +1 -1
  162. package/src/lib/app-utils/repeat-query.d.ts +56 -0
  163. package/src/lib/app-utils/{dataset-query.js → repeat-query.js} +16 -16
  164. package/src/lib/app-utils/repeat-query.js.map +1 -0
  165. package/src/lib/app-utils/repeat-sources.d.ts +9 -0
  166. package/src/lib/app-utils/repeat-sources.js.map +1 -1
  167. package/src/lib/app-utils/retained-refusals.d.ts +73 -0
  168. package/src/lib/app-utils/retained-refusals.js +186 -0
  169. package/src/lib/app-utils/retained-refusals.js.map +1 -0
  170. package/src/lib/app-utils/scope-tokens.d.ts +27 -0
  171. package/src/lib/app-utils/scope-tokens.js +61 -0
  172. package/src/lib/app-utils/scope-tokens.js.map +1 -1
  173. package/src/lib/app-utils/screen-link-context.js +3 -3
  174. package/src/lib/app-utils/screen-link-context.js.map +1 -1
  175. package/src/lib/app-utils/screen-route.js +1 -1
  176. package/src/lib/app-utils/screen-route.js.map +1 -1
  177. package/src/lib/app-utils/seo-audit.d.ts +132 -0
  178. package/src/lib/app-utils/seo-audit.js +246 -0
  179. package/src/lib/app-utils/seo-audit.js.map +1 -0
  180. package/src/lib/app-utils/seo-keywords.d.ts +48 -0
  181. package/src/lib/app-utils/seo-keywords.js +60 -0
  182. package/src/lib/app-utils/seo-keywords.js.map +1 -0
  183. package/src/lib/app-utils/seo-page-facts.d.ts +66 -0
  184. package/src/lib/app-utils/seo-page-facts.js +155 -0
  185. package/src/lib/app-utils/seo-page-facts.js.map +1 -0
  186. package/src/lib/app-utils/seo-site-scan.d.ts +126 -0
  187. package/src/lib/app-utils/seo-site-scan.js +162 -0
  188. package/src/lib/app-utils/seo-site-scan.js.map +1 -0
  189. package/src/lib/app-utils/seo-title-variables.js +1 -1
  190. package/src/lib/app-utils/seo-title-variables.js.map +1 -1
  191. package/src/lib/app-utils/server.d.ts +13 -18
  192. package/src/lib/app-utils/server.js +33 -51
  193. package/src/lib/app-utils/server.js.map +1 -1
  194. package/src/lib/app-utils/site-interactions.d.ts +501 -0
  195. package/src/lib/app-utils/site-interactions.js +554 -0
  196. package/src/lib/app-utils/site-interactions.js.map +1 -0
  197. package/src/lib/app-utils/{marketplace-theme.d.ts → site-theme.d.ts} +13 -2
  198. package/src/lib/app-utils/{marketplace-theme.js → site-theme.js} +2 -2
  199. package/src/lib/app-utils/site-theme.js.map +1 -0
  200. package/src/lib/app-utils/sitemap.d.ts +4 -3
  201. package/src/lib/app-utils/sitemap.js +9 -7
  202. package/src/lib/app-utils/sitemap.js.map +1 -1
  203. package/src/lib/app-utils/stale-build-error.d.ts +51 -0
  204. package/src/lib/app-utils/stale-build-error.js +100 -1
  205. package/src/lib/app-utils/stale-build-error.js.map +1 -1
  206. package/src/lib/app-utils/starter-template-nodes.d.ts +137 -0
  207. package/src/lib/app-utils/starter-template-nodes.js +129 -0
  208. package/src/lib/app-utils/starter-template-nodes.js.map +1 -0
  209. package/src/lib/app-utils/starter-templates.d.ts +11 -34
  210. package/src/lib/app-utils/starter-templates.js +19 -230
  211. package/src/lib/app-utils/starter-templates.js.map +1 -1
  212. package/src/lib/app-utils/{email-topics.d.ts → subscription-topics.d.ts} +64 -48
  213. package/src/lib/app-utils/{email-topics.js → subscription-topics.js} +39 -109
  214. package/src/lib/app-utils/subscription-topics.js.map +1 -0
  215. package/src/lib/app-utils/tax-jurisdiction-figures.d.ts +118 -0
  216. package/src/lib/app-utils/tax-jurisdiction-figures.js +123 -0
  217. package/src/lib/app-utils/tax-jurisdiction-figures.js.map +1 -0
  218. package/src/lib/app-utils/theme-library.d.ts +10 -3
  219. package/src/lib/app-utils/theme-library.js +13 -4
  220. package/src/lib/app-utils/theme-library.js.map +1 -1
  221. package/src/lib/app-utils/usage-budget.d.ts +73 -188
  222. package/src/lib/app-utils/usage-budget.js +58 -194
  223. package/src/lib/app-utils/usage-budget.js.map +1 -1
  224. package/src/lib/app-utils/{campaign-attribution.d.ts → utm-attribution.d.ts} +11 -6
  225. package/src/lib/app-utils/{campaign-attribution.js → utm-attribution.js} +13 -8
  226. package/src/lib/app-utils/utm-attribution.js.map +1 -0
  227. package/src/lib/app-utils/{campaign-forwarding.d.ts → utm-forwarding.d.ts} +14 -14
  228. package/src/lib/app-utils/{campaign-forwarding.js → utm-forwarding.js} +26 -26
  229. package/src/lib/app-utils/utm-forwarding.js.map +1 -0
  230. package/src/lib/app-utils/{campaign-touch.d.ts → utm-touch.d.ts} +25 -17
  231. package/src/lib/app-utils/{campaign-touch.js → utm-touch.js} +38 -30
  232. package/src/lib/app-utils/utm-touch.js.map +1 -0
  233. package/src/lib/app-utils/variables.d.ts +9 -9
  234. package/src/lib/app-utils/variables.js.map +1 -1
  235. package/src/lib/app-utils/video-object.js +6 -5
  236. package/src/lib/app-utils/video-object.js.map +1 -1
  237. package/src/lib/app-utils/visitor-consent.d.ts +41 -164
  238. package/src/lib/app-utils/visitor-consent.js +66 -277
  239. package/src/lib/app-utils/visitor-consent.js.map +1 -1
  240. package/src/lib/app-utils/visitor-record-ceiling.d.ts +32 -0
  241. package/src/lib/app-utils/visitor-record-ceiling.js +39 -0
  242. package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -1
  243. package/src/lib/app-utils/web-vitals-rum.d.ts +7 -7
  244. package/src/lib/app-utils/web-vitals-rum.js +31 -63
  245. package/src/lib/app-utils/web-vitals-rum.js.map +1 -1
  246. package/src/lib/app-utils/where-used.d.ts +11 -6
  247. package/src/lib/app-utils/where-used.js +3 -8
  248. package/src/lib/app-utils/where-used.js.map +1 -1
  249. package/src/lib/foundation/definitions/components.types.d.ts +1 -1
  250. package/src/lib/foundation/definitions/components.types.js +1 -1
  251. package/src/lib/foundation/definitions/components.types.js.map +1 -1
  252. package/src/lib/foundation/definitions/org-billing.types.d.ts +11 -137
  253. package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
  254. package/src/lib/foundation/definitions/organization.types.d.ts +1 -3
  255. package/src/lib/foundation/definitions/organization.types.js.map +1 -1
  256. package/src/lib/foundation/definitions/platform.types.d.ts +11 -5
  257. package/src/lib/foundation/definitions/platform.types.js.map +1 -1
  258. package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +16 -0
  259. package/src/lib/foundation/definitions/write-deny-coverage.util.js +20 -0
  260. package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -1
  261. package/src/lib/foundation/index.d.ts +1 -1
  262. package/src/lib/foundation/index.js.map +1 -1
  263. package/src/lib/plugin-manager/besigner-documents.d.ts +96 -0
  264. package/src/lib/plugin-manager/besigner-documents.js +61 -0
  265. package/src/lib/plugin-manager/besigner-documents.js.map +1 -0
  266. package/src/lib/plugin-manager/computed-variables.d.ts +71 -0
  267. package/src/lib/plugin-manager/computed-variables.js +74 -0
  268. package/src/lib/plugin-manager/computed-variables.js.map +1 -0
  269. package/src/lib/plugin-manager/custom-fields.d.ts +29 -2
  270. package/src/lib/plugin-manager/custom-fields.js +47 -1
  271. package/src/lib/plugin-manager/custom-fields.js.map +1 -1
  272. package/src/lib/plugin-manager/feature-plugins.d.ts +372 -99
  273. package/src/lib/plugin-manager/feature-plugins.js +126 -51
  274. package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
  275. package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +134 -0
  276. package/src/lib/plugin-manager/first-party-plugins.generated.js +840 -10
  277. package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
  278. package/src/lib/plugin-manager/index.d.ts +0 -1
  279. package/src/lib/plugin-manager/index.js +0 -1
  280. package/src/lib/plugin-manager/index.js.map +1 -1
  281. package/src/lib/plugin-manager/plugin-activity-actions.d.ts +12 -0
  282. package/src/lib/plugin-manager/plugin-activity-actions.js +25 -0
  283. package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -1
  284. package/src/lib/plugin-manager/plugin-contact-capture.d.ts +9 -4
  285. package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -1
  286. package/src/lib/plugin-manager/plugin-containers.d.ts +68 -0
  287. package/src/lib/plugin-manager/plugin-containers.generated.d.ts +10 -0
  288. package/src/lib/plugin-manager/plugin-containers.generated.js +20 -0
  289. package/src/lib/plugin-manager/plugin-containers.generated.js.map +1 -0
  290. package/src/lib/plugin-manager/plugin-containers.js +27 -0
  291. package/src/lib/plugin-manager/plugin-containers.js.map +1 -0
  292. package/src/lib/plugin-manager/plugin-contributions.d.ts +1 -1
  293. package/src/lib/plugin-manager/plugin-contributions.js.map +1 -1
  294. package/src/lib/plugin-manager/plugin-declarations-repair.d.ts +36 -0
  295. package/src/lib/plugin-manager/plugin-declarations-repair.js +64 -0
  296. package/src/lib/plugin-manager/plugin-declarations-repair.js.map +1 -0
  297. package/src/lib/plugin-manager/plugin-dependents.d.ts +101 -0
  298. package/src/lib/plugin-manager/plugin-dependents.js +75 -0
  299. package/src/lib/plugin-manager/plugin-dependents.js.map +1 -0
  300. package/src/lib/plugin-manager/plugin-distribution.d.ts +55 -0
  301. package/src/lib/plugin-manager/plugin-distribution.js +45 -0
  302. package/src/lib/plugin-manager/plugin-distribution.js.map +1 -0
  303. package/src/lib/plugin-manager/plugin-entitlements.d.ts +8 -0
  304. package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -1
  305. package/src/lib/plugin-manager/plugin-host-collections.d.ts +17 -0
  306. package/src/lib/plugin-manager/plugin-host-collections.js +6 -0
  307. package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -1
  308. package/src/lib/plugin-manager/plugin-host-resources.d.ts +133 -0
  309. package/src/lib/plugin-manager/plugin-host-resources.js +52 -0
  310. package/src/lib/plugin-manager/plugin-host-resources.js.map +1 -0
  311. package/src/lib/plugin-manager/plugin-membership-detach.js +1 -1
  312. package/src/lib/plugin-manager/plugin-membership-detach.js.map +1 -1
  313. package/src/lib/plugin-manager/plugin-org-erasure.d.ts +28 -2
  314. package/src/lib/plugin-manager/plugin-org-erasure.js +61 -2
  315. package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -1
  316. package/src/lib/plugin-manager/plugin-plan-entitlements.d.ts +123 -0
  317. package/src/lib/plugin-manager/plugin-plan-entitlements.js +101 -0
  318. package/src/lib/plugin-manager/plugin-plan-entitlements.js.map +1 -0
  319. package/src/lib/plugin-manager/plugin-record-email-state.d.ts +69 -0
  320. package/src/lib/plugin-manager/plugin-record-email-state.js +32 -0
  321. package/src/lib/plugin-manager/plugin-record-email-state.js.map +1 -1
  322. package/src/lib/plugin-manager/plugin-record-index.d.ts +95 -0
  323. package/src/lib/plugin-manager/plugin-record-index.js +51 -0
  324. package/src/lib/plugin-manager/plugin-record-index.js.map +1 -0
  325. package/src/lib/plugin-manager/plugin-record-lists.d.ts +115 -0
  326. package/src/lib/plugin-manager/plugin-record-lists.js +75 -0
  327. package/src/lib/plugin-manager/plugin-record-lists.js.map +1 -0
  328. package/src/lib/plugin-manager/plugin-record-timeline.d.ts +42 -8
  329. package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -1
  330. package/src/lib/plugin-manager/plugin-record-written.d.ts +58 -0
  331. package/src/lib/plugin-manager/plugin-record-written.js +42 -0
  332. package/src/lib/plugin-manager/plugin-record-written.js.map +1 -0
  333. package/src/lib/plugin-manager/plugin-revenue-sources.d.ts +213 -0
  334. package/src/lib/plugin-manager/plugin-revenue-sources.js +194 -0
  335. package/src/lib/plugin-manager/plugin-revenue-sources.js.map +1 -0
  336. package/src/lib/plugin-manager/plugin-site-beacons.d.ts +71 -0
  337. package/src/lib/plugin-manager/plugin-site-beacons.js +54 -0
  338. package/src/lib/plugin-manager/plugin-site-beacons.js.map +1 -0
  339. package/src/lib/plugin-manager/plugin-site-bundle.d.ts +145 -0
  340. package/src/lib/plugin-manager/plugin-site-bundle.js +78 -0
  341. package/src/lib/plugin-manager/plugin-site-bundle.js.map +1 -0
  342. package/src/lib/plugin-manager/plugin-site-cache.d.ts +12 -0
  343. package/src/lib/plugin-manager/plugin-site-cache.js.map +1 -1
  344. package/src/lib/plugin-manager/plugin-site-export.d.ts +81 -0
  345. package/src/lib/plugin-manager/plugin-site-export.js +40 -0
  346. package/src/lib/plugin-manager/plugin-site-export.js.map +1 -0
  347. package/src/lib/plugin-manager/plugin-sitemap-sections.d.ts +88 -0
  348. package/src/lib/plugin-manager/plugin-sitemap-sections.js +29 -0
  349. package/src/lib/plugin-manager/plugin-sitemap-sections.js.map +1 -0
  350. package/src/lib/plugin-manager/plugin-subscription-topics.generated.d.ts +11 -0
  351. package/src/lib/plugin-manager/plugin-subscription-topics.generated.js +41 -0
  352. package/src/lib/plugin-manager/plugin-subscription-topics.generated.js.map +1 -0
  353. package/src/lib/plugin-manager/plugin-tax-profile.d.ts +20 -4
  354. package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -1
  355. package/src/lib/plugin-manager/plugin-tax-return-sources.d.ts +255 -0
  356. package/src/lib/plugin-manager/plugin-tax-return-sources.js +191 -0
  357. package/src/lib/plugin-manager/plugin-tax-return-sources.js.map +1 -0
  358. package/src/lib/plugin-manager/plugin-template-sources.d.ts +75 -0
  359. package/src/lib/plugin-manager/plugin-template-sources.js +37 -0
  360. package/src/lib/plugin-manager/plugin-template-sources.js.map +1 -0
  361. package/src/lib/plugin-manager/plugin-usage-axes.d.ts +319 -0
  362. package/src/lib/plugin-manager/plugin-usage-axes.js +186 -0
  363. package/src/lib/plugin-manager/plugin-usage-axes.js.map +1 -0
  364. package/src/lib/plugin-manager/plugin-usage-meters.d.ts +108 -0
  365. package/src/lib/plugin-manager/plugin-usage-meters.js +105 -0
  366. package/src/lib/plugin-manager/plugin-usage-meters.js.map +1 -0
  367. package/src/lib/plugin-manager/plugin-zones.d.ts +4 -5
  368. package/src/lib/plugin-manager/plugin-zones.js.map +1 -1
  369. package/src/lib/plugin-manager/realm-host-aglyn.generated.js +2 -0
  370. package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
  371. package/src/lib/plugin-manager/record-captured-contact.d.ts +1 -14
  372. package/src/lib/plugin-manager/record-captured-contact.js +10 -32
  373. package/src/lib/plugin-manager/record-captured-contact.js.map +1 -1
  374. package/src/lib/plugin-manager/repeat-rows.d.ts +124 -0
  375. package/src/lib/plugin-manager/repeat-rows.js +108 -0
  376. package/src/lib/plugin-manager/repeat-rows.js.map +1 -0
  377. package/src/lib/plugin-manager/submission-record-target.d.ts +144 -0
  378. package/src/lib/plugin-manager/submission-record-target.js +125 -0
  379. package/src/lib/plugin-manager/submission-record-target.js.map +1 -0
  380. package/src/lib/plugin-manager/usage-alert-contributors.d.ts +76 -6
  381. package/src/lib/plugin-manager/usage-alert-contributors.js +23 -10
  382. package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -1
  383. package/src/lib/plugin-manager/video-embed-provider.d.ts +108 -0
  384. package/src/lib/plugin-manager/video-embed-provider.js +165 -0
  385. package/src/lib/plugin-manager/video-embed-provider.js.map +1 -0
  386. package/src/lib/types/nodes.d.ts +2 -2
  387. package/src/lib/types/nodes.js.map +1 -1
  388. package/src/lib/app-utils/assist-credits.d.ts +0 -482
  389. package/src/lib/app-utils/assist-credits.js +0 -509
  390. package/src/lib/app-utils/assist-credits.js.map +0 -1
  391. package/src/lib/app-utils/campaign-attribution.js.map +0 -1
  392. package/src/lib/app-utils/campaign-forwarding.js.map +0 -1
  393. package/src/lib/app-utils/campaign-membership.d.ts +0 -121
  394. package/src/lib/app-utils/campaign-membership.js +0 -189
  395. package/src/lib/app-utils/campaign-membership.js.map +0 -1
  396. package/src/lib/app-utils/campaign-touch.js.map +0 -1
  397. package/src/lib/app-utils/console-record-links.d.ts +0 -163
  398. package/src/lib/app-utils/console-record-links.js +0 -180
  399. package/src/lib/app-utils/console-record-links.js.map +0 -1
  400. package/src/lib/app-utils/contact-holder.d.ts +0 -68
  401. package/src/lib/app-utils/contact-holder.js +0 -129
  402. package/src/lib/app-utils/contact-holder.js.map +0 -1
  403. package/src/lib/app-utils/contact-merge.d.ts +0 -136
  404. package/src/lib/app-utils/contact-merge.js +0 -412
  405. package/src/lib/app-utils/contact-merge.js.map +0 -1
  406. package/src/lib/app-utils/crm-booking.d.ts +0 -75
  407. package/src/lib/app-utils/crm-booking.js +0 -133
  408. package/src/lib/app-utils/crm-booking.js.map +0 -1
  409. package/src/lib/app-utils/crm-csv.d.ts +0 -239
  410. package/src/lib/app-utils/crm-csv.js +0 -467
  411. package/src/lib/app-utils/crm-csv.js.map +0 -1
  412. package/src/lib/app-utils/crm-digest.d.ts +0 -185
  413. package/src/lib/app-utils/crm-digest.js +0 -272
  414. package/src/lib/app-utils/crm-digest.js.map +0 -1
  415. package/src/lib/app-utils/crm-inbound.d.ts +0 -245
  416. package/src/lib/app-utils/crm-inbound.js +0 -407
  417. package/src/lib/app-utils/crm-inbound.js.map +0 -1
  418. package/src/lib/app-utils/crm-reports.d.ts +0 -479
  419. package/src/lib/app-utils/crm-reports.js +0 -680
  420. package/src/lib/app-utils/crm-reports.js.map +0 -1
  421. package/src/lib/app-utils/dataset-csv.js.map +0 -1
  422. package/src/lib/app-utils/dataset-query.d.ts +0 -57
  423. package/src/lib/app-utils/dataset-query.js.map +0 -1
  424. package/src/lib/app-utils/email-topics.js.map +0 -1
  425. package/src/lib/app-utils/form-dataset-binding.d.ts +0 -50
  426. package/src/lib/app-utils/form-dataset-binding.js +0 -74
  427. package/src/lib/app-utils/form-dataset-binding.js.map +0 -1
  428. package/src/lib/app-utils/list-assignment-policy.js.map +0 -1
  429. package/src/lib/app-utils/list-import.d.ts +0 -158
  430. package/src/lib/app-utils/list-import.js +0 -332
  431. package/src/lib/app-utils/list-import.js.map +0 -1
  432. package/src/lib/app-utils/marketplace-listing-visibility.d.ts +0 -122
  433. package/src/lib/app-utils/marketplace-listing-visibility.js +0 -147
  434. package/src/lib/app-utils/marketplace-listing-visibility.js.map +0 -1
  435. package/src/lib/app-utils/marketplace-overrides.js.map +0 -1
  436. package/src/lib/app-utils/marketplace-provenance.js.map +0 -1
  437. package/src/lib/app-utils/marketplace-theme.js.map +0 -1
  438. package/src/lib/app-utils/marketplace-update-state.d.ts +0 -119
  439. package/src/lib/app-utils/marketplace-update-state.js +0 -132
  440. package/src/lib/app-utils/marketplace-update-state.js.map +0 -1
  441. package/src/lib/app-utils/publisher-agreement.d.ts +0 -289
  442. package/src/lib/app-utils/publisher-agreement.js +0 -321
  443. package/src/lib/app-utils/publisher-agreement.js.map +0 -1
  444. package/src/lib/app-utils/wistia-embed.d.ts +0 -104
  445. package/src/lib/app-utils/wistia-embed.js +0 -138
  446. package/src/lib/app-utils/wistia-embed.js.map +0 -1
  447. package/src/lib/app-utils/workflows.d.ts +0 -136
  448. package/src/lib/app-utils/workflows.js +0 -346
  449. package/src/lib/app-utils/workflows.js.map +0 -1
  450. package/src/lib/plugin-manager/commerce-zone-props.d.ts +0 -172
  451. package/src/lib/plugin-manager/commerce-zone-props.js +0 -31
  452. package/src/lib/plugin-manager/commerce-zone-props.js.map +0 -1
  453. package/src/lib/plugin-manager/plugin-metered-lines.d.ts +0 -97
  454. package/src/lib/plugin-manager/plugin-metered-lines.js +0 -123
  455. package/src/lib/plugin-manager/plugin-metered-lines.js.map +0 -1
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { RepeatableDataset } from '../app-utils/expand-repeatables';
18
+ /**
19
+ * WHERE A PUBLISHED PAGE'S REPEATED ROWS COME FROM (AGL-3080).
20
+ *
21
+ * Any element can repeat, and the platform decides what a repeat MEANS — the
22
+ * scope, the copies, the filter, the bound (`expand-repeatables.ts`). What it
23
+ * does not decide is where the rows live. That is the plugin's that keeps
24
+ * them, and the composition that renders a published page asks it here, with
25
+ * the keys the page's tree repeats over, and never reads a collection itself.
26
+ *
27
+ * `repeat-sources.ts` is the editor's side of the same line: a hook the
28
+ * besigner's canvas mounts to preview the rows. This is the server's side,
29
+ * read once per compose, and it is a different registry because its readers
30
+ * are different processes with different failure costs.
31
+ *
32
+ * ## Declared, then registered — and an absent reader is refused
33
+ *
34
+ * The reader is registered from the owning plugin's `serverDeclarations`
35
+ * entry, which every app runs at boot, so every process that composes a page
36
+ * has it before the first request. But a registry is only safe where an empty
37
+ * one cannot be mistaken for an answer, and here it can: a page whose repeat
38
+ * found no reader would render the template once where the author put a list,
39
+ * and nothing anywhere would be red. That is the AGL-3025 shape on the most
40
+ * public surface the product has.
41
+ *
42
+ * So the plugin that answers also DECLARES that it does, in
43
+ * `plugins.config.json` (`repeatSource`), and the generator compiles that into
44
+ * core. The two together tell the one case that is a real answer from the one
45
+ * that is a broken boot:
46
+ *
47
+ * - nothing declared — this deployment ships no plugin that keeps rows, and a
48
+ * repeat renders its element once, as written, exactly as a key naming
49
+ * nothing does;
50
+ * - declared and registered — the reader answers;
51
+ * - declared and NOT registered — the boot failed. The app's declarations
52
+ * step is run again ({@link runPluginDeclarationsRepair}); if the reader is
53
+ * still missing, {@link readRepeatRows} THROWS. A render that throws keeps
54
+ * the page it last rendered in the cache and is loud in the logs, which is
55
+ * the right way round for a page that would otherwise go out wrong.
56
+ *
57
+ * Per-key failures are the reader's to absorb, as they always were: a deleted
58
+ * or unreadable entry leaves its element rendering once and costs the page
59
+ * nothing else.
60
+ *
61
+ * Reached by path, never through a barrel: only the server composition asks.
62
+ */
63
+ /** One composition's question: the keys a page's tree repeats over. */
64
+ export interface RepeatRowsRequest {
65
+ /** The site being rendered. A reader answers only what that site may see. */
66
+ hostId: string;
67
+ /**
68
+ * The keys exactly as the nodes store them (`repeatKeys`), trimmed,
69
+ * sorted and without repeats.
70
+ */
71
+ keys: readonly string[];
72
+ }
73
+ /**
74
+ * The rows for a request, under every key the expansion looks them up by: the
75
+ * key as the node stores it, the entry's own id, and each entry a one-hop
76
+ * reference in the rows reads. A key with nothing to render is absent.
77
+ */
78
+ export type RepeatRowsAnswer = Record<string, RepeatableDataset>;
79
+ /** Answers one composition's request. Never rejects for a single bad key. */
80
+ export type RepeatRowReader = (request: RepeatRowsRequest) => Promise<RepeatRowsAnswer>;
81
+ /** The compiled declaration: which plugin answers, under which source id. */
82
+ export interface RepeatSourceDeclaration {
83
+ pluginId: string;
84
+ /** The same id the plugin's editor source (`repeat-sources.ts`) uses. */
85
+ id: string;
86
+ }
87
+ /** The plugin declared to answer repeats, or `null` when none is. */
88
+ export declare function declaredRepeatSource(): RepeatSourceDeclaration | null;
89
+ interface RegisteredReader {
90
+ pluginId: string;
91
+ reader: RepeatRowReader;
92
+ }
93
+ /**
94
+ * Registers the reader for a source. Returns the unregister, which removes it
95
+ * only while it is still the one registered.
96
+ *
97
+ * The owner is the plugin whose register fn is running, or the `pluginId`
98
+ * passed for a boot declaration, where the loader's marker is not set. A
99
+ * registration with neither is refused, and so is one from a plugin other
100
+ * than the one the declaration names — two readers for one source would each
101
+ * answer for the other's rows. The same plugin registering again replaces its
102
+ * reader (a second surface, a repeated boot).
103
+ */
104
+ export declare function registerRepeatRowReader(sourceId: string, reader: RepeatRowReader, options?: {
105
+ pluginId?: string;
106
+ }): () => void;
107
+ /** The reader registered for a source, with its owner, or `null`. */
108
+ export declare function repeatRowReader(sourceId: string): RegisteredReader | null;
109
+ /** Only for specs: forgets every registered reader. */
110
+ export declare function resetRepeatRowReadersForTests(): void;
111
+ /**
112
+ * The declared source's reader was not registered, even after the app's
113
+ * declarations step ran again. Thrown, never answered: see the module note.
114
+ */
115
+ export declare class RepeatRowsUnavailableError extends Error {
116
+ readonly source: RepeatSourceDeclaration;
117
+ constructor(source: RepeatSourceDeclaration);
118
+ }
119
+ /**
120
+ * The rows a composition's repeats render. See the module note for what each
121
+ * of the three cases answers; with no keys it answers `{}` and asks nobody.
122
+ */
123
+ export declare function readRepeatRows(request: RepeatRowsRequest): Promise<RepeatRowsAnswer>;
124
+ export {};
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ var _globalScope_READERS_KEY;
17
+ import { getRegisteringPluginId } from "../app-utils/registering-plugin.js";
18
+ import { PLUGIN_REPEAT_SOURCE_DECLARED } from "./first-party-plugins.generated.js";
19
+ import { runPluginDeclarationsRepair } from "./plugin-declarations-repair.js";
20
+ /** The plugin declared to answer repeats, or `null` when none is. */ export function declaredRepeatSource() {
21
+ return PLUGIN_REPEAT_SOURCE_DECLARED;
22
+ }
23
+ /**
24
+ * One table per process, on `globalThis` (AGL-3412): the app registers from
25
+ * `instrumentation.ts`, which Next compiles apart from the routes that read,
26
+ * and a module-scoped map would be filled in one copy and read empty in the
27
+ * other — the exact failure this module exists to refuse.
28
+ */ const READERS_KEY = Symbol.for('@aglyn/aglyn:repeat-row-readers');
29
+ const globalScope = globalThis;
30
+ const readers = (_globalScope_READERS_KEY = globalScope[READERS_KEY]) != null ? _globalScope_READERS_KEY : globalScope[READERS_KEY] = new Map();
31
+ /**
32
+ * Registers the reader for a source. Returns the unregister, which removes it
33
+ * only while it is still the one registered.
34
+ *
35
+ * The owner is the plugin whose register fn is running, or the `pluginId`
36
+ * passed for a boot declaration, where the loader's marker is not set. A
37
+ * registration with neither is refused, and so is one from a plugin other
38
+ * than the one the declaration names — two readers for one source would each
39
+ * answer for the other's rows. The same plugin registering again replaces its
40
+ * reader (a second surface, a repeated boot).
41
+ */ export function registerRepeatRowReader(sourceId, reader, options) {
42
+ var _ref, _getRegisteringPluginId;
43
+ const id = sourceId.trim();
44
+ const pluginId = ((_ref = (_getRegisteringPluginId = getRegisteringPluginId()) != null ? _getRegisteringPluginId : options == null ? void 0 : options.pluginId) != null ? _ref : '').trim();
45
+ if (!id) throw new Error('a repeat row reader needs a source id');
46
+ if (!pluginId) {
47
+ throw new Error(`repeat row reader "${id}" registered with no owner: pass { pluginId } ` + 'when registering outside a plugin register fn');
48
+ }
49
+ const declared = declaredRepeatSource();
50
+ if ((declared == null ? void 0 : declared.id) === id && declared.pluginId !== pluginId) {
51
+ throw new Error(`repeat source "${id}" is declared by "${declared.pluginId}"; ` + `refused a reader from "${pluginId}"`);
52
+ }
53
+ const held = readers.get(id);
54
+ if (held && held.pluginId !== pluginId) {
55
+ throw new Error(`repeat source "${id}" already has a reader from "${held.pluginId}"; ` + `refused "${pluginId}"`);
56
+ }
57
+ const entry = {
58
+ pluginId,
59
+ reader
60
+ };
61
+ readers.set(id, entry);
62
+ return ()=>{
63
+ if (readers.get(id) === entry) readers.delete(id);
64
+ };
65
+ }
66
+ /** The reader registered for a source, with its owner, or `null`. */ export function repeatRowReader(sourceId) {
67
+ var _readers_get;
68
+ return (_readers_get = readers.get(sourceId)) != null ? _readers_get : null;
69
+ }
70
+ /** Only for specs: forgets every registered reader. */ export function resetRepeatRowReadersForTests() {
71
+ readers.clear();
72
+ }
73
+ /**
74
+ * The declared source's reader was not registered, even after the app's
75
+ * declarations step ran again. Thrown, never answered: see the module note.
76
+ */ export class RepeatRowsUnavailableError extends Error {
77
+ constructor(source){
78
+ super(`repeat source "${source.id}" is declared by "${source.pluginId}" but ` + 'no reader is registered in this process — its server declarations ' + 'did not run. Refusing to render repeats as if they had no rows.'), this.source = source;
79
+ this.name = 'RepeatRowsUnavailableError';
80
+ }
81
+ }
82
+ /**
83
+ * The rows a composition's repeats render. See the module note for what each
84
+ * of the three cases answers; with no keys it answers `{}` and asks nobody.
85
+ */ export async function readRepeatRows(request) {
86
+ const keys = [
87
+ ...new Set(request.keys.map((key)=>key.trim()).filter(Boolean))
88
+ ].sort();
89
+ if (!keys.length) return {};
90
+ const declared = declaredRepeatSource();
91
+ if (!declared) return {};
92
+ let registered = readers.get(declared.id);
93
+ if (!registered) {
94
+ try {
95
+ await runPluginDeclarationsRepair();
96
+ } catch (error) {
97
+ console.error('[repeat-rows] the declarations repair failed', error);
98
+ }
99
+ registered = readers.get(declared.id);
100
+ }
101
+ if (!registered) throw new RepeatRowsUnavailableError(declared);
102
+ return registered.reader({
103
+ hostId: request.hostId,
104
+ keys
105
+ });
106
+ }
107
+
108
+ //# sourceMappingURL=repeat-rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/repeat-rows.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { RepeatableDataset } from '../app-utils/expand-repeatables'\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\nimport { PLUGIN_REPEAT_SOURCE_DECLARED } from './first-party-plugins.generated'\nimport { runPluginDeclarationsRepair } from './plugin-declarations-repair'\n\n/**\n * WHERE A PUBLISHED PAGE'S REPEATED ROWS COME FROM (AGL-3080).\n *\n * Any element can repeat, and the platform decides what a repeat MEANS — the\n * scope, the copies, the filter, the bound (`expand-repeatables.ts`). What it\n * does not decide is where the rows live. That is the plugin's that keeps\n * them, and the composition that renders a published page asks it here, with\n * the keys the page's tree repeats over, and never reads a collection itself.\n *\n * `repeat-sources.ts` is the editor's side of the same line: a hook the\n * besigner's canvas mounts to preview the rows. This is the server's side,\n * read once per compose, and it is a different registry because its readers\n * are different processes with different failure costs.\n *\n * ## Declared, then registered — and an absent reader is refused\n *\n * The reader is registered from the owning plugin's `serverDeclarations`\n * entry, which every app runs at boot, so every process that composes a page\n * has it before the first request. But a registry is only safe where an empty\n * one cannot be mistaken for an answer, and here it can: a page whose repeat\n * found no reader would render the template once where the author put a list,\n * and nothing anywhere would be red. That is the AGL-3025 shape on the most\n * public surface the product has.\n *\n * So the plugin that answers also DECLARES that it does, in\n * `plugins.config.json` (`repeatSource`), and the generator compiles that into\n * core. The two together tell the one case that is a real answer from the one\n * that is a broken boot:\n *\n * - nothing declared — this deployment ships no plugin that keeps rows, and a\n * repeat renders its element once, as written, exactly as a key naming\n * nothing does;\n * - declared and registered — the reader answers;\n * - declared and NOT registered — the boot failed. The app's declarations\n * step is run again ({@link runPluginDeclarationsRepair}); if the reader is\n * still missing, {@link readRepeatRows} THROWS. A render that throws keeps\n * the page it last rendered in the cache and is loud in the logs, which is\n * the right way round for a page that would otherwise go out wrong.\n *\n * Per-key failures are the reader's to absorb, as they always were: a deleted\n * or unreadable entry leaves its element rendering once and costs the page\n * nothing else.\n *\n * Reached by path, never through a barrel: only the server composition asks.\n */\n\n/** One composition's question: the keys a page's tree repeats over. */\nexport interface RepeatRowsRequest {\n /** The site being rendered. A reader answers only what that site may see. */\n hostId: string\n /**\n * The keys exactly as the nodes store them (`repeatKeys`), trimmed,\n * sorted and without repeats.\n */\n keys: readonly string[]\n}\n\n/**\n * The rows for a request, under every key the expansion looks them up by: the\n * key as the node stores it, the entry's own id, and each entry a one-hop\n * reference in the rows reads. A key with nothing to render is absent.\n */\nexport type RepeatRowsAnswer = Record<string, RepeatableDataset>\n\n/** Answers one composition's request. Never rejects for a single bad key. */\nexport type RepeatRowReader = (\n request: RepeatRowsRequest,\n) => Promise<RepeatRowsAnswer>\n\n/** The compiled declaration: which plugin answers, under which source id. */\nexport interface RepeatSourceDeclaration {\n pluginId: string\n /** The same id the plugin's editor source (`repeat-sources.ts`) uses. */\n id: string\n}\n\n/** The plugin declared to answer repeats, or `null` when none is. */\nexport function declaredRepeatSource(): RepeatSourceDeclaration | null {\n return PLUGIN_REPEAT_SOURCE_DECLARED\n}\n\ninterface RegisteredReader {\n pluginId: string\n reader: RepeatRowReader\n}\n\n/**\n * One table per process, on `globalThis` (AGL-3412): the app registers from\n * `instrumentation.ts`, which Next compiles apart from the routes that read,\n * and a module-scoped map would be filled in one copy and read empty in the\n * other — the exact failure this module exists to refuse.\n */\nconst READERS_KEY = Symbol.for('@aglyn/aglyn:repeat-row-readers')\n\nconst globalScope = globalThis as typeof globalThis & {\n [READERS_KEY]?: Map<string, RegisteredReader>\n}\n\nconst readers: Map<string, RegisteredReader> =\n globalScope[READERS_KEY] ?? (globalScope[READERS_KEY] = new Map())\n\n/**\n * Registers the reader for a source. Returns the unregister, which removes it\n * only while it is still the one registered.\n *\n * The owner is the plugin whose register fn is running, or the `pluginId`\n * passed for a boot declaration, where the loader's marker is not set. A\n * registration with neither is refused, and so is one from a plugin other\n * than the one the declaration names — two readers for one source would each\n * answer for the other's rows. The same plugin registering again replaces its\n * reader (a second surface, a repeated boot).\n */\nexport function registerRepeatRowReader(\n sourceId: string,\n reader: RepeatRowReader,\n options?: { pluginId?: string },\n): () => void {\n const id = sourceId.trim()\n const pluginId = (getRegisteringPluginId() ?? options?.pluginId ?? '').trim()\n if (!id) throw new Error('a repeat row reader needs a source id')\n if (!pluginId) {\n throw new Error(\n `repeat row reader \"${id}\" registered with no owner: pass { pluginId } ` +\n 'when registering outside a plugin register fn',\n )\n }\n const declared = declaredRepeatSource()\n if (declared?.id === id && declared.pluginId !== pluginId) {\n throw new Error(\n `repeat source \"${id}\" is declared by \"${declared.pluginId}\"; ` +\n `refused a reader from \"${pluginId}\"`,\n )\n }\n const held = readers.get(id)\n if (held && held.pluginId !== pluginId) {\n throw new Error(\n `repeat source \"${id}\" already has a reader from \"${held.pluginId}\"; ` +\n `refused \"${pluginId}\"`,\n )\n }\n const entry: RegisteredReader = { pluginId, reader }\n readers.set(id, entry)\n return () => {\n if (readers.get(id) === entry) readers.delete(id)\n }\n}\n\n/** The reader registered for a source, with its owner, or `null`. */\nexport function repeatRowReader(sourceId: string): RegisteredReader | null {\n return readers.get(sourceId) ?? null\n}\n\n/** Only for specs: forgets every registered reader. */\nexport function resetRepeatRowReadersForTests(): void {\n readers.clear()\n}\n\n/**\n * The declared source's reader was not registered, even after the app's\n * declarations step ran again. Thrown, never answered: see the module note.\n */\nexport class RepeatRowsUnavailableError extends Error {\n constructor(readonly source: RepeatSourceDeclaration) {\n super(\n `repeat source \"${source.id}\" is declared by \"${source.pluginId}\" but ` +\n 'no reader is registered in this process — its server declarations ' +\n 'did not run. Refusing to render repeats as if they had no rows.',\n )\n this.name = 'RepeatRowsUnavailableError'\n }\n}\n\n/**\n * The rows a composition's repeats render. See the module note for what each\n * of the three cases answers; with no keys it answers `{}` and asks nobody.\n */\nexport async function readRepeatRows(\n request: RepeatRowsRequest,\n): Promise<RepeatRowsAnswer> {\n const keys = [\n ...new Set(request.keys.map((key) => key.trim()).filter(Boolean)),\n ].sort()\n if (!keys.length) return {}\n const declared = declaredRepeatSource()\n if (!declared) return {}\n let registered = readers.get(declared.id)\n if (!registered) {\n try {\n await runPluginDeclarationsRepair()\n } catch (error) {\n console.error('[repeat-rows] the declarations repair failed', error)\n }\n registered = readers.get(declared.id)\n }\n if (!registered) throw new RepeatRowsUnavailableError(declared)\n return registered.reader({ hostId: request.hostId, keys })\n}\n"],"names":["globalScope","getRegisteringPluginId","PLUGIN_REPEAT_SOURCE_DECLARED","runPluginDeclarationsRepair","declaredRepeatSource","READERS_KEY","Symbol","for","globalThis","readers","Map","registerRepeatRowReader","sourceId","reader","options","id","trim","pluginId","Error","declared","held","get","entry","set","delete","repeatRowReader","resetRepeatRowReadersForTests","clear","RepeatRowsUnavailableError","source","name","readRepeatRows","request","keys","Set","map","key","filter","Boolean","sort","length","registered","error","console","hostId"],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * WHERE A FORM'S SUBMISSION IS ALSO SAVED AS A RECORD (AGL-3080).
19
+ *
20
+ * A form on a published page can file every submission as a record another
21
+ * plugin keeps — a row in a dataset, today. The form is one plugin's element
22
+ * and the record is another plugin's storage, so neither may know the other:
23
+ * this is the contract between them, and core names neither the target nor
24
+ * where it keeps anything.
25
+ *
26
+ * It has two halves, because the decision of where a record lands must be
27
+ * made where the visitor cannot reach it:
28
+ *
29
+ * 1. {@link stampFormRecordTargets} — the page's composition hands the target
30
+ * the tree it is about to ship, and the target stamps each form it will
31
+ * write for with whatever it needs to trust at submit time (a signed
32
+ * binding). The submit route is public and unauthenticated, so nothing
33
+ * the body says on its own may choose a destination.
34
+ * 2. {@link writeFormRecordTarget} — the submit route hands the target the
35
+ * submission as posted, after the submission itself is stored. The target
36
+ * reads back what it stamped, writes the record or refuses it, and answers
37
+ * what to note on the submission (`routing`) so the Inbox can say where it
38
+ * went or why it did not.
39
+ *
40
+ * ## Declared, then registered — and an absent target is loud
41
+ *
42
+ * The target registers from its plugin's `serverDeclarations` entry, which
43
+ * every app runs at boot, and also DECLARES itself in `plugins.config.json`
44
+ * (`formRecordTarget`), compiled into core. A registry alone would read a
45
+ * failed boot as "no form writes anywhere", and every bound form would keep
46
+ * accepting submissions while its records quietly stopped — the AGL-3025
47
+ * shape. With the declaration the three cases are distinct:
48
+ *
49
+ * - nothing declared — this deployment ships no plugin that keeps records; no
50
+ * form is stamped and no submission writes one, which is a real answer;
51
+ * - declared and registered — the target answers;
52
+ * - declared and NOT registered — the app's declarations step runs again. If
53
+ * the target is still missing, a page carrying a form THROWS at render (the
54
+ * cache keeps the last good page, and the logs are red), and a submission
55
+ * is kept — the Inbox copy is written before this is asked — with the
56
+ * failure logged and noted on it under `routing.recordTargetUnavailable`.
57
+ *
58
+ * Server-only, and reached by path, never through a barrel.
59
+ */
60
+ /** One submission, as the route stored it. */
61
+ export interface FormRecordWriteRequest {
62
+ /** The site the form was submitted on. */
63
+ hostId: string;
64
+ /** The organization that owns the site, when it has one. */
65
+ orgId: string | null;
66
+ /** The organization's billing document — the entitlements a write is held to. */
67
+ orgBilling: unknown;
68
+ /**
69
+ * The request body as posted. The target reads back only what it stamped
70
+ * onto the form, and must trust nothing else in it.
71
+ */
72
+ body: Readonly<Record<string, unknown>>;
73
+ /** The submitted values, sanitized, keyed by the name each field submits under. */
74
+ fields: Readonly<Record<string, string>>;
75
+ }
76
+ /** What a target answers for one submission. */
77
+ export interface FormRecordWriteOutcome {
78
+ /**
79
+ * Written as the stored submission's `routing` when present: where the
80
+ * record went, or why it was refused. Absent when the form writes nowhere.
81
+ */
82
+ routing?: Record<string, unknown>;
83
+ }
84
+ /** A plugin that keeps the records forms may file into. */
85
+ export interface FormRecordTarget {
86
+ /**
87
+ * Stamps each form in a composed tree this target will write for. Never
88
+ * mutates `nodes`, and answers the same object when it stamps nothing.
89
+ */
90
+ stamp<N extends Record<string, unknown>>(nodes: N, hostId: string): Promise<N>;
91
+ /**
92
+ * Writes one submission's record, or refuses it. Never rejects: a record
93
+ * that cannot be written is no reason to fail a submission already stored.
94
+ */
95
+ write(request: FormRecordWriteRequest): Promise<FormRecordWriteOutcome>;
96
+ }
97
+ /** The compiled declaration: which plugin keeps the records forms file into. */
98
+ export interface FormRecordTargetDeclaration {
99
+ pluginId: string;
100
+ id: string;
101
+ }
102
+ /** The plugin declared as the forms' record target, or `null` when none is. */
103
+ export declare function declaredFormRecordTarget(): FormRecordTargetDeclaration | null;
104
+ interface RegisteredTarget {
105
+ pluginId: string;
106
+ target: FormRecordTarget;
107
+ }
108
+ /**
109
+ * Registers the target. The owner is the plugin whose register fn is running,
110
+ * or the `pluginId` passed for a boot declaration; with neither, or from a
111
+ * plugin other than the one declared, it throws. The same plugin registering
112
+ * again replaces its target. Returns the unregister.
113
+ */
114
+ export declare function registerFormRecordTarget(target: FormRecordTarget, options?: {
115
+ pluginId?: string;
116
+ }): () => void;
117
+ /** The registered target with its owner, or `null`. */
118
+ export declare function formRecordTarget(): RegisteredTarget | null;
119
+ /** Only for specs: forgets the registered target. */
120
+ export declare function resetFormRecordTargetForTests(): void;
121
+ /**
122
+ * The declared target's registration was not found, even after the app's
123
+ * declarations step ran again.
124
+ */
125
+ export declare class FormRecordTargetUnavailableError extends Error {
126
+ readonly declared: FormRecordTargetDeclaration;
127
+ constructor(declared: FormRecordTargetDeclaration);
128
+ }
129
+ /**
130
+ * The tree a page ships, with each form the target writes for stamped.
131
+ *
132
+ * A tree with no form asks nobody and comes back as the same object. A tree
133
+ * with one THROWS when the declared target is missing — see the module note.
134
+ */
135
+ export declare function stampFormRecordTargets<N extends Record<string, unknown>>(nodes: N, hostId: string): Promise<N>;
136
+ /**
137
+ * Files one stored submission as a record where the page's form said to.
138
+ *
139
+ * Never rejects. With no target declared it answers nothing; with the declared
140
+ * target missing it logs the failure and answers a `routing` note saying so,
141
+ * because the submission is already kept and losing it now would be worse.
142
+ */
143
+ export declare function writeFormRecordTarget(request: FormRecordWriteRequest): Promise<FormRecordWriteOutcome>;
144
+ export {};
@@ -0,0 +1,125 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { getRegisteringPluginId } from "../app-utils/registering-plugin.js";
17
+ import { FORM_COMPONENT_ID } from "../app-utils/forms.js";
18
+ import { PLUGIN_FORM_RECORD_TARGET_DECLARED } from "./first-party-plugins.generated.js";
19
+ import { runPluginDeclarationsRepair } from "./plugin-declarations-repair.js";
20
+ /** The plugin declared as the forms' record target, or `null` when none is. */ export function declaredFormRecordTarget() {
21
+ return PLUGIN_FORM_RECORD_TARGET_DECLARED;
22
+ }
23
+ /**
24
+ * One slot per process, on `globalThis` (AGL-3412): the app registers from
25
+ * `instrumentation.ts`, which Next compiles apart from the routes that read.
26
+ */ const TARGET_KEY = Symbol.for('@aglyn/aglyn:submission-record-target');
27
+ const globalScope = globalThis;
28
+ /**
29
+ * Registers the target. The owner is the plugin whose register fn is running,
30
+ * or the `pluginId` passed for a boot declaration; with neither, or from a
31
+ * plugin other than the one declared, it throws. The same plugin registering
32
+ * again replaces its target. Returns the unregister.
33
+ */ export function registerFormRecordTarget(target, options) {
34
+ var _ref, _getRegisteringPluginId;
35
+ const pluginId = ((_ref = (_getRegisteringPluginId = getRegisteringPluginId()) != null ? _getRegisteringPluginId : options == null ? void 0 : options.pluginId) != null ? _ref : '').trim();
36
+ if (!pluginId) {
37
+ throw new Error('the form record target was registered with no owner: pass ' + '{ pluginId } when registering outside a plugin register fn');
38
+ }
39
+ const declared = declaredFormRecordTarget();
40
+ if (declared && declared.pluginId !== pluginId) {
41
+ throw new Error(`the form record target is declared by "${declared.pluginId}"; ` + `refused "${pluginId}"`);
42
+ }
43
+ const held = globalScope[TARGET_KEY];
44
+ if (held && held.pluginId !== pluginId) {
45
+ throw new Error(`the form record target is already registered by "${held.pluginId}"; ` + `refused "${pluginId}"`);
46
+ }
47
+ const entry = {
48
+ pluginId,
49
+ target
50
+ };
51
+ globalScope[TARGET_KEY] = entry;
52
+ return ()=>{
53
+ if (globalScope[TARGET_KEY] === entry) globalScope[TARGET_KEY] = null;
54
+ };
55
+ }
56
+ /** The registered target with its owner, or `null`. */ export function formRecordTarget() {
57
+ var _globalScope_TARGET_KEY;
58
+ return (_globalScope_TARGET_KEY = globalScope[TARGET_KEY]) != null ? _globalScope_TARGET_KEY : null;
59
+ }
60
+ /** Only for specs: forgets the registered target. */ export function resetFormRecordTargetForTests() {
61
+ globalScope[TARGET_KEY] = null;
62
+ }
63
+ /**
64
+ * The declared target's registration was not found, even after the app's
65
+ * declarations step ran again.
66
+ */ export class FormRecordTargetUnavailableError extends Error {
67
+ constructor(declared){
68
+ super(`the form record target is declared by "${declared.pluginId}" but none ` + 'is registered in this process — its server declarations did not run. ' + 'Refusing to treat bound forms as writing nowhere.'), this.declared = declared;
69
+ this.name = 'FormRecordTargetUnavailableError';
70
+ }
71
+ }
72
+ /** The declared target, repaired once if missing; `null` when none is declared. */ async function requireDeclaredTarget() {
73
+ const declared = declaredFormRecordTarget();
74
+ if (!declared) return null;
75
+ let registered = formRecordTarget();
76
+ if (!registered) {
77
+ try {
78
+ await runPluginDeclarationsRepair();
79
+ } catch (error) {
80
+ console.error('[submission-record-target] the declarations repair failed', error);
81
+ }
82
+ registered = formRecordTarget();
83
+ }
84
+ if (!registered) throw new FormRecordTargetUnavailableError(declared);
85
+ return registered.target;
86
+ }
87
+ const placesAForm = (nodes)=>Object.values(nodes).some((node)=>(node == null ? void 0 : node.componentId) === FORM_COMPONENT_ID);
88
+ /**
89
+ * The tree a page ships, with each form the target writes for stamped.
90
+ *
91
+ * A tree with no form asks nobody and comes back as the same object. A tree
92
+ * with one THROWS when the declared target is missing — see the module note.
93
+ */ export async function stampFormRecordTargets(nodes, hostId) {
94
+ if (!placesAForm(nodes)) return nodes;
95
+ const target = await requireDeclaredTarget();
96
+ return target ? target.stamp(nodes, hostId) : nodes;
97
+ }
98
+ /**
99
+ * Files one stored submission as a record where the page's form said to.
100
+ *
101
+ * Never rejects. With no target declared it answers nothing; with the declared
102
+ * target missing it logs the failure and answers a `routing` note saying so,
103
+ * because the submission is already kept and losing it now would be worse.
104
+ */ export async function writeFormRecordTarget(request) {
105
+ let target;
106
+ try {
107
+ target = await requireDeclaredTarget();
108
+ } catch (error) {
109
+ console.error('[submission-record-target] a submission could not be filed', error);
110
+ return {
111
+ routing: {
112
+ recordTargetUnavailable: true
113
+ }
114
+ };
115
+ }
116
+ if (!target) return {};
117
+ try {
118
+ return await target.write(request);
119
+ } catch (error) {
120
+ console.error('[submission-record-target] the target failed a write', error);
121
+ return {};
122
+ }
123
+ }
124
+
125
+ //# sourceMappingURL=submission-record-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/plugin-manager/submission-record-target.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getRegisteringPluginId } from '../app-utils/registering-plugin'\nimport { FORM_COMPONENT_ID } from '../app-utils/forms'\nimport { PLUGIN_FORM_RECORD_TARGET_DECLARED } from './first-party-plugins.generated'\nimport { runPluginDeclarationsRepair } from './plugin-declarations-repair'\n\n/**\n * WHERE A FORM'S SUBMISSION IS ALSO SAVED AS A RECORD (AGL-3080).\n *\n * A form on a published page can file every submission as a record another\n * plugin keeps — a row in a dataset, today. The form is one plugin's element\n * and the record is another plugin's storage, so neither may know the other:\n * this is the contract between them, and core names neither the target nor\n * where it keeps anything.\n *\n * It has two halves, because the decision of where a record lands must be\n * made where the visitor cannot reach it:\n *\n * 1. {@link stampFormRecordTargets} — the page's composition hands the target\n * the tree it is about to ship, and the target stamps each form it will\n * write for with whatever it needs to trust at submit time (a signed\n * binding). The submit route is public and unauthenticated, so nothing\n * the body says on its own may choose a destination.\n * 2. {@link writeFormRecordTarget} — the submit route hands the target the\n * submission as posted, after the submission itself is stored. The target\n * reads back what it stamped, writes the record or refuses it, and answers\n * what to note on the submission (`routing`) so the Inbox can say where it\n * went or why it did not.\n *\n * ## Declared, then registered — and an absent target is loud\n *\n * The target registers from its plugin's `serverDeclarations` entry, which\n * every app runs at boot, and also DECLARES itself in `plugins.config.json`\n * (`formRecordTarget`), compiled into core. A registry alone would read a\n * failed boot as \"no form writes anywhere\", and every bound form would keep\n * accepting submissions while its records quietly stopped — the AGL-3025\n * shape. With the declaration the three cases are distinct:\n *\n * - nothing declared — this deployment ships no plugin that keeps records; no\n * form is stamped and no submission writes one, which is a real answer;\n * - declared and registered — the target answers;\n * - declared and NOT registered — the app's declarations step runs again. If\n * the target is still missing, a page carrying a form THROWS at render (the\n * cache keeps the last good page, and the logs are red), and a submission\n * is kept — the Inbox copy is written before this is asked — with the\n * failure logged and noted on it under `routing.recordTargetUnavailable`.\n *\n * Server-only, and reached by path, never through a barrel.\n */\n\n/** One submission, as the route stored it. */\nexport interface FormRecordWriteRequest {\n /** The site the form was submitted on. */\n hostId: string\n /** The organization that owns the site, when it has one. */\n orgId: string | null\n /** The organization's billing document — the entitlements a write is held to. */\n orgBilling: unknown\n /**\n * The request body as posted. The target reads back only what it stamped\n * onto the form, and must trust nothing else in it.\n */\n body: Readonly<Record<string, unknown>>\n /** The submitted values, sanitized, keyed by the name each field submits under. */\n fields: Readonly<Record<string, string>>\n}\n\n/** What a target answers for one submission. */\nexport interface FormRecordWriteOutcome {\n /**\n * Written as the stored submission's `routing` when present: where the\n * record went, or why it was refused. Absent when the form writes nowhere.\n */\n routing?: Record<string, unknown>\n}\n\n/** A plugin that keeps the records forms may file into. */\nexport interface FormRecordTarget {\n /**\n * Stamps each form in a composed tree this target will write for. Never\n * mutates `nodes`, and answers the same object when it stamps nothing.\n */\n stamp<N extends Record<string, unknown>>(nodes: N, hostId: string): Promise<N>\n /**\n * Writes one submission's record, or refuses it. Never rejects: a record\n * that cannot be written is no reason to fail a submission already stored.\n */\n write(request: FormRecordWriteRequest): Promise<FormRecordWriteOutcome>\n}\n\n/** The compiled declaration: which plugin keeps the records forms file into. */\nexport interface FormRecordTargetDeclaration {\n pluginId: string\n id: string\n}\n\n/** The plugin declared as the forms' record target, or `null` when none is. */\nexport function declaredFormRecordTarget(): FormRecordTargetDeclaration | null {\n return PLUGIN_FORM_RECORD_TARGET_DECLARED\n}\n\ninterface RegisteredTarget {\n pluginId: string\n target: FormRecordTarget\n}\n\n/**\n * One slot per process, on `globalThis` (AGL-3412): the app registers from\n * `instrumentation.ts`, which Next compiles apart from the routes that read.\n */\nconst TARGET_KEY = Symbol.for('@aglyn/aglyn:submission-record-target')\n\nconst globalScope = globalThis as typeof globalThis & {\n [TARGET_KEY]?: RegisteredTarget | null\n}\n\n/**\n * Registers the target. The owner is the plugin whose register fn is running,\n * or the `pluginId` passed for a boot declaration; with neither, or from a\n * plugin other than the one declared, it throws. The same plugin registering\n * again replaces its target. Returns the unregister.\n */\nexport function registerFormRecordTarget(\n target: FormRecordTarget,\n options?: { pluginId?: string },\n): () => void {\n const pluginId = (getRegisteringPluginId() ?? options?.pluginId ?? '').trim()\n if (!pluginId) {\n throw new Error(\n 'the form record target was registered with no owner: pass ' +\n '{ pluginId } when registering outside a plugin register fn',\n )\n }\n const declared = declaredFormRecordTarget()\n if (declared && declared.pluginId !== pluginId) {\n throw new Error(\n `the form record target is declared by \"${declared.pluginId}\"; ` +\n `refused \"${pluginId}\"`,\n )\n }\n const held = globalScope[TARGET_KEY]\n if (held && held.pluginId !== pluginId) {\n throw new Error(\n `the form record target is already registered by \"${held.pluginId}\"; ` +\n `refused \"${pluginId}\"`,\n )\n }\n const entry: RegisteredTarget = { pluginId, target }\n globalScope[TARGET_KEY] = entry\n return () => {\n if (globalScope[TARGET_KEY] === entry) globalScope[TARGET_KEY] = null\n }\n}\n\n/** The registered target with its owner, or `null`. */\nexport function formRecordTarget(): RegisteredTarget | null {\n return globalScope[TARGET_KEY] ?? null\n}\n\n/** Only for specs: forgets the registered target. */\nexport function resetFormRecordTargetForTests(): void {\n globalScope[TARGET_KEY] = null\n}\n\n/**\n * The declared target's registration was not found, even after the app's\n * declarations step ran again.\n */\nexport class FormRecordTargetUnavailableError extends Error {\n constructor(readonly declared: FormRecordTargetDeclaration) {\n super(\n `the form record target is declared by \"${declared.pluginId}\" but none ` +\n 'is registered in this process — its server declarations did not run. ' +\n 'Refusing to treat bound forms as writing nowhere.',\n )\n this.name = 'FormRecordTargetUnavailableError'\n }\n}\n\n/** The declared target, repaired once if missing; `null` when none is declared. */\nasync function requireDeclaredTarget(): Promise<FormRecordTarget | null> {\n const declared = declaredFormRecordTarget()\n if (!declared) return null\n let registered = formRecordTarget()\n if (!registered) {\n try {\n await runPluginDeclarationsRepair()\n } catch (error) {\n console.error('[submission-record-target] the declarations repair failed', error)\n }\n registered = formRecordTarget()\n }\n if (!registered) throw new FormRecordTargetUnavailableError(declared)\n return registered.target\n}\n\nconst placesAForm = (nodes: Record<string, unknown>): boolean =>\n Object.values(nodes).some(\n (node) =>\n (node as { componentId?: unknown } | null)?.componentId === FORM_COMPONENT_ID,\n )\n\n/**\n * The tree a page ships, with each form the target writes for stamped.\n *\n * A tree with no form asks nobody and comes back as the same object. A tree\n * with one THROWS when the declared target is missing — see the module note.\n */\nexport async function stampFormRecordTargets<N extends Record<string, unknown>>(\n nodes: N,\n hostId: string,\n): Promise<N> {\n if (!placesAForm(nodes)) return nodes\n const target = await requireDeclaredTarget()\n return target ? target.stamp(nodes, hostId) : nodes\n}\n\n/**\n * Files one stored submission as a record where the page's form said to.\n *\n * Never rejects. With no target declared it answers nothing; with the declared\n * target missing it logs the failure and answers a `routing` note saying so,\n * because the submission is already kept and losing it now would be worse.\n */\nexport async function writeFormRecordTarget(\n request: FormRecordWriteRequest,\n): Promise<FormRecordWriteOutcome> {\n let target: FormRecordTarget | null\n try {\n target = await requireDeclaredTarget()\n } catch (error) {\n console.error('[submission-record-target] a submission could not be filed', error)\n return { routing: { recordTargetUnavailable: true } }\n }\n if (!target) return {}\n try {\n return await target.write(request)\n } catch (error) {\n console.error('[submission-record-target] the target failed a write', error)\n return {}\n }\n}\n"],"names":["getRegisteringPluginId","FORM_COMPONENT_ID","PLUGIN_FORM_RECORD_TARGET_DECLARED","runPluginDeclarationsRepair","declaredFormRecordTarget","TARGET_KEY","Symbol","for","globalScope","globalThis","registerFormRecordTarget","target","options","pluginId","trim","Error","declared","held","entry","formRecordTarget","resetFormRecordTargetForTests","FormRecordTargetUnavailableError","name","requireDeclaredTarget","registered","error","console","placesAForm","nodes","Object","values","some","node","componentId","stampFormRecordTargets","hostId","stamp","writeFormRecordTarget","request","routing","recordTargetUnavailable","write"],"mappings":"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"}