@opendatalabs/personal-server-ts-core 1.34.2 → 1.35.1

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 (414) hide show
  1. package/dist/additions/durable.d.ts +32 -2
  2. package/dist/additions/durable.d.ts.map +1 -1
  3. package/dist/additions/durable.js +237 -88
  4. package/dist/additions/durable.js.map +1 -1
  5. package/dist/additions/version-inventory.d.ts +4 -0
  6. package/dist/additions/version-inventory.d.ts.map +1 -1
  7. package/dist/additions/version-inventory.js +11 -1
  8. package/dist/additions/version-inventory.js.map +1 -1
  9. package/dist/api/index.d.ts +18 -1
  10. package/dist/api/index.d.ts.map +1 -1
  11. package/dist/api/index.js +172 -4
  12. package/dist/api/index.js.map +1 -1
  13. package/dist/api/oura-collection-requirements.d.ts +16 -0
  14. package/dist/api/oura-collection-requirements.d.ts.map +1 -0
  15. package/dist/api/oura-collection-requirements.js +70 -0
  16. package/dist/api/oura-collection-requirements.js.map +1 -0
  17. package/dist/api/scope-upload-batches.d.ts +18 -0
  18. package/dist/api/scope-upload-batches.d.ts.map +1 -0
  19. package/dist/api/scope-upload-batches.js +71 -0
  20. package/dist/api/scope-upload-batches.js.map +1 -0
  21. package/dist/api/scope-uploads.d.ts +112 -0
  22. package/dist/api/scope-uploads.d.ts.map +1 -0
  23. package/dist/api/scope-uploads.js +369 -0
  24. package/dist/api/scope-uploads.js.map +1 -0
  25. package/dist/client.d.ts +70 -0
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +1 -0
  28. package/dist/client.js.map +1 -1
  29. package/dist/contracts/data.d.ts +8 -0
  30. package/dist/contracts/data.d.ts.map +1 -1
  31. package/dist/contracts/data.js +31 -1
  32. package/dist/contracts/data.js.map +1 -1
  33. package/dist/contracts/grants.d.ts.map +1 -1
  34. package/dist/contracts/grants.js +3 -0
  35. package/dist/contracts/grants.js.map +1 -1
  36. package/dist/contracts/index.d.ts +3 -1
  37. package/dist/contracts/index.d.ts.map +1 -1
  38. package/dist/contracts/index.js +3 -1
  39. package/dist/contracts/index.js.map +1 -1
  40. package/dist/contracts/oura-collection-requirements.d.ts +17 -0
  41. package/dist/contracts/oura-collection-requirements.d.ts.map +1 -0
  42. package/dist/contracts/oura-collection-requirements.js +49 -0
  43. package/dist/contracts/oura-collection-requirements.js.map +1 -0
  44. package/dist/legacy-projection/bindings.d.ts +1 -7
  45. package/dist/legacy-projection/bindings.d.ts.map +1 -1
  46. package/dist/legacy-projection/bindings.js +162 -28
  47. package/dist/legacy-projection/bindings.js.map +1 -1
  48. package/dist/legacy-projection/index.d.ts +6 -5
  49. package/dist/legacy-projection/index.d.ts.map +1 -1
  50. package/dist/legacy-projection/index.js +9 -21
  51. package/dist/legacy-projection/index.js.map +1 -1
  52. package/dist/legacy-projection/oura-browser-bindings.d.ts +2 -0
  53. package/dist/legacy-projection/oura-browser-bindings.d.ts.map +1 -1
  54. package/dist/legacy-projection/oura-browser-bindings.js +2 -0
  55. package/dist/legacy-projection/oura-browser-bindings.js.map +1 -1
  56. package/dist/legacy-projection/strava-browser-bindings.d.ts +3 -0
  57. package/dist/legacy-projection/strava-browser-bindings.d.ts.map +1 -0
  58. package/dist/legacy-projection/strava-browser-bindings.js +32 -0
  59. package/dist/legacy-projection/strava-browser-bindings.js.map +1 -0
  60. package/dist/legacy-projection/types.d.ts +44 -12
  61. package/dist/legacy-projection/types.d.ts.map +1 -1
  62. package/dist/mcp/connection-api.d.ts +11 -1
  63. package/dist/mcp/connection-api.d.ts.map +1 -1
  64. package/dist/mcp/connection-api.js +94 -9
  65. package/dist/mcp/connection-api.js.map +1 -1
  66. package/dist/mcp/index.d.ts +1 -0
  67. package/dist/mcp/index.d.ts.map +1 -1
  68. package/dist/mcp/index.js +1 -0
  69. package/dist/mcp/index.js.map +1 -1
  70. package/dist/mcp/server.d.ts +9 -0
  71. package/dist/mcp/server.d.ts.map +1 -1
  72. package/dist/mcp/server.js +19 -6
  73. package/dist/mcp/server.js.map +1 -1
  74. package/dist/mcp/store.d.ts +10 -1
  75. package/dist/mcp/store.d.ts.map +1 -1
  76. package/dist/mcp/store.js +51 -0
  77. package/dist/mcp/store.js.map +1 -1
  78. package/dist/mcp/tools.d.ts +52 -2
  79. package/dist/mcp/tools.d.ts.map +1 -1
  80. package/dist/mcp/tools.js +395 -11
  81. package/dist/mcp/tools.js.map +1 -1
  82. package/dist/mcp/types.d.ts +36 -2
  83. package/dist/mcp/types.d.ts.map +1 -1
  84. package/dist/mcp/types.js +12 -0
  85. package/dist/mcp/types.js.map +1 -1
  86. package/dist/mcp/write-client.d.ts +81 -0
  87. package/dist/mcp/write-client.d.ts.map +1 -0
  88. package/dist/mcp/write-client.js +140 -0
  89. package/dist/mcp/write-client.js.map +1 -0
  90. package/dist/oura/history-policy.d.ts +12 -0
  91. package/dist/oura/history-policy.d.ts.map +1 -0
  92. package/dist/oura/history-policy.js +54 -0
  93. package/dist/oura/history-policy.js.map +1 -0
  94. package/dist/oura/index.d.ts +51 -0
  95. package/dist/oura/index.d.ts.map +1 -0
  96. package/dist/oura/index.js +315 -0
  97. package/dist/oura/index.js.map +1 -0
  98. package/dist/pdpp/approval.d.ts +1 -1
  99. package/dist/pdpp/approval.d.ts.map +1 -1
  100. package/dist/pdpp/approval.js +29 -10
  101. package/dist/pdpp/approval.js.map +1 -1
  102. package/dist/pdpp/declaration-limits.d.ts +7 -0
  103. package/dist/pdpp/declaration-limits.d.ts.map +1 -0
  104. package/dist/pdpp/declaration-limits.js +7 -0
  105. package/dist/pdpp/declaration-limits.js.map +1 -0
  106. package/dist/pdpp/declaration.d.ts +2 -1
  107. package/dist/pdpp/declaration.d.ts.map +1 -1
  108. package/dist/pdpp/declaration.js +2 -1
  109. package/dist/pdpp/declaration.js.map +1 -1
  110. package/dist/pdpp/index.d.ts +3 -2
  111. package/dist/pdpp/index.d.ts.map +1 -1
  112. package/dist/pdpp/index.js +3 -2
  113. package/dist/pdpp/index.js.map +1 -1
  114. package/dist/pdpp/issuance.d.ts.map +1 -1
  115. package/dist/pdpp/issuance.js +6 -2
  116. package/dist/pdpp/issuance.js.map +1 -1
  117. package/dist/pdpp/resolve.d.ts +12 -1
  118. package/dist/pdpp/resolve.d.ts.map +1 -1
  119. package/dist/pdpp/resolve.js +156 -58
  120. package/dist/pdpp/resolve.js.map +1 -1
  121. package/dist/pdpp/selection.d.ts +30 -1
  122. package/dist/pdpp/selection.d.ts.map +1 -1
  123. package/dist/pdpp/selection.js +77 -26
  124. package/dist/pdpp/selection.js.map +1 -1
  125. package/dist/pdpp/time.d.ts +39 -0
  126. package/dist/pdpp/time.d.ts.map +1 -0
  127. package/dist/pdpp/time.js +173 -0
  128. package/dist/pdpp/time.js.map +1 -0
  129. package/dist/pdpp/tokens.d.ts.map +1 -1
  130. package/dist/pdpp/tokens.js +4 -2
  131. package/dist/pdpp/tokens.js.map +1 -1
  132. package/dist/pdpp/types.d.ts +18 -2
  133. package/dist/pdpp/types.d.ts.map +1 -1
  134. package/dist/pdpp/types.js +7 -0
  135. package/dist/pdpp/types.js.map +1 -1
  136. package/dist/policy/reserved-scopes.d.ts +7 -0
  137. package/dist/policy/reserved-scopes.d.ts.map +1 -1
  138. package/dist/policy/reserved-scopes.js +12 -1
  139. package/dist/policy/reserved-scopes.js.map +1 -1
  140. package/dist/ports/index.d.ts +85 -1
  141. package/dist/ports/index.d.ts.map +1 -1
  142. package/dist/ports/index.js.map +1 -1
  143. package/dist/ports/pdpp-auth.d.ts +17 -27
  144. package/dist/ports/pdpp-auth.d.ts.map +1 -1
  145. package/dist/ports/pdpp-auth.js +14 -28
  146. package/dist/ports/pdpp-auth.js.map +1 -1
  147. package/dist/publication/publish.d.ts +96 -0
  148. package/dist/publication/publish.d.ts.map +1 -0
  149. package/dist/publication/publish.js +261 -0
  150. package/dist/publication/publish.js.map +1 -0
  151. package/dist/replication/completion.d.ts +20 -0
  152. package/dist/replication/completion.d.ts.map +1 -0
  153. package/dist/replication/completion.js +73 -0
  154. package/dist/replication/completion.js.map +1 -0
  155. package/dist/replication/coordinator-state.d.ts +29 -0
  156. package/dist/replication/coordinator-state.d.ts.map +1 -0
  157. package/dist/replication/coordinator-state.js +88 -0
  158. package/dist/replication/coordinator-state.js.map +1 -0
  159. package/dist/replication/coordinator-state.test-utils.d.ts +32 -0
  160. package/dist/replication/coordinator-state.test-utils.d.ts.map +1 -0
  161. package/dist/replication/coordinator-state.test-utils.js +113 -0
  162. package/dist/replication/coordinator-state.test-utils.js.map +1 -0
  163. package/dist/replication/coordinator.d.ts +264 -0
  164. package/dist/replication/coordinator.d.ts.map +1 -0
  165. package/dist/replication/coordinator.js +499 -0
  166. package/dist/replication/coordinator.js.map +1 -0
  167. package/dist/replication/copies.d.ts +126 -0
  168. package/dist/replication/copies.d.ts.map +1 -0
  169. package/dist/replication/copies.js +437 -0
  170. package/dist/replication/copies.js.map +1 -0
  171. package/dist/replication/copy-promotion.d.ts +132 -0
  172. package/dist/replication/copy-promotion.d.ts.map +1 -0
  173. package/dist/replication/copy-promotion.js +126 -0
  174. package/dist/replication/copy-promotion.js.map +1 -0
  175. package/dist/replication/door.d.ts +33 -0
  176. package/dist/replication/door.d.ts.map +1 -0
  177. package/dist/replication/door.js +10 -0
  178. package/dist/replication/door.js.map +1 -0
  179. package/dist/replication/dpv2.d.ts +141 -0
  180. package/dist/replication/dpv2.d.ts.map +1 -0
  181. package/dist/replication/dpv2.js +320 -0
  182. package/dist/replication/dpv2.js.map +1 -0
  183. package/dist/replication/effects.d.ts +68 -0
  184. package/dist/replication/effects.d.ts.map +1 -0
  185. package/dist/replication/effects.js +89 -0
  186. package/dist/replication/effects.js.map +1 -0
  187. package/dist/replication/engine.d.ts +378 -0
  188. package/dist/replication/engine.d.ts.map +1 -0
  189. package/dist/replication/engine.js +3197 -0
  190. package/dist/replication/engine.js.map +1 -0
  191. package/dist/replication/envelope.d.ts +481 -0
  192. package/dist/replication/envelope.d.ts.map +1 -0
  193. package/dist/replication/envelope.js +192 -0
  194. package/dist/replication/envelope.js.map +1 -0
  195. package/dist/replication/evidence.d.ts +118 -0
  196. package/dist/replication/evidence.d.ts.map +1 -0
  197. package/dist/replication/evidence.js +198 -0
  198. package/dist/replication/evidence.js.map +1 -0
  199. package/dist/replication/finality.d.ts +16 -0
  200. package/dist/replication/finality.d.ts.map +1 -0
  201. package/dist/replication/finality.js +11 -0
  202. package/dist/replication/finality.js.map +1 -0
  203. package/dist/replication/fixtures.d.ts +16 -0
  204. package/dist/replication/fixtures.d.ts.map +1 -0
  205. package/dist/replication/fixtures.js +47 -0
  206. package/dist/replication/fixtures.js.map +1 -0
  207. package/dist/replication/host-config.d.ts +52 -0
  208. package/dist/replication/host-config.d.ts.map +1 -0
  209. package/dist/replication/host-config.js +111 -0
  210. package/dist/replication/host-config.js.map +1 -0
  211. package/dist/replication/host-driver.d.ts +95 -0
  212. package/dist/replication/host-driver.d.ts.map +1 -0
  213. package/dist/replication/host-driver.js +202 -0
  214. package/dist/replication/host-driver.js.map +1 -0
  215. package/dist/replication/host-ports.d.ts +48 -0
  216. package/dist/replication/host-ports.d.ts.map +1 -0
  217. package/dist/replication/host-ports.js +69 -0
  218. package/dist/replication/host-ports.js.map +1 -0
  219. package/dist/replication/identity.d.ts +13 -0
  220. package/dist/replication/identity.d.ts.map +1 -0
  221. package/dist/replication/identity.js +22 -0
  222. package/dist/replication/identity.js.map +1 -0
  223. package/dist/replication/limits.d.ts +124 -0
  224. package/dist/replication/limits.d.ts.map +1 -0
  225. package/dist/replication/limits.js +182 -0
  226. package/dist/replication/limits.js.map +1 -0
  227. package/dist/replication/merge-plan.d.ts +92 -0
  228. package/dist/replication/merge-plan.d.ts.map +1 -0
  229. package/dist/replication/merge-plan.js +229 -0
  230. package/dist/replication/merge-plan.js.map +1 -0
  231. package/dist/replication/namespace.d.ts +4 -0
  232. package/dist/replication/namespace.d.ts.map +1 -0
  233. package/dist/replication/namespace.js +7 -0
  234. package/dist/replication/namespace.js.map +1 -0
  235. package/dist/replication/outcome.d.ts +178 -0
  236. package/dist/replication/outcome.d.ts.map +1 -0
  237. package/dist/replication/outcome.js +83 -0
  238. package/dist/replication/outcome.js.map +1 -0
  239. package/dist/replication/payload.d.ts +39 -0
  240. package/dist/replication/payload.d.ts.map +1 -0
  241. package/dist/replication/payload.js +137 -0
  242. package/dist/replication/payload.js.map +1 -0
  243. package/dist/replication/preparation.d.ts +42 -0
  244. package/dist/replication/preparation.d.ts.map +1 -0
  245. package/dist/replication/preparation.js +118 -0
  246. package/dist/replication/preparation.js.map +1 -0
  247. package/dist/replication/rebaseline.d.ts +33 -0
  248. package/dist/replication/rebaseline.d.ts.map +1 -0
  249. package/dist/replication/rebaseline.js +40 -0
  250. package/dist/replication/rebaseline.js.map +1 -0
  251. package/dist/replication/rebinding.d.ts +43 -0
  252. package/dist/replication/rebinding.d.ts.map +1 -0
  253. package/dist/replication/rebinding.js +52 -0
  254. package/dist/replication/rebinding.js.map +1 -0
  255. package/dist/replication/receive.d.ts +57 -0
  256. package/dist/replication/receive.d.ts.map +1 -0
  257. package/dist/replication/receive.js +114 -0
  258. package/dist/replication/receive.js.map +1 -0
  259. package/dist/replication/record-reducer.d.ts +16 -0
  260. package/dist/replication/record-reducer.d.ts.map +1 -0
  261. package/dist/replication/record-reducer.js +52 -0
  262. package/dist/replication/record-reducer.js.map +1 -0
  263. package/dist/replication/revision.d.ts +24 -0
  264. package/dist/replication/revision.d.ts.map +1 -0
  265. package/dist/replication/revision.js +35 -0
  266. package/dist/replication/revision.js.map +1 -0
  267. package/dist/replication/roster.d.ts +53 -0
  268. package/dist/replication/roster.d.ts.map +1 -0
  269. package/dist/replication/roster.js +115 -0
  270. package/dist/replication/roster.js.map +1 -0
  271. package/dist/replication/schedule.d.ts +73 -0
  272. package/dist/replication/schedule.d.ts.map +1 -0
  273. package/dist/replication/schedule.js +182 -0
  274. package/dist/replication/schedule.js.map +1 -0
  275. package/dist/replication/stream.d.ts +73 -0
  276. package/dist/replication/stream.d.ts.map +1 -0
  277. package/dist/replication/stream.js +542 -0
  278. package/dist/replication/stream.js.map +1 -0
  279. package/dist/replication/transport.d.ts +236 -0
  280. package/dist/replication/transport.d.ts.map +1 -0
  281. package/dist/replication/transport.js +440 -0
  282. package/dist/replication/transport.js.map +1 -0
  283. package/dist/replication/visibility-engine.d.ts +337 -0
  284. package/dist/replication/visibility-engine.d.ts.map +1 -0
  285. package/dist/replication/visibility-engine.js +602 -0
  286. package/dist/replication/visibility-engine.js.map +1 -0
  287. package/dist/replication/visibility-policy.d.ts +26 -0
  288. package/dist/replication/visibility-policy.d.ts.map +1 -0
  289. package/dist/replication/visibility-policy.js +33 -0
  290. package/dist/replication/visibility-policy.js.map +1 -0
  291. package/dist/replication/writer-identity-store.d.ts +100 -0
  292. package/dist/replication/writer-identity-store.d.ts.map +1 -0
  293. package/dist/replication/writer-identity-store.js +218 -0
  294. package/dist/replication/writer-identity-store.js.map +1 -0
  295. package/dist/replication/writer-identity.d.ts +252 -0
  296. package/dist/replication/writer-identity.d.ts.map +1 -0
  297. package/dist/replication/writer-identity.js +281 -0
  298. package/dist/replication/writer-identity.js.map +1 -0
  299. package/dist/replication/writer-identity.test-utils.d.ts +24 -0
  300. package/dist/replication/writer-identity.test-utils.d.ts.map +1 -0
  301. package/dist/replication/writer-identity.test-utils.js +86 -0
  302. package/dist/replication/writer-identity.test-utils.js.map +1 -0
  303. package/dist/schemas/server-config.d.ts +13 -0
  304. package/dist/schemas/server-config.d.ts.map +1 -1
  305. package/dist/schemas/server-config.js +24 -0
  306. package/dist/schemas/server-config.js.map +1 -1
  307. package/dist/storage/adapters/index.d.ts +3 -1
  308. package/dist/storage/adapters/index.d.ts.map +1 -1
  309. package/dist/storage/adapters/index.js +2 -0
  310. package/dist/storage/adapters/index.js.map +1 -1
  311. package/dist/storage/adapters/interface.d.ts +18 -1
  312. package/dist/storage/adapters/interface.d.ts.map +1 -1
  313. package/dist/storage/adapters/interface.js +13 -1
  314. package/dist/storage/adapters/interface.js.map +1 -1
  315. package/dist/storage/adapters/sdk.d.ts +2 -1
  316. package/dist/storage/adapters/sdk.d.ts.map +1 -1
  317. package/dist/storage/adapters/sdk.js +21 -3
  318. package/dist/storage/adapters/sdk.js.map +1 -1
  319. package/dist/storage/adapters/vana-audience.d.ts +17 -5
  320. package/dist/storage/adapters/vana-audience.d.ts.map +1 -1
  321. package/dist/storage/adapters/vana-audience.js +24 -9
  322. package/dist/storage/adapters/vana-audience.js.map +1 -1
  323. package/dist/storage/adapters/vana.d.ts +2 -2
  324. package/dist/storage/adapters/vana.d.ts.map +1 -1
  325. package/dist/storage/adapters/vana.js +30 -22
  326. package/dist/storage/adapters/vana.js.map +1 -1
  327. package/dist/storage/canonical-legacy-projection.d.ts +1 -1
  328. package/dist/storage/canonical-legacy-projection.d.ts.map +1 -1
  329. package/dist/storage/canonical-legacy-projection.js +13 -15
  330. package/dist/storage/canonical-legacy-projection.js.map +1 -1
  331. package/dist/storage/legacy-projection.d.ts.map +1 -1
  332. package/dist/storage/legacy-projection.js +16 -1
  333. package/dist/storage/legacy-projection.js.map +1 -1
  334. package/dist/storage/legacy-scope-coverage-exceptions.d.ts +5 -0
  335. package/dist/storage/legacy-scope-coverage-exceptions.d.ts.map +1 -1
  336. package/dist/storage/legacy-scope-coverage-exceptions.js +4 -0
  337. package/dist/storage/legacy-scope-coverage-exceptions.js.map +1 -1
  338. package/dist/storage/legacy-scope-coverage.d.ts.map +1 -1
  339. package/dist/storage/legacy-scope-coverage.js +14 -1
  340. package/dist/storage/legacy-scope-coverage.js.map +1 -1
  341. package/dist/storage/legacy-scope-entity-keys.d.ts +14 -1
  342. package/dist/storage/legacy-scope-entity-keys.d.ts.map +1 -1
  343. package/dist/storage/legacy-scope-entity-keys.js +18 -1
  344. package/dist/storage/legacy-scope-entity-keys.js.map +1 -1
  345. package/dist/storage/legacy-scope-view.d.ts +57 -5
  346. package/dist/storage/legacy-scope-view.d.ts.map +1 -1
  347. package/dist/storage/legacy-scope-view.js +644 -318
  348. package/dist/storage/legacy-scope-view.js.map +1 -1
  349. package/dist/storage/pdpp-records/cursor.d.ts +47 -2
  350. package/dist/storage/pdpp-records/cursor.d.ts.map +1 -1
  351. package/dist/storage/pdpp-records/cursor.js +7 -0
  352. package/dist/storage/pdpp-records/cursor.js.map +1 -1
  353. package/dist/storage/pdpp-records/enforcement.d.ts +3 -16
  354. package/dist/storage/pdpp-records/enforcement.d.ts.map +1 -1
  355. package/dist/storage/pdpp-records/enforcement.js +40 -13
  356. package/dist/storage/pdpp-records/enforcement.js.map +1 -1
  357. package/dist/storage/pdpp-records/index.d.ts +2 -0
  358. package/dist/storage/pdpp-records/index.d.ts.map +1 -1
  359. package/dist/storage/pdpp-records/index.js +1 -0
  360. package/dist/storage/pdpp-records/index.js.map +1 -1
  361. package/dist/storage/pdpp-records/interface.d.ts +8 -1
  362. package/dist/storage/pdpp-records/interface.d.ts.map +1 -1
  363. package/dist/storage/pdpp-records/list-page.d.ts +35 -0
  364. package/dist/storage/pdpp-records/list-page.d.ts.map +1 -0
  365. package/dist/storage/pdpp-records/list-page.js +106 -0
  366. package/dist/storage/pdpp-records/list-page.js.map +1 -0
  367. package/dist/storage/pdpp-records/memory-store.d.ts.map +1 -1
  368. package/dist/storage/pdpp-records/memory-store.js +95 -99
  369. package/dist/storage/pdpp-records/memory-store.js.map +1 -1
  370. package/dist/storage/pdpp-records/portable.d.ts +3 -0
  371. package/dist/storage/pdpp-records/portable.d.ts.map +1 -1
  372. package/dist/storage/pdpp-records/portable.js +3 -0
  373. package/dist/storage/pdpp-records/portable.js.map +1 -1
  374. package/dist/storage/pdpp-records/replication-journal.d.ts +20 -0
  375. package/dist/storage/pdpp-records/replication-journal.d.ts.map +1 -0
  376. package/dist/storage/pdpp-records/replication-journal.js +2 -0
  377. package/dist/storage/pdpp-records/replication-journal.js.map +1 -0
  378. package/dist/storage/pdpp-records/stream-declaration.d.ts +0 -2
  379. package/dist/storage/pdpp-records/stream-declaration.d.ts.map +1 -1
  380. package/dist/storage/pdpp-records/stream-declaration.js +0 -9
  381. package/dist/storage/pdpp-records/stream-declaration.js.map +1 -1
  382. package/dist/storage/pdpp-records/sync-selection.d.ts +4 -0
  383. package/dist/storage/pdpp-records/sync-selection.d.ts.map +1 -0
  384. package/dist/storage/pdpp-records/sync-selection.js +37 -0
  385. package/dist/storage/pdpp-records/sync-selection.js.map +1 -0
  386. package/dist/storage/pdpp-records/types.d.ts +64 -0
  387. package/dist/storage/pdpp-records/types.d.ts.map +1 -1
  388. package/dist/storage/pdpp-records/types.js.map +1 -1
  389. package/dist/sync/delete-data-port.d.ts +15 -0
  390. package/dist/sync/delete-data-port.d.ts.map +1 -1
  391. package/dist/sync/delete-data-port.js +19 -7
  392. package/dist/sync/delete-data-port.js.map +1 -1
  393. package/dist/sync/index.d.ts +2 -1
  394. package/dist/sync/index.d.ts.map +1 -1
  395. package/dist/sync/index.js +2 -1
  396. package/dist/sync/index.js.map +1 -1
  397. package/dist/sync/pending-blob-deletions.d.ts +18 -2
  398. package/dist/sync/pending-blob-deletions.d.ts.map +1 -1
  399. package/dist/sync/pending-blob-deletions.js +69 -23
  400. package/dist/sync/pending-blob-deletions.js.map +1 -1
  401. package/dist/sync/workers/delete.d.ts.map +1 -1
  402. package/dist/sync/workers/delete.js +332 -142
  403. package/dist/sync/workers/delete.js.map +1 -1
  404. package/dist/sync/workers/download.d.ts.map +1 -1
  405. package/dist/sync/workers/download.js +53 -5
  406. package/dist/sync/workers/download.js.map +1 -1
  407. package/dist/sync/workers/upload.d.ts +24 -5
  408. package/dist/sync/workers/upload.d.ts.map +1 -1
  409. package/dist/sync/workers/upload.js +160 -275
  410. package/dist/sync/workers/upload.js.map +1 -1
  411. package/dist/test-utils/memory-storage.d.ts.map +1 -1
  412. package/dist/test-utils/memory-storage.js +17 -2
  413. package/dist/test-utils/memory-storage.js.map +1 -1
  414. package/package.json +24 -2
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Closed outcome algebra for replication work. Every phase of the durable
3
+ * coordinator returns exactly one of these. Diagnostics are closed codes and
4
+ * bounded cause chains: exception text never crosses this boundary.
5
+ */
6
+ import type { ReplicaAuthorityRefusal } from "./writer-identity.js";
7
+ export type ReplicaPhase = "retain" | "prepare" | "publish" | "discover" | "download" | "fetch" | "revalidate" | "import" | "reconcile";
8
+ /** What a Wait waits for. A key is stable across restarts. */
9
+ export type ReplicaDependency = {
10
+ kind: "registration";
11
+ key: string;
12
+ reason: "own_key_conflict" | "version_squat";
13
+ } | {
14
+ kind: "predecessor";
15
+ key: string;
16
+ } | {
17
+ kind: "finality";
18
+ key: string;
19
+ checkedBlock: string;
20
+ }
21
+ /** A writer's registration intent is unresolved at this publication slot. */
22
+ | {
23
+ kind: "registration_pending";
24
+ key: string;
25
+ version: number;
26
+ since: number;
27
+ checkedBlock?: string;
28
+ /** Next evidence check for a successor waiting on this registration. */
29
+ nextCheckAt?: number;
30
+ }
31
+ /** Sender preparation cannot proceed; unknown failures still use Retry backoff. */
32
+ | {
33
+ kind: "preparation";
34
+ key: string;
35
+ reason: "unknown" | "upload_started" | "all_ops_unsupported";
36
+ } | {
37
+ kind: "fragments";
38
+ key: string;
39
+ } | {
40
+ kind: "mapping";
41
+ key: string;
42
+ } | {
43
+ kind: "declaration";
44
+ key: string;
45
+ } | {
46
+ kind: "blob";
47
+ key: string;
48
+ } | {
49
+ kind: "reset";
50
+ key: string;
51
+ }
52
+ /** The gateway roster for a server address could not be read. */
53
+ | {
54
+ kind: "roster";
55
+ key: string;
56
+ }
57
+ /**
58
+ * Every retained copy of a batch is disproved and the refetch budget is
59
+ * spent (copy_conflict_unresolved). A new finalized fact for the batch
60
+ * wakes it; otherwise only the owner can resolve it.
61
+ */
62
+ | {
63
+ kind: "owner";
64
+ key: string;
65
+ };
66
+ export declare const dependencyKey: (dependency: ReplicaDependency) => string;
67
+ /** Why a transient attempt failed. Never exception text. */
68
+ export type ReplicaProblem = "evidence_unavailable" | "registration_unconfirmed" | "head_unavailable" | "publish_failed" | "download_failed" | "resource_busy" | "commitment_mismatch" | "payload_invalid" | "import_failed" | "prepare_failed" | "retain_failed" | "discovery_failed" | "reconcile_failed" | "deadline_exceeded" | "storage_failed" | "unknown";
69
+ /** Error class name plus optional code per level, at most four levels deep. */
70
+ export interface ReplicaCause {
71
+ name: string;
72
+ code?: string;
73
+ cause?: ReplicaCause;
74
+ }
75
+ /** Structured, bounded cause chain. Reads class names and codes, never messages. */
76
+ export declare function replicaCause(error: unknown, depth?: number): ReplicaCause;
77
+ /** A failure whose closed problem code the thrower knows. */
78
+ export declare class ReplicaProblemError extends Error {
79
+ readonly problem: ReplicaProblem;
80
+ readonly code: ReplicaProblem;
81
+ constructor(problem: ReplicaProblem, options?: {
82
+ cause?: unknown;
83
+ });
84
+ }
85
+ /**
86
+ * A framing Unsupported, separate from sender input and resource admission.
87
+ * Thrown where encrypted framing exceeds the storage cap. The preparer may retry a
88
+ * smaller chunk size; at the smallest size framing is proven impossible.
89
+ */
90
+ export declare class ReplicaFramingUnsupported extends Error {
91
+ readonly actual: number;
92
+ readonly limit: number;
93
+ /**
94
+ * fragment_bytes: one encrypted fragment exceeds the cap. fragment_count:
95
+ * too many fragments. manifest_bytes: the encrypted manifest exceeds the cap.
96
+ */
97
+ readonly dimension: "fragment_bytes" | "fragment_count" | "manifest_bytes";
98
+ readonly code = "replica_framing_unsupported";
99
+ constructor(actual: number, limit: number,
100
+ /**
101
+ * fragment_bytes: one encrypted fragment exceeds the cap. fragment_count:
102
+ * too many fragments. manifest_bytes: the encrypted manifest exceeds the cap.
103
+ */
104
+ dimension?: "fragment_bytes" | "fragment_count" | "manifest_bytes");
105
+ }
106
+ export type ReplicaAdmission = {
107
+ reason: "operation_encoding_unsupported";
108
+ } | {
109
+ reason: "replica_framing_unsupported";
110
+ actual: number;
111
+ limit: number;
112
+ /** The admitted capability the decision was measured against. */
113
+ capability: string;
114
+ } | {
115
+ reason: "resource_unsupported";
116
+ limit: string;
117
+ limitsVersion: number;
118
+ };
119
+ export interface ReplicaQuarantineProof {
120
+ reason: "immutable_registration_conflict"
121
+ /** Finalized facts contradict a batch, or its writer chain is terminal. */
122
+ | "finalized_conflict" | "batch_equivocation" | "source_binding_conflict" | "local_mapping_conflict"
123
+ /**
124
+ * A finalized manifest is over the storage cap, compressed, outside the
125
+ * writers' OpenPGP profile or the JSON bounds, or its authentic bytes
126
+ * decode to an invalid statement.
127
+ */
128
+ | "manifest_invalid"
129
+ /**
130
+ * Storage has no object at a fragment address of a finalized manifest.
131
+ * Storage reads are strongly consistent and the writer stores every
132
+ * fragment before it registers the manifest.
133
+ */
134
+ | "fragment_missing"
135
+ /** Fetched fragment bytes or their content disagree with the finalized manifest. */
136
+ | "fragment_mismatch"
137
+ /** Writer authority (host contract §3.4). None of these touch writer state. */
138
+ | ReplicaAuthorityRefusal;
139
+ key: string;
140
+ }
141
+ export interface ReplicaReceipt {
142
+ phase: ReplicaPhase;
143
+ key: string;
144
+ }
145
+ /** A phase verdict. Retry has no deadline yet: the schedule assigns it. */
146
+ export type ReplicaPhaseOutcome = {
147
+ tag: "progress";
148
+ receipt: ReplicaReceipt;
149
+ } | {
150
+ tag: "wait";
151
+ dependency: ReplicaDependency;
152
+ } | {
153
+ tag: "retry";
154
+ problem: ReplicaProblem;
155
+ cause?: ReplicaCause;
156
+ } | {
157
+ tag: "quarantine";
158
+ proof: ReplicaQuarantineProof;
159
+ } | {
160
+ tag: "unsupported";
161
+ admission: ReplicaAdmission;
162
+ };
163
+ /** The durable outcome after scheduling. */
164
+ export type ReplicaOutcome = Exclude<ReplicaPhaseOutcome, {
165
+ tag: "retry";
166
+ }> | {
167
+ tag: "retry";
168
+ problem: ReplicaProblem;
169
+ cause?: ReplicaCause;
170
+ nextEligible: number;
171
+ };
172
+ /** The persisted reason code of an outcome. */
173
+ export declare function outcomeReason(outcome: ReplicaPhaseOutcome): string;
174
+ /** Map any thrown value to Retry. Only a typed problem code chooses the problem. */
175
+ export declare function retryFromError(error: unknown, fallback: ReplicaProblem): Extract<ReplicaPhaseOutcome, {
176
+ tag: "retry";
177
+ }>;
178
+ //# sourceMappingURL=outcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../../src/replication/outcome.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Closed outcome algebra for replication work. Every phase of the durable
3
+ * coordinator returns exactly one of these. Diagnostics are closed codes and
4
+ * bounded cause chains: exception text never crosses this boundary.
5
+ */
6
+ export const dependencyKey = (dependency) => `${dependency.kind}:${dependency.key}`;
7
+ const MAX_CAUSE_DEPTH = 4;
8
+ const safe = (value) => value.replace(/[^\w.:-]/g, "").slice(0, 64);
9
+ /** Structured, bounded cause chain. Reads class names and codes, never messages. */
10
+ export function replicaCause(error, depth = 1) {
11
+ if (!(error instanceof Error))
12
+ return { name: error === null ? "null" : typeof error };
13
+ const code = error.code;
14
+ const cause = error.cause;
15
+ return {
16
+ name: safe(error.name) || "Error",
17
+ ...((typeof code === "string" || typeof code === "number") && {
18
+ code: safe(String(code)),
19
+ }),
20
+ ...(cause !== undefined &&
21
+ depth < MAX_CAUSE_DEPTH && { cause: replicaCause(cause, depth + 1) }),
22
+ };
23
+ }
24
+ /** A failure whose closed problem code the thrower knows. */
25
+ export class ReplicaProblemError extends Error {
26
+ problem;
27
+ code;
28
+ constructor(problem, options) {
29
+ super(problem, options);
30
+ this.problem = problem;
31
+ this.name = "ReplicaProblemError";
32
+ this.code = problem;
33
+ }
34
+ }
35
+ /**
36
+ * A framing Unsupported, separate from sender input and resource admission.
37
+ * Thrown where encrypted framing exceeds the storage cap. The preparer may retry a
38
+ * smaller chunk size; at the smallest size framing is proven impossible.
39
+ */
40
+ export class ReplicaFramingUnsupported extends Error {
41
+ actual;
42
+ limit;
43
+ dimension;
44
+ code = "replica_framing_unsupported";
45
+ constructor(actual, limit,
46
+ /**
47
+ * fragment_bytes: one encrypted fragment exceeds the cap. fragment_count:
48
+ * too many fragments. manifest_bytes: the encrypted manifest exceeds the cap.
49
+ */
50
+ dimension = "fragment_bytes") {
51
+ super("replica_framing_unsupported");
52
+ this.actual = actual;
53
+ this.limit = limit;
54
+ this.dimension = dimension;
55
+ this.name = "ReplicaFramingUnsupported";
56
+ }
57
+ }
58
+ /** The persisted reason code of an outcome. */
59
+ export function outcomeReason(outcome) {
60
+ switch (outcome.tag) {
61
+ case "progress":
62
+ return outcome.receipt.phase;
63
+ case "wait":
64
+ return outcome.dependency.kind === "registration"
65
+ ? outcome.dependency.reason
66
+ : outcome.dependency.kind;
67
+ case "retry":
68
+ return outcome.problem;
69
+ case "quarantine":
70
+ return outcome.proof.reason;
71
+ case "unsupported":
72
+ return outcome.admission.reason;
73
+ }
74
+ }
75
+ /** Map any thrown value to Retry. Only a typed problem code chooses the problem. */
76
+ export function retryFromError(error, fallback) {
77
+ return {
78
+ tag: "retry",
79
+ problem: error instanceof ReplicaProblemError ? error.problem : fallback,
80
+ cause: replicaCause(error),
81
+ };
82
+ }
83
+ //# sourceMappingURL=outcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outcome.js","sourceRoot":"","sources":["../../src/replication/outcome.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type ReplicaEffect } from "./effects.js";
2
+ export declare const REPLICA_PAYLOAD_CHUNK_BYTES: number;
3
+ /** The tables, for a host whose storage does not create them already. */
4
+ export declare const REPLICA_PAYLOAD_MIGRATION = "\nCREATE TABLE IF NOT EXISTS pdpp_binary_manifests (\n namespace TEXT NOT NULL, blob_id TEXT NOT NULL, size_bytes INTEGER NOT NULL,\n PRIMARY KEY(namespace,blob_id));\nCREATE TABLE IF NOT EXISTS pdpp_binary_chunks (\n namespace TEXT NOT NULL, blob_id TEXT NOT NULL, position INTEGER NOT NULL, bytes BLOB NOT NULL,\n PRIMARY KEY(namespace,blob_id,position));\n";
5
+ export declare function deleteReplicaPayload(key: string): ReplicaEffect<void>;
6
+ export interface ReplicaPayloadWriter {
7
+ write(bytes: Uint8Array): ReplicaEffect<void>;
8
+ /** Publish the manifest, after the last chunk. Returns the size. */
9
+ finish(): ReplicaEffect<number>;
10
+ }
11
+ /** Drop any bytes under `key`, then write fresh ones. */
12
+ export declare function replicaPayloadWriter(key: string): ReplicaEffect<ReplicaPayloadWriter>;
13
+ /** The published size, or undefined when absent or malformed. */
14
+ export declare function replicaPayloadLength(key: string): ReplicaEffect<number | undefined>;
15
+ /** Chunk `position` of `key`, checked against the published size. */
16
+ export declare function replicaPayloadChunk(key: string, position: number, offset: number, size: number): ReplicaEffect<Uint8Array>;
17
+ /**
18
+ * Stream a payload one chunk per storage call, so no transaction spans the
19
+ * consumer's awaits. `run` is the host's one-effect runner.
20
+ */
21
+ export declare function readReplicaPayload(run: <T>(effect: ReplicaEffect<T>) => T | Promise<T>, key: string): AsyncGenerator<Uint8Array>;
22
+ /** Where a chunked read resumes: a chunk row and a byte offset inside it. */
23
+ export interface ReplicaPayloadCursor {
24
+ position: number;
25
+ offset: number;
26
+ }
27
+ /**
28
+ * Exactly `length` bytes of the payload under `key` from `from`, and the
29
+ * cursor after them. Rows may have any length, so a caller that reads a
30
+ * payload in parts keeps the returned cursor and never seeks by arithmetic.
31
+ * Memory is `length`.
32
+ */
33
+ export declare function readReplicaPayloadWindow(key: string, from: ReplicaPayloadCursor, length: number): ReplicaEffect<{
34
+ bytes: Uint8Array;
35
+ next: ReplicaPayloadCursor;
36
+ }>;
37
+ /** In the caller's transaction: do the bytes under `key` hash to `digest`? */
38
+ export declare function verifyReplicaPayload(key: string, digest: string, size: number): ReplicaEffect<boolean>;
39
+ //# sourceMappingURL=payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../src/replication/payload.ts"],"names":[],"mappings":"AASA,OAAO,EAAO,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAEvD,eAAO,MAAM,2BAA2B,QAAY,CAAC;AAGrD,yEAAyE;AACzE,eAAO,MAAM,yBAAyB,4WAOrC,CAAC;AAEF,wBAAiB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAWtE;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAC9C,oEAAoE;IACpE,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;CACjC;AAED,yDAAyD;AACzD,wBAAiB,oBAAoB,CACnC,GAAG,EAAE,MAAM,GACV,aAAa,CAAC,oBAAoB,CAAC,CAmCrC;AAED,iEAAiE;AACjE,wBAAiB,oBAAoB,CACnC,GAAG,EAAE,MAAM,GACV,aAAa,CAAC,MAAM,GAAG,SAAS,CAAC,CASnC;AAED,qEAAqE;AACrE,wBAAiB,mBAAmB,CAClC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,aAAa,CAAC,UAAU,CAAC,CAe3B;AAcD;;;GAGG;AACH,wBAAuB,kBAAkB,CACvC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACpD,GAAG,EAAE,MAAM,GACV,cAAc,CAAC,UAAU,CAAC,CAW5B;AAED,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAiB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,MAAM,GACb,aAAa,CAAC;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAAC,CAuClE;AAED,8EAA8E;AAC9E,wBAAiB,oBAAoB,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,aAAa,CAAC,OAAO,CAAC,CAgBxB"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Retained batch payloads, as storage effects over the binary chunk tables
3
+ * (`pdpp_binary_chunks`, `pdpp_binary_manifests`) in their `payload`
4
+ * namespace. Node's `pdpp-binary-chunks.ts` owns the same tables for every
5
+ * namespace; the `payload` namespace never had a legacy whole-value table,
6
+ * so its rows mean the same on both hosts.
7
+ */
8
+ import { sha256 } from "@noble/hashes/sha256";
9
+ import { bytesToHex } from "@noble/hashes/utils";
10
+ import { sql } from "./effects.js";
11
+ export const REPLICA_PAYLOAD_CHUNK_BYTES = 64 * 1024;
12
+ const NAMESPACE = "payload";
13
+ /** The tables, for a host whose storage does not create them already. */
14
+ export const REPLICA_PAYLOAD_MIGRATION = `
15
+ CREATE TABLE IF NOT EXISTS pdpp_binary_manifests (
16
+ namespace TEXT NOT NULL, blob_id TEXT NOT NULL, size_bytes INTEGER NOT NULL,
17
+ PRIMARY KEY(namespace,blob_id));
18
+ CREATE TABLE IF NOT EXISTS pdpp_binary_chunks (
19
+ namespace TEXT NOT NULL, blob_id TEXT NOT NULL, position INTEGER NOT NULL, bytes BLOB NOT NULL,
20
+ PRIMARY KEY(namespace,blob_id,position));
21
+ `;
22
+ export function* deleteReplicaPayload(key) {
23
+ yield* sql.run("DELETE FROM pdpp_binary_chunks WHERE namespace=? AND blob_id=?", NAMESPACE, key);
24
+ yield* sql.run("DELETE FROM pdpp_binary_manifests WHERE namespace=? AND blob_id=?", NAMESPACE, key);
25
+ }
26
+ /** Drop any bytes under `key`, then write fresh ones. */
27
+ export function* replicaPayloadWriter(key) {
28
+ yield* deleteReplicaPayload(key);
29
+ let size = 0, position = 0;
30
+ return {
31
+ *write(bytes) {
32
+ for (let offset = 0; offset < bytes.length; offset += REPLICA_PAYLOAD_CHUNK_BYTES) {
33
+ const part = bytes.subarray(offset, offset + REPLICA_PAYLOAD_CHUNK_BYTES);
34
+ yield* sql.run("INSERT INTO pdpp_binary_chunks VALUES (?,?,?,?)", NAMESPACE, key, position++, part);
35
+ size += part.length;
36
+ }
37
+ },
38
+ *finish() {
39
+ yield* sql.run("INSERT INTO pdpp_binary_manifests VALUES (?,?,?)", NAMESPACE, key, size);
40
+ return size;
41
+ },
42
+ };
43
+ }
44
+ /** The published size, or undefined when absent or malformed. */
45
+ export function* replicaPayloadLength(key) {
46
+ const manifest = yield* sql.get("SELECT size_bytes AS size FROM pdpp_binary_manifests WHERE namespace=? AND blob_id=?", NAMESPACE, key);
47
+ return manifest && Number.isSafeInteger(manifest.size) && manifest.size >= 0
48
+ ? manifest.size
49
+ : undefined;
50
+ }
51
+ /** Chunk `position` of `key`, checked against the published size. */
52
+ export function* replicaPayloadChunk(key, position, offset, size) {
53
+ const row = yield* sql.get("SELECT bytes FROM pdpp_binary_chunks WHERE namespace=? AND blob_id=? AND position=?", NAMESPACE, key, position);
54
+ if (!row ||
55
+ !row.bytes.length ||
56
+ row.bytes.length > REPLICA_PAYLOAD_CHUNK_BYTES ||
57
+ offset + row.bytes.length > size)
58
+ throw new Error("corrupt binary chunks");
59
+ return row.bytes;
60
+ }
61
+ function* assertNoExcess(key, position) {
62
+ if (yield* sql.get("SELECT 1 FROM pdpp_binary_chunks WHERE namespace=? AND blob_id=? AND position>=? LIMIT 1", NAMESPACE, key, position))
63
+ throw new Error("excess binary chunks");
64
+ }
65
+ /**
66
+ * Stream a payload one chunk per storage call, so no transaction spans the
67
+ * consumer's awaits. `run` is the host's one-effect runner.
68
+ */
69
+ export async function* readReplicaPayload(run, key) {
70
+ const size = await run(replicaPayloadLength(key));
71
+ if (size === undefined)
72
+ throw new Error("missing binary bytes");
73
+ let offset = 0, position = 0;
74
+ while (offset < size) {
75
+ const bytes = await run(replicaPayloadChunk(key, position++, offset, size));
76
+ offset += bytes.length;
77
+ yield bytes;
78
+ }
79
+ await run(assertNoExcess(key, position));
80
+ }
81
+ /**
82
+ * Exactly `length` bytes of the payload under `key` from `from`, and the
83
+ * cursor after them. Rows may have any length, so a caller that reads a
84
+ * payload in parts keeps the returned cursor and never seeks by arithmetic.
85
+ * Memory is `length`.
86
+ */
87
+ export function* readReplicaPayloadWindow(key, from, length) {
88
+ const size = yield* replicaPayloadLength(key);
89
+ if (size === undefined ||
90
+ !Number.isSafeInteger(length) ||
91
+ length < 1 ||
92
+ !Number.isSafeInteger(from.position) ||
93
+ from.position < 0 ||
94
+ !Number.isSafeInteger(from.offset) ||
95
+ from.offset < 0)
96
+ throw new Error("missing binary bytes");
97
+ const bytes = new Uint8Array(length);
98
+ let filled = 0;
99
+ let { position, offset } = from;
100
+ while (filled < length) {
101
+ const row = yield* sql.get("SELECT bytes FROM pdpp_binary_chunks WHERE namespace=? AND blob_id=? AND position=?", NAMESPACE, key, position);
102
+ if (!row ||
103
+ !row.bytes.length ||
104
+ row.bytes.length > REPLICA_PAYLOAD_CHUNK_BYTES ||
105
+ offset >= row.bytes.length)
106
+ throw new Error("corrupt binary chunks");
107
+ const take = Math.min(row.bytes.length - offset, length - filled);
108
+ bytes.set(row.bytes.subarray(offset, offset + take), filled);
109
+ filled += take;
110
+ offset += take;
111
+ if (offset === row.bytes.length) {
112
+ position++;
113
+ offset = 0;
114
+ }
115
+ }
116
+ return { bytes, next: { position, offset } };
117
+ }
118
+ /** In the caller's transaction: do the bytes under `key` hash to `digest`? */
119
+ export function* verifyReplicaPayload(key, digest, size) {
120
+ if ((yield* replicaPayloadLength(key)) !== size)
121
+ return false;
122
+ const hash = sha256.create();
123
+ try {
124
+ let offset = 0, position = 0;
125
+ while (offset < size) {
126
+ const bytes = yield* replicaPayloadChunk(key, position++, offset, size);
127
+ offset += bytes.length;
128
+ hash.update(bytes);
129
+ }
130
+ yield* assertNoExcess(key, position);
131
+ }
132
+ catch {
133
+ return false;
134
+ }
135
+ return `sha256:${bytesToHex(hash.digest())}` === digest;
136
+ }
137
+ //# sourceMappingURL=payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../src/replication/payload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { type ReplicaOperation } from "./envelope.js";
2
+ import { ReplicaResourceLimitError, type ReplicaResourceLimits } from "./limits.js";
3
+ import type { ReplicaAdmission } from "./outcome.js";
4
+ /** Created only by an enabled worker, alongside the admission schema. */
5
+ export declare const REPLICA_PREPARATION_MIGRATION = "\nCREATE TABLE IF NOT EXISTS pdpp_transport_preparation (\n batch TEXT PRIMARY KEY, version INTEGER NOT NULL,\n state TEXT NOT NULL CHECK(state IN ('preparing','prep_failed_permanent','rebuilding','prep_failed_unknown','prepared','released')),\n wait_json TEXT);\nCREATE TABLE IF NOT EXISTS pdpp_transport_operation_outcomes (\n batch TEXT NOT NULL, position INTEGER NOT NULL, operation_json TEXT,\n writer_id TEXT, operation_id TEXT,\n encoding_failed INTEGER NOT NULL DEFAULT 0, outcome TEXT, reason TEXT, admission_json TEXT,\n PRIMARY KEY(batch,position));\nCREATE TABLE IF NOT EXISTS pdpp_transport_upload_attempts (\n batch TEXT NOT NULL, kind TEXT NOT NULL, position INTEGER NOT NULL, started_at INTEGER NOT NULL,\n PRIMARY KEY(batch,kind,position));\n";
6
+ export type ReplicaPreparationState = "preparing" | "prep_failed_permanent" | "rebuilding" | "prep_failed_unknown" | "prepared" | "released";
7
+ export type ReplicaPreparation = {
8
+ batch: string;
9
+ version: number;
10
+ state: ReplicaPreparationState;
11
+ wait_json: string | null;
12
+ };
13
+ export type RetainedPreparationOperation = {
14
+ position: number;
15
+ operation_json: string | null;
16
+ encoding_failed: number;
17
+ };
18
+ /** This error is minted only at the sender's own operation-encoding boundary. */
19
+ export declare class ReplicaPreparationInputError extends Error {
20
+ readonly positions: readonly number[];
21
+ constructor(positions: readonly number[]);
22
+ }
23
+ export type ReplicaPreparationFailure = {
24
+ kind: "permanent";
25
+ admission: ReplicaAdmission;
26
+ positions?: readonly number[];
27
+ } | {
28
+ kind: "unknown";
29
+ };
30
+ /** No message matching, generic RangeError, crypto error or I/O error is permanent. */
31
+ export declare function classifyReplicaPreparationError(error: unknown): ReplicaPreparationFailure;
32
+ /** An invalid operation retains its position, never a lossy JSON replacement. */
33
+ export declare function snapshotReplicaOperation(operation: ReplicaOperation): {
34
+ operation_json: string | null;
35
+ encoding_failed: number;
36
+ };
37
+ /** Attribute each sender-owned streamed limit to the op that crosses it. */
38
+ export declare function preparationOperationFailures(rows: readonly RetainedPreparationOperation[], limits: ReplicaResourceLimits): {
39
+ positions: number[];
40
+ error: ReplicaPreparationInputError | ReplicaResourceLimitError;
41
+ } | undefined;
42
+ //# sourceMappingURL=preparation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preparation.d.ts","sourceRoot":"","sources":["../../src/replication/preparation.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,yBAAyB,EACzB,KAAK,qBAAqB,EAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,yEAAyE;AACzE,eAAO,MAAM,6BAA6B,4vBAazC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B,WAAW,GACX,uBAAuB,GACvB,YAAY,GACZ,qBAAqB,GACrB,UAAU,GACV,UAAU,CAAC;AACf,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,uBAAuB,CAAC;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AACF,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,iFAAiF;AACjF,qBAAa,4BAA6B,SAAQ,KAAK;IACzC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE;gBAA5B,SAAS,EAAE,SAAS,MAAM,EAAE;CAIlD;AAED,MAAM,MAAM,yBAAyB,GACjC;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,GACD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,uFAAuF;AACvF,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,GACb,yBAAyB,CA2B3B;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,gBAAgB,GAAG;IACrE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;CACzB,CAMA;AAED,4EAA4E;AAC5E,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,SAAS,4BAA4B,EAAE,EAC7C,MAAM,EAAE,qBAAqB,GAE3B;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,4BAA4B,GAAG,yBAAyB,CAAC;CACjE,GACD,SAAS,CA6EZ"}
@@ -0,0 +1,118 @@
1
+ import { canonicalJson, replicaOperationSchema, } from "./envelope.js";
2
+ import { REPLICA_LIMITS_VERSION, ReplicaResourceLimitError, } from "./limits.js";
3
+ /** Created only by an enabled worker, alongside the admission schema. */
4
+ export const REPLICA_PREPARATION_MIGRATION = `
5
+ CREATE TABLE IF NOT EXISTS pdpp_transport_preparation (
6
+ batch TEXT PRIMARY KEY, version INTEGER NOT NULL,
7
+ state TEXT NOT NULL CHECK(state IN ('preparing','prep_failed_permanent','rebuilding','prep_failed_unknown','prepared','released')),
8
+ wait_json TEXT);
9
+ CREATE TABLE IF NOT EXISTS pdpp_transport_operation_outcomes (
10
+ batch TEXT NOT NULL, position INTEGER NOT NULL, operation_json TEXT,
11
+ writer_id TEXT, operation_id TEXT,
12
+ encoding_failed INTEGER NOT NULL DEFAULT 0, outcome TEXT, reason TEXT, admission_json TEXT,
13
+ PRIMARY KEY(batch,position));
14
+ CREATE TABLE IF NOT EXISTS pdpp_transport_upload_attempts (
15
+ batch TEXT NOT NULL, kind TEXT NOT NULL, position INTEGER NOT NULL, started_at INTEGER NOT NULL,
16
+ PRIMARY KEY(batch,kind,position));
17
+ `;
18
+ /** This error is minted only at the sender's own operation-encoding boundary. */
19
+ export class ReplicaPreparationInputError extends Error {
20
+ positions;
21
+ constructor(positions) {
22
+ super("replica operation cannot be encoded");
23
+ this.positions = positions;
24
+ this.name = "ReplicaPreparationInputError";
25
+ }
26
+ }
27
+ /** No message matching, generic RangeError, crypto error or I/O error is permanent. */
28
+ export function classifyReplicaPreparationError(error) {
29
+ if (error instanceof ReplicaPreparationInputError)
30
+ return {
31
+ kind: "permanent",
32
+ positions: error.positions,
33
+ admission: { reason: "operation_encoding_unsupported" },
34
+ };
35
+ if (error instanceof ReplicaResourceLimitError &&
36
+ [
37
+ "operation_count",
38
+ "operation_bytes",
39
+ "single_blob_bytes",
40
+ "aggregate_blob_bytes",
41
+ "aggregate_ciphertext_bytes",
42
+ "total_bytes",
43
+ ].includes(error.limit))
44
+ return {
45
+ kind: "permanent",
46
+ admission: {
47
+ reason: "resource_unsupported",
48
+ limit: error.limit,
49
+ limitsVersion: REPLICA_LIMITS_VERSION,
50
+ },
51
+ };
52
+ return { kind: "unknown" };
53
+ }
54
+ /** An invalid operation retains its position, never a lossy JSON replacement. */
55
+ export function snapshotReplicaOperation(operation) {
56
+ // A parser must not silently strip input fields. A false parse proves an
57
+ // input problem; an exception here remains unknown and must never drop it.
58
+ if (!replicaOperationSchema.safeParse(operation).success)
59
+ return { operation_json: null, encoding_failed: 1 };
60
+ return { operation_json: canonicalJson(operation), encoding_failed: 0 };
61
+ }
62
+ /** Attribute each sender-owned streamed limit to the op that crosses it. */
63
+ export function preparationOperationFailures(rows, limits) {
64
+ const encoding = rows
65
+ .filter((row) => row.encoding_failed)
66
+ .map((row) => row.position);
67
+ if (encoding.length)
68
+ return {
69
+ positions: encoding,
70
+ error: new ReplicaPreparationInputError(encoding),
71
+ };
72
+ const acceptedBlobs = new Set();
73
+ let blobBytes = 0;
74
+ let count = 0;
75
+ const failures = [];
76
+ for (const row of rows) {
77
+ const op = JSON.parse(row.operation_json);
78
+ const blobs = op.kind === "upsert"
79
+ ? op.blobs
80
+ : op.kind === "blob-claim"
81
+ ? [op.blob]
82
+ : [];
83
+ const newBlobs = [
84
+ ...new Map(blobs
85
+ .filter((blob) => !acceptedBlobs.has(blob.blobId))
86
+ .map((blob) => [blob.blobId, blob])).values(),
87
+ ];
88
+ const newBytes = newBlobs.reduce((n, blob) => n + blob.sizeBytes, 0);
89
+ const bytes = new TextEncoder().encode(row.operation_json).length;
90
+ const oversizedBlob = blobs.find((blob) => blob.sizeBytes > limits.maxSingleBlobBytes);
91
+ const error = count >= limits.maxOperations
92
+ ? new ReplicaResourceLimitError("operation_count", count + 1, limits.maxOperations)
93
+ : bytes > limits.maxOperationBytes
94
+ ? new ReplicaResourceLimitError("operation_bytes", bytes, limits.maxOperationBytes)
95
+ : oversizedBlob
96
+ ? new ReplicaResourceLimitError("single_blob_bytes", oversizedBlob.sizeBytes, limits.maxSingleBlobBytes)
97
+ : blobBytes + newBytes > limits.maxBlobTotalBytes
98
+ ? new ReplicaResourceLimitError("aggregate_blob_bytes", blobBytes + newBytes, limits.maxBlobTotalBytes)
99
+ : undefined;
100
+ if (error) {
101
+ failures.push({ position: row.position, error });
102
+ continue;
103
+ }
104
+ count++;
105
+ blobBytes += newBytes;
106
+ for (const blob of newBlobs)
107
+ acceptedBlobs.add(blob.blobId);
108
+ }
109
+ // Settle one reason per transition; a subsequent pass checks the survivors.
110
+ const first = failures[0];
111
+ return (first && {
112
+ positions: failures
113
+ .filter((failure) => failure.error.limit === first.error.limit)
114
+ .map((failure) => failure.position),
115
+ error: first.error,
116
+ });
117
+ }
118
+ //# sourceMappingURL=preparation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preparation.js","sourceRoot":"","sources":["../../src/replication/preparation.ts"],"names":[],"mappings":"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"}