@hraness/ghostget 0.17.2

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 (500) hide show
  1. package/CHANGELOG.md +458 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1359 -0
  4. package/bunfig.toml +2 -0
  5. package/dist/apple-photos-client.js +704 -0
  6. package/dist/beeper-client.js +4602 -0
  7. package/dist/client.js +1605 -0
  8. package/dist/index-26yq8q16.js +31 -0
  9. package/dist/index-9t13b4k7.js +508 -0
  10. package/dist/index-axwm9b3v.js +5 -0
  11. package/dist/index-gwk7rbyj.js +30 -0
  12. package/dist/index.js +701 -0
  13. package/dist/messaging.js +1130 -0
  14. package/dist/omni-client.js +1406 -0
  15. package/dist/whatsapp-client.js +355 -0
  16. package/docs/imessage-direct-provider.md +106 -0
  17. package/docs/rental-listings.md +94 -0
  18. package/package.json +600 -0
  19. package/skills/ghostget/SKILL.md +251 -0
  20. package/skills/ghostget/agents/openai.yaml +4 -0
  21. package/skills/ghostget/references/adapter-contract.md +181 -0
  22. package/skills/ghostget/references/apple-photos.md +115 -0
  23. package/skills/ghostget/references/article-drafts.md +235 -0
  24. package/skills/ghostget/references/code-owned-provider-scaffold.md +134 -0
  25. package/skills/ghostget/references/cross-posting-video.md +139 -0
  26. package/skills/ghostget/references/cross-posting.md +82 -0
  27. package/skills/ghostget/references/derivation.md +390 -0
  28. package/skills/ghostget/references/hraness-social-profile-stats.json +269 -0
  29. package/skills/ghostget/references/install.md +66 -0
  30. package/skills/ghostget/references/linkedin-adapter.md +442 -0
  31. package/skills/ghostget/references/messaging.md +168 -0
  32. package/skills/ghostget/references/meta-comet-contract.md +153 -0
  33. package/skills/ghostget/references/platform-patterns.md +122 -0
  34. package/skills/ghostget/references/provider-plugins.md +496 -0
  35. package/skills/ghostget/references/reddit-flair.md +78 -0
  36. package/skills/ghostget/references/safety-and-state.md +214 -0
  37. package/skills/ghostget/references/settlement-and-duplicate-cleanup.md +79 -0
  38. package/skills/ghostget/references/social-platform-routing.md +66 -0
  39. package/skills/ghostget/references/social-profile-stats.md +195 -0
  40. package/skills/ghostget/references/social-video-platform-routing.md +89 -0
  41. package/skills/ghostget/references/whatsapp-adapter.md +101 -0
  42. package/skills/ghostget/references/x-adapter.md +332 -0
  43. package/skills/ghostget/references/x-ai-disclosure.md +71 -0
  44. package/src/apple-photos-cli.ts +639 -0
  45. package/src/apple-photos-client-types.ts +168 -0
  46. package/src/apple-photos-client.ts +201 -0
  47. package/src/apple-photos-contact-evidence.ts +838 -0
  48. package/src/apple-photos-local-source.ts +1131 -0
  49. package/src/args.ts +2053 -0
  50. package/src/article-draft-document.ts +417 -0
  51. package/src/article-draft-embeds.ts +123 -0
  52. package/src/article-draft-images.ts +214 -0
  53. package/src/assets/adapter-template/wrench-adapter.json +40 -0
  54. package/src/assets/adapters/beeper/wrench-web-adapter.json +1500 -0
  55. package/src/assets/adapters/beeper/wrench-web-adapter.v1.0.0.json +129 -0
  56. package/src/assets/adapters/beeper/wrench-web-adapter.v1.1.0.json +207 -0
  57. package/src/assets/adapters/beeper/wrench-web-adapter.v2.0.0.json +1463 -0
  58. package/src/assets/adapters/beeper/wrench-web-adapter.v2.1.0.json +1463 -0
  59. package/src/assets/adapters/beeper/wrench-web-adapter.v2.2.0.json +1475 -0
  60. package/src/assets/adapters/beeper/wrench-web-adapter.v2.3.0.json +1488 -0
  61. package/src/assets/adapters/bluesky/wrench-web-adapter.json +684 -0
  62. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.0.0.json +581 -0
  63. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.1.0.json +581 -0
  64. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.2.0.json +581 -0
  65. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.3.0.json +615 -0
  66. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.4.0.json +684 -0
  67. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.5.0.json +684 -0
  68. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.6.0.json +684 -0
  69. package/src/assets/adapters/clasificados/wrench-web-adapter.json +54 -0
  70. package/src/assets/adapters/facebook/wrench-web-adapter.json +750 -0
  71. package/src/assets/adapters/facebook/wrench-web-adapter.v1.0.0.json +706 -0
  72. package/src/assets/adapters/facebook/wrench-web-adapter.v1.1.0.json +703 -0
  73. package/src/assets/adapters/facebook/wrench-web-adapter.v1.2.0.json +750 -0
  74. package/src/assets/adapters/facebook-group/wrench-web-adapter.json +682 -0
  75. package/src/assets/adapters/facebook-group/wrench-web-adapter.v1.0.0.json +583 -0
  76. package/src/assets/adapters/facebook-group/wrench-web-adapter.v1.1.0.json +682 -0
  77. package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.json +437 -0
  78. package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.0.0.json +383 -0
  79. package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.1.0.json +437 -0
  80. package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.1.1.json +437 -0
  81. package/src/assets/adapters/facebook-page/wrench-web-adapter.json +880 -0
  82. package/src/assets/adapters/facebook-page/wrench-web-adapter.v1.0.0.json +740 -0
  83. package/src/assets/adapters/facebook-page/wrench-web-adapter.v1.1.0.json +880 -0
  84. package/src/assets/adapters/github/wrench-web-adapter.json +69 -0
  85. package/src/assets/adapters/github/wrench-web-adapter.v1.0.0.json +42 -0
  86. package/src/assets/adapters/github/wrench-web-adapter.v1.1.0.json +69 -0
  87. package/src/assets/adapters/gmail/wrench-adapter.json +161 -0
  88. package/src/assets/adapters/gmail/wrench-adapter.v1.2.0.json +157 -0
  89. package/src/assets/adapters/hacker-news/wrench-web-adapter.json +315 -0
  90. package/src/assets/adapters/hacker-news/wrench-web-adapter.v1.0.0.json +315 -0
  91. package/src/assets/adapters/imessage/wrench-web-adapter.json +236 -0
  92. package/src/assets/adapters/instagram/wrench-web-adapter.json +719 -0
  93. package/src/assets/adapters/instagram/wrench-web-adapter.v1.0.0.json +627 -0
  94. package/src/assets/adapters/instagram/wrench-web-adapter.v1.1.0.json +609 -0
  95. package/src/assets/adapters/instagram/wrench-web-adapter.v1.2.0.json +640 -0
  96. package/src/assets/adapters/instagram/wrench-web-adapter.v1.3.0.json +671 -0
  97. package/src/assets/adapters/instagram/wrench-web-adapter.v1.4.0.json +710 -0
  98. package/src/assets/adapters/instagram/wrench-web-adapter.v1.5.0.json +710 -0
  99. package/src/assets/adapters/instagram/wrench-web-adapter.v1.6.0.json +719 -0
  100. package/src/assets/adapters/instagram/wrench-web-adapter.v1.7.0.json +719 -0
  101. package/src/assets/adapters/linkedin/wrench-adapter.json +442 -0
  102. package/src/assets/adapters/linkedin/wrench-adapter.v0.4.0.json +124 -0
  103. package/src/assets/adapters/linkedin/wrench-adapter.v1.0.0.json +411 -0
  104. package/src/assets/adapters/linkedin/wrench-web-adapter.json +914 -0
  105. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.0.0.json +604 -0
  106. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.1.0.json +604 -0
  107. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.10.0.json +809 -0
  108. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.11.0.json +809 -0
  109. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.12.0.json +820 -0
  110. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.13.0.json +819 -0
  111. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.14.0.json +819 -0
  112. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.15.0.json +819 -0
  113. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.16.0.json +874 -0
  114. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.17.0.json +874 -0
  115. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.18.0.json +874 -0
  116. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.19.0.json +874 -0
  117. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.2.0.json +731 -0
  118. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.3.0.json +768 -0
  119. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.4.0.json +808 -0
  120. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.5.0.json +808 -0
  121. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.6.0.json +808 -0
  122. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.7.0.json +825 -0
  123. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.8.0.json +792 -0
  124. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.9.0.json +809 -0
  125. package/src/assets/adapters/reddit/wrench-web-adapter.json +855 -0
  126. package/src/assets/adapters/reddit/wrench-web-adapter.v1.0.0.json +577 -0
  127. package/src/assets/adapters/reddit/wrench-web-adapter.v1.1.0.json +604 -0
  128. package/src/assets/adapters/reddit/wrench-web-adapter.v1.10.0.json +712 -0
  129. package/src/assets/adapters/reddit/wrench-web-adapter.v1.11.0.json +712 -0
  130. package/src/assets/adapters/reddit/wrench-web-adapter.v1.12.0.json +712 -0
  131. package/src/assets/adapters/reddit/wrench-web-adapter.v1.2.0.json +653 -0
  132. package/src/assets/adapters/reddit/wrench-web-adapter.v1.3.0.json +712 -0
  133. package/src/assets/adapters/reddit/wrench-web-adapter.v1.4.0.json +713 -0
  134. package/src/assets/adapters/reddit/wrench-web-adapter.v1.5.0.json +712 -0
  135. package/src/assets/adapters/reddit/wrench-web-adapter.v1.6.0.json +713 -0
  136. package/src/assets/adapters/reddit/wrench-web-adapter.v1.7.0.json +713 -0
  137. package/src/assets/adapters/reddit/wrench-web-adapter.v1.8.0.json +713 -0
  138. package/src/assets/adapters/reddit/wrench-web-adapter.v1.9.0.json +713 -0
  139. package/src/assets/adapters/substack/wrench-web-adapter.json +936 -0
  140. package/src/assets/adapters/substack/wrench-web-adapter.v1.0.0.json +817 -0
  141. package/src/assets/adapters/substack/wrench-web-adapter.v1.1.0.json +812 -0
  142. package/src/assets/adapters/substack/wrench-web-adapter.v1.2.0.json +812 -0
  143. package/src/assets/adapters/substack/wrench-web-adapter.v1.3.0.json +902 -0
  144. package/src/assets/adapters/substack/wrench-web-adapter.v1.4.0.json +936 -0
  145. package/src/assets/adapters/substack/wrench-web-adapter.v1.5.0.json +936 -0
  146. package/src/assets/adapters/substack/wrench-web-adapter.v1.6.0.json +936 -0
  147. package/src/assets/adapters/threads/wrench-web-adapter.json +692 -0
  148. package/src/assets/adapters/threads/wrench-web-adapter.v1.0.0.json +629 -0
  149. package/src/assets/adapters/threads/wrench-web-adapter.v1.1.0.json +623 -0
  150. package/src/assets/adapters/threads/wrench-web-adapter.v1.2.0.json +622 -0
  151. package/src/assets/adapters/threads/wrench-web-adapter.v1.3.0.json +622 -0
  152. package/src/assets/adapters/threads/wrench-web-adapter.v1.4.0.json +622 -0
  153. package/src/assets/adapters/threads/wrench-web-adapter.v1.5.0.json +699 -0
  154. package/src/assets/adapters/threads/wrench-web-adapter.v1.6.0.json +693 -0
  155. package/src/assets/adapters/threads/wrench-web-adapter.v1.7.0.json +692 -0
  156. package/src/assets/adapters/tiktok/wrench-web-adapter.json +762 -0
  157. package/src/assets/adapters/tiktok/wrench-web-adapter.v1.0.0.json +681 -0
  158. package/src/assets/adapters/tiktok/wrench-web-adapter.v1.1.0.json +708 -0
  159. package/src/assets/adapters/tiktok/wrench-web-adapter.v1.2.0.json +762 -0
  160. package/src/assets/adapters/tiktok/wrench-web-adapter.v1.3.0.json +762 -0
  161. package/src/assets/adapters/twitch/wrench-web-adapter.json +42 -0
  162. package/src/assets/adapters/twitch/wrench-web-adapter.v1.0.0.json +42 -0
  163. package/src/assets/adapters/whatsapp/wrench-web-adapter.json +400 -0
  164. package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.0.0.json +355 -0
  165. package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.1.0.json +386 -0
  166. package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.2.0.json +386 -0
  167. package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.3.0.json +400 -0
  168. package/src/assets/adapters/x/wrench-adapter.json +749 -0
  169. package/src/assets/adapters/x/wrench-adapter.v1.0.0.json +700 -0
  170. package/src/assets/adapters/x/wrench-adapter.v1.1.0.json +707 -0
  171. package/src/assets/adapters/x/wrench-web-adapter.json +712 -0
  172. package/src/assets/adapters/x/wrench-web-adapter.v1.1.0.json +579 -0
  173. package/src/assets/adapters/x/wrench-web-adapter.v1.10.0.json +685 -0
  174. package/src/assets/adapters/x/wrench-web-adapter.v1.11.0.json +712 -0
  175. package/src/assets/adapters/x/wrench-web-adapter.v1.12.0.json +712 -0
  176. package/src/assets/adapters/x/wrench-web-adapter.v1.13.0.json +712 -0
  177. package/src/assets/adapters/x/wrench-web-adapter.v1.2.0.json +578 -0
  178. package/src/assets/adapters/x/wrench-web-adapter.v1.3.0.json +610 -0
  179. package/src/assets/adapters/x/wrench-web-adapter.v1.4.0.json +617 -0
  180. package/src/assets/adapters/x/wrench-web-adapter.v1.5.0.json +634 -0
  181. package/src/assets/adapters/x/wrench-web-adapter.v1.6.0.json +632 -0
  182. package/src/assets/adapters/x/wrench-web-adapter.v1.7.0.json +649 -0
  183. package/src/assets/adapters/x/wrench-web-adapter.v1.8.0.json +649 -0
  184. package/src/assets/adapters/x/wrench-web-adapter.v1.9.0.json +683 -0
  185. package/src/assets/adapters/youtube/wrench-web-adapter.json +561 -0
  186. package/src/assets/adapters/youtube/wrench-web-adapter.v1.0.0.json +465 -0
  187. package/src/assets/adapters/youtube/wrench-web-adapter.v1.1.0.json +519 -0
  188. package/src/assets/adapters/youtube/wrench-web-adapter.v1.2.0.json +561 -0
  189. package/src/assets/adapters/youtube/wrench-web-adapter.v1.3.0.json +561 -0
  190. package/src/assets/code-owned-provider-template/plugin.test.ts.template +54 -0
  191. package/src/assets/code-owned-provider-template/plugin.ts.template +102 -0
  192. package/src/assets/code-owned-provider-template/runtime.internal.test.ts.template +44 -0
  193. package/src/assets/code-owned-provider-template/runtime.ts.template +59 -0
  194. package/src/assets/code-owned-provider-template/wrench-adapter.json.template +33 -0
  195. package/src/assets/fonts/nebula-sans/LICENSE.txt +96 -0
  196. package/src/assets/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
  197. package/src/assets/fonts/nebula-sans/PROVENANCE.md +14 -0
  198. package/src/assets.d.ts +4 -0
  199. package/src/auth.ts +1157 -0
  200. package/src/beeper-client-types.ts +169 -0
  201. package/src/beeper-client.ts +250 -0
  202. package/src/beeper-contact-interactions-cli.ts +180 -0
  203. package/src/beeper-contact-interactions.ts +1612 -0
  204. package/src/beeper-message-bundle-v1.ts +257 -0
  205. package/src/beeper-message-like-me-cli.ts +84 -0
  206. package/src/beeper-message-like-me-export.ts +2274 -0
  207. package/src/beeper-message-like-me-recovery.ts +931 -0
  208. package/src/beeper-message-like-me-source.ts +4034 -0
  209. package/src/browser-admission.ts +928 -0
  210. package/src/browser-snapshots.ts +260 -0
  211. package/src/browser.ts +3873 -0
  212. package/src/canonical-json.ts +60 -0
  213. package/src/catalog-cli.ts +638 -0
  214. package/src/cli.ts +208 -0
  215. package/src/client-types.ts +301 -0
  216. package/src/client.ts +2726 -0
  217. package/src/confirmed-write-failure.ts +44 -0
  218. package/src/confirmed-write-model.ts +72 -0
  219. package/src/confirmed-write-platform.ts +1055 -0
  220. package/src/confirmed-write-program.ts +224 -0
  221. package/src/confirmed-write-runtime.ts +16 -0
  222. package/src/cursor-token.ts +228 -0
  223. package/src/derivation-dnr-readiness.ts +367 -0
  224. package/src/derivation-file-chooser.ts +384 -0
  225. package/src/derivation-network-boundary.ts +835 -0
  226. package/src/derivation-network-guard.ts +782 -0
  227. package/src/derivation-network-proxy-helper.ts +440 -0
  228. package/src/derivation-network-proxy.ts +385 -0
  229. package/src/derive-command-helper.ts +693 -0
  230. package/src/derive-fixtures.ts +343 -0
  231. package/src/derive-review.ts +980 -0
  232. package/src/derive.ts +4754 -0
  233. package/src/fixtures/beeper-message-like-me-v1/accounts.ndjson +2 -0
  234. package/src/fixtures/beeper-message-like-me-v1/conversations.ndjson +1 -0
  235. package/src/fixtures/beeper-message-like-me-v1/manifest.json +1 -0
  236. package/src/fixtures/beeper-message-like-me-v1/messages.ndjson +2 -0
  237. package/src/fixtures/beeper-message-like-me-v1/participants.ndjson +3 -0
  238. package/src/fixtures/beeper-message-like-me-v1/reactions.ndjson +1 -0
  239. package/src/fixtures/beeper-message-like-me-v1/tombstones.ndjson +1 -0
  240. package/src/ghostget.ts +3672 -0
  241. package/src/gmail-capture.ts +1244 -0
  242. package/src/har-internal.ts +1242 -0
  243. package/src/har.ts +743 -0
  244. package/src/index.ts +218 -0
  245. package/src/invocation-read-platform.ts +55 -0
  246. package/src/invocation-read-program.ts +93 -0
  247. package/src/invocation-read-runtime.ts +11 -0
  248. package/src/linked-device-lifecycle-admission.ts +450 -0
  249. package/src/linked-device-lifecycle-journal.ts +1560 -0
  250. package/src/linked-device-lifecycle-runtime.ts +1602 -0
  251. package/src/local-cli-admission.ts +135 -0
  252. package/src/local-cli-contracts.ts +271 -0
  253. package/src/local-cli-execution.ts +98 -0
  254. package/src/local-cli-surface-contract.ts +1510 -0
  255. package/src/local-cli-tool-identity.ts +336 -0
  256. package/src/media/archive.ts +2325 -0
  257. package/src/media/args.ts +303 -0
  258. package/src/media/cli.ts +287 -0
  259. package/src/media/doctor.ts +475 -0
  260. package/src/media/ffmpeg.ts +1330 -0
  261. package/src/media/http-capture.ts +711 -0
  262. package/src/media/http-probe.ts +593 -0
  263. package/src/media/http.ts +387 -0
  264. package/src/media/index.ts +10 -0
  265. package/src/media/local-transcription.ts +613 -0
  266. package/src/media/lock.ts +321 -0
  267. package/src/media/manifest.ts +1712 -0
  268. package/src/media/metadata.ts +906 -0
  269. package/src/media/process.ts +723 -0
  270. package/src/media/revision.ts +166 -0
  271. package/src/media/runtime-closure.ts +1063 -0
  272. package/src/media/source-router.ts +187 -0
  273. package/src/media/transcriber-config.ts +1122 -0
  274. package/src/media/transcript-persistence-model.ts +15 -0
  275. package/src/media/transcript-persistence-platform.ts +89 -0
  276. package/src/media/transcript-persistence-program.ts +39 -0
  277. package/src/media/transcript-persistence-runtime.ts +24 -0
  278. package/src/media/transcript.ts +616 -0
  279. package/src/media/utf8-order.ts +30 -0
  280. package/src/media/whisper-cpp.ts +464 -0
  281. package/src/media/whisper-language.ts +58 -0
  282. package/src/media/yt-dlp.ts +439 -0
  283. package/src/message-like-me-agentic-messaging.ts +882 -0
  284. package/src/messaging-action-store.ts +793 -0
  285. package/src/messaging-runtime.ts +2136 -0
  286. package/src/messaging-store.ts +539 -0
  287. package/src/messaging-types.ts +1663 -0
  288. package/src/messaging.ts +334 -0
  289. package/src/model.ts +2671 -0
  290. package/src/oauth-google.ts +888 -0
  291. package/src/omni-client-types.ts +306 -0
  292. package/src/omni-client.ts +2225 -0
  293. package/src/omni-limits.ts +34 -0
  294. package/src/omni-model.ts +1614 -0
  295. package/src/omni-request.ts +379 -0
  296. package/src/omni-runtime.ts +1632 -0
  297. package/src/operation-deadline.ts +189 -0
  298. package/src/path-helper.ts +1656 -0
  299. package/src/pinned-https.ts +194 -0
  300. package/src/plan-assets.ts +832 -0
  301. package/src/platform-catalog.ts +1832 -0
  302. package/src/plugins/beeper-linked-device/plugin.ts +310 -0
  303. package/src/plugins/bluesky-web/plugin.ts +178 -0
  304. package/src/plugins/clasificados-web/plugin.ts +66 -0
  305. package/src/plugins/github-web/plugin.ts +80 -0
  306. package/src/plugins/gmail-official/plugin.ts +110 -0
  307. package/src/plugins/hacker-news-web/plugin.ts +52 -0
  308. package/src/plugins/imessage-direct/plugin.ts +195 -0
  309. package/src/plugins/imessage-direct/vendor/0001-fix-keep-AppleScript-send-payloads-out-of-child-argv.patch +1430 -0
  310. package/src/plugins/imessage-direct/vendor/0002-feat-rpc-add-exact-chat-lookup.patch +225 -0
  311. package/src/plugins/imessage-direct/vendor/provenance.json +80 -0
  312. package/src/plugins/linkedin-official/plugin.ts +84 -0
  313. package/src/plugins/linkedin-web/plugin.ts +412 -0
  314. package/src/plugins/meta-web/plugin.ts +317 -0
  315. package/src/plugins/reddit-web/flair.ts +492 -0
  316. package/src/plugins/reddit-web/plugin.ts +477 -0
  317. package/src/plugins/substack-web/plugin.ts +124 -0
  318. package/src/plugins/tiktok-web/plugin.ts +67 -0
  319. package/src/plugins/twitch-web/plugin.ts +54 -0
  320. package/src/plugins/whatsapp-linked-device/plugin.ts +105 -0
  321. package/src/plugins/x-official/plugin.ts +64 -0
  322. package/src/plugins/x-web/plugin.ts +488 -0
  323. package/src/plugins/youtube-web/plugin.ts +101 -0
  324. package/src/portable-run-recovery.ts +466 -0
  325. package/src/process-identity.ts +501 -0
  326. package/src/profile-clone-helper.ts +104 -0
  327. package/src/provider-catalog-views.ts +51 -0
  328. package/src/provider-context.ts +69 -0
  329. package/src/provider-contract-definitions-x.ts +45 -0
  330. package/src/provider-contract-definitions.ts +948 -0
  331. package/src/provider-contract-input-gmail.ts +176 -0
  332. package/src/provider-contract-input-linkedin.ts +77 -0
  333. package/src/provider-contract-input-x.ts +304 -0
  334. package/src/provider-contract-planning.ts +23 -0
  335. package/src/provider-contract-semantic-identity.ts +54 -0
  336. package/src/provider-contracts.ts +251 -0
  337. package/src/provider-http.ts +723 -0
  338. package/src/provider-plugin-auth.ts +36 -0
  339. package/src/provider-plugin-builtins.ts +229 -0
  340. package/src/provider-plugin-cleanup-barrier.ts +229 -0
  341. package/src/provider-plugin-cleanup-execution.ts +79 -0
  342. package/src/provider-plugin-cleanup-resource.ts +470 -0
  343. package/src/provider-plugin-contract-identity.ts +707 -0
  344. package/src/provider-plugin-host.ts +1972 -0
  345. package/src/provider-plugin-identifiers.ts +60 -0
  346. package/src/provider-plugin-invocation-lease.ts +889 -0
  347. package/src/provider-plugin-lifecycle-kernel.ts +566 -0
  348. package/src/provider-plugin-lifecycle.ts +1455 -0
  349. package/src/provider-plugin-module-analysis.ts +336 -0
  350. package/src/provider-plugin-package.ts +2530 -0
  351. package/src/provider-plugin-portable-authority.ts +106 -0
  352. package/src/provider-plugin-portable-catalog.ts +94 -0
  353. package/src/provider-plugin-portable-identity.ts +315 -0
  354. package/src/provider-plugin-portable-runtime.ts +2057 -0
  355. package/src/provider-plugin-protocol.ts +1625 -0
  356. package/src/provider-plugin-registry.ts +3342 -0
  357. package/src/provider-plugin-store.ts +2155 -0
  358. package/src/provider-plugin-test-fixture.ts +5 -0
  359. package/src/provider-plugin.ts +4907 -0
  360. package/src/provider-plugins.generated.ts +43 -0
  361. package/src/provider-plugins.ts +8 -0
  362. package/src/provider-subject.ts +41 -0
  363. package/src/provider.ts +315 -0
  364. package/src/providers/beeper-local-runtime.ts +5426 -0
  365. package/src/providers/beeper-local.ts +2739 -0
  366. package/src/providers/beeper-messaging.ts +462 -0
  367. package/src/providers/beeper-omni.ts +1159 -0
  368. package/src/providers/bluesky-web-runtime.ts +2895 -0
  369. package/src/providers/bluesky-web.ts +1614 -0
  370. package/src/providers/clasificados-web-runtime.ts +255 -0
  371. package/src/providers/clasificados-web.ts +503 -0
  372. package/src/providers/contact-projection.ts +301 -0
  373. package/src/providers/github-read-model.ts +94 -0
  374. package/src/providers/github-read-platform.ts +165 -0
  375. package/src/providers/github-read-program.ts +97 -0
  376. package/src/providers/github-web-runtime.ts +320 -0
  377. package/src/providers/github-web.ts +403 -0
  378. package/src/providers/gmail-api.ts +2834 -0
  379. package/src/providers/gmail-omni.ts +830 -0
  380. package/src/providers/gmail.ts +1130 -0
  381. package/src/providers/hacker-news-web-runtime.ts +220 -0
  382. package/src/providers/hacker-news-web.ts +809 -0
  383. package/src/providers/imessage-direct-install.ts +354 -0
  384. package/src/providers/imessage-direct-messaging.ts +532 -0
  385. package/src/providers/imessage-direct-omni.ts +400 -0
  386. package/src/providers/imessage-direct-runtime.ts +1498 -0
  387. package/src/providers/imessage-direct.ts +351 -0
  388. package/src/providers/instagram-video-foundations.ts +913 -0
  389. package/src/providers/instagram-web-profile-browser.ts +600 -0
  390. package/src/providers/iso-bmff.ts +338 -0
  391. package/src/providers/linkedin-company-platform.ts +42 -0
  392. package/src/providers/linkedin-company-program.ts +88 -0
  393. package/src/providers/linkedin-contact-failure.ts +84 -0
  394. package/src/providers/linkedin-contact-platform.ts +45 -0
  395. package/src/providers/linkedin-contact-program.ts +91 -0
  396. package/src/providers/linkedin-profile-activity-failure.ts +76 -0
  397. package/src/providers/linkedin-profile-activity-platform.ts +41 -0
  398. package/src/providers/linkedin-profile-activity-program.ts +67 -0
  399. package/src/providers/linkedin-read-failure.ts +52 -0
  400. package/src/providers/linkedin-self-platform.ts +53 -0
  401. package/src/providers/linkedin-self-program.ts +122 -0
  402. package/src/providers/linkedin-web-article-browser.ts +794 -0
  403. package/src/providers/linkedin-web-bootstrap.ts +146 -0
  404. package/src/providers/linkedin-web-contact.ts +830 -0
  405. package/src/providers/linkedin-web-feed-browser.ts +832 -0
  406. package/src/providers/linkedin-web-feed.ts +864 -0
  407. package/src/providers/linkedin-web-post-browser.ts +653 -0
  408. package/src/providers/linkedin-web-profile-browser.ts +683 -0
  409. package/src/providers/linkedin-web-runtime.ts +2388 -0
  410. package/src/providers/linkedin-web.ts +3305 -0
  411. package/src/providers/linkedin.ts +1885 -0
  412. package/src/providers/meta-bootstrap.ts +1043 -0
  413. package/src/providers/meta-facebook-group.ts +690 -0
  414. package/src/providers/meta-marketplace-relay.ts +747 -0
  415. package/src/providers/meta-omni.ts +373 -0
  416. package/src/providers/meta-relay-bundle.ts +1049 -0
  417. package/src/providers/meta-web-descriptors.ts +1740 -0
  418. package/src/providers/meta-web-runtime.ts +3388 -0
  419. package/src/providers/meta-web.ts +2931 -0
  420. package/src/providers/read-failure.ts +139 -0
  421. package/src/providers/reddit-omni.ts +462 -0
  422. package/src/providers/reddit-web-runtime.ts +1929 -0
  423. package/src/providers/reddit-web.ts +1611 -0
  424. package/src/providers/rental-listings.ts +460 -0
  425. package/src/providers/substack-omni.ts +406 -0
  426. package/src/providers/substack-video-mp4.ts +33 -0
  427. package/src/providers/substack-web-runtime.ts +2812 -0
  428. package/src/providers/substack-web.ts +1502 -0
  429. package/src/providers/tiktok-video-mp4.ts +33 -0
  430. package/src/providers/tiktok-web-runtime.ts +770 -0
  431. package/src/providers/tiktok-web.ts +2786 -0
  432. package/src/providers/twitch-web-runtime.ts +226 -0
  433. package/src/providers/twitch-web.ts +274 -0
  434. package/src/providers/whatsapp-account-identity.ts +55 -0
  435. package/src/providers/whatsapp-contact-projection-helper.ts +874 -0
  436. package/src/providers/whatsapp-contact-projection-protocol.ts +403 -0
  437. package/src/providers/whatsapp-interaction-projection-helper.ts +1452 -0
  438. package/src/providers/whatsapp-interaction-projection-protocol.ts +462 -0
  439. package/src/providers/whatsapp-message-export-projection-protocol.ts +532 -0
  440. package/src/providers/whatsapp-messaging.ts +132 -0
  441. package/src/providers/whatsapp-omni.ts +586 -0
  442. package/src/providers/whatsapp-web-runtime.ts +3108 -0
  443. package/src/providers/whatsapp-web.ts +1037 -0
  444. package/src/providers/x-image-provenance.ts +523 -0
  445. package/src/providers/x-made-with-ai.ts +106 -0
  446. package/src/providers/x-transaction-id.ts +413 -0
  447. package/src/providers/x-web-runtime.ts +3485 -0
  448. package/src/providers/x-web.ts +2332 -0
  449. package/src/providers/x.ts +1889 -0
  450. package/src/providers/youtube-web-runtime.ts +1400 -0
  451. package/src/providers/youtube-web.ts +1221 -0
  452. package/src/read-admission-runtime.ts +91 -0
  453. package/src/read-client.ts +521 -0
  454. package/src/read-effect-platform.ts +7 -0
  455. package/src/read-effect-runtime.ts +14 -0
  456. package/src/read-effect.ts +52 -0
  457. package/src/read-projection-admission.ts +866 -0
  458. package/src/read-projections.ts +3151 -0
  459. package/src/recovery.ts +1492 -0
  460. package/src/reviewed-template.ts +146 -0
  461. package/src/run-journal.ts +1272 -0
  462. package/src/runtime.ts +5116 -0
  463. package/src/scripts/generate-provider-plugin-catalog.ts +121 -0
  464. package/src/scripts/install-whatsapp-protocol.sh +232 -0
  465. package/src/scripts/recover-install-stages.ts +1491 -0
  466. package/src/scripts/resolve-state-home.ts +30 -0
  467. package/src/scripts/scaffold-web-provider.ts +973 -0
  468. package/src/scripts/sync-bundled-adapters.ts +695 -0
  469. package/src/session-secrets.ts +1183 -0
  470. package/src/state-helper.bunfig.toml +2 -0
  471. package/src/state-helper.ts +2914 -0
  472. package/src/storage.ts +3842 -0
  473. package/src/transport-policy.ts +2 -0
  474. package/src/usage.ts +182 -0
  475. package/src/version.ts +2 -0
  476. package/src/web-session-authentication-policy.ts +136 -0
  477. package/src/web-session-cleanup-admission.ts +2344 -0
  478. package/src/web-session-cleanup-join.ts +99 -0
  479. package/src/web-session-client.ts +996 -0
  480. package/src/web-session-contract-definitions.ts +820 -0
  481. package/src/web-session-contract-planning.ts +42 -0
  482. package/src/web-session-contracts.ts +228 -0
  483. package/src/web-session-cookies.ts +500 -0
  484. package/src/web-session-execution.ts +385 -0
  485. package/src/web-session-http.ts +373 -0
  486. package/src/web-session-read-errors.ts +19 -0
  487. package/src/web-session-read-runtime.ts +124 -0
  488. package/src/web-session-recovery.ts +818 -0
  489. package/src/web-session-sites.ts +58 -0
  490. package/src/web-session-template.ts +994 -0
  491. package/src/web-session.ts +93 -0
  492. package/src/whatsapp-client-binding.ts +21 -0
  493. package/src/whatsapp-client-types.ts +75 -0
  494. package/src/whatsapp-client.ts +395 -0
  495. package/src/whatsapp-export-coordinate.ts +17 -0
  496. package/src/whatsapp-message-bundle-v2.ts +195 -0
  497. package/src/whatsapp-message-like-me-cli.ts +195 -0
  498. package/src/whatsapp-message-like-me-export.ts +1072 -0
  499. package/src/whatsapp-message-like-me-source.ts +1012 -0
  500. package/tsconfig.json +67 -0
@@ -0,0 +1,1632 @@
1
+ import { types as nodeTypes } from "node:util";
2
+
3
+ import { canonicalJson, sha256 } from "./canonical-json";
4
+ import { loadAuthSnapshotIfPresent } from "./auth";
5
+ import {
6
+ isProviderOperation,
7
+ isLocalCliOperation,
8
+ isWebSessionOperation,
9
+ } from "./model";
10
+ import {
11
+ markOmniSourceDriftV1,
12
+ OMNI_MAX_SOURCE_PAGES,
13
+ parseMaterializedPageV1,
14
+ parseOmniSourceStateV1,
15
+ queryOmniSourceStatesV1,
16
+ reduceOmniSourceStateV1,
17
+ type OmniEntityV1,
18
+ type OmniJsonValue,
19
+ type OmniNormalizationStatusV1,
20
+ type OmniPageProvenanceV1,
21
+ type OmniSourceIdentityV1,
22
+ type OmniSourceStateV1,
23
+ type OmniStoredPageV1,
24
+ } from "./omni-model";
25
+ import {
26
+ boundedOmniText,
27
+ OMNI_MAX_REASON_BYTES,
28
+ OMNI_MAX_RESPONSE_BYTES,
29
+ } from "./omni-limits";
30
+ import {
31
+ omniRequestDigest,
32
+ openOmniViewCursorV1,
33
+ parseOmniViewRequestV1,
34
+ sealOmniViewCursorV1,
35
+ type OmniViewRequestV1,
36
+ type OmniViewSourceRequestV1,
37
+ } from "./omni-request";
38
+ import type {
39
+ ProviderPluginOmniDefinitionV1,
40
+ } from "./provider-plugin";
41
+ import type {
42
+ ProviderPluginOperationResolutionV1,
43
+ ProviderPluginRegistry,
44
+ } from "./provider-plugin-registry";
45
+ import { providerPluginRegistry } from "./provider-plugins";
46
+ import { revalidatePreparedCapability } from "./read-client";
47
+ import {
48
+ createOmniProjectionQuery,
49
+ readOmniProjection,
50
+ readReadProjectionForMaterialization,
51
+ reduceOmniProjection,
52
+ projectionAuthIdentityHash,
53
+ type OmniProjectionQuery,
54
+ type ReadProjectionExactHeadFence,
55
+ type ReadProjectionMaterializationSnapshot,
56
+ type ReadProjectionQuery,
57
+ } from "./read-projections";
58
+ import {
59
+ createReadProjectionQueryForInvocation,
60
+ prepareInvocation,
61
+ type PreparedInvocation,
62
+ } from "./runtime";
63
+ import type { executeReadInvocation } from "./runtime";
64
+
65
+ type Environment = Readonly<Record<string, string | undefined>>;
66
+ const MAX_MATERIALIZATION_SETTLEMENT_ATTEMPTS = 4;
67
+
68
+ export type OmniExactSourceStatusV1 =
69
+ | {
70
+ readonly state: "miss";
71
+ readonly key: string;
72
+ }
73
+ | {
74
+ readonly state: "hit";
75
+ readonly key: string;
76
+ readonly dataRevision: string;
77
+ readonly validatedAt: string;
78
+ readonly ageMs: number;
79
+ readonly freshness: {
80
+ readonly state: "fresh" | "stale" | "unclassified";
81
+ readonly freshForMs: number | null;
82
+ };
83
+ }
84
+ | {
85
+ readonly state: "error";
86
+ readonly key: string;
87
+ readonly reason: string;
88
+ };
89
+
90
+ export type OmniNormalizationSourceStatusV1 =
91
+ | { readonly state: "missing" }
92
+ | { readonly state: "unsupported"; readonly reason: string }
93
+ | {
94
+ readonly state: "current";
95
+ readonly exactQueryKey: string;
96
+ readonly exactDataRevision: string;
97
+ readonly lastGoodAt: string;
98
+ }
99
+ | {
100
+ readonly state: "retained-after-drift";
101
+ readonly exactQueryKey: string;
102
+ readonly reason: string;
103
+ readonly failedExactDataRevision: string;
104
+ readonly newerExactDataRevision: string | null;
105
+ readonly lastGoodExactDataRevision: string | null;
106
+ readonly lastGoodAt: string | null;
107
+ }
108
+ | {
109
+ readonly state: "stale";
110
+ readonly exactQueryKey: string;
111
+ /** Null when a failed provider attempt produced no new exact revision. */
112
+ readonly exactDataRevision: string | null;
113
+ /** Null when this exact query has never produced a normalized page. */
114
+ readonly normalizedExactDataRevision: string | null;
115
+ readonly lastGoodAt: string | null;
116
+ readonly reason: string;
117
+ }
118
+ | {
119
+ readonly state: "error";
120
+ readonly reason: string;
121
+ readonly lastGoodAt: string | null;
122
+ };
123
+
124
+ export type OmniSourceCoverageV1 =
125
+ | {
126
+ readonly state: "unavailable";
127
+ readonly reason: string;
128
+ }
129
+ | {
130
+ readonly state: "observed";
131
+ readonly kind: OmniStoredPageV1["completeness"]["kind"];
132
+ readonly continuation: "none" | "pending" | "unavailable";
133
+ readonly reason: string | null;
134
+ };
135
+
136
+ export type OmniViewSourceStatusV1 = {
137
+ readonly adapterId: string;
138
+ readonly operationId: "messaging.list" | "messaging.read";
139
+ readonly authId: string;
140
+ /** Client-verifiable identity of the exact raw request input. */
141
+ readonly requestInputHash: string;
142
+ /** Provider-parsed/defaulted identity used by the exact projection. */
143
+ readonly projectionInputHash: string;
144
+ /** Opaque keyed revision of the durable normalized source state, if any. */
145
+ readonly normalizationDataRevision: string | null;
146
+ readonly surfaceId: string;
147
+ readonly exact: OmniExactSourceStatusV1;
148
+ readonly normalization: OmniNormalizationSourceStatusV1;
149
+ readonly coverage: OmniSourceCoverageV1;
150
+ };
151
+
152
+ export type OmniViewV1 = {
153
+ readonly schemaVersion: 1;
154
+ readonly viewRevision: string;
155
+ readonly entities: readonly OmniEntityV1[];
156
+ readonly nextCursor: string | null;
157
+ readonly sources: readonly OmniViewSourceStatusV1[];
158
+ };
159
+
160
+ export type OmniViewIdentityV1 = {
161
+ /** Full canonical SDK/CLI invocation identity, including the local cursor. */
162
+ readonly invocationDigest: string;
163
+ /** Cursor-independent logical request identity. */
164
+ readonly requestDigest: string;
165
+ readonly sourceSetDigest: string;
166
+ };
167
+
168
+ export type OmniReadResultV1 = {
169
+ readonly ok: true;
170
+ readonly schemaVersion: 1;
171
+ readonly source:
172
+ | "omni-cache"
173
+ | "omni-live"
174
+ | "omni-exact-cache"
175
+ | "omni-identity";
176
+ readonly identity: OmniViewIdentityV1;
177
+ readonly view: OmniViewV1 | null;
178
+ };
179
+
180
+ type PreparedOmniSource = {
181
+ readonly request: OmniViewSourceRequestV1;
182
+ readonly invocation: PreparedInvocation;
183
+ readonly exactQuery: ReadProjectionQuery;
184
+ readonly resolution: ProviderPluginOperationResolutionV1 | null;
185
+ readonly surfaceId: string;
186
+ readonly omni: ProviderPluginOmniDefinitionV1 | null;
187
+ readonly sourceIdentity: OmniSourceIdentityV1 | null;
188
+ readonly omniQuery: OmniProjectionQuery | null;
189
+ readonly identityDescriptor: unknown;
190
+ };
191
+
192
+ type OmniRuntimeOptions = {
193
+ readonly environment?: Environment;
194
+ readonly registry?: ProviderPluginRegistry;
195
+ readonly now?: Date;
196
+ readonly freshForMs?: number;
197
+ };
198
+
199
+ type OmniLiveRuntimeOptions = OmniRuntimeOptions & {
200
+ readonly headed?: boolean;
201
+ readonly signal?: AbortSignal;
202
+ readonly executeRead?: typeof executeReadInvocation;
203
+ /** Internal resource budget. The product default remains the schema cap. */
204
+ readonly sourcePageLimit?: number;
205
+ };
206
+
207
+ type OmniSourceUpdateError = {
208
+ readonly exactQueryKey: string;
209
+ readonly reason: string;
210
+ };
211
+
212
+ type OmniMaterializationResult = ReturnType<typeof materializeCurrentExact>;
213
+
214
+ const EXACT_READ_ERROR_REASON = "exact provider snapshot could not be read";
215
+ const NORMALIZED_STATE_READ_ERROR_REASON = "normalized source state could not be read";
216
+ const NORMALIZED_STATE_PARSE_ERROR_REASON = "normalized source state could not be parsed";
217
+ const NORMALIZED_STATE_OBSERVE_ERROR_REASON = "normalized source state could not be observed";
218
+ const PROVIDER_READ_ERROR_REASON =
219
+ "provider read failed before the normalized source could be refreshed";
220
+ const EXACT_PUBLICATION_ERROR_REASON =
221
+ "exact provider snapshot could not be published during omni revalidation";
222
+ const NORMALIZATION_UPDATE_ERROR_REASON =
223
+ "exact provider snapshot could not be normalized";
224
+ const CONTINUATION_PREPARATION_ERROR_REASON =
225
+ "provider continuation could not be prepared from normalized state";
226
+
227
+ function parseSourcePageLimit(value: number | undefined): number {
228
+ const parsed = value ?? OMNI_MAX_SOURCE_PAGES;
229
+ if (
230
+ !Number.isSafeInteger(parsed)
231
+ || parsed < 1
232
+ || parsed > OMNI_MAX_SOURCE_PAGES
233
+ ) {
234
+ throw new Error(
235
+ `omni source page limit must be an integer from 1 through ${String(OMNI_MAX_SOURCE_PAGES)}`,
236
+ );
237
+ }
238
+ return parsed;
239
+ }
240
+
241
+ export function createOmniContinuationGuard(
242
+ rootExactQueryKey: string,
243
+ pageLimitValue?: number,
244
+ ): Readonly<{
245
+ beforeNext(): string | null;
246
+ observe(exactQueryKey: string): string | null;
247
+ }> {
248
+ const pageLimit = parseSourcePageLimit(pageLimitValue);
249
+ let pages = 1;
250
+ const visited = new Set([rootExactQueryKey]);
251
+ return Object.freeze({
252
+ beforeNext(): string | null {
253
+ return pages >= pageLimit
254
+ ? `provider continuation exceeds the ${String(pageLimit)}-page normalized capacity`
255
+ : null;
256
+ },
257
+ observe(exactQueryKey: string): string | null {
258
+ if (visited.has(exactQueryKey)) {
259
+ return "provider continuation repeated an exact page query";
260
+ }
261
+ visited.add(exactQueryKey);
262
+ pages += 1;
263
+ return null;
264
+ },
265
+ });
266
+ }
267
+
268
+ function boundedError(error: unknown): string {
269
+ const value = error instanceof Error ? error.message : String(error);
270
+ return boundedOmniText(value, OMNI_MAX_REASON_BYTES);
271
+ }
272
+
273
+ function privateDriftError(error: unknown): Error {
274
+ if (!nodeTypes.isProxy(error) && error instanceof Error) {
275
+ const descriptor = Object.getOwnPropertyDescriptor(error, "message");
276
+ if (
277
+ descriptor !== undefined
278
+ && "value" in descriptor
279
+ && typeof descriptor.value === "string"
280
+ ) {
281
+ return new Error(boundedOmniText(descriptor.value, OMNI_MAX_REASON_BYTES));
282
+ }
283
+ }
284
+ return new Error("provider materializer threw a non-Error diagnostic");
285
+ }
286
+
287
+ function internalDriftCode(
288
+ error: unknown,
289
+ ): "materializer-drift" | "capacity-exceeded" {
290
+ const message = error instanceof Error ? error.message : "";
291
+ return /(?:must be a plain array of at most \d+ items|exceeds its JSON bound|has too many properties|exceeds its (?:byte|entity, page, complete-coverage, tombstone, or normalization|normalization frontier) capacity)$/u
292
+ .test(message)
293
+ ? "capacity-exceeded"
294
+ : "materializer-drift";
295
+ }
296
+
297
+ function throwIfAborted(signal: AbortSignal | undefined): void {
298
+ if (signal?.aborted !== true) return;
299
+ throw signal.reason instanceof Error
300
+ ? signal.reason
301
+ : new DOMException("omni revalidation was aborted", "AbortError");
302
+ }
303
+
304
+ function sourceUpdateError(
305
+ source: PreparedOmniSource,
306
+ reason: string,
307
+ ): OmniSourceUpdateError {
308
+ return Object.freeze({
309
+ exactQueryKey: source.exactQuery.key,
310
+ reason,
311
+ });
312
+ }
313
+
314
+ function publicDriftReason(
315
+ source: PreparedOmniSource,
316
+ code: Extract<OmniNormalizationStatusV1, { readonly state: "drift" }>["code"],
317
+ ): string {
318
+ if (code === "capacity-exceeded") {
319
+ return `${source.surfaceId} ${source.request.operationId} normalized state exceeded its reviewed capacity`;
320
+ }
321
+ const materializer = source.omni?.state === "supported"
322
+ ? `${source.omni.materializerId}@${String(source.omni.materializerVersion)}`
323
+ : "unavailable";
324
+ return `${source.surfaceId} ${source.request.operationId} materializer ${materializer} rejected the exact provider shape`;
325
+ }
326
+
327
+ function publicCoverageReason(
328
+ kind: OmniStoredPageV1["completeness"]["kind"],
329
+ ): string {
330
+ switch (kind) {
331
+ case "complete":
332
+ return "the provider materializer declared complete partition coverage";
333
+ case "page":
334
+ return "the provider materializer declared page-scoped coverage";
335
+ case "unknown":
336
+ return "the provider materializer could not establish coverage completeness";
337
+ case "first-page-only":
338
+ return "the provider contract supports only the first observed page";
339
+ case "bounded-local":
340
+ return "the provider materializer exposed a bounded local projection";
341
+ case "search-window":
342
+ return "the provider materializer exposed a bounded search window";
343
+ case "truncated":
344
+ return "the provider materializer reported truncated coverage";
345
+ }
346
+ }
347
+
348
+ function resolvePluginOperation(
349
+ invocation: PreparedInvocation,
350
+ registry: ProviderPluginRegistry,
351
+ ): ProviderPluginOperationResolutionV1 | null {
352
+ const operation = invocation.manifest.operations[invocation.operationId];
353
+ if (operation === undefined) throw new Error("omni source operation disappeared");
354
+ if (isProviderOperation(operation)) {
355
+ return registry.requireOperationDefinition(
356
+ "provider-api",
357
+ operation.provider.provider,
358
+ operation.provider.action,
359
+ operation.provider.contractVersion,
360
+ );
361
+ }
362
+ if (isWebSessionOperation(operation)) {
363
+ const binding = registry.requireSessionRoute(operation.webSession.site);
364
+ return registry.requireOperationDefinition(
365
+ binding.transport,
366
+ operation.webSession.site,
367
+ operation.webSession.action,
368
+ operation.webSession.contractVersion,
369
+ );
370
+ }
371
+ if (isLocalCliOperation(operation)) {
372
+ return registry.requireOperationDefinition(
373
+ "local-cli",
374
+ operation.localCli.surface,
375
+ operation.localCli.action,
376
+ operation.localCli.contractVersion,
377
+ );
378
+ }
379
+ return null;
380
+ }
381
+
382
+ function materializerDescriptors(
383
+ resolution: ProviderPluginOperationResolutionV1,
384
+ ): readonly unknown[] {
385
+ return Object.freeze(resolution.binding.operations
386
+ .filter((operation) =>
387
+ operation.name === "messaging.list" || operation.name === "messaging.read")
388
+ .map((operation) => {
389
+ if (operation.omni === undefined) {
390
+ throw new Error(
391
+ `provider plugin ${resolution.plugin.id} ${resolution.binding.surfaceId}/${operation.name} is missing its required omni declaration`,
392
+ );
393
+ }
394
+ return Object.freeze({
395
+ operation: operation.name,
396
+ contractVersions: operation.contractVersions,
397
+ ...(operation.omni.state === "supported"
398
+ ? {
399
+ state: "supported" as const,
400
+ schemaVersion: operation.omni.schemaVersion,
401
+ materializerId: operation.omni.materializerId,
402
+ materializerVersion: operation.omni.materializerVersion,
403
+ }
404
+ : {
405
+ state: "unsupported" as const,
406
+ reason: operation.omni.reason,
407
+ }),
408
+ });
409
+ })
410
+ .sort((left, right) => canonicalJson(left).localeCompare(canonicalJson(right))));
411
+ }
412
+
413
+ function prepareSource(
414
+ request: OmniViewSourceRequestV1,
415
+ environment: Environment,
416
+ registry: ProviderPluginRegistry,
417
+ ): PreparedOmniSource {
418
+ const invocation = prepareInvocation(
419
+ request.adapterId,
420
+ request.operationId,
421
+ request.input,
422
+ request.authId,
423
+ environment,
424
+ registry,
425
+ );
426
+ const exactQuery = createReadProjectionQueryForInvocation(
427
+ invocation,
428
+ environment,
429
+ registry,
430
+ );
431
+ const resolution = resolvePluginOperation(invocation, registry);
432
+ if (resolution === null) {
433
+ return Object.freeze({
434
+ request,
435
+ invocation,
436
+ exactQuery,
437
+ resolution: null,
438
+ surfaceId: invocation.manifest.id,
439
+ omni: null,
440
+ sourceIdentity: null,
441
+ omniQuery: null,
442
+ identityDescriptor: Object.freeze({
443
+ request: Object.freeze({
444
+ adapterId: request.adapterId,
445
+ operationId: request.operationId,
446
+ authId: request.authId,
447
+ inputHash: exactQuery.identity.inputHash,
448
+ }),
449
+ exactQueryKey: exactQuery.key,
450
+ surfaceId: invocation.manifest.id,
451
+ materialization: Object.freeze({
452
+ state: "unsupported",
453
+ reason: "operation is not backed by a reviewed provider plugin materializer",
454
+ }),
455
+ }),
456
+ });
457
+ }
458
+ const omni = resolution.operation.omni;
459
+ if (omni === undefined) {
460
+ throw new Error(
461
+ `provider plugin ${resolution.plugin.id} ${resolution.binding.surfaceId}/${request.operationId} is missing its required omni declaration`,
462
+ );
463
+ }
464
+ const closureHash = registry.implementationClosureHash(resolution.binding);
465
+ const sourceIdentity: OmniSourceIdentityV1 = Object.freeze({
466
+ schemaVersion: 1,
467
+ adapter: exactQuery.identity.adapter,
468
+ plugin: Object.freeze({
469
+ id: resolution.plugin.id,
470
+ version: resolution.plugin.version,
471
+ closureHash,
472
+ }),
473
+ surfaceId: resolution.binding.surfaceId,
474
+ auth: exactQuery.identity.auth,
475
+ });
476
+ const descriptors = materializerDescriptors(resolution);
477
+ const aggregateIdentity = Object.freeze({
478
+ schemaVersion: 1,
479
+ surfaceId: resolution.binding.surfaceId,
480
+ plugin: sourceIdentity.plugin,
481
+ materializers: descriptors,
482
+ });
483
+ const omniContract = exactQuery.identity.contract.transport === "local-cli"
484
+ ? Object.freeze({
485
+ transport: "local-cli" as const,
486
+ hash: sha256(canonicalJson(aggregateIdentity)),
487
+ tool: exactQuery.identity.contract.tool,
488
+ })
489
+ : Object.freeze({
490
+ transport: exactQuery.identity.contract.transport,
491
+ hash: sha256(canonicalJson(aggregateIdentity)),
492
+ });
493
+ const omniQuery = createOmniProjectionQuery({
494
+ adapter: exactQuery.identity.adapter,
495
+ operation: "omni.source.v1",
496
+ input: aggregateIdentity,
497
+ inputHash: sha256(canonicalJson(aggregateIdentity)),
498
+ auth: exactQuery.identity.auth,
499
+ contract: omniContract,
500
+ }, environment);
501
+ return Object.freeze({
502
+ request,
503
+ invocation,
504
+ exactQuery,
505
+ resolution,
506
+ surfaceId: resolution.binding.surfaceId,
507
+ omni,
508
+ sourceIdentity,
509
+ omniQuery,
510
+ identityDescriptor: Object.freeze({
511
+ request: Object.freeze({
512
+ adapterId: request.adapterId,
513
+ operationId: request.operationId,
514
+ authId: request.authId,
515
+ inputHash: exactQuery.identity.inputHash,
516
+ }),
517
+ exactQueryKey: exactQuery.key,
518
+ omniQueryKey: omniQuery.key,
519
+ source: sourceIdentity,
520
+ materialization: omni.state === "supported"
521
+ ? Object.freeze({
522
+ state: "supported",
523
+ schemaVersion: omni.schemaVersion,
524
+ materializerId: omni.materializerId,
525
+ materializerVersion: omni.materializerVersion,
526
+ })
527
+ : Object.freeze({ state: "unsupported", reason: omni.reason }),
528
+ }),
529
+ });
530
+ }
531
+
532
+ function prepareSources(
533
+ requestValue: unknown,
534
+ options: OmniRuntimeOptions,
535
+ ): {
536
+ readonly request: OmniViewRequestV1;
537
+ readonly sources: readonly PreparedOmniSource[];
538
+ readonly identity: OmniViewIdentityV1;
539
+ readonly environment: Environment;
540
+ readonly registry: ProviderPluginRegistry;
541
+ } {
542
+ const request = parseOmniViewRequestV1(requestValue);
543
+ const environment = options.environment ?? process.env;
544
+ const registry = options.registry ?? providerPluginRegistry;
545
+ const sources = Object.freeze(request.sources.map((source) =>
546
+ prepareSource(source, environment, registry)));
547
+ const sourceSetDigest = sha256(canonicalJson(
548
+ sources.map((source) => source.identityDescriptor),
549
+ ));
550
+ return Object.freeze({
551
+ request,
552
+ sources,
553
+ identity: Object.freeze({
554
+ invocationDigest: sha256(canonicalJson(request)),
555
+ requestDigest: omniRequestDigest(request),
556
+ sourceSetDigest,
557
+ }),
558
+ environment,
559
+ registry,
560
+ });
561
+ }
562
+
563
+ function exactStatus(
564
+ source: PreparedOmniSource,
565
+ options: OmniRuntimeOptions,
566
+ ): {
567
+ readonly snapshot: ReadProjectionMaterializationSnapshot | null;
568
+ readonly status: OmniExactSourceStatusV1;
569
+ } {
570
+ try {
571
+ const snapshot = readReadProjectionForMaterialization(source.exactQuery, {
572
+ environment: options.environment ?? process.env,
573
+ ...(options.now === undefined ? {} : { now: options.now }),
574
+ ...(options.freshForMs === undefined ? {} : { freshForMs: options.freshForMs }),
575
+ });
576
+ if (snapshot.status === "miss") {
577
+ return Object.freeze({
578
+ snapshot,
579
+ status: Object.freeze({ state: "miss", key: snapshot.key }),
580
+ });
581
+ }
582
+ return Object.freeze({
583
+ snapshot,
584
+ status: Object.freeze({
585
+ state: "hit",
586
+ key: snapshot.key,
587
+ dataRevision: snapshot.dataRevision,
588
+ validatedAt: snapshot.validatedAt,
589
+ ageMs: snapshot.ageMs,
590
+ freshness: snapshot.freshness,
591
+ }),
592
+ });
593
+ } catch {
594
+ return Object.freeze({
595
+ snapshot: null,
596
+ status: Object.freeze({
597
+ state: "error",
598
+ key: source.exactQuery.key,
599
+ reason: EXACT_READ_ERROR_REASON,
600
+ }),
601
+ });
602
+ }
603
+ }
604
+
605
+ function sameExactHead(
606
+ left: ReadProjectionMaterializationSnapshot,
607
+ right: ReadProjectionMaterializationSnapshot,
608
+ ): boolean {
609
+ return left.status === right.status
610
+ && (
611
+ left.status === "miss"
612
+ || (
613
+ right.status === "hit"
614
+ && left.storageRevisionId === right.storageRevisionId
615
+ && left.dataRevision === right.dataRevision
616
+ && left.runId === right.runId
617
+ )
618
+ );
619
+ }
620
+
621
+ function provenance(
622
+ source: PreparedOmniSource,
623
+ exact: Extract<ReadProjectionMaterializationSnapshot, { readonly status: "hit" }>,
624
+ ): OmniPageProvenanceV1 {
625
+ if (source.omni?.state !== "supported") {
626
+ throw new Error("unsupported omni source cannot produce provenance");
627
+ }
628
+ return Object.freeze({
629
+ operation: source.request.operationId,
630
+ inputHash: source.exactQuery.identity.inputHash,
631
+ exactQueryKey: source.exactQuery.key,
632
+ exactDataRevision: exact.dataRevision,
633
+ validatedAt: exact.validatedAt,
634
+ startedAt: exact.startedAt,
635
+ finishedAt: exact.finishedAt,
636
+ runId: exact.runId,
637
+ materializerId: source.omni.materializerId,
638
+ materializerVersion: source.omni.materializerVersion,
639
+ });
640
+ }
641
+
642
+ function exactHeadFence(
643
+ source: PreparedOmniSource,
644
+ exact: Extract<ReadProjectionMaterializationSnapshot, { readonly status: "hit" }>,
645
+ ): ReadProjectionExactHeadFence {
646
+ return Object.freeze({
647
+ query: source.exactQuery,
648
+ storageRevisionId: exact.storageRevisionId,
649
+ dataRevision: exact.dataRevision,
650
+ runId: exact.runId,
651
+ });
652
+ }
653
+
654
+ function assertCurrentAuthLifetime(
655
+ source: PreparedOmniSource,
656
+ environment: Environment,
657
+ ): void {
658
+ const expected = source.invocation.readProjectionAuthIdentityHash;
659
+ if (expected === undefined) {
660
+ throw new Error("prepared omni source is missing its auth lifetime identity");
661
+ }
662
+ const snapshot = loadAuthSnapshotIfPresent(source.invocation.auth.id, environment);
663
+ if (snapshot === null) {
664
+ throw new Error(`auth locator ${source.invocation.auth.id} was removed`);
665
+ }
666
+ const contentHash = sha256(canonicalJson(snapshot.auth));
667
+ const current = projectionAuthIdentityHash(
668
+ snapshot.auth.id,
669
+ contentHash,
670
+ environment,
671
+ );
672
+ if (
673
+ current !== expected
674
+ || source.exactQuery.identity.auth.hash !== expected
675
+ || snapshot.auth.subject !== source.invocation.auth.subject
676
+ ) {
677
+ throw new Error(
678
+ `auth locator ${source.invocation.auth.id} changed since this omni source was prepared`,
679
+ );
680
+ }
681
+ }
682
+
683
+ function markDrift(
684
+ source: PreparedOmniSource,
685
+ exact: Extract<ReadProjectionMaterializationSnapshot, { readonly status: "hit" }>,
686
+ error: unknown,
687
+ options: OmniRuntimeOptions,
688
+ code: "materializer-drift" | "capacity-exceeded",
689
+ ): void {
690
+ if (source.omniQuery === null || source.sourceIdentity === null) {
691
+ throw new Error("unsupported omni source cannot retain drift state");
692
+ }
693
+ const privateError = privateDriftError(error);
694
+ reduceOmniProjection(source.omniQuery, (current) =>
695
+ markOmniSourceDriftV1(current, {
696
+ source: source.sourceIdentity!,
697
+ exactQueryKey: source.exactQuery.key,
698
+ exactDataRevision: exact.dataRevision,
699
+ failedAt: (options.now ?? new Date()).toISOString(),
700
+ error: privateError,
701
+ code,
702
+ }), {
703
+ environment: options.environment ?? process.env,
704
+ ...(options.now === undefined ? {} : { now: options.now }),
705
+ exactHead: exactHeadFence(source, exact),
706
+ assertCurrent: () => assertCurrentAuthLifetime(
707
+ source,
708
+ options.environment ?? process.env,
709
+ ),
710
+ });
711
+ }
712
+
713
+ function materializeCurrentExact(
714
+ source: PreparedOmniSource,
715
+ options: OmniRuntimeOptions,
716
+ ):
717
+ | { readonly state: "missing" }
718
+ | {
719
+ readonly state: "materialized";
720
+ readonly page: ReturnType<typeof parseMaterializedPageV1>;
721
+ }
722
+ | { readonly state: "drift" } {
723
+ if (
724
+ source.omni?.state !== "supported"
725
+ || source.omniQuery === null
726
+ || source.sourceIdentity === null
727
+ ) return Object.freeze({ state: "missing" });
728
+ for (let attempt = 0; attempt < MAX_MATERIALIZATION_SETTLEMENT_ATTEMPTS; attempt += 1) {
729
+ const before = readReadProjectionForMaterialization(source.exactQuery, {
730
+ environment: options.environment ?? process.env,
731
+ ...(options.now === undefined ? {} : { now: options.now }),
732
+ ...(options.freshForMs === undefined ? {} : { freshForMs: options.freshForMs }),
733
+ });
734
+ if (before.status === "miss") return Object.freeze({ state: "missing" });
735
+ let page: ReturnType<typeof parseMaterializedPageV1> | null = null;
736
+ let materializerError: unknown = null;
737
+ let driftCode: "materializer-drift" | "capacity-exceeded" =
738
+ "materializer-drift";
739
+ let materializedOutput: unknown;
740
+ try {
741
+ materializedOutput = source.omni.materialize(
742
+ source.invocation.input,
743
+ before.output,
744
+ );
745
+ } catch (error) {
746
+ materializerError = error;
747
+ }
748
+ if (materializerError === null) {
749
+ try {
750
+ page = parseMaterializedPageV1(materializedOutput);
751
+ } catch (error) {
752
+ materializerError = error;
753
+ driftCode = internalDriftCode(error);
754
+ }
755
+ }
756
+ const fenced = readReadProjectionForMaterialization(source.exactQuery, {
757
+ environment: options.environment ?? process.env,
758
+ ...(options.now === undefined ? {} : { now: options.now }),
759
+ ...(options.freshForMs === undefined ? {} : { freshForMs: options.freshForMs }),
760
+ });
761
+ if (!sameExactHead(before, fenced)) continue;
762
+ if (materializerError !== null || page === null) {
763
+ try {
764
+ markDrift(source, before, materializerError, options, driftCode);
765
+ } catch (error) {
766
+ const changed = readReadProjectionForMaterialization(source.exactQuery, {
767
+ environment: options.environment ?? process.env,
768
+ ...(options.now === undefined ? {} : { now: options.now }),
769
+ ...(options.freshForMs === undefined
770
+ ? {}
771
+ : { freshForMs: options.freshForMs }),
772
+ });
773
+ if (!sameExactHead(before, changed)) continue;
774
+ throw error;
775
+ }
776
+ } else {
777
+ try {
778
+ const pageProvenance = provenance(source, before);
779
+ reduceOmniProjection(source.omniQuery, (current) =>
780
+ reduceOmniSourceStateV1(current, page, {
781
+ source: source.sourceIdentity!,
782
+ provenance: pageProvenance,
783
+ }), {
784
+ environment: options.environment ?? process.env,
785
+ ...(options.now === undefined ? {} : { now: options.now }),
786
+ exactHead: exactHeadFence(source, before),
787
+ assertCurrent: () => assertCurrentAuthLifetime(
788
+ source,
789
+ options.environment ?? process.env,
790
+ ),
791
+ });
792
+ } catch (error) {
793
+ const changed = readReadProjectionForMaterialization(source.exactQuery, {
794
+ environment: options.environment ?? process.env,
795
+ ...(options.now === undefined ? {} : { now: options.now }),
796
+ ...(options.freshForMs === undefined
797
+ ? {}
798
+ : { freshForMs: options.freshForMs }),
799
+ });
800
+ if (!sameExactHead(before, changed)) continue;
801
+ markDrift(
802
+ source,
803
+ before,
804
+ error,
805
+ options,
806
+ internalDriftCode(error),
807
+ );
808
+ materializerError = error;
809
+ }
810
+ }
811
+ const after = readReadProjectionForMaterialization(source.exactQuery, {
812
+ environment: options.environment ?? process.env,
813
+ ...(options.now === undefined ? {} : { now: options.now }),
814
+ ...(options.freshForMs === undefined ? {} : { freshForMs: options.freshForMs }),
815
+ });
816
+ if (!sameExactHead(before, after)) continue;
817
+ return materializerError === null && page !== null
818
+ ? Object.freeze({ state: "materialized" as const, page })
819
+ : Object.freeze({ state: "drift" as const });
820
+ }
821
+ throw new Error(
822
+ `exact projection ${source.exactQuery.key} did not settle while its normalized derivative was being updated`,
823
+ );
824
+ }
825
+
826
+ function prepareContinuationSource(
827
+ parent: PreparedOmniSource,
828
+ nextInput: Readonly<Record<string, OmniJsonValue>>,
829
+ prepared: ReturnType<typeof prepareSources>,
830
+ ): PreparedOmniSource {
831
+ const continuation = prepareSource(Object.freeze({
832
+ adapterId: parent.request.adapterId,
833
+ operationId: parent.request.operationId,
834
+ authId: parent.request.authId,
835
+ input: nextInput,
836
+ }), prepared.environment, prepared.registry);
837
+ if (
838
+ parent.omni?.state !== "supported"
839
+ || continuation.omni?.state !== "supported"
840
+ || parent.omni.materializerId !== continuation.omni.materializerId
841
+ || parent.omni.materializerVersion !== continuation.omni.materializerVersion
842
+ || parent.omniQuery === null
843
+ || continuation.omniQuery === null
844
+ || parent.omniQuery.key !== continuation.omniQuery.key
845
+ || parent.sourceIdentity === null
846
+ || continuation.sourceIdentity === null
847
+ || canonicalJson(parent.sourceIdentity)
848
+ !== canonicalJson(continuation.sourceIdentity)
849
+ ) {
850
+ throw new Error(
851
+ "provider continuation crossed its source, materializer, or auth identity",
852
+ );
853
+ }
854
+ return continuation;
855
+ }
856
+
857
+ function rebuildExactContinuationChain(
858
+ root: PreparedOmniSource,
859
+ prepared: ReturnType<typeof prepareSources>,
860
+ options: OmniRuntimeOptions,
861
+ ): OmniSourceUpdateError | undefined {
862
+ let current = root;
863
+ let materialized: OmniMaterializationResult;
864
+ try {
865
+ materialized = materializeCurrentExact(current, options);
866
+ } catch {
867
+ return sourceUpdateError(current, NORMALIZATION_UPDATE_ERROR_REASON);
868
+ }
869
+ const guard = createOmniContinuationGuard(root.exactQuery.key);
870
+ for (; materialized.state === "materialized";) {
871
+ const nextInput = materialized.page.cursor.nextInput;
872
+ if (nextInput === null) return undefined;
873
+ const capacityReason = guard.beforeNext();
874
+ if (capacityReason !== null) return sourceUpdateError(current, capacityReason);
875
+ let continuation: PreparedOmniSource;
876
+ try {
877
+ continuation = prepareContinuationSource(root, nextInput, prepared);
878
+ } catch {
879
+ return sourceUpdateError(current, CONTINUATION_PREPARATION_ERROR_REASON);
880
+ }
881
+ const repeatedReason = guard.observe(continuation.exactQuery.key);
882
+ if (repeatedReason !== null) {
883
+ return sourceUpdateError(continuation, repeatedReason);
884
+ }
885
+ current = continuation;
886
+ try {
887
+ materialized = materializeCurrentExact(current, options);
888
+ } catch {
889
+ return sourceUpdateError(current, NORMALIZATION_UPDATE_ERROR_REASON);
890
+ }
891
+ }
892
+ return undefined;
893
+ }
894
+
895
+ type OmniSourceRevalidation =
896
+ | {
897
+ readonly state: "observed";
898
+ readonly materialized: OmniMaterializationResult;
899
+ readonly error?: string;
900
+ }
901
+ | {
902
+ readonly state: "failed";
903
+ readonly error: string;
904
+ };
905
+
906
+ async function revalidateOneOmniSource(
907
+ source: PreparedOmniSource,
908
+ prepared: ReturnType<typeof prepareSources>,
909
+ options: OmniLiveRuntimeOptions,
910
+ ): Promise<OmniSourceRevalidation> {
911
+ let live;
912
+ try {
913
+ live = await revalidatePreparedCapability(source.invocation, {
914
+ environment: prepared.environment,
915
+ registry: prepared.registry,
916
+ headed: options.headed ?? false,
917
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
918
+ ...(options.now === undefined ? {} : { now: options.now }),
919
+ ...(options.freshForMs === undefined
920
+ ? {}
921
+ : { freshForMs: options.freshForMs }),
922
+ ...(options.executeRead === undefined
923
+ ? {}
924
+ : { executeRead: options.executeRead }),
925
+ });
926
+ } catch {
927
+ throwIfAborted(options.signal);
928
+ return Object.freeze({
929
+ state: "failed" as const,
930
+ error: PROVIDER_READ_ERROR_REASON,
931
+ });
932
+ }
933
+ throwIfAborted(options.signal);
934
+ const error = live.live.receipt.status !== "succeeded"
935
+ ? PROVIDER_READ_ERROR_REASON
936
+ : live.cache.status === "error"
937
+ ? EXACT_PUBLICATION_ERROR_REASON
938
+ : undefined;
939
+ if (error !== undefined) {
940
+ return Object.freeze({ state: "failed" as const, error });
941
+ }
942
+ let materialized: OmniMaterializationResult;
943
+ try {
944
+ materialized = materializeCurrentExact(source, options);
945
+ } catch {
946
+ throwIfAborted(options.signal);
947
+ return Object.freeze({
948
+ state: "failed" as const,
949
+ error: NORMALIZATION_UPDATE_ERROR_REASON,
950
+ });
951
+ }
952
+ return Object.freeze({
953
+ state: "observed" as const,
954
+ materialized,
955
+ ...(error === undefined ? {} : { error }),
956
+ });
957
+ }
958
+
959
+ async function revalidateOmniSourceChain(
960
+ root: PreparedOmniSource,
961
+ prepared: ReturnType<typeof prepareSources>,
962
+ options: OmniLiveRuntimeOptions,
963
+ ): Promise<OmniSourceUpdateError | undefined> {
964
+ const guard = createOmniContinuationGuard(
965
+ root.exactQuery.key,
966
+ options.sourcePageLimit,
967
+ );
968
+ let observed = await revalidateOneOmniSource(root, prepared, options);
969
+ throwIfAborted(options.signal);
970
+ if (observed.state === "failed") {
971
+ return sourceUpdateError(root, observed.error);
972
+ }
973
+ if (observed.error !== undefined) {
974
+ return sourceUpdateError(root, observed.error);
975
+ }
976
+ let current = root;
977
+ for (; observed.materialized.state === "materialized";) {
978
+ throwIfAborted(options.signal);
979
+ const nextInput = observed.materialized.page.cursor.nextInput;
980
+ if (nextInput === null) return undefined;
981
+ const capacityReason = guard.beforeNext();
982
+ if (capacityReason !== null) return sourceUpdateError(current, capacityReason);
983
+ let continuation: PreparedOmniSource;
984
+ try {
985
+ continuation = prepareContinuationSource(root, nextInput, prepared);
986
+ } catch {
987
+ return sourceUpdateError(current, CONTINUATION_PREPARATION_ERROR_REASON);
988
+ }
989
+ const repeatedReason = guard.observe(continuation.exactQuery.key);
990
+ if (repeatedReason !== null) {
991
+ return Object.freeze({
992
+ exactQueryKey: continuation.exactQuery.key,
993
+ reason: repeatedReason,
994
+ });
995
+ }
996
+ current = continuation;
997
+ observed = await revalidateOneOmniSource(continuation, prepared, options);
998
+ throwIfAborted(options.signal);
999
+ if (observed.state === "failed") {
1000
+ return sourceUpdateError(continuation, observed.error);
1001
+ }
1002
+ if (observed.error !== undefined) {
1003
+ return sourceUpdateError(continuation, observed.error);
1004
+ }
1005
+ }
1006
+ return undefined;
1007
+ }
1008
+
1009
+ type StoredOmniChainObservation = {
1010
+ readonly coverage: OmniSourceCoverageV1;
1011
+ readonly frontiers: readonly {
1012
+ readonly exactQueryKey: string;
1013
+ readonly status: OmniNormalizationStatusV1;
1014
+ }[];
1015
+ readonly exact: readonly {
1016
+ readonly exactQueryKey: string;
1017
+ readonly status: OmniExactSourceStatusV1;
1018
+ }[];
1019
+ readonly issue: StoredOmniStaleEvidence | null;
1020
+ };
1021
+
1022
+ type StoredOmniStaleEvidence = {
1023
+ readonly exactQueryKey: string;
1024
+ readonly exactDataRevision: string | null;
1025
+ readonly normalizedExactDataRevision: string | null;
1026
+ readonly lastGoodAt: string | null;
1027
+ readonly reason: string;
1028
+ };
1029
+
1030
+ function normalizationFrontier(
1031
+ state: OmniSourceStateV1,
1032
+ exactQueryKey: string,
1033
+ ) {
1034
+ return state.normalization.find((entry) =>
1035
+ entry.exactQueryKey === exactQueryKey) ?? null;
1036
+ }
1037
+
1038
+ function pageForExactQuery(
1039
+ state: OmniSourceStateV1,
1040
+ exactQueryKey: string,
1041
+ ): OmniStoredPageV1 | null {
1042
+ const pages = state.pages.filter((page) =>
1043
+ page.provenance.exactQueryKey === exactQueryKey);
1044
+ if (pages.length > 1) {
1045
+ throw new Error(
1046
+ "normalized state retained multiple pages for one exact provider query",
1047
+ );
1048
+ }
1049
+ return pages[0] ?? null;
1050
+ }
1051
+
1052
+ function staleEvidence(
1053
+ exactQueryKey: string,
1054
+ frontier: ReturnType<typeof normalizationFrontier>,
1055
+ exact: OmniExactSourceStatusV1,
1056
+ reason: string,
1057
+ options: { readonly omitExactRevision?: boolean } = {},
1058
+ ): StoredOmniStaleEvidence {
1059
+ const normalizedExactDataRevision = frontier === null
1060
+ ? null
1061
+ : frontier.status.state === "ready"
1062
+ ? frontier.status.exactDataRevision
1063
+ : frontier.status.lastGoodExactDataRevision;
1064
+ return Object.freeze({
1065
+ exactQueryKey,
1066
+ exactDataRevision: options.omitExactRevision === true
1067
+ ? null
1068
+ : exact.state === "hit"
1069
+ ? exact.dataRevision
1070
+ : null,
1071
+ normalizedExactDataRevision,
1072
+ lastGoodAt: frontier?.status.lastGoodAt ?? null,
1073
+ reason: boundedError(reason),
1074
+ });
1075
+ }
1076
+
1077
+ function observeStoredOmniChain(
1078
+ root: PreparedOmniSource,
1079
+ state: OmniSourceStateV1,
1080
+ prepared: ReturnType<typeof prepareSources>,
1081
+ options: OmniRuntimeOptions,
1082
+ rootExact: OmniExactSourceStatusV1,
1083
+ ): StoredOmniChainObservation {
1084
+ let current = root;
1085
+ const visited = new Set<string>();
1086
+ const frontiers: {
1087
+ readonly exactQueryKey: string;
1088
+ readonly status: OmniNormalizationStatusV1;
1089
+ }[] = [];
1090
+ const exact: {
1091
+ readonly exactQueryKey: string;
1092
+ readonly status: OmniExactSourceStatusV1;
1093
+ }[] = [];
1094
+ let rootPage: OmniStoredPageV1 | null = null;
1095
+ let issue: StoredOmniStaleEvidence | null = null;
1096
+ for (let pages = 0; pages < OMNI_MAX_SOURCE_PAGES; pages += 1) {
1097
+ if (visited.has(current.exactQuery.key)) {
1098
+ const reason = "normalized provider continuation repeats an exact page query";
1099
+ const frontier = normalizationFrontier(state, current.exactQuery.key);
1100
+ const currentExact = exact.find((entry) =>
1101
+ entry.exactQueryKey === current.exactQuery.key)?.status
1102
+ ?? exactStatus(current, options).status;
1103
+ return Object.freeze({
1104
+ coverage: Object.freeze({ state: "unavailable" as const, reason }),
1105
+ frontiers: Object.freeze(frontiers),
1106
+ exact: Object.freeze(exact),
1107
+ issue: staleEvidence(
1108
+ current.exactQuery.key,
1109
+ frontier,
1110
+ currentExact,
1111
+ reason,
1112
+ ),
1113
+ });
1114
+ }
1115
+ visited.add(current.exactQuery.key);
1116
+ const frontier = normalizationFrontier(state, current.exactQuery.key);
1117
+ const page = pageForExactQuery(state, current.exactQuery.key);
1118
+ if (frontier !== null) frontiers.push(frontier);
1119
+ const currentExact = current.exactQuery.key === root.exactQuery.key
1120
+ ? rootExact
1121
+ : exactStatus(current, options).status;
1122
+ exact.push(Object.freeze({
1123
+ exactQueryKey: current.exactQuery.key,
1124
+ status: currentExact,
1125
+ }));
1126
+ if (frontier?.status.state === "ready") {
1127
+ if (
1128
+ current.exactQuery.key !== root.exactQuery.key
1129
+ && currentExact.state === "hit"
1130
+ && currentExact.freshness.state === "stale"
1131
+ ) {
1132
+ issue ??= staleEvidence(
1133
+ current.exactQuery.key,
1134
+ frontier,
1135
+ currentExact,
1136
+ "a provider continuation exact snapshot is stale",
1137
+ );
1138
+ } else if (
1139
+ currentExact.state === "hit"
1140
+ && currentExact.dataRevision !== frontier.status.exactDataRevision
1141
+ ) {
1142
+ issue ??= staleEvidence(
1143
+ current.exactQuery.key,
1144
+ frontier,
1145
+ currentExact,
1146
+ current.exactQuery.key === root.exactQuery.key
1147
+ ? "the normalized derivative has not observed the current exact revision"
1148
+ : "a provider continuation exact snapshot is newer than its normalized frontier",
1149
+ );
1150
+ } else if (currentExact.state === "miss") {
1151
+ issue ??= staleEvidence(
1152
+ current.exactQuery.key,
1153
+ frontier,
1154
+ currentExact,
1155
+ current.exactQuery.key === root.exactQuery.key
1156
+ ? "the exact provider snapshot is unavailable"
1157
+ : "a normalized provider continuation has no exact snapshot",
1158
+ );
1159
+ } else if (currentExact.state === "error") {
1160
+ issue ??= staleEvidence(
1161
+ current.exactQuery.key,
1162
+ frontier,
1163
+ currentExact,
1164
+ currentExact.reason,
1165
+ );
1166
+ }
1167
+ }
1168
+ if (frontier === null || page === null) {
1169
+ if (frontier?.status.state !== "drift") {
1170
+ issue ??= staleEvidence(
1171
+ current.exactQuery.key,
1172
+ frontier,
1173
+ currentExact,
1174
+ frontier === null
1175
+ ? "a provider continuation has not reached a normalized frontier"
1176
+ : "a normalized provider continuation has no retained page",
1177
+ );
1178
+ }
1179
+ if (rootPage === null) {
1180
+ const reason = frontier === null
1181
+ ? "the requested exact query has no normalized frontier"
1182
+ : "the requested exact query has no retained normalized page";
1183
+ return Object.freeze({
1184
+ coverage: Object.freeze({ state: "unavailable" as const, reason }),
1185
+ frontiers: Object.freeze(frontiers),
1186
+ exact: Object.freeze(exact),
1187
+ issue,
1188
+ });
1189
+ }
1190
+ return Object.freeze({
1191
+ coverage: Object.freeze({
1192
+ state: "observed" as const,
1193
+ kind: rootPage.completeness.kind,
1194
+ continuation: "pending" as const,
1195
+ reason: publicCoverageReason(rootPage.completeness.kind),
1196
+ }),
1197
+ frontiers: Object.freeze(frontiers),
1198
+ exact: Object.freeze(exact),
1199
+ issue,
1200
+ });
1201
+ }
1202
+ rootPage ??= page;
1203
+ if (page.cursor.nextInput === null) {
1204
+ const continuation = page.completeness.kind === "complete"
1205
+ || page.completeness.kind === "page"
1206
+ ? "none" as const
1207
+ : "unavailable" as const;
1208
+ return Object.freeze({
1209
+ coverage: Object.freeze({
1210
+ state: "observed" as const,
1211
+ kind: rootPage.completeness.kind,
1212
+ continuation,
1213
+ reason: publicCoverageReason(rootPage.completeness.kind),
1214
+ }),
1215
+ frontiers: Object.freeze(frontiers),
1216
+ exact: Object.freeze(exact),
1217
+ issue,
1218
+ });
1219
+ }
1220
+ try {
1221
+ current = prepareContinuationSource(root, page.cursor.nextInput, prepared);
1222
+ } catch {
1223
+ const reason = CONTINUATION_PREPARATION_ERROR_REASON;
1224
+ return Object.freeze({
1225
+ coverage: Object.freeze({ state: "unavailable" as const, reason }),
1226
+ frontiers: Object.freeze(frontiers),
1227
+ exact: Object.freeze(exact),
1228
+ issue: issue ?? staleEvidence(
1229
+ current.exactQuery.key,
1230
+ frontier,
1231
+ currentExact,
1232
+ reason,
1233
+ ),
1234
+ });
1235
+ }
1236
+ }
1237
+ const reason = `normalized provider continuation exceeds the ${String(OMNI_MAX_SOURCE_PAGES)}-page capacity`;
1238
+ return Object.freeze({
1239
+ coverage: Object.freeze({ state: "unavailable" as const, reason }),
1240
+ frontiers: Object.freeze(frontiers),
1241
+ exact: Object.freeze(exact),
1242
+ issue: issue ?? staleEvidence(
1243
+ current.exactQuery.key,
1244
+ normalizationFrontier(state, current.exactQuery.key),
1245
+ exactStatus(current, options).status,
1246
+ reason,
1247
+ ),
1248
+ });
1249
+ }
1250
+
1251
+ function sourceState(
1252
+ source: PreparedOmniSource,
1253
+ prepared: ReturnType<typeof prepareSources>,
1254
+ options: OmniRuntimeOptions,
1255
+ updateError: OmniSourceUpdateError | undefined,
1256
+ ): {
1257
+ readonly status: OmniViewSourceStatusV1;
1258
+ readonly state: OmniSourceStateV1 | null;
1259
+ } {
1260
+ const exact = exactStatus(source, options).status;
1261
+ const common = Object.freeze({
1262
+ adapterId: source.request.adapterId,
1263
+ operationId: source.request.operationId,
1264
+ authId: source.request.authId,
1265
+ requestInputHash: sha256(canonicalJson(source.request.input)),
1266
+ projectionInputHash: source.exactQuery.identity.inputHash,
1267
+ normalizationDataRevision: null,
1268
+ surfaceId: source.surfaceId,
1269
+ exact,
1270
+ });
1271
+ if (source.omni === null || source.omni.state === "unsupported") {
1272
+ const reason = source.omni?.state === "unsupported"
1273
+ ? source.omni.reason
1274
+ : "operation is not backed by a reviewed provider plugin materializer";
1275
+ return Object.freeze({
1276
+ state: null,
1277
+ status: Object.freeze({
1278
+ ...common,
1279
+ normalization: Object.freeze({
1280
+ state: "unsupported",
1281
+ reason,
1282
+ }),
1283
+ coverage: Object.freeze({ state: "unavailable", reason }),
1284
+ }),
1285
+ });
1286
+ }
1287
+ if (source.omniQuery === null) throw new Error("supported omni source has no private query");
1288
+ let cached;
1289
+ try {
1290
+ cached = readOmniProjection(source.omniQuery, {
1291
+ environment: options.environment ?? process.env,
1292
+ ...(options.now === undefined ? {} : { now: options.now }),
1293
+ ...(options.freshForMs === undefined ? {} : { freshForMs: options.freshForMs }),
1294
+ });
1295
+ } catch {
1296
+ const reason = NORMALIZED_STATE_READ_ERROR_REASON;
1297
+ return Object.freeze({
1298
+ state: null,
1299
+ status: Object.freeze({
1300
+ ...common,
1301
+ normalization: Object.freeze({
1302
+ state: "error",
1303
+ reason,
1304
+ lastGoodAt: null,
1305
+ }),
1306
+ coverage: Object.freeze({ state: "unavailable", reason }),
1307
+ }),
1308
+ });
1309
+ }
1310
+ if (cached.status === "miss") {
1311
+ const reason = updateError?.reason
1312
+ ?? "the requested source has no normalized state";
1313
+ return Object.freeze({
1314
+ state: null,
1315
+ status: Object.freeze({
1316
+ ...common,
1317
+ normalization: updateError === undefined
1318
+ ? Object.freeze({ state: "missing" })
1319
+ : Object.freeze({
1320
+ state: "error",
1321
+ reason: updateError.reason,
1322
+ lastGoodAt: null,
1323
+ }),
1324
+ coverage: Object.freeze({ state: "unavailable", reason }),
1325
+ }),
1326
+ });
1327
+ }
1328
+ const normalizedCommon = Object.freeze({
1329
+ ...common,
1330
+ normalizationDataRevision: cached.dataRevision,
1331
+ });
1332
+ let state: OmniSourceStateV1;
1333
+ try {
1334
+ state = parseOmniSourceStateV1(cached.output);
1335
+ } catch {
1336
+ const reason = NORMALIZED_STATE_PARSE_ERROR_REASON;
1337
+ return Object.freeze({
1338
+ state: null,
1339
+ status: Object.freeze({
1340
+ ...normalizedCommon,
1341
+ normalization: Object.freeze({
1342
+ state: "error",
1343
+ reason,
1344
+ lastGoodAt: null,
1345
+ }),
1346
+ coverage: Object.freeze({ state: "unavailable", reason }),
1347
+ }),
1348
+ });
1349
+ }
1350
+ let chain: StoredOmniChainObservation;
1351
+ try {
1352
+ chain = observeStoredOmniChain(source, state, prepared, options, exact);
1353
+ } catch {
1354
+ const reason = NORMALIZED_STATE_OBSERVE_ERROR_REASON;
1355
+ return Object.freeze({
1356
+ state: null,
1357
+ status: Object.freeze({
1358
+ ...normalizedCommon,
1359
+ normalization: Object.freeze({
1360
+ state: "error",
1361
+ reason,
1362
+ lastGoodAt: null,
1363
+ }),
1364
+ coverage: Object.freeze({ state: "unavailable", reason }),
1365
+ }),
1366
+ });
1367
+ }
1368
+ const rootFrontier = normalizationFrontier(state, source.exactQuery.key);
1369
+ const exactForQuery = (exactQueryKey: string): OmniExactSourceStatusV1 =>
1370
+ exactQueryKey === source.exactQuery.key
1371
+ ? exact
1372
+ : chain.exact.find((entry) =>
1373
+ entry.exactQueryKey === exactQueryKey)?.status
1374
+ ?? Object.freeze({ state: "miss", key: exactQueryKey });
1375
+ let normalization: OmniNormalizationSourceStatusV1;
1376
+ const drift = chain.frontiers.find((entry) =>
1377
+ entry.status.state === "drift");
1378
+ const chainPosition = (exactQueryKey: string): number => {
1379
+ const index = chain.exact.findIndex((entry) =>
1380
+ entry.exactQueryKey === exactQueryKey);
1381
+ if (index >= 0) return index;
1382
+ return exactQueryKey === source.exactQuery.key ? 0 : chain.exact.length;
1383
+ };
1384
+ const driftPosition = drift === undefined
1385
+ ? Number.POSITIVE_INFINITY
1386
+ : chainPosition(drift.exactQueryKey);
1387
+ const issuePosition = chain.issue === null
1388
+ ? Number.POSITIVE_INFINITY
1389
+ : chainPosition(chain.issue.exactQueryKey);
1390
+ const updatePosition = updateError === undefined
1391
+ ? Number.POSITIVE_INFINITY
1392
+ : chainPosition(updateError.exactQueryKey);
1393
+ if (
1394
+ drift?.status.state === "drift"
1395
+ && driftPosition <= issuePosition
1396
+ && driftPosition < updatePosition
1397
+ ) {
1398
+ const driftExact = exactForQuery(drift.exactQueryKey);
1399
+ normalization = Object.freeze({
1400
+ state: "retained-after-drift",
1401
+ exactQueryKey: drift.exactQueryKey,
1402
+ reason: publicDriftReason(source, drift.status.code),
1403
+ failedExactDataRevision: drift.status.exactDataRevision,
1404
+ newerExactDataRevision: driftExact.state === "hit"
1405
+ && driftExact.dataRevision !== drift.status.exactDataRevision
1406
+ ? driftExact.dataRevision
1407
+ : null,
1408
+ lastGoodExactDataRevision: drift.status.lastGoodExactDataRevision,
1409
+ lastGoodAt: drift.status.lastGoodAt,
1410
+ });
1411
+ } else if (
1412
+ chain.issue !== null
1413
+ && issuePosition < updatePosition
1414
+ ) {
1415
+ normalization = Object.freeze({ state: "stale", ...chain.issue });
1416
+ } else if (updateError !== undefined) {
1417
+ const updateFrontier = normalizationFrontier(
1418
+ state,
1419
+ updateError.exactQueryKey,
1420
+ );
1421
+ const updateExact = exactForQuery(updateError.exactQueryKey);
1422
+ const normalizedUpdateRevision = updateFrontier === null
1423
+ ? null
1424
+ : updateFrontier.status.state === "ready"
1425
+ ? updateFrontier.status.exactDataRevision
1426
+ : updateFrontier.status.lastGoodExactDataRevision;
1427
+ const evidence = staleEvidence(
1428
+ updateError.exactQueryKey,
1429
+ updateFrontier,
1430
+ updateExact,
1431
+ updateError.reason,
1432
+ {
1433
+ omitExactRevision: updateExact.state !== "hit"
1434
+ || updateExact.dataRevision === normalizedUpdateRevision,
1435
+ },
1436
+ );
1437
+ normalization = Object.freeze({ state: "stale", ...evidence });
1438
+ } else if (rootFrontier === null) {
1439
+ normalization = Object.freeze({ state: "missing" });
1440
+ } else {
1441
+ if (rootFrontier.status.state !== "ready") {
1442
+ throw new Error("normalized root drift was omitted from its observed chain");
1443
+ }
1444
+ normalization = Object.freeze({
1445
+ state: "current",
1446
+ exactQueryKey: source.exactQuery.key,
1447
+ exactDataRevision: rootFrontier.status.exactDataRevision,
1448
+ lastGoodAt: rootFrontier.status.lastGoodAt,
1449
+ });
1450
+ }
1451
+ return Object.freeze({
1452
+ state,
1453
+ status: Object.freeze({
1454
+ ...normalizedCommon,
1455
+ normalization,
1456
+ coverage: chain.coverage,
1457
+ }),
1458
+ });
1459
+ }
1460
+
1461
+ function view(
1462
+ prepared: ReturnType<typeof prepareSources>,
1463
+ options: OmniRuntimeOptions,
1464
+ updateErrors: ReadonlyMap<string, OmniSourceUpdateError> = new Map(),
1465
+ ): OmniViewV1 {
1466
+ const observed = prepared.sources.map((source) => sourceState(
1467
+ source,
1468
+ prepared,
1469
+ options,
1470
+ updateErrors.get(canonicalJson(source.request)),
1471
+ ));
1472
+ const uniqueStates = new Map<string, OmniSourceStateV1>();
1473
+ for (let index = 0; index < observed.length; index += 1) {
1474
+ const state = observed[index]?.state;
1475
+ const query = prepared.sources[index]?.omniQuery;
1476
+ if (state !== null && state !== undefined && query !== null && query !== undefined) {
1477
+ uniqueStates.set(query.key, state);
1478
+ }
1479
+ }
1480
+ const entities = queryOmniSourceStatesV1(
1481
+ [...uniqueStates.values()],
1482
+ prepared.request.filter,
1483
+ );
1484
+ const viewRevision = sha256(canonicalJson({
1485
+ schemaVersion: 1,
1486
+ requestDigest: prepared.identity.requestDigest,
1487
+ sourceSetDigest: prepared.identity.sourceSetDigest,
1488
+ entities: entities.map((entity) => Object.freeze({ id: entity.id, revision: entity.revision })),
1489
+ }));
1490
+ const cursor = prepared.request.page?.cursor;
1491
+ let offset = 0;
1492
+ if (cursor !== undefined) {
1493
+ const anchor = openOmniViewCursorV1(
1494
+ prepared.request,
1495
+ prepared.identity.sourceSetDigest,
1496
+ viewRevision,
1497
+ cursor,
1498
+ prepared.environment,
1499
+ );
1500
+ const index = entities.findIndex((entity) =>
1501
+ entity.id === anchor.id && entity.orderedAt === anchor.orderedAt);
1502
+ if (index < 0) throw new Error("omni cursor anchor is absent from its authenticated view");
1503
+ offset = index + 1;
1504
+ }
1505
+ const limit = prepared.request.page?.limit ?? 100;
1506
+ const pageEntities = Object.freeze(entities.slice(offset, offset + limit));
1507
+ const hasMore = offset + pageEntities.length < entities.length;
1508
+ const last = pageEntities.at(-1);
1509
+ const nextCursor = hasMore && last !== undefined
1510
+ ? sealOmniViewCursorV1(
1511
+ prepared.request,
1512
+ prepared.identity.sourceSetDigest,
1513
+ viewRevision,
1514
+ Object.freeze({ orderedAt: last.orderedAt, id: last.id }),
1515
+ prepared.environment,
1516
+ )
1517
+ : null;
1518
+ const currentSet = prepareSources(prepared.request, {
1519
+ environment: prepared.environment,
1520
+ registry: prepared.registry,
1521
+ });
1522
+ if (
1523
+ currentSet.identity.invocationDigest !== prepared.identity.invocationDigest
1524
+ || currentSet.identity.requestDigest !== prepared.identity.requestDigest
1525
+ || currentSet.identity.sourceSetDigest !== prepared.identity.sourceSetDigest
1526
+ ) {
1527
+ throw new Error(
1528
+ "omni source or auth identity changed while the local view was being observed",
1529
+ );
1530
+ }
1531
+ return Object.freeze({
1532
+ schemaVersion: 1,
1533
+ viewRevision,
1534
+ entities: pageEntities,
1535
+ nextCursor,
1536
+ sources: Object.freeze(observed.map((entry) => entry.status)),
1537
+ });
1538
+ }
1539
+
1540
+ function result(
1541
+ source: OmniReadResultV1["source"],
1542
+ prepared: ReturnType<typeof prepareSources>,
1543
+ selectedView: OmniViewV1 | null,
1544
+ ): OmniReadResultV1 {
1545
+ const envelope = Object.freeze({
1546
+ ok: true,
1547
+ schemaVersion: 1,
1548
+ source,
1549
+ identity: prepared.identity,
1550
+ view: selectedView,
1551
+ });
1552
+ // The CLI writes one trailing newline. Keep the complete process envelope
1553
+ // inside the same bound enforced by the public SDK.
1554
+ if (
1555
+ Buffer.byteLength(canonicalJson(envelope), "utf8") + 1
1556
+ > OMNI_MAX_RESPONSE_BYTES
1557
+ ) {
1558
+ throw new Error("omni response exceeds its aggregate byte bound");
1559
+ }
1560
+ return envelope;
1561
+ }
1562
+
1563
+ export function identifyOmniView(
1564
+ requestValue: unknown,
1565
+ options: OmniRuntimeOptions = {},
1566
+ ): OmniReadResultV1 {
1567
+ const prepared = prepareSources(requestValue, options);
1568
+ return result("omni-identity", prepared, null);
1569
+ }
1570
+
1571
+ export function readCachedOmniViewInternal(
1572
+ requestValue: unknown,
1573
+ options: OmniRuntimeOptions = {},
1574
+ ): OmniReadResultV1 {
1575
+ const prepared = prepareSources(requestValue, options);
1576
+ return result("omni-cache", prepared, view(prepared, options));
1577
+ }
1578
+
1579
+ export function rebuildOmniViewFromExactCache(
1580
+ requestValue: unknown,
1581
+ options: OmniRuntimeOptions = {},
1582
+ ): OmniReadResultV1 {
1583
+ const prepared = prepareSources(requestValue, options);
1584
+ const errors = new Map<string, OmniSourceUpdateError>();
1585
+ for (const source of prepared.sources) {
1586
+ if (source.omni?.state !== "supported") continue;
1587
+ try {
1588
+ const error = rebuildExactContinuationChain(source, prepared, options);
1589
+ if (error !== undefined) {
1590
+ errors.set(canonicalJson(source.request), error);
1591
+ }
1592
+ } catch {
1593
+ errors.set(
1594
+ canonicalJson(source.request),
1595
+ sourceUpdateError(source, NORMALIZATION_UPDATE_ERROR_REASON),
1596
+ );
1597
+ }
1598
+ }
1599
+ return result("omni-exact-cache", prepared, view(prepared, options, errors));
1600
+ }
1601
+
1602
+ export async function revalidateOmniViewInternal(
1603
+ requestValue: unknown,
1604
+ options: OmniLiveRuntimeOptions = {},
1605
+ ): Promise<OmniReadResultV1> {
1606
+ parseSourcePageLimit(options.sourcePageLimit);
1607
+ const prepared = prepareSources(requestValue, options);
1608
+ const errors = new Map<string, OmniSourceUpdateError>();
1609
+ for (const source of prepared.sources) {
1610
+ throwIfAborted(options.signal);
1611
+ if (source.omni?.state !== "supported") continue;
1612
+ try {
1613
+ const error = await revalidateOmniSourceChain(source, prepared, options);
1614
+ if (error !== undefined) {
1615
+ errors.set(
1616
+ canonicalJson(source.request),
1617
+ error,
1618
+ );
1619
+ }
1620
+ } catch {
1621
+ throwIfAborted(options.signal);
1622
+ errors.set(
1623
+ canonicalJson(source.request),
1624
+ sourceUpdateError(source, PROVIDER_READ_ERROR_REASON),
1625
+ );
1626
+ }
1627
+ }
1628
+ throwIfAborted(options.signal);
1629
+ const selectedView = view(prepared, options, errors);
1630
+ throwIfAborted(options.signal);
1631
+ return result("omni-live", prepared, selectedView);
1632
+ }