@superbee/core 0.2.0-pre.40 → 0.2.0-pre.42

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 (300) hide show
  1. package/README.md +96 -9
  2. package/dist/backend.d.ts +17 -1
  3. package/dist/backend.d.ts.map +1 -1
  4. package/dist/backend.js +41 -6
  5. package/dist/backend.js.map +1 -1
  6. package/dist/body-pages.d.ts +20 -0
  7. package/dist/body-pages.d.ts.map +1 -0
  8. package/dist/body-pages.js +56 -0
  9. package/dist/body-pages.js.map +1 -0
  10. package/dist/body-replace-guards.d.ts +29 -3
  11. package/dist/body-replace-guards.d.ts.map +1 -1
  12. package/dist/body-replace-guards.js +112 -19
  13. package/dist/body-replace-guards.js.map +1 -1
  14. package/dist/bounded-yaml.d.ts +28 -0
  15. package/dist/bounded-yaml.d.ts.map +1 -0
  16. package/dist/bounded-yaml.js +182 -0
  17. package/dist/bounded-yaml.js.map +1 -0
  18. package/dist/builtin-recipes/site.d.ts +5 -0
  19. package/dist/builtin-recipes/site.d.ts.map +1 -0
  20. package/dist/builtin-recipes/site.js +83 -0
  21. package/dist/builtin-recipes/site.js.map +1 -0
  22. package/dist/builtin-recipes.d.ts.map +1 -1
  23. package/dist/builtin-recipes.js +22 -0
  24. package/dist/builtin-recipes.js.map +1 -1
  25. package/dist/bundle-health/index.d.ts +2 -2
  26. package/dist/bundle-health/index.d.ts.map +1 -1
  27. package/dist/bundle-health/index.js +1 -1
  28. package/dist/bundle-health/index.js.map +1 -1
  29. package/dist/bundle-health/legacy-page.d.ts +8 -26
  30. package/dist/bundle-health/legacy-page.d.ts.map +1 -1
  31. package/dist/bundle-health/legacy-page.js +10 -35
  32. package/dist/bundle-health/legacy-page.js.map +1 -1
  33. package/dist/bundle-health/report.d.ts +0 -16
  34. package/dist/bundle-health/report.d.ts.map +1 -1
  35. package/dist/bundle-health/report.js +24 -54
  36. package/dist/bundle-health/report.js.map +1 -1
  37. package/dist/bundle-ops.d.ts +4 -1
  38. package/dist/bundle-ops.d.ts.map +1 -1
  39. package/dist/bundle-ops.js +6 -2
  40. package/dist/bundle-ops.js.map +1 -1
  41. package/dist/bundle.d.ts +1 -1
  42. package/dist/bundle.d.ts.map +1 -1
  43. package/dist/bundle.js +1 -1
  44. package/dist/bundle.js.map +1 -1
  45. package/dist/cross-bundle.d.ts +2 -2
  46. package/dist/cross-bundle.js +2 -2
  47. package/dist/document-codec.d.ts +3 -1
  48. package/dist/document-codec.d.ts.map +1 -1
  49. package/dist/document-codec.js +3 -1
  50. package/dist/document-codec.js.map +1 -1
  51. package/dist/document-mutation.d.ts +2 -0
  52. package/dist/document-mutation.d.ts.map +1 -1
  53. package/dist/document-mutation.js +44 -9
  54. package/dist/document-mutation.js.map +1 -1
  55. package/dist/document-scan.d.ts +23 -0
  56. package/dist/document-scan.d.ts.map +1 -0
  57. package/dist/document-scan.js +70 -0
  58. package/dist/document-scan.js.map +1 -0
  59. package/dist/document-transfer.d.ts +110 -4
  60. package/dist/document-transfer.d.ts.map +1 -1
  61. package/dist/document-transfer.js +490 -30
  62. package/dist/document-transfer.js.map +1 -1
  63. package/dist/engine.d.ts +4 -19
  64. package/dist/engine.d.ts.map +1 -1
  65. package/dist/engine.js +7 -47
  66. package/dist/engine.js.map +1 -1
  67. package/dist/errors.d.ts +37 -1
  68. package/dist/errors.d.ts.map +1 -1
  69. package/dist/errors.js +75 -3
  70. package/dist/errors.js.map +1 -1
  71. package/dist/file-journaled-backend.d.ts.map +1 -1
  72. package/dist/file-journaled-backend.js +2 -2
  73. package/dist/file-journaled-backend.js.map +1 -1
  74. package/dist/filesystem-identity.d.ts +9 -0
  75. package/dist/filesystem-identity.d.ts.map +1 -1
  76. package/dist/filesystem-identity.js +186 -64
  77. package/dist/filesystem-identity.js.map +1 -1
  78. package/dist/filesystem-lock.d.ts +2 -2
  79. package/dist/filesystem-lock.d.ts.map +1 -1
  80. package/dist/filesystem-lock.js +81 -14
  81. package/dist/filesystem-lock.js.map +1 -1
  82. package/dist/filesystem-temp-name.d.ts +9 -0
  83. package/dist/filesystem-temp-name.d.ts.map +1 -0
  84. package/dist/filesystem-temp-name.js +20 -0
  85. package/dist/filesystem-temp-name.js.map +1 -0
  86. package/dist/filesystem.d.ts +6 -0
  87. package/dist/filesystem.d.ts.map +1 -1
  88. package/dist/filesystem.js +2 -1
  89. package/dist/filesystem.js.map +1 -1
  90. package/dist/frontmatter-contract.d.ts +14 -0
  91. package/dist/frontmatter-contract.d.ts.map +1 -1
  92. package/dist/frontmatter-contract.js +22 -0
  93. package/dist/frontmatter-contract.js.map +1 -1
  94. package/dist/frontmatter-splitter.d.ts +6 -0
  95. package/dist/frontmatter-splitter.d.ts.map +1 -1
  96. package/dist/frontmatter-splitter.js +8 -0
  97. package/dist/frontmatter-splitter.js.map +1 -1
  98. package/dist/frontmatter.d.ts +8 -1
  99. package/dist/frontmatter.d.ts.map +1 -1
  100. package/dist/frontmatter.js +43 -7
  101. package/dist/frontmatter.js.map +1 -1
  102. package/dist/hosted-client/client.d.ts +22 -5
  103. package/dist/hosted-client/client.d.ts.map +1 -1
  104. package/dist/hosted-client/client.js +57 -10
  105. package/dist/hosted-client/client.js.map +1 -1
  106. package/dist/hosted-client/index.d.ts +1 -0
  107. package/dist/hosted-client/index.d.ts.map +1 -1
  108. package/dist/hosted-client/index.js +1 -0
  109. package/dist/hosted-client/index.js.map +1 -1
  110. package/dist/hosted-client/view-content.d.ts +107 -0
  111. package/dist/hosted-client/view-content.d.ts.map +1 -0
  112. package/dist/hosted-client/view-content.js +155 -0
  113. package/dist/hosted-client/view-content.js.map +1 -0
  114. package/dist/hosted-transport/carrier.d.ts +1 -1
  115. package/dist/hosted-transport/carrier.d.ts.map +1 -1
  116. package/dist/hosted-transport/carrier.js +27 -18
  117. package/dist/hosted-transport/carrier.js.map +1 -1
  118. package/dist/hosted-transport/document-backend.d.ts +74 -0
  119. package/dist/hosted-transport/document-backend.d.ts.map +1 -0
  120. package/dist/hosted-transport/document-backend.js +160 -0
  121. package/dist/hosted-transport/document-backend.js.map +1 -0
  122. package/dist/hosted-transport/index.d.ts +1 -0
  123. package/dist/hosted-transport/index.d.ts.map +1 -1
  124. package/dist/hosted-transport/index.js +1 -0
  125. package/dist/hosted-transport/index.js.map +1 -1
  126. package/dist/hosted-transport/read-adapter.d.ts +1 -2
  127. package/dist/hosted-transport/read-adapter.d.ts.map +1 -1
  128. package/dist/hosted-transport/read-adapter.js.map +1 -1
  129. package/dist/identity-fold.d.ts +12 -14
  130. package/dist/identity-fold.d.ts.map +1 -1
  131. package/dist/identity-fold.js +17 -15
  132. package/dist/identity-fold.js.map +1 -1
  133. package/dist/index-projection.d.ts +2 -1
  134. package/dist/index-projection.d.ts.map +1 -1
  135. package/dist/index-projection.js +14 -5
  136. package/dist/index-projection.js.map +1 -1
  137. package/dist/index.d.ts +24 -15
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +19 -15
  140. package/dist/index.js.map +1 -1
  141. package/dist/indexeddb-backend.d.ts.map +1 -1
  142. package/dist/indexeddb-backend.js +2 -2
  143. package/dist/indexeddb-backend.js.map +1 -1
  144. package/dist/json-data.d.ts +3 -0
  145. package/dist/json-data.d.ts.map +1 -0
  146. package/dist/json-data.js +19 -0
  147. package/dist/json-data.js.map +1 -0
  148. package/dist/kind-authoring.d.ts +18 -0
  149. package/dist/kind-authoring.d.ts.map +1 -1
  150. package/dist/kind-authoring.js +54 -4
  151. package/dist/kind-authoring.js.map +1 -1
  152. package/dist/kind-coverage.d.ts +1 -0
  153. package/dist/kind-coverage.d.ts.map +1 -1
  154. package/dist/kind-coverage.js +4 -5
  155. package/dist/kind-coverage.js.map +1 -1
  156. package/dist/kind-undeclared-fields.d.ts +70 -0
  157. package/dist/kind-undeclared-fields.d.ts.map +1 -0
  158. package/dist/kind-undeclared-fields.js +120 -0
  159. package/dist/kind-undeclared-fields.js.map +1 -0
  160. package/dist/kinds-load.d.ts.map +1 -1
  161. package/dist/kinds-load.js +4 -1
  162. package/dist/kinds-load.js.map +1 -1
  163. package/dist/kinds.d.ts +9 -0
  164. package/dist/kinds.d.ts.map +1 -1
  165. package/dist/kinds.js +20 -0
  166. package/dist/kinds.js.map +1 -1
  167. package/dist/link-findings.d.ts +130 -0
  168. package/dist/link-findings.d.ts.map +1 -0
  169. package/dist/link-findings.js +272 -0
  170. package/dist/link-findings.js.map +1 -0
  171. package/dist/link-types.d.ts +7 -0
  172. package/dist/link-types.d.ts.map +1 -1
  173. package/dist/link-types.js +17 -2
  174. package/dist/link-types.js.map +1 -1
  175. package/dist/memory-backend.d.ts.map +1 -1
  176. package/dist/memory-backend.js +2 -2
  177. package/dist/memory-backend.js.map +1 -1
  178. package/dist/page.d.ts +3 -7
  179. package/dist/page.d.ts.map +1 -1
  180. package/dist/page.js +3 -7
  181. package/dist/page.js.map +1 -1
  182. package/dist/path-fold.d.ts +29 -16
  183. package/dist/path-fold.d.ts.map +1 -1
  184. package/dist/path-fold.js +30 -17
  185. package/dist/path-fold.js.map +1 -1
  186. package/dist/paths.d.ts +28 -0
  187. package/dist/paths.d.ts.map +1 -1
  188. package/dist/paths.js +82 -1
  189. package/dist/paths.js.map +1 -1
  190. package/dist/platform.d.ts +9 -0
  191. package/dist/platform.d.ts.map +1 -1
  192. package/dist/platform.js.map +1 -1
  193. package/dist/portable-frontmatter.d.ts +6 -0
  194. package/dist/portable-frontmatter.d.ts.map +1 -1
  195. package/dist/portable-frontmatter.js +26 -2
  196. package/dist/portable-frontmatter.js.map +1 -1
  197. package/dist/recipe-lifecycle/install.d.ts +4 -7
  198. package/dist/recipe-lifecycle/install.d.ts.map +1 -1
  199. package/dist/recipe-lifecycle/install.js +3 -20
  200. package/dist/recipe-lifecycle/install.js.map +1 -1
  201. package/dist/recipe-lifecycle/legacy-aliases.d.ts +1 -13
  202. package/dist/recipe-lifecycle/legacy-aliases.d.ts.map +1 -1
  203. package/dist/recipe-lifecycle/legacy-aliases.js +5 -34
  204. package/dist/recipe-lifecycle/legacy-aliases.js.map +1 -1
  205. package/dist/record-overlay/apply.d.ts.map +1 -1
  206. package/dist/record-overlay/apply.js +0 -4
  207. package/dist/record-overlay/apply.js.map +1 -1
  208. package/dist/record-overlay/findings.d.ts.map +1 -1
  209. package/dist/record-overlay/findings.js +4 -1
  210. package/dist/record-overlay/findings.js.map +1 -1
  211. package/dist/record-overlay/plan.js +3 -3
  212. package/dist/record-overlay/plan.js.map +1 -1
  213. package/dist/record-overlay/signal-text.d.ts +9 -2
  214. package/dist/record-overlay/signal-text.d.ts.map +1 -1
  215. package/dist/record-overlay/signal-text.js +21 -11
  216. package/dist/record-overlay/signal-text.js.map +1 -1
  217. package/dist/remote-backend.d.ts +9 -19
  218. package/dist/remote-backend.d.ts.map +1 -1
  219. package/dist/remote-backend.js +17 -5
  220. package/dist/remote-backend.js.map +1 -1
  221. package/dist/remote-operations.d.ts.map +1 -1
  222. package/dist/remote-operations.js +2 -0
  223. package/dist/remote-operations.js.map +1 -1
  224. package/dist/remote-parsers.d.ts +19 -0
  225. package/dist/remote-parsers.d.ts.map +1 -1
  226. package/dist/remote-parsers.js.map +1 -1
  227. package/dist/remote.d.ts +2 -4
  228. package/dist/remote.d.ts.map +1 -1
  229. package/dist/remote.js +2 -3
  230. package/dist/remote.js.map +1 -1
  231. package/dist/reserved-write.d.ts +9 -0
  232. package/dist/reserved-write.d.ts.map +1 -0
  233. package/dist/reserved-write.js +15 -0
  234. package/dist/reserved-write.js.map +1 -0
  235. package/dist/search/backend-source.d.ts +2 -2
  236. package/dist/search/backend-source.d.ts.map +1 -1
  237. package/dist/search/backend-source.js +30 -6
  238. package/dist/search/backend-source.js.map +1 -1
  239. package/dist/search/contract.d.ts +3 -0
  240. package/dist/search/contract.d.ts.map +1 -1
  241. package/dist/search/contract.js.map +1 -1
  242. package/dist/search/search.d.ts.map +1 -1
  243. package/dist/search/search.js +4 -1
  244. package/dist/search/search.js.map +1 -1
  245. package/dist/search/source.d.ts +3 -0
  246. package/dist/search/source.d.ts.map +1 -1
  247. package/dist/site-manifest.d.ts +49 -0
  248. package/dist/site-manifest.d.ts.map +1 -0
  249. package/dist/site-manifest.js +113 -0
  250. package/dist/site-manifest.js.map +1 -0
  251. package/dist/skip-reasons.d.ts +12 -0
  252. package/dist/skip-reasons.d.ts.map +1 -0
  253. package/dist/skip-reasons.js +15 -0
  254. package/dist/skip-reasons.js.map +1 -0
  255. package/dist/source-engine/driver.d.ts +4 -4
  256. package/dist/source-engine/driver.d.ts.map +1 -1
  257. package/dist/source-engine/driver.js +155 -34
  258. package/dist/source-engine/driver.js.map +1 -1
  259. package/dist/source-engine/index.d.ts +3 -1
  260. package/dist/source-engine/index.d.ts.map +1 -1
  261. package/dist/source-engine/index.js +1 -0
  262. package/dist/source-engine/index.js.map +1 -1
  263. package/dist/source-engine/machine-state.d.ts +19 -6
  264. package/dist/source-engine/machine-state.d.ts.map +1 -1
  265. package/dist/source-engine/machine-state.js +48 -2
  266. package/dist/source-engine/machine-state.js.map +1 -1
  267. package/dist/source-engine/observe.d.ts.map +1 -1
  268. package/dist/source-engine/observe.js +10 -4
  269. package/dist/source-engine/observe.js.map +1 -1
  270. package/dist/source-engine/snapshot.js +1 -1
  271. package/dist/source-engine/snapshot.js.map +1 -1
  272. package/dist/source-engine/target-consumer.d.ts +12 -0
  273. package/dist/source-engine/target-consumer.d.ts.map +1 -0
  274. package/dist/source-engine/target-consumer.js +15 -0
  275. package/dist/source-engine/target-consumer.js.map +1 -0
  276. package/dist/source-engine/target-descriptor.d.ts +3 -0
  277. package/dist/source-engine/target-descriptor.d.ts.map +1 -0
  278. package/dist/source-engine/target-descriptor.js +26 -0
  279. package/dist/source-engine/target-descriptor.js.map +1 -0
  280. package/dist/source-engine/target.d.ts +82 -0
  281. package/dist/source-engine/target.d.ts.map +1 -0
  282. package/dist/source-engine/target.js +213 -0
  283. package/dist/source-engine/target.js.map +1 -0
  284. package/dist/source-engine/types.d.ts +5 -1
  285. package/dist/source-engine/types.d.ts.map +1 -1
  286. package/dist/source-profiles/index.d.ts +1 -1
  287. package/dist/source-profiles/index.js +1 -1
  288. package/dist/string-identity-agreement.d.ts +1 -1
  289. package/dist/string-identity-agreement.d.ts.map +1 -1
  290. package/dist/string-identity-agreement.js +6 -0
  291. package/dist/string-identity-agreement.js.map +1 -1
  292. package/dist/system-documents.d.ts +13 -0
  293. package/dist/system-documents.d.ts.map +1 -0
  294. package/dist/system-documents.js +44 -0
  295. package/dist/system-documents.js.map +1 -0
  296. package/dist/types.d.ts +7 -0
  297. package/dist/types.d.ts.map +1 -1
  298. package/dist/validation.d.ts +5 -0
  299. package/dist/validation.d.ts.map +1 -1
  300. package/package.json +19 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site-manifest.d.ts","sourceRoot":"","sources":["../src/site-manifest.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,SAAS,SAAS,CAAC;AAChC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,iFAAiF;AACjF,eAAO,MAAM,UAAU,QAAmC,CAAC;AAC3D,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACwB,CAAC;AAC/E,eAAO,MAAM,kBAAkB,+HAAgI,CAAC;AAEhK,MAAM,MAAM,yBAAyB,GACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC7E;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AACjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,yBAAyB,CAAC;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;CACjF;AACD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,MAAM,uBAAuB,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GACxF;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,CAAC;AA8B1E;qGACqG;AACrG,wBAAgB,oBAAoB,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAAE,GAAG,uBAAuB,CA6CnJ"}
@@ -0,0 +1,113 @@
1
+ /** Portable Site declaration grammar. Parsing grants no build, install or publication authority. */
2
+ import { assertSafeBlobKey, assertSafeConceptId, nonCanonicalDocumentId } from "./paths.js";
3
+ import { isJsonData } from "./json-data.js";
4
+ import { isOkfStandardField } from "./okf-standard-fields.js";
5
+ import { isManagedDocumentMetadataField } from "./managed-document-metadata.js";
6
+ export const SITE_TYPE = "Site";
7
+ export const SITES_PREFIX = "sites/";
8
+ /** One site label leaves room for its workspace label in a combined DNS name. */
9
+ export const SITE_LABEL = /^[a-z][a-z0-9-]{1,30}[a-z0-9]$/;
10
+ export const isSiteLabel = (value) => typeof value === "string" && SITE_LABEL.test(value) && !value.includes("--");
11
+ export const SITE_DOCUMENT_KEYS = ["type", "title", "description", "presentation", "landing", "views", "audience", "capabilities", "options", "brand"];
12
+ const record = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
13
+ const packageName = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
14
+ const exactVersion = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
15
+ const encoder = new TextEncoder();
16
+ function presentationReference(raw) {
17
+ if (typeof raw !== "string" || raw.length > 512)
18
+ return undefined;
19
+ if (raw.startsWith("repo:")) {
20
+ const repository = raw.slice(5);
21
+ return /^[A-Za-z0-9][A-Za-z0-9-]{0,38}\/[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/.test(repository) && !repository.endsWith(".git")
22
+ ? { kind: "repository", repository } : undefined;
23
+ }
24
+ const at = raw.lastIndexOf("@");
25
+ if (at < 1)
26
+ return undefined;
27
+ const name = raw.slice(0, at), version = raw.slice(at + 1), match = exactVersion.exec(version);
28
+ if (name.length > 214 || !packageName.test(name) || !match ||
29
+ !match.slice(1, 4).every(part => Number.isSafeInteger(Number(part))) ||
30
+ match[4]?.split(".").some(part => /^\d+$/.test(part) && (part.length > 1 && part.startsWith("0") || !Number.isSafeInteger(Number(part)))))
31
+ return undefined;
32
+ return { kind: "package", name, version };
33
+ }
34
+ const concept = (raw) => {
35
+ if (typeof raw !== "string")
36
+ return false;
37
+ try {
38
+ assertSafeConceptId(raw);
39
+ return nonCanonicalDocumentId(raw) === null;
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ };
45
+ const blob = (raw) => {
46
+ if (typeof raw !== "string")
47
+ return false;
48
+ try {
49
+ assertSafeBlobKey(raw);
50
+ return true;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ };
56
+ /** Standard OKF and managed metadata survive on the document; only Site fields enter this value.
57
+ * Presentation owners validate option semantics. Builders separately admit trusted resolved code. */
58
+ export function parseSiteManifestDoc(doc) {
59
+ const errors = [];
60
+ const fail = (path, message) => { errors.push({ code: "SITE_MANIFEST_INVALID", path, message }); };
61
+ const fm = record(doc?.frontmatter) ? doc.frontmatter : {};
62
+ const site = typeof doc?.id === "string" && doc.id.startsWith(SITES_PREFIX) ? doc.id.slice(SITES_PREFIX.length) : "";
63
+ if (!isSiteLabel(site))
64
+ fail("/id", "a Site lives at sites/<site>, using one site label");
65
+ if (fm.type !== SITE_TYPE)
66
+ fail("/type", "type must be Site");
67
+ if (Object.keys(fm).some(key => !SITE_DOCUMENT_KEYS.includes(key) && !isOkfStandardField(key) && !isManagedDocumentMetadataField(key)))
68
+ fail("", "unrecognized Site fields");
69
+ if (typeof fm.title !== "string" || fm.title.trim() === "" || encoder.encode(fm.title).byteLength > 512)
70
+ fail("/title", "title must be a nonempty string of at most 512 bytes");
71
+ if (fm.description !== undefined && (typeof fm.description !== "string" || encoder.encode(fm.description).byteLength > 8192))
72
+ fail("/description", "description must be a string of at most 8192 bytes");
73
+ const presentation = presentationReference(fm.presentation);
74
+ if (!presentation)
75
+ fail("/presentation", "presentation must name an exact npm version or repo:owner/name");
76
+ if (fm.audience !== "restricted")
77
+ fail("/audience", "only the restricted audience is supported");
78
+ const list = (raw, path, maximum, valid) => {
79
+ if (!Array.isArray(raw) || raw.length > maximum || !raw.every(valid) || new Set(raw).size !== raw.length) {
80
+ fail(path, "expected a bounded list of unique valid references");
81
+ return [];
82
+ }
83
+ return [...raw];
84
+ };
85
+ const views = list(fm.views, "/views", 64, concept);
86
+ const capability = (v) => typeof v === "string" && /^[a-z][a-z0-9-]{0,63}$/.test(v);
87
+ const capabilities = list(fm.capabilities ?? [], "/capabilities", 16, capability);
88
+ if (fm.landing !== undefined && !concept(fm.landing))
89
+ fail("/landing", "landing must be a canonical document or View id");
90
+ const options = fm.options ?? {};
91
+ if (!record(options) || !isJsonData(options) || encoder.encode(JSON.stringify(options)).byteLength > 16384)
92
+ fail("/options", "options must be JSON data of at most 16384 bytes");
93
+ let brand;
94
+ if (fm.brand !== undefined) {
95
+ if (!record(fm.brand) || Object.keys(fm.brand).some(key => key !== "logo" && key !== "fonts"))
96
+ fail("/brand", "brand may only name a logo and fonts");
97
+ else {
98
+ if (fm.brand.logo !== undefined && !blob(fm.brand.logo))
99
+ fail("/brand/logo", "logo must be a bundle blob reference");
100
+ const fonts = fm.brand.fonts === undefined ? undefined : list(fm.brand.fonts, "/brand/fonts", 16, blob);
101
+ brand = { ...(typeof fm.brand.logo === "string" ? { logo: fm.brand.logo } : {}), ...(fonts ? { fonts } : {}) };
102
+ }
103
+ }
104
+ if (errors.length)
105
+ return { ok: false, errors };
106
+ return { ok: true, manifest: {
107
+ id: doc.id, site, title: fm.title, presentation: presentation, audience: "restricted", views, capabilities,
108
+ options: JSON.parse(JSON.stringify(options)),
109
+ ...(fm.description === undefined ? {} : { description: fm.description }),
110
+ ...(fm.landing === undefined ? {} : { landing: fm.landing }), ...(brand ? { brand } : {}),
111
+ } };
112
+ }
113
+ //# sourceMappingURL=site-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site-manifest.js","sourceRoot":"","sources":["../src/site-manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The skip reason a resilient scan gives a document the host refused to read, and the one test
3
+ * for it. Dependency-free so a browser bundle can tell a permission problem from a malformed
4
+ * document without loading the scan.
5
+ */
6
+ /** The skip reason for a read refused with `code` (`EACCES` or `EPERM`); never the host path. */
7
+ export declare function permissionDeniedReason(code: "EACCES" | "EPERM"): string;
8
+ /** True when a scan skipped this document because the host refused to read it, not because it is malformed. */
9
+ export declare function isPermissionDeniedSkip(skip: {
10
+ reason: string;
11
+ }): boolean;
12
+ //# sourceMappingURL=skip-reasons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skip-reasons.d.ts","sourceRoot":"","sources":["../src/skip-reasons.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,iGAAiG;AACjG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAEvE;AAED,+GAA+G;AAC/G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAExE"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The skip reason a resilient scan gives a document the host refused to read, and the one test
3
+ * for it. Dependency-free so a browser bundle can tell a permission problem from a malformed
4
+ * document without loading the scan.
5
+ */
6
+ const PERMISSION_DENIED_PREFIX = "permission denied (";
7
+ /** The skip reason for a read refused with `code` (`EACCES` or `EPERM`); never the host path. */
8
+ export function permissionDeniedReason(code) {
9
+ return `${PERMISSION_DENIED_PREFIX}${code})`;
10
+ }
11
+ /** True when a scan skipped this document because the host refused to read it, not because it is malformed. */
12
+ export function isPermissionDeniedSkip(skip) {
13
+ return skip.reason.startsWith(PERMISSION_DENIED_PREFIX);
14
+ }
15
+ //# sourceMappingURL=skip-reasons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skip-reasons.js","sourceRoot":"","sources":["../src/skip-reasons.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAEvD,iGAAiG;AACjG,MAAM,UAAU,sBAAsB,CAAC,IAAwB;IAC7D,OAAO,GAAG,wBAAwB,GAAG,IAAI,GAAG,CAAC;AAC/C,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,sBAAsB,CAAC,IAAwB;IAC7D,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;AAC1D,CAAC"}
@@ -1,15 +1,15 @@
1
+ export { isJsonData } from "../json-data.js";
1
2
  /** Internal observation owner shared by network and finite acquisition wrappers. */
2
3
  import { type BoundFeed } from "../connectors.js";
3
4
  import type { Finding } from "../record-overlay/types.js";
5
+ import type { SourceCommitPreparation } from "./target.js";
4
6
  import { type Stop } from "./guard.js";
5
- import type { MachineState, SourceState } from "./machine-state.js";
7
+ import { type MachineState, type SourceState } from "./machine-state.js";
6
8
  import type { CommitResult, PageCommit, SourceRunReceipt } from "./types.js";
7
9
  export declare const DEFAULT_MISSING_THRESHOLD = 2;
8
10
  export declare const MAX_CURSOR_CHARS = 8192;
9
11
  export declare const MAX_REPLAY_FAILURES = 5;
10
12
  export declare const UNSUPPORTED_CONTENT = "SOURCE_UNSUPPORTED_CONTENT";
11
- /** JSON data only: finite numbers, plain objects and arrays, no undefined members. */
12
- export declare function isJsonData(value: unknown, depth?: number): boolean;
13
13
  interface DriverOptions {
14
14
  bound: BoundFeed;
15
15
  state: MachineState;
@@ -33,8 +33,8 @@ interface DriverOptions {
33
33
  lastUrl?(): string | undefined;
34
34
  stop(stop: Stop, url?: string): void;
35
35
  extraFindings: Finding[];
36
+ prepareCommit?(page: PageCommit): Promise<SourceCommitPreparation>;
36
37
  commit(page: PageCommit): Promise<CommitResult | void>;
37
38
  }
38
39
  export declare function driveObservation(options: DriverOptions): Promise<void>;
39
- export {};
40
40
  //# sourceMappingURL=driver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/source-engine/driver.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,OAAO,EAA4B,KAAK,SAAS,EAA0B,MAAM,kBAAkB,CAAC;AAEpG,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAA8B,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChG,OAAO,KAAK,EAAE,YAAY,EAAe,UAAU,EAAqB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE7G,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAMhE,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,OAAO,CAU7D;AAiGD,UAAU,aAAa;IACrB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,GAAG,UAAU,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAC;QAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/J,OAAO,CAAC,IAAI,IAAI,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CACxD;AACD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0N5E"}
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/source-engine/driver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,oFAAoF;AACpF,OAAO,EAA4B,KAAK,SAAS,EAA0B,MAAM,kBAAkB,CAAC;AAEpG,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,4BAA4B,CAAC;AAKxE,OAAO,KAAK,EAAE,uBAAuB,EAAuB,MAAM,aAAa,CAAC;AAChF,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAA4C,KAAK,YAAY,EAAwC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACzJ,OAAO,KAAK,EAAE,YAAY,EAAe,UAAU,EAAqB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE7G,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAyGhE,UAAU,aAAa;IACrB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,GAAG,UAAU,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAC;QAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/J,OAAO,CAAC,IAAI,IAAI,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,aAAa,CAAC,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACnE,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CACxD;AACD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsU5E"}
@@ -1,31 +1,23 @@
1
+ import { isJsonData } from "../json-data.js";
2
+ export { isJsonData } from "../json-data.js";
1
3
  /** Internal observation owner shared by network and finite acquisition wrappers. */
2
4
  import { changeBetween, mapRecord } from "../connectors.js";
3
5
  import { overlayCanonicalJson } from "../record-overlay/canonical.js";
6
+ import { parseIsoInstant } from "../verification.js";
7
+ import { parseMarkdown } from "../document-codec.js";
8
+ import { discardSourceTargetConsumer, isSourceTargetConsumer } from "./target-consumer.js";
9
+ import { isSourceEstablishment } from "./target-descriptor.js";
4
10
  import { SourceStop } from "./guard.js";
11
+ import { hasProtectedSourcePending, isSourceState } from "./machine-state.js";
5
12
  export const DEFAULT_MISSING_THRESHOLD = 2;
6
13
  export const MAX_CURSOR_CHARS = 8192;
7
14
  export const MAX_REPLAY_FAILURES = 5;
8
15
  export const UNSUPPORTED_CONTENT = "SOURCE_UNSUPPORTED_CONTENT";
9
16
  const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
10
17
  const clip = (text, n) => (text.length > n ? text.slice(0, n - 1) + "…" : text);
11
- /** JSON data only: finite numbers, plain objects and arrays, no undefined members. */
12
- export function isJsonData(value, depth = 0) {
13
- if (depth > 32)
14
- return false;
15
- if (value === null || typeof value === "string" || typeof value === "boolean")
16
- return true;
17
- if (typeof value === "number")
18
- return Number.isFinite(value);
19
- if (Array.isArray(value))
20
- return value.every((item) => isJsonData(item, depth + 1));
21
- if (!record(value))
22
- return false;
23
- // A plain object from any realm: its prototype is null or a prototype that itself has none.
24
- const proto = Object.getPrototypeOf(value);
25
- if (proto !== null && Object.getPrototypeOf(proto) !== null)
26
- return false;
27
- return Object.values(value).every((item) => item !== undefined && isJsonData(item, depth + 1));
28
- }
18
+ /** External identities are arbitrary strings, including Object.prototype member names. */
19
+ const idMap = (entries) => Object.assign(Object.create(null), entries);
20
+ const ownEntry = (entries, id) => Object.hasOwn(entries, id) ? entries[id] : undefined;
29
21
  /** The page as the engine accepts it, or why not. */
30
22
  function pageProblem(page) {
31
23
  if (!record(page))
@@ -74,7 +66,7 @@ function diffPage(state, page, bound, observedAt) {
74
66
  const changes = [];
75
67
  const entries = new Map();
76
68
  for (const [id, mapped] of last) {
77
- const stored = Object.hasOwn(state.records, id) ? state.records[id] : undefined;
69
+ const stored = ownEntry(state.records, id);
78
70
  if (mapped.kind === "refused") {
79
71
  // Refused but present: still observed, so never missing; its accepted values stay.
80
72
  if (stored)
@@ -126,6 +118,7 @@ function commitResult(result) {
126
118
  export async function driveObservation(options) {
127
119
  const { bound, receipt, observedAt, mode, resumed, signal, extraFindings } = options;
128
120
  const key = bound.policy.feed;
121
+ const qualified = isSourceTargetConsumer(options.prepareCommit, options.commit);
129
122
  let state = options.initial;
130
123
  let version = options.version;
131
124
  const baseline = version === null;
@@ -138,6 +131,12 @@ export async function driveObservation(options) {
138
131
  /** Store `next` after a commit; false when the store refused it and the run has stopped. */
139
132
  const store = async (next) => {
140
133
  try {
134
+ if ((qualified || options.prepareCommit || hasProtectedSourcePending(state))
135
+ && ((qualified ? Object.keys(next.pending ?? {}).length : Object.values(next.pending ?? {}).filter(p => p.establishment).length) > 100
136
+ || new TextEncoder().encode(JSON.stringify(next)).length > 4194304))
137
+ throw new Error("source establishment state limit");
138
+ if (!isSourceState(next))
139
+ throw new Error("invalid source state");
141
140
  version = await options.state.write(key, next, version);
142
141
  state = next;
143
142
  receipt.pending = Object.keys(next.pending ?? {}).length;
@@ -153,28 +152,92 @@ export async function driveObservation(options) {
153
152
  // Changes an earlier commit asked to retry are planned again before anything is fetched. A
154
153
  // record that has since disappeared has nothing left to write, unless the held change is the
155
154
  // record coming back.
155
+ const retained = hasProtectedSourcePending(state);
156
+ if (retained && !qualified) {
157
+ stop = { outcome: "failed", reason: "establishment_consumer_required", retry: false };
158
+ return;
159
+ }
160
+ if (retained && (Object.keys(state.pending ?? {}).length > 100 || new TextEncoder().encode(JSON.stringify(state)).length > 4194304)) {
161
+ stop = { outcome: "failed", reason: "establishment_state_limit", retry: false };
162
+ return;
163
+ }
164
+ if (retained && !signal.aborted) {
165
+ const pending = state.pending;
166
+ const context = state.pending_commit;
167
+ // Old establishment checkpoints never recorded page order/flags. Retain their stable
168
+ // legacy order only when every entry belongs to one original group and observation.
169
+ const ids = context?.order ?? Object.keys(pending).sort();
170
+ const at = pending[ids[0]].held_at;
171
+ const first = pending[ids[0]].establishment;
172
+ if (!context && (!first || parseIsoInstant(at) === null || ids.some(id => {
173
+ const p = pending[id], e = p.establishment;
174
+ return !e || e.group !== first.group || e.generation !== first.generation || e.observed_at !== at || p.held_at !== at;
175
+ }))) {
176
+ stop = { outcome: "failed", reason: "establishment_scope_changed", retry: false };
177
+ return;
178
+ }
179
+ const records = idMap();
180
+ for (const id of ids)
181
+ records[id] = { fields: { ...(pending[id].change.after ?? pending[id].change.before ?? {}) } };
182
+ let result;
183
+ try {
184
+ const establishments = Object.fromEntries(ids.filter(id => pending[id].establishment !== undefined).map(id => [id, pending[id].establishment]));
185
+ result = commitResult(await options.commit(structuredClone({ feed: key, provider: bound.policy.provider,
186
+ observed_at: at, page: context?.page ?? 0, replay: true, changes: ids.map(id => pending[id].change), records,
187
+ baseline: context?.baseline ?? false, complete: context?.complete ?? false,
188
+ ...(Object.keys(establishments).length ? { establishments } : {}) })));
189
+ }
190
+ catch (error) {
191
+ receipt.held += ids.length;
192
+ stop = { outcome: "failed", reason: "establishment_pending", retry: true, detail: errorText(error) };
193
+ return;
194
+ }
195
+ if (ids.some(id => result.hold.has(id) || result.retry.has(id))) {
196
+ receipt.held += ids.length;
197
+ stop = { outcome: "failed", reason: "establishment_pending", retry: true };
198
+ return;
199
+ }
200
+ const nextRecords = idMap(state.records);
201
+ for (const id of ids)
202
+ nextRecords[id] = entryJson(pending[id].entry);
203
+ const next = { ...state, records: nextRecords };
204
+ delete next.pending;
205
+ delete next.pending_commit;
206
+ // No next cursor/validators were stored in the supplying checkpoint. A successful
207
+ // recovery may rescan from the old cursor; it cannot claim the lost page completed.
208
+ if (!(await store(next)))
209
+ return;
210
+ }
156
211
  const pendingIds = signal.aborted ? [] : Object.keys(state.pending ?? {}).sort();
157
212
  if (pendingIds.length) {
158
213
  const pending = state.pending;
159
- const live = pendingIds.filter((id) => !state.records[id]?.gone || pending[id].change.change_kind === "new");
214
+ const live = pendingIds.filter((id) => pending[id].establishment !== undefined || !ownEntry(state.records, id)?.gone || pending[id].change.change_kind === "new");
215
+ const marked = live.filter(id => pending[id].establishment !== undefined);
216
+ const establishments = Object.fromEntries(marked.map(id => [id, pending[id].establishment]));
160
217
  const changes = live.map((id) => pending[id].change);
161
- const records = {};
218
+ const records = idMap();
162
219
  for (const change of changes)
163
220
  records[change.external_id] = { fields: { ...(change.after ?? change.before ?? {}) } };
164
221
  let result;
165
222
  let failure;
166
223
  if (live.length) {
167
224
  try {
168
- result = commitResult(await options.commit({
225
+ result = commitResult(await options.commit(structuredClone({
169
226
  feed: key, provider: bound.policy.provider, observed_at: observedAt, page: 0, replay: true, changes, records, baseline: false, complete: false,
170
- }));
227
+ ...(marked.length ? { establishments } : {}),
228
+ })));
171
229
  }
172
230
  catch (error) {
173
231
  failure = errorText(error);
174
232
  }
175
233
  }
176
- const nextRecords = { ...state.records };
177
- const nextPending = {};
234
+ if (marked.some(id => failure !== undefined || result.retry.has(id) || result.hold.has(id))) {
235
+ receipt.held += marked.length;
236
+ stop = { outcome: "failed", reason: "establishment_pending", retry: true, ...(failure ? { detail: failure } : {}) };
237
+ return;
238
+ }
239
+ const nextRecords = idMap(state.records);
240
+ const nextPending = idMap();
178
241
  const dropped = [];
179
242
  for (const id of live) {
180
243
  const entry = pending[id];
@@ -193,7 +256,7 @@ export async function driveObservation(options) {
193
256
  else if (!result.hold.has(id)) {
194
257
  // The record's absence since the hold is newer than the change, so its count stays; a
195
258
  // record that comes back starts afresh.
196
- const current = state.records[id];
259
+ const current = ownEntry(state.records, id);
197
260
  nextRecords[id] = entryJson(current?.gone ? entry.entry : { ...entry.entry, missing: current?.missing ?? 0, first_missing_at: current?.first_missing_at });
198
261
  }
199
262
  }
@@ -224,6 +287,10 @@ export async function driveObservation(options) {
224
287
  if (!(await store(next)))
225
288
  return;
226
289
  }
290
+ if (qualified && Object.keys(state.pending ?? {}).length) {
291
+ stop = { outcome: "failed", reason: "establishment_pending", retry: true };
292
+ return;
293
+ }
227
294
  if (signal.aborted) {
228
295
  stop = { outcome: "deferred", reason: "deadline", retry: true };
229
296
  return;
@@ -295,7 +362,7 @@ export async function driveObservation(options) {
295
362
  seen.add(id);
296
363
  const ended = !page.more;
297
364
  const complete = ended && mode === "complete" && page.complete && sourceComplete;
298
- const merged = { ...state.records };
365
+ const merged = idMap(state.records);
299
366
  for (const [id, entry] of diff.entries)
300
367
  merged[id] = entry;
301
368
  const missing = complete ? missingAfterComplete(merged, seen, threshold, observedAt) : { changes: [], entries: new Map() };
@@ -308,7 +375,7 @@ export async function driveObservation(options) {
308
375
  const unlisted = complete ? Object.keys(state.pending ?? {}).filter((id) => !seen.has(id)) : [];
309
376
  const superseded = [...new Set([...diff.seen, ...missing.entries.keys(), ...unlisted])].filter((id) => state.pending !== undefined && Object.hasOwn(state.pending, id));
310
377
  if (superseded.length) {
311
- const remaining = { ...state.pending };
378
+ const remaining = idMap(state.pending);
312
379
  for (const id of superseded)
313
380
  delete remaining[id];
314
381
  const pre = { ...state };
@@ -319,15 +386,64 @@ export async function driveObservation(options) {
319
386
  if (!(await store(pre)))
320
387
  break;
321
388
  }
322
- const records = {};
389
+ const records = idMap();
323
390
  for (const change of changes)
324
391
  records[change.external_id] = { fields: { ...(change.after ?? change.before ?? {}) } };
325
392
  let result;
326
393
  try {
327
- result = commitResult(await options.commit({
394
+ const commitPage = JSON.parse(JSON.stringify({
328
395
  feed: key, provider: bound.policy.provider, observed_at: observedAt, page: receipt.pages + 1, replay: false,
329
396
  changes, records, baseline, complete,
330
397
  }));
398
+ if (options.prepareCommit) {
399
+ const prepared = await options.prepareCommit(structuredClone(commitPage));
400
+ if (!isJsonData(prepared) || !record(prepared.establishments))
401
+ throw new Error("invalid source preparation");
402
+ const descriptors = JSON.parse(JSON.stringify(prepared.establishments));
403
+ const ids = Object.keys(descriptors);
404
+ if (ids.length > 100)
405
+ throw new Error("source establishment page limit");
406
+ const pending = idMap(state.pending);
407
+ for (const id of ids) {
408
+ const change = byId.get(id), entry = diff.entries.get(id), e = descriptors[id];
409
+ if (!change?.after || !entry || !isSourceEstablishment(e) || e.observed_at !== observedAt)
410
+ throw new Error("invalid source establishment");
411
+ if (e.intent) {
412
+ const fm = parseMarkdown(e.intent.content, e.target).frontmatter;
413
+ if (fm.type !== bound.kind.governs || !Array.isArray(fm.sources) || fm.sources.length !== 1
414
+ || fm.sources[0]?.resource !== bound.resource || fm.sources[0]?.id !== id)
415
+ throw new Error("invalid source establishment identity");
416
+ }
417
+ pending[id] = { change: structuredClone(change), entry: entryJson(structuredClone(entry)), held_at: observedAt, establishment: e };
418
+ }
419
+ if (qualified && changes.length) {
420
+ for (const change of changes) {
421
+ const id = change.external_id, entry = diff.entries.get(id) ?? missing.entries.get(id);
422
+ if (!entry)
423
+ throw new Error("source pending entry missing");
424
+ pending[id] = { change: structuredClone(change), entry: entryJson(structuredClone(entry)), held_at: observedAt,
425
+ ...(Object.hasOwn(descriptors, id) ? { establishment: descriptors[id] } : {}) };
426
+ }
427
+ }
428
+ if ((qualified ? Object.keys(pending).length : Object.values(pending).filter(p => p.establishment).length) > 100)
429
+ throw new Error("source establishment pending limit");
430
+ if (ids.length || qualified && changes.length) {
431
+ const pre = { ...state, pending, ...(qualified ? { pending_commit: {
432
+ v: 1, order: changes.map(change => change.external_id), page: commitPage.page,
433
+ baseline: commitPage.baseline, complete: commitPage.complete,
434
+ } } : {}) };
435
+ if (new TextEncoder().encode(JSON.stringify(pre)).length > 4194304)
436
+ throw new Error("source establishment envelope limit");
437
+ if (!(await store(pre)))
438
+ return;
439
+ commitPage.establishments = structuredClone(descriptors);
440
+ }
441
+ }
442
+ result = commitResult(await options.commit(commitPage));
443
+ if ((qualified ? changes.map(c => c.external_id) : Object.keys(commitPage.establishments ?? {})).some(id => result.hold.has(id) || result.retry.has(id))) {
444
+ stop = { outcome: "failed", reason: "establishment_pending", retry: true };
445
+ return;
446
+ }
331
447
  }
332
448
  catch (error) {
333
449
  stop = { outcome: "failed", reason: "commit_failed", retry: true, detail: errorText(error) };
@@ -335,13 +451,15 @@ export async function driveObservation(options) {
335
451
  }
336
452
  const notWritten = (id) => byId.has(id) && (result.hold.has(id) || result.retry.has(id));
337
453
  // The page committed: now, and only now, its records and cursor are stored.
338
- const nextRecords = { ...state.records };
339
- const nextPending = { ...state.pending };
454
+ const nextRecords = idMap(state.records);
455
+ const nextPending = idMap(state.pending);
340
456
  for (const [id, entry] of [...diff.entries, ...missing.entries]) {
341
457
  if (byId.has(id) && result.retry.has(id))
342
458
  nextPending[id] = { change: byId.get(id), entry: entryJson(entry), held_at: observedAt };
343
- else if (!notWritten(id))
459
+ else if (!notWritten(id)) {
344
460
  nextRecords[id] = entryJson(entry);
461
+ delete nextPending[id];
462
+ }
345
463
  }
346
464
  const next = {
347
465
  ...state,
@@ -356,6 +474,7 @@ export async function driveObservation(options) {
356
474
  next.pending = nextPending;
357
475
  else
358
476
  delete next.pending;
477
+ delete next.pending_commit;
359
478
  if (!(await store(next)))
360
479
  break;
361
480
  receipt.pages += 1;
@@ -385,8 +504,10 @@ export async function driveObservation(options) {
385
504
  return;
386
505
  }
387
506
  finally {
388
- if (stop)
507
+ if (stop) {
508
+ discardSourceTargetConsumer(options.prepareCommit, options.commit);
389
509
  options.stop(stop, stopUrl);
510
+ }
390
511
  }
391
512
  }
392
513
  //# sourceMappingURL=driver.js.map