@wowok/agent-mcp 3.4.0 → 3.4.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 (405) hide show
  1. package/README.md +8 -0
  2. package/dist/chain-semantics/composition-truth.d.ts +102 -0
  3. package/dist/chain-semantics/composition-truth.js +1 -0
  4. package/dist/chain-semantics/eval-order.js +1 -1
  5. package/dist/chain-semantics/fund-flow.js +1 -1
  6. package/dist/chain-semantics/index.d.ts +1 -0
  7. package/dist/chain-semantics/index.js +1 -1
  8. package/dist/composition/audit.js +1 -1
  9. package/dist/composition/blueprint-view.d.ts +3 -3
  10. package/dist/composition/blueprint-view.js +1 -1
  11. package/dist/composition/compile.d.ts +24 -3
  12. package/dist/composition/compile.js +1 -1
  13. package/dist/composition/emit-phases.d.ts +206 -0
  14. package/dist/composition/emit-phases.js +1 -0
  15. package/dist/composition/generate.d.ts +40 -0
  16. package/dist/composition/generate.js +1 -0
  17. package/dist/composition/guard-fill.d.ts +44 -0
  18. package/dist/composition/guard-fill.js +1 -0
  19. package/dist/composition/inflight.d.ts +20 -2
  20. package/dist/composition/inflight.js +1 -1
  21. package/dist/composition/input-normalize.d.ts +15 -0
  22. package/dist/composition/input-normalize.js +1 -0
  23. package/dist/composition/materialize.d.ts +18 -13
  24. package/dist/composition/materialize.js +1 -1
  25. package/dist/composition/mode-gates.d.ts +35 -0
  26. package/dist/composition/mode-gates.js +1 -0
  27. package/dist/composition/param-disclosure.js +1 -1
  28. package/dist/composition/plan-retry-ledger.d.ts +21 -0
  29. package/dist/composition/plan-retry-ledger.js +1 -0
  30. package/dist/composition/plan.d.ts +7 -2
  31. package/dist/composition/plan.js +1 -1
  32. package/dist/composition/product-card.d.ts +94 -0
  33. package/dist/composition/product-card.js +1 -0
  34. package/dist/composition/supply-chain-emit.d.ts +46 -0
  35. package/dist/composition/supply-chain-emit.js +1 -0
  36. package/dist/config/config-audit.spec.js +1 -1
  37. package/dist/config/config-warnings.d.ts +2 -0
  38. package/dist/config/config-warnings.js +1 -0
  39. package/dist/config/exposure.d.ts +2 -2
  40. package/dist/config/judgment.d.ts +31 -5
  41. package/dist/config/judgment.js +1 -1
  42. package/dist/config/judgment.spec.js +1 -1
  43. package/dist/config/match-policy-file.d.ts +34 -0
  44. package/dist/config/match-policy-file.js +1 -0
  45. package/dist/config/match-policy-file.spec.d.ts +1 -0
  46. package/dist/config/match-policy-file.spec.js +1 -0
  47. package/dist/config/rule-engine.d.ts +5 -5
  48. package/dist/config/rule-engine.js +1 -1
  49. package/dist/config/runtime.d.ts +0 -1
  50. package/dist/config/runtime.js +1 -1
  51. package/dist/config/severity.d.ts +0 -2
  52. package/dist/config/severity.js +1 -1
  53. package/dist/config/store-policy.spec.js +1 -1
  54. package/dist/config/template-params.d.ts +42 -0
  55. package/dist/config/template-params.js +1 -0
  56. package/dist/config/template-params.spec.d.ts +1 -0
  57. package/dist/config/template-params.spec.js +1 -0
  58. package/dist/data/api/api.spec.js +1 -1
  59. package/dist/data/api/server.js +1 -1
  60. package/dist/data/projection/store.d.ts +2 -1
  61. package/dist/data/projection/store.js +1 -1
  62. package/dist/data/projection/types.d.ts +22 -0
  63. package/dist/data/sync/cdc.d.ts +1 -2
  64. package/dist/data/sync/cdc.js +1 -1
  65. package/dist/evaluation/acceptance.d.ts +8 -0
  66. package/dist/evaluation/acceptance.js +1 -1
  67. package/dist/evaluation/builtins/demand-match.js +1 -1
  68. package/dist/evaluation/builtins/graph-service.spec.js +1 -1
  69. package/dist/evaluation/capability.d.ts +2 -0
  70. package/dist/evaluation/category-match-rules.d.ts +0 -1
  71. package/dist/evaluation/category-match-rules.js +1 -1
  72. package/dist/evaluation/composer.d.ts +25 -0
  73. package/dist/evaluation/composer.js +1 -1
  74. package/dist/evaluation/engine.js +1 -1
  75. package/dist/evaluation/extract.d.ts +7 -0
  76. package/dist/evaluation/extract.js +1 -1
  77. package/dist/evaluation/game-strategy.d.ts +0 -3
  78. package/dist/evaluation/game-strategy.js +1 -1
  79. package/dist/evaluation/match-operation.d.ts +9 -0
  80. package/dist/evaluation/match-operation.js +1 -1
  81. package/dist/evaluation/match-policy-resolver.d.ts +9 -0
  82. package/dist/evaluation/match-policy-resolver.js +1 -0
  83. package/dist/evaluation/match-policy.d.ts +3 -1
  84. package/dist/evaluation/match-policy.js +1 -1
  85. package/dist/evaluation/region.d.ts +0 -6
  86. package/dist/evaluation/region.js +1 -1
  87. package/dist/evaluation/standards.d.ts +2 -1
  88. package/dist/evaluation/standards.js +1 -1
  89. package/dist/evaluation/structured-lines.d.ts +8 -0
  90. package/dist/evaluation/structured-lines.js +1 -0
  91. package/dist/evaluation/types.d.ts +6 -0
  92. package/dist/experience/realtime-feedback.js +1 -1
  93. package/dist/extensions/capability-manifest.d.ts +1 -0
  94. package/dist/extensions/capability-manifest.js +1 -1
  95. package/dist/extensions/capability.d.ts +91 -0
  96. package/dist/extensions/capability.js +1 -0
  97. package/dist/extensions/industry-audit.spec.js +1 -1
  98. package/dist/extensions/industry-pack.d.ts +13 -0
  99. package/dist/extensions/industry-pack.js +1 -1
  100. package/dist/extensions/modes.js +1 -1
  101. package/dist/extensions/registry.d.ts +0 -2
  102. package/dist/extensions/registry.js +1 -1
  103. package/dist/goal/GoalEngine.js +1 -1
  104. package/dist/graph/onchain/analyze.js +1 -1
  105. package/dist/graph/onchain/expand.js +1 -1
  106. package/dist/graph/onchain/exposure.js +1 -1
  107. package/dist/graph/onchain/facts.js +1 -1
  108. package/dist/graph/onchain/order-status.d.ts +0 -1
  109. package/dist/graph/onchain/order-status.js +1 -1
  110. package/dist/harness/recover.js +1 -1
  111. package/dist/harness/verify.d.ts +0 -3
  112. package/dist/harness/verify.js +1 -1
  113. package/dist/intent/types.d.ts +0 -1
  114. package/dist/intent/types.js +1 -1
  115. package/dist/keeper/detectors.js +1 -1
  116. package/dist/keeper/types.d.ts +0 -1
  117. package/dist/keeper/types.js +1 -1
  118. package/dist/knowledge/allocation-risk.d.ts +1 -0
  119. package/dist/knowledge/allocation-risk.js +1 -1
  120. package/dist/knowledge/allocator-rail-verifier.d.ts +6 -1
  121. package/dist/knowledge/allocator-rail-verifier.js +1 -1
  122. package/dist/knowledge/arbitration-ledger.js +1 -1
  123. package/dist/knowledge/arbitration-puzzle.js +1 -1
  124. package/dist/knowledge/audit-rules.d.ts +2 -2
  125. package/dist/knowledge/audit-rules.js +1 -1
  126. package/dist/knowledge/baselines/judgment-baselines.json +21 -2
  127. package/dist/knowledge/baselines/rules/oracle.json +120 -0
  128. package/dist/knowledge/baselines/rules/plan.json +384 -17
  129. package/dist/knowledge/baselines/rules/progress.json +20 -2
  130. package/dist/knowledge/builtin-templates.d.ts +12 -1
  131. package/dist/knowledge/builtin-templates.js +1 -1
  132. package/dist/knowledge/component-schema.js +1 -1
  133. package/dist/knowledge/contact-templates.d.ts +0 -1
  134. package/dist/knowledge/contact-templates.js +1 -1
  135. package/dist/knowledge/dynamic-pricing.js +1 -1
  136. package/dist/knowledge/fee-param-bindings.js +1 -1
  137. package/dist/knowledge/fund-layer.d.ts +1 -0
  138. package/dist/knowledge/fund-layer.js +1 -1
  139. package/dist/knowledge/game-scenarios.js +1 -1
  140. package/dist/knowledge/getting-started.js +1 -1
  141. package/dist/knowledge/guard-binding-table.d.ts +52 -0
  142. package/dist/knowledge/guard-binding-table.js +1 -0
  143. package/dist/knowledge/guard-binding-verifier.d.ts +30 -0
  144. package/dist/knowledge/guard-binding-verifier.js +1 -0
  145. package/dist/knowledge/guard-bindings.js +1 -1
  146. package/dist/knowledge/guard-blueprint.d.ts +68 -0
  147. package/dist/knowledge/guard-blueprint.js +1 -0
  148. package/dist/knowledge/guard-design-patterns.d.ts +1 -1
  149. package/dist/knowledge/guard-design-patterns.js +1 -1
  150. package/dist/knowledge/guard-field-cognition.js +1 -1
  151. package/dist/knowledge/guard-host-context.d.ts +24 -0
  152. package/dist/knowledge/guard-host-context.js +1 -0
  153. package/dist/knowledge/guard-lint.js +1 -1
  154. package/dist/knowledge/guard-node-gates.d.ts +3 -0
  155. package/dist/knowledge/guard-node-gates.js +1 -1
  156. package/dist/knowledge/guard-puzzle.js +1 -1
  157. package/dist/knowledge/guard-render.js +1 -1
  158. package/dist/knowledge/guard-risk.js +1 -1
  159. package/dist/knowledge/guard-submission-prompt.d.ts +11 -0
  160. package/dist/knowledge/guard-submission-prompt.js +1 -1
  161. package/dist/knowledge/guard-templates.d.ts +1 -1
  162. package/dist/knowledge/guard-templates.js +1 -1
  163. package/dist/knowledge/guard-translation.js +1 -1
  164. package/dist/knowledge/index.d.ts +1 -1
  165. package/dist/knowledge/index.js +1 -1
  166. package/dist/knowledge/industry-generalizer.d.ts +6 -1
  167. package/dist/knowledge/industry-generalizer.js +1 -1
  168. package/dist/knowledge/industry-registry.js +1 -1
  169. package/dist/knowledge/jsonrpc-enum.d.ts +38 -0
  170. package/dist/knowledge/jsonrpc-enum.js +1 -1
  171. package/dist/knowledge/machine-topology.js +1 -1
  172. package/dist/knowledge/machine-translation.js +1 -1
  173. package/dist/knowledge/object-dependency.d.ts +31 -0
  174. package/dist/knowledge/object-dependency.js +1 -0
  175. package/dist/knowledge/onchain-constants.d.ts +2 -0
  176. package/dist/knowledge/onchain-constants.js +1 -1
  177. package/dist/knowledge/param-schema.d.ts +23 -0
  178. package/dist/knowledge/param-schema.js +1 -1
  179. package/dist/knowledge/param-tiers.js +1 -1
  180. package/dist/knowledge/passport-ledger.js +1 -1
  181. package/dist/knowledge/path-oracle/coverage.d.ts +16 -0
  182. package/dist/knowledge/path-oracle/coverage.js +1 -0
  183. package/dist/knowledge/path-oracle/index.d.ts +5 -0
  184. package/dist/knowledge/path-oracle/index.js +1 -0
  185. package/dist/knowledge/path-oracle/products/food-delivery.d.ts +2 -0
  186. package/dist/knowledge/path-oracle/products/food-delivery.js +1 -0
  187. package/dist/knowledge/path-oracle/schema.d.ts +188 -0
  188. package/dist/knowledge/path-oracle/schema.js +1 -0
  189. package/dist/knowledge/pattern-resolutions.d.ts +2 -0
  190. package/dist/knowledge/pattern-resolutions.js +1 -1
  191. package/dist/knowledge/progress-ledger.js +1 -1
  192. package/dist/knowledge/progress-risk.js +1 -1
  193. package/dist/knowledge/projection.spec.js +1 -1
  194. package/dist/knowledge/protocol-facts.js +1 -1
  195. package/dist/knowledge/requirement-families.d.ts +13 -0
  196. package/dist/knowledge/requirement-families.js +1 -0
  197. package/dist/knowledge/reward-ledger.js +1 -1
  198. package/dist/knowledge/scenario-modes.d.ts +1 -0
  199. package/dist/knowledge/scenario-modes.js +1 -1
  200. package/dist/knowledge/semantic-ir.d.ts +4 -0
  201. package/dist/knowledge/semantic-ir.js +1 -1
  202. package/dist/knowledge/service-ledger.d.ts +1 -1
  203. package/dist/knowledge/service-ledger.js +1 -1
  204. package/dist/knowledge/sku-name-gate.d.ts +17 -0
  205. package/dist/knowledge/sku-name-gate.js +1 -0
  206. package/dist/knowledge/supply-chain.d.ts +9 -0
  207. package/dist/knowledge/supply-chain.js +1 -1
  208. package/dist/knowledge/template-loader.d.ts +14 -6
  209. package/dist/knowledge/template-loader.js +1 -1
  210. package/dist/knowledge/template-nav.d.ts +3 -1
  211. package/dist/knowledge/template-nav.js +1 -1
  212. package/dist/knowledge/template-prose.d.ts +1 -1
  213. package/dist/knowledge/template-registry.js +1 -1
  214. package/dist/knowledge/template-scanner.d.ts +62 -0
  215. package/dist/knowledge/template-scanner.js +1 -1
  216. package/dist/knowledge/template-test-profiles.js +1 -1
  217. package/dist/knowledge/tools-reference.js +1 -1
  218. package/dist/knowledge/workflow-guidance.d.ts +5 -0
  219. package/dist/knowledge/workflow-guidance.js +1 -1
  220. package/dist/monitor/MonitorLoop.js +1 -1
  221. package/dist/participation/radar-core.js +1 -1
  222. package/dist/participation/time-window.js +1 -1
  223. package/dist/persona/address-format.d.ts +0 -1
  224. package/dist/persona/address-format.js +1 -1
  225. package/dist/persona/bridge.js +1 -1
  226. package/dist/persona/index.d.ts +0 -2
  227. package/dist/persona/index.js +1 -1
  228. package/dist/persona/model.js +1 -1
  229. package/dist/persona/persona-audit.spec.js +1 -1
  230. package/dist/persona/types.d.ts +6 -0
  231. package/dist/playbooks/service-build/business-puzzle.js +1 -1
  232. package/dist/playbooks/service-build/game-theory.d.ts +2 -2
  233. package/dist/playbooks/service-build/intent-analyzer.js +1 -1
  234. package/dist/playbooks/service-build/machine-panorama.js +1 -1
  235. package/dist/playbooks/service-build/merchant-guide.d.ts +50 -23
  236. package/dist/playbooks/service-build/merchant-guide.js +1 -1
  237. package/dist/playbooks/service-build/migration-planner.d.ts +2 -0
  238. package/dist/playbooks/service-build/migration-planner.js +1 -1
  239. package/dist/playbooks/service-build/mode-actions.js +1 -1
  240. package/dist/playbooks/service-build/object-panorama.d.ts +8 -0
  241. package/dist/playbooks/service-build/object-panorama.js +1 -1
  242. package/dist/playbooks/service-build/participation-radar.js +1 -1
  243. package/dist/playbooks/service-build/relationship-profile.js +1 -1
  244. package/dist/playbooks/service-build/reverse-mapping.d.ts +6 -0
  245. package/dist/playbooks/service-build/reverse-mapping.js +1 -1
  246. package/dist/playbooks/service-build/service-panorama.d.ts +1 -0
  247. package/dist/playbooks/service-build/service-panorama.js +1 -1
  248. package/dist/playbooks/service-build/service-quote.js +1 -1
  249. package/dist/playbooks/service-build/service-quote.spec.js +1 -1
  250. package/dist/playbooks/service-build/workflow-design-assessment.d.ts +10 -1
  251. package/dist/playbooks/service-build/workflow-design-assessment.js +1 -1
  252. package/dist/review/index.js +1 -1
  253. package/dist/review/repository.js +1 -1
  254. package/dist/safety/confirm-gate.js +1 -1
  255. package/dist/schema/benchmark-migration/index.d.ts +104 -0
  256. package/dist/schema/benchmark-migration/index.js +1 -1
  257. package/dist/schema/call/allocation.d.ts +15 -6
  258. package/dist/schema/call/allocation.js +1 -1
  259. package/dist/schema/call/base.d.ts +256 -0
  260. package/dist/schema/call/base.js +1 -1
  261. package/dist/schema/call/bridge.d.ts +32 -6
  262. package/dist/schema/call/demand.d.ts +15 -6
  263. package/dist/schema/call/demand.js +1 -1
  264. package/dist/schema/call/guard.d.ts +8 -8
  265. package/dist/schema/call/guard.js +1 -1
  266. package/dist/schema/call/handler.d.ts +3 -0
  267. package/dist/schema/call/handler.js +1 -1
  268. package/dist/schema/call/machine.d.ts +32 -8
  269. package/dist/schema/call/machine.js +1 -1
  270. package/dist/schema/call/order.d.ts +26 -8
  271. package/dist/schema/call/order.js +1 -1
  272. package/dist/schema/call/payment.d.ts +20 -8
  273. package/dist/schema/call/payment.js +1 -1
  274. package/dist/schema/call/permission-handler.js +1 -1
  275. package/dist/schema/call/permission.d.ts +330 -114
  276. package/dist/schema/call/permission.js +1 -1
  277. package/dist/schema/call/personal.d.ts +10 -4
  278. package/dist/schema/call/personal.js +1 -1
  279. package/dist/schema/call/progress.d.ts +16 -4
  280. package/dist/schema/call/reward.d.ts +10 -4
  281. package/dist/schema/call/reward.js +1 -1
  282. package/dist/schema/call/semantic.d.ts +1 -0
  283. package/dist/schema/call/semantic.js +1 -1
  284. package/dist/schema/call/service.d.ts +128 -40
  285. package/dist/schema/call/service.js +1 -1
  286. package/dist/schema/call/treasury.d.ts +15 -6
  287. package/dist/schema/call/treasury.js +1 -1
  288. package/dist/schema/common/index.js +1 -1
  289. package/dist/schema/config/index.d.ts +61 -0
  290. package/dist/schema/config/index.js +1 -1
  291. package/dist/schema/envelope-unify.d.ts +4 -0
  292. package/dist/schema/envelope-unify.js +1 -0
  293. package/dist/schema/evaluation/index.d.ts +216 -19
  294. package/dist/schema/evaluation/index.js +1 -1
  295. package/dist/schema/goal/index.d.ts +47 -0
  296. package/dist/schema/goal/planning.d.ts +115 -1
  297. package/dist/schema/goal/planning.js +1 -1
  298. package/dist/schema/industry-pack/index.d.ts +137 -6
  299. package/dist/schema/industry-pack/index.js +1 -1
  300. package/dist/schema/industry-pack/modes.d.ts +6 -6
  301. package/dist/schema/keeper/index.d.ts +26 -0
  302. package/dist/schema/local/index.d.ts +137 -0
  303. package/dist/schema/local/index.js +1 -1
  304. package/dist/schema/local/wip.d.ts +6 -0
  305. package/dist/schema/local/wip.js +1 -1
  306. package/dist/schema/messenger/index.d.ts +26 -0
  307. package/dist/schema/operations.d.ts +342 -83
  308. package/dist/schema/operations.js +1 -1
  309. package/dist/schema/persona/index.d.ts +2907 -640
  310. package/dist/schema/persona/index.js +1 -1
  311. package/dist/schema/query/bi.d.ts +145 -4
  312. package/dist/schema/query/bi.js +1 -1
  313. package/dist/schema/query/index.d.ts +266 -73
  314. package/dist/schema/query/index.js +1 -1
  315. package/dist/schema/schema-query/index.d.ts +1 -1
  316. package/dist/schema/schema-query/index.js +1 -1
  317. package/dist/schema/schema-version.js +1 -1
  318. package/dist/schema/utils/permission-machine-check.d.ts +2 -0
  319. package/dist/schema/utils/permission-machine-check.js +1 -1
  320. package/dist/schema/watch/index.d.ts +16 -0
  321. package/dist/schema/watch/index.js +1 -1
  322. package/dist/schema/workflow/index.d.ts +2 -2
  323. package/dist/schema/workflow/index.js +1 -1
  324. package/dist/schema-query-impl/index.d.ts +1 -1
  325. package/dist/schema-query-impl/index.js +1 -1
  326. package/dist/schemas/account_operation.output.json +94 -0
  327. package/dist/schemas/benchmark_migration_operation.output.json +338 -9
  328. package/dist/schemas/benchmark_migration_operation.schema.json +26 -1
  329. package/dist/schemas/bridge_operation.output.json +94 -0
  330. package/dist/schemas/config_operation.output.json +352 -0
  331. package/dist/schemas/config_operation.schema.json +20 -2
  332. package/dist/schemas/evaluation_operation.output.json +570 -4
  333. package/dist/schemas/evaluation_operation.schema.json +194 -3
  334. package/dist/schemas/goal_operation.schema.json +183 -0
  335. package/dist/schemas/index.json +1 -1
  336. package/dist/schemas/industry_pack_operation.output.json +621 -0
  337. package/dist/schemas/industry_pack_operation.schema.json +20 -2
  338. package/dist/schemas/keeper_operation.output.json +94 -0
  339. package/dist/schemas/local_cache_operation.output.json +94 -0
  340. package/dist/schemas/local_history_operation.output.json +94 -0
  341. package/dist/schemas/local_info_operation.output.json +94 -0
  342. package/dist/schemas/local_mark_operation.output.json +94 -0
  343. package/dist/schemas/messenger_operation.output.json +94 -0
  344. package/dist/schemas/monitor_events.output.json +94 -0
  345. package/dist/schemas/monitor_subscription.output.json +94 -0
  346. package/dist/schemas/onchain_events.output.json +94 -0
  347. package/dist/schemas/onchain_operations.output.json +313 -1
  348. package/dist/schemas/onchain_operations.schema.json +1248 -664
  349. package/dist/schemas/onchain_operations_allocation.schema.json +30 -15
  350. package/dist/schemas/onchain_operations_arbitration.schema.json +9 -2
  351. package/dist/schemas/onchain_operations_contact.schema.json +8 -1
  352. package/dist/schemas/onchain_operations_demand.schema.json +29 -14
  353. package/dist/schemas/onchain_operations_gen_passport.schema.json +8 -1
  354. package/dist/schemas/onchain_operations_guard.schema.json +290 -105
  355. package/dist/schemas/onchain_operations_machine.schema.json +49 -34
  356. package/dist/schemas/onchain_operations_order.schema.json +63 -40
  357. package/dist/schemas/onchain_operations_payment.schema.json +26 -11
  358. package/dist/schemas/onchain_operations_permission.schema.json +362 -235
  359. package/dist/schemas/onchain_operations_personal.schema.json +27 -15
  360. package/dist/schemas/onchain_operations_progress.schema.json +45 -30
  361. package/dist/schemas/onchain_operations_proof.schema.json +8 -1
  362. package/dist/schemas/onchain_operations_repository.schema.json +8 -1
  363. package/dist/schemas/onchain_operations_reward.schema.json +32 -17
  364. package/dist/schemas/onchain_operations_service.schema.json +221 -124
  365. package/dist/schemas/onchain_operations_treasury.schema.json +32 -17
  366. package/dist/schemas/onchain_table_data.output.json +258 -6
  367. package/dist/schemas/onchain_table_data.schema.json +92 -52
  368. package/dist/schemas/persona_operation.output.json +7752 -0
  369. package/dist/schemas/persona_operation.schema.json +1232 -4
  370. package/dist/schemas/query_toolkit.output.json +756 -116
  371. package/dist/schemas/query_toolkit.schema.json +138 -7
  372. package/dist/schemas/schema_query.schema.json +1 -1
  373. package/dist/schemas/watch_operation.output.json +83 -0
  374. package/dist/schemas/wip_file.output.json +8 -0
  375. package/dist/schemas/workflow_operation.schema.json +2 -2
  376. package/dist/tools/handlers/benchmark-migration.d.ts +11 -3
  377. package/dist/tools/handlers/benchmark-migration.js +1 -1
  378. package/dist/tools/handlers/config.js +1 -1
  379. package/dist/tools/handlers/evaluation.js +1 -1
  380. package/dist/tools/handlers/evaluation.spec.js +1 -1
  381. package/dist/tools/handlers/industry-pack.js +1 -1
  382. package/dist/tools/handlers/onchain.d.ts +20 -0
  383. package/dist/tools/handlers/onchain.js +1 -1
  384. package/dist/tools/handlers/persona.js +1 -1
  385. package/dist/tools/handlers/query.d.ts +8 -0
  386. package/dist/tools/handlers/query.js +1 -1
  387. package/dist/tools/handlers/winner-derivation.d.ts +20 -0
  388. package/dist/tools/handlers/winner-derivation.js +1 -0
  389. package/dist/tools/handlers/wip-upload.js +1 -1
  390. package/dist/tools/index.d.ts +1 -0
  391. package/dist/tools/index.js +1 -1
  392. package/dist/tools/registry/business.js +1 -1
  393. package/dist/tools/registry/config.js +1 -1
  394. package/dist/tools/registry/evaluation.js +1 -1
  395. package/dist/tools/registry/identity.js +1 -1
  396. package/dist/tools/registry/query.js +1 -1
  397. package/dist/tools/transport-integrity.d.ts +7 -0
  398. package/dist/tools/transport-integrity.js +1 -0
  399. package/dist/tools/upgrade-check.js +1 -1
  400. package/dist/tools/wrap.d.ts +5 -0
  401. package/dist/tools/wrap.js +1 -1
  402. package/package.json +2 -2
  403. package/dist/extensions/business-modules.d.ts +0 -54
  404. package/dist/extensions/business-modules.js +0 -1
  405. package/dist/schemas/guard-templates.json +0 -379
@@ -1,7 +1,5 @@
1
1
  export declare const SEVERITY_ORDER: readonly ["critical", "high", "medium", "low", "info"];
2
2
  export type Severity = (typeof SEVERITY_ORDER)[number];
3
- export declare function compareSeverity(a: Severity, b: Severity): number;
4
3
  export declare function severityRank(s: Severity): number;
5
4
  export declare function maxSeverity(list: ReadonlyArray<Severity>): Severity;
6
5
  export declare function normalizeSeverity(raw: string): Severity;
7
- export declare function isSeverity(raw: string): raw is Severity;
@@ -1 +1 @@
1
- export const SEVERITY_ORDER=['critical','high','medium','low','info'];const RANK={'critical':0x4,'high':0x3,'medium':0x2,'low':0x1,'info':0x0},LEGACY_ALIASES={'warning':'high','warn':'high'};export function compareSeverity(c,d){return RANK[c]-RANK[d];}export function severityRank(a){return RANK[a];}export function maxSeverity(a){let b='info';for(const c of a){if(RANK[c]>RANK[b])b=c;}return b;}export function normalizeSeverity(a){const b=a?.['toLowerCase']();if(SEVERITY_ORDER['includes'](b))return b;return LEGACY_ALIASES[b]??'info';}export function isSeverity(a){return SEVERITY_ORDER['includes'](a?.['toLowerCase']());}
1
+ export const SEVERITY_ORDER=['critical','high','medium','low','info'];const RANK={'critical':0x4,'high':0x3,'medium':0x2,'low':0x1,'info':0x0},LEGACY_ALIASES={'warning':'high','warn':'high'};export function severityRank(a){return RANK[a];}export function maxSeverity(a){let b='info';for(const c of a){if(RANK[c]>RANK[b])b=c;}return b;}export function normalizeSeverity(a){const b=a?.['toLowerCase']();if(SEVERITY_ORDER['includes'](b))return b;return LEGACY_ALIASES[b]??'info';}
@@ -1 +1 @@
1
- import{mkdtempSync,writeFileSync}from'fs';import{tmpdir}from'os';import{join}from'path';import{describe,expect,it,beforeEach}from'vitest';import{getStoreDualPayoutPolicy,setStoreDualPayoutPreauthorization,clearStoreDualPayoutPreauthorization,isDualPayoutPreauthorized}from'./store-policy.js';const ACC='0xABCdef1234567890abcdef1234567890abcdef12',ACC_LOWER=ACC['toLowerCase']();describe('store-policy\x20D-1\x20ledger',()=>{let a;beforeEach(()=>{a=mkdtempSync(join(tmpdir(),'wowok-store-policy-')),process['env']['WOWOK_CONFIG_DIR']=a;}),it('set\x20WITHOUT\x20confirm\x20throws\x20and\x20records\x20nothing',()=>{expect(()=>setStoreDualPayoutPreauthorization(ACC,{'confirm':![]}))['toThrow'](/confirm=true/),expect(()=>setStoreDualPayoutPreauthorization(ACC,{}))['toThrow'](/confirm=true/),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined']();}),it('set\x20with\x20confirm:true\x20persists\x20and\x20get\x20roundtrips\x20(case-insensitive\x20key)',()=>{const b=setStoreDualPayoutPreauthorization(ACC,{'confirm':!![],'note':'merchant\x20standing\x20netting','network':'mainnet'});expect(b['preauthorized'])['toBe'](!![]),expect(b['authorized_at'])['toBeTruthy'](),expect(b['note'])['toBe']('merchant\x20standing\x20netting'),expect(getStoreDualPayoutPolicy(ACC['toLowerCase']())?.['preauthorized'])['toBe'](!![]),expect(getStoreDualPayoutPolicy(ACC['toUpperCase']())?.['preauthorized'])['toBe'](!![]),expect(isDualPayoutPreauthorized(ACC))['toBe'](!![]);}),it('unconfigured\x20account\x20→\x20not\x20preauthorized\x20(safe\x20hard-block\x20default)',()=>{expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),expect(isDualPayoutPreauthorized(undefined))['toBe'](![]),expect(isDualPayoutPreauthorized(''))['toBe'](![]);}),it('clear\x20removes\x20an\x20existing\x20record\x20(true)\x20and\x20reports\x20false\x20when\x20absent',()=>{setStoreDualPayoutPreauthorization(ACC,{'confirm':!![]}),expect(clearStoreDualPayoutPreauthorization(ACC['toUpperCase']()))['toBe'](!![]),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),expect(clearStoreDualPayoutPreauthorization(ACC))['toBe'](![]);}),it('corrupt\x20policy\x20file\x20→\x20fail-soft\x20to\x20not-preauthorized\x20(never\x20crashes\x20the\x20gate\x20read)',()=>{writeFileSync(join(a,'store-policies.json'),'{not\x20json\x20at\x20all','utf-8'),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),setStoreDualPayoutPreauthorization(ACC,{'confirm':!![]}),expect(isDualPayoutPreauthorized(ACC))['toBe'](!![]);});});
1
+ import{mkdtempSync,writeFileSync}from'fs';import{tmpdir}from'os';import{join}from'path';import{describe,expect,it,beforeEach}from'vitest';import{getStoreDualPayoutPolicy,setStoreDualPayoutPreauthorization,clearStoreDualPayoutPreauthorization,isDualPayoutPreauthorized}from'./store-policy.js';const ACC='0xABCdef1234567890abcdef1234567890abcdef12';describe('store-policy\x20D-1\x20ledger',()=>{let a;beforeEach(()=>{a=mkdtempSync(join(tmpdir(),'wowok-store-policy-')),process['env']['WOWOK_CONFIG_DIR']=a;}),it('set\x20WITHOUT\x20confirm\x20throws\x20and\x20records\x20nothing',()=>{expect(()=>setStoreDualPayoutPreauthorization(ACC,{'confirm':![]}))['toThrow'](/confirm=true/),expect(()=>setStoreDualPayoutPreauthorization(ACC,{}))['toThrow'](/confirm=true/),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined']();}),it('set\x20with\x20confirm:true\x20persists\x20and\x20get\x20roundtrips\x20(case-insensitive\x20key)',()=>{const b=setStoreDualPayoutPreauthorization(ACC,{'confirm':!![],'note':'merchant\x20standing\x20netting','network':'mainnet'});expect(b['preauthorized'])['toBe'](!![]),expect(b['authorized_at'])['toBeTruthy'](),expect(b['note'])['toBe']('merchant\x20standing\x20netting'),expect(getStoreDualPayoutPolicy(ACC['toLowerCase']())?.['preauthorized'])['toBe'](!![]),expect(getStoreDualPayoutPolicy(ACC['toUpperCase']())?.['preauthorized'])['toBe'](!![]),expect(isDualPayoutPreauthorized(ACC))['toBe'](!![]);}),it('unconfigured\x20account\x20→\x20not\x20preauthorized\x20(safe\x20hard-block\x20default)',()=>{expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),expect(isDualPayoutPreauthorized(undefined))['toBe'](![]),expect(isDualPayoutPreauthorized(''))['toBe'](![]);}),it('clear\x20removes\x20an\x20existing\x20record\x20(true)\x20and\x20reports\x20false\x20when\x20absent',()=>{setStoreDualPayoutPreauthorization(ACC,{'confirm':!![]}),expect(clearStoreDualPayoutPreauthorization(ACC['toUpperCase']()))['toBe'](!![]),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),expect(clearStoreDualPayoutPreauthorization(ACC))['toBe'](![]);}),it('corrupt\x20policy\x20file\x20→\x20fail-soft\x20to\x20not-preauthorized\x20(never\x20crashes\x20the\x20gate\x20read)',()=>{writeFileSync(join(a,'store-policies.json'),'{not\x20json\x20at\x20all','utf-8'),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),setStoreDualPayoutPreauthorization(ACC,{'confirm':!![]}),expect(isDualPayoutPreauthorized(ACC))['toBe'](!![]);});});
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ declare const TemplateParamsFileSchema: z.ZodObject<{
3
+ version: z.ZodOptional<z.ZodNumber>;
4
+ comment: z.ZodOptional<z.ZodString>;
5
+ defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>;
6
+ templates: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>>;
7
+ }, z.core.$strict>;
8
+ export type TemplateParamsFileState = z.infer<typeof TemplateParamsFileSchema>;
9
+ export interface TemplateParamFileRead {
10
+ path: string;
11
+ exists: boolean;
12
+ error: string | null;
13
+ comment?: string;
14
+ defaults?: Record<string, number | string>;
15
+ templates?: Record<string, Record<string, number | string>>;
16
+ }
17
+ export declare function templateParamsFilePath(): string;
18
+ export declare function getTemplateParamFileState(): TemplateParamFileRead;
19
+ export declare function getTemplateParamFileLayer(templateId: string): Record<string, number | string>;
20
+ export declare function resetTemplateParamFileCache(): void;
21
+ export interface TemplateParamPatchChange {
22
+ path: string;
23
+ old: unknown;
24
+ new: unknown;
25
+ }
26
+ export interface TemplateParamPatchResult {
27
+ applied: true;
28
+ path: string;
29
+ backup_path: string | null;
30
+ changed: TemplateParamPatchChange[];
31
+ error: string | null;
32
+ }
33
+ export declare function patchTemplateParamFile(patch: unknown): TemplateParamPatchResult;
34
+ export interface TemplateParamClearResult {
35
+ cleared: boolean;
36
+ path: string;
37
+ scope: "file" | "defaults" | "template";
38
+ template_id?: string;
39
+ backup_path: string | null;
40
+ }
41
+ export declare function clearTemplateParamFile(template?: string): TemplateParamClearResult;
42
+ export {};
@@ -0,0 +1 @@
1
+ import*as a42a from'node:fs';import*as a42b from'node:path';import{z}from'zod';import{getWowMcpDir}from'@wowok/wowok';const FILE_NAME='template-params.json',ParamValueSchema=z['union']([z['number']()['finite']()['nonnegative'](),z['string']()['min'](0x1)]),TemplateParamsFileSchema=z['object']({'version':z['number']()['int']()['nonnegative']()['optional'](),'comment':z['string']()['optional'](),'defaults':z['record'](z['string'](),ParamValueSchema)['optional'](),'templates':z['record'](z['string'](),z['record'](z['string'](),ParamValueSchema))['optional']()})['strict']();export function templateParamsFilePath(){const a=process['env']['WOWOK_CONFIG_DIR']||getWowMcpDir();return a42b['join'](a,FILE_NAME);}let cache=null;function zodMessage(a){return a instanceof z['ZodError']?a['issues']['map'](b=>b['path']['join']('.')+':\x20'+b['message'])['join'](';\x20'):a instanceof Error?a['message']:String(a);}function readAndParse(a){let b;try{b=a42a['readFileSync'](a,'utf-8');}catch(c){return{'path':a,'exists':!![],'error':'unreadable:\x20'+(c instanceof Error?c['message']:String(c))};}try{const d=TemplateParamsFileSchema['parse'](JSON['parse'](b));return{'path':a,'exists':!![],'error':null,...d['comment']!==undefined?{'comment':d['comment']}:{},...d['defaults']!==undefined?{'defaults':d['defaults']}:{},...d['templates']!==undefined?{'templates':d['templates']}:{}};}catch(f){return{'path':a,'exists':!![],'error':zodMessage(f)};}}export function getTemplateParamFileState(){const a=templateParamsFilePath();try{const b=a42a['statSync'](a);if(cache&&cache['mtimeMs']===b['mtimeMs'])return cache['state'];const c=readAndParse(a);if(c['error']===null)cache={'mtimeMs':b['mtimeMs'],'state':c};return c;}catch{return{'path':a,'exists':![],'error':null};}}export function getTemplateParamFileLayer(a){const b=getTemplateParamFileState();if(b['error']!==null)return{};const c=b['templates']?.[a];return{...b['defaults']??{},...c??{}};}export function resetTemplateParamFileCache(){cache=null;}function isPlainObject(a){return typeof a==='object'&&a!==null&&!Array['isArray'](a);}function deepMergeValues(a,b){if(isPlainObject(a)&&isPlainObject(b)){const c={...a};for(const [d,e]of Object['entries'](b)){c[d]=d in a?deepMergeValues(a[d],e):e;}return c;}return b;}function collectLeafChanges(a,c,d,e){if(isPlainObject(c)){const f=isPlainObject(a)?a:{};for(const [g,h]of Object['entries'](c)){collectLeafChanges(f[g],h,d?d+'.'+g:g,e);}return;}JSON['stringify'](a)!==JSON['stringify'](c)&&e['push']({'path':d||'(root)','old':a===undefined?null:a,'new':c});}export function patchTemplateParamFile(a){const b=templateParamsFilePath(),c=a42b['join'](a42b['dirname'](b),'template-params.backup.json');if(!isPlainObject(a))throw new Error('\x27patch\x27\x20must\x20be\x20an\x20object\x20like\x20{\x22defaults\x22:\x20{…},\x20\x22templates\x22:\x20{\x22<tpl-id>\x22:\x20{…}}}');const d=Object['keys'](a)['filter'](m=>m!=='defaults'&&m!=='templates'&&m!=='comment');if(d['length']>0x0)throw new Error('patch\x20rejected:\x20unknown\x20key(s)\x20'+d['map'](m=>'\x27'+m+'\x27')['join'](',\x20')+'\x20—\x20allowed:\x20defaults,\x20templates,\x20comment');let f={},g=![];try{const m=a42a['readFileSync'](b,'utf-8');g=!![],f=TemplateParamsFileSchema['parse'](JSON['parse'](m));}catch(n){if(g)throw new Error('the\x20current\x20template-params.json\x20is\x20not\x20a\x20valid\x20template-params\x20document\x20('+zodMessage(n)+')\x20—\x20fix\x20or\x20remove\x20'+b+'\x20by\x20hand\x20first');f={};}const h={...f},i=[];for(const o of['defaults','templates']){const p=a[o];if(p===undefined)continue;if(!isPlainObject(p))throw new Error('patch.'+o+'\x20must\x20be\x20an\x20object\x20(param\x20→\x20value'+(o==='templates'?',\x20keyed\x20by\x20template\x20id':'')+')');const q=deepMergeValues(f[o]??{},p);try{h[o]=TemplateParamsFileSchema['shape'][o]['parse'](q);}catch(r){throw new Error('patch.'+o+'\x20rejected:\x20'+zodMessage(r));}collectLeafChanges(f[o]??{},p,o,i);}if(a['comment']!==undefined){if(typeof a['comment']!=='string')throw new Error('patch.comment\x20must\x20be\x20a\x20string');h['comment']=a['comment'];}if(i['length']===0x0)return{'applied':!![],'path':b,'backup_path':null,'changed':i,'error':null};const j={'version':0x1,...h};TemplateParamsFileSchema['parse'](j);const k=JSON['stringify'](j,null,0x2)+'\x0a';a42a['mkdirSync'](a42b['dirname'](b),{'recursive':!![]});if(g)a42a['copyFileSync'](b,c);const l=b+'.tmp';return a42a['writeFileSync'](l,k,'utf-8'),a42a['renameSync'](l,b),cache={'mtimeMs':a42a['statSync'](b)['mtimeMs'],'state':readAndParse(b)},{'applied':!![],'path':b,'backup_path':g?c:null,'changed':i,'error':cache['state']['error']};}export function clearTemplateParamFile(a){const b=templateParamsFilePath(),c=a42b['join'](a42b['dirname'](b),'template-params.backup.json');try{a42a['statSync'](b);}catch{return{'cleared':![],'path':b,'scope':'file','backup_path':null};}a42a['copyFileSync'](b,c);if(!a)return a42a['rmSync'](b),cache=null,{'cleared':!![],'path':b,'scope':'file','backup_path':c};let d;try{d=JSON['parse'](a42a['readFileSync'](b,'utf-8'));}catch(g){throw new Error('template-params.json\x20is\x20unreadable\x20('+zodMessage(g)+')\x20—\x20clear\x20the\x20WHOLE\x20file\x20(omit\x20\x27template\x27)\x20or\x20remove\x20'+b+'\x20by\x20hand');}if(a==='defaults')delete d['defaults'];else{const h=isPlainObject(d['templates'])?{...d['templates']}:{};if(!(a in h))return{'cleared':![],'path':b,'scope':'template','template_id':a,'backup_path':null};delete h[a],d['templates']=h;}const f=isPlainObject(d['defaults'])&&Object['keys'](d['defaults'])['length']>0x0||isPlainObject(d['templates'])&&Object['keys'](d['templates'])['length']>0x0;if(f){const i=JSON['stringify'](d,null,0x2)+'\x0a',j=b+'.tmp';a42a['writeFileSync'](j,i,'utf-8'),a42a['renameSync'](j,b);}else a42a['rmSync'](b);return cache=null,{'cleared':!![],'path':b,'scope':a==='defaults'?'defaults':'template','template_id':a==='defaults'?undefined:a,'backup_path':c};}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import{mkdtempSync,rmSync,writeFileSync,existsSync}from'node:fs';import{tmpdir}from'node:os';import{join}from'node:path';import{afterEach,beforeEach,describe,expect,it}from'vitest';import{getTemplateParamFileLayer,getTemplateParamFileState,patchTemplateParamFile,clearTemplateParamFile,resetTemplateParamFileCache,templateParamsFilePath}from'./template-params.js';let dir;beforeEach(()=>{dir=mkdtempSync(join(tmpdir(),'tpl-params-')),process['env']['WOWOK_CONFIG_DIR']=dir,resetTemplateParamFileCache();}),afterEach(()=>{delete process['env']['WOWOK_CONFIG_DIR'],resetTemplateParamFileCache(),rmSync(dir,{'recursive':!![],'force':!![]});}),describe('template-params\x20config\x20layer',()=>{it('is\x20inert\x20when\x20no\x20file\x20exists\x20({}\x20layer,\x20shipped\x20defaults\x20in\x20force)',()=>{const a=getTemplateParamFileState();expect(a['exists'])['toBe'](![]),expect(a['error'])['toBeNull'](),expect(getTemplateParamFileLayer('travel/global-ota'))['toEqual']({});}),it('patches\x20defaults\x20+\x20per-template\x20sections;\x20the\x20template\x20section\x20wins\x20over\x20defaults',()=>{const a=patchTemplateParamFile({'defaults':{'review_window_days':0x7,'platform_commission_bps':0x0},'templates':{'travel/global-ota':{'review_window_days':0x3}}});expect(a['applied'])['toBe'](!![]),expect(a['error'])['toBeNull'](),expect(existsSync(templateParamsFilePath()))['toBe'](!![]),expect(getTemplateParamFileLayer('freelance/agent-task'))['toEqual']({'review_window_days':0x7,'platform_commission_bps':0x0}),expect(getTemplateParamFileLayer('travel/global-ota'))['toEqual']({'review_window_days':0x3,'platform_commission_bps':0x0});}),it('deep-merges\x20a\x20second\x20patch\x20into\x20the\x20current\x20file\x20and\x20records\x20leaf\x20changes',()=>{patchTemplateParamFile({'defaults':{'review_window_days':0x7}});const a=patchTemplateParamFile({'defaults':{'escrow_release_days':0x2}});expect(a['changed']['map'](b=>b['path']))['toContain']('defaults.escrow_release_days'),expect(getTemplateParamFileLayer('retail/vertical-handmade'))['toEqual']({'review_window_days':0x7,'escrow_release_days':0x2});}),it('rejects\x20an\x20illegal\x20value\x20BEFORE\x20any\x20disk\x20write\x20(string\x20or\x20finite\x20non-negative\x20number\x20only)',()=>{expect(()=>patchTemplateParamFile({'defaults':{'review_window_days':-0x1}}))['toThrow'](),expect(()=>patchTemplateParamFile({'defaults':{'review_window_days':!![]}}))['toThrow'](),expect(existsSync(templateParamsFilePath()))['toBe'](![]);}),it('never\x20patches\x20over\x20an\x20existing\x20invalid\x20file\x20—\x20the\x20human\x20fixes\x20it\x20by\x20hand',()=>{writeFileSync(templateParamsFilePath(),'{\x20not\x20json','utf-8'),expect(()=>patchTemplateParamFile({'defaults':{'review_window_days':0x7}}))['toThrow'](/not a valid template-params document/);}),it('clears\x20one\x20template\x20section,\x20keeps\x20the\x20rest;\x20clears\x20the\x20whole\x20file\x20without\x20an\x20id',()=>{patchTemplateParamFile({'defaults':{'review_window_days':0x7},'templates':{'travel/global-ota':{'escrow_release_days':0x3},'retail/vertical-handmade':{}}});const a=clearTemplateParamFile('travel/global-ota');expect(a['cleared'])['toBe'](!![]),expect(a['scope'])['toBe']('template'),expect(getTemplateParamFileLayer('travel/global-ota'))['toEqual']({'review_window_days':0x7});const b=clearTemplateParamFile();expect(b['cleared'])['toBe'](!![]),expect(b['scope'])['toBe']('file'),expect(existsSync(templateParamsFilePath()))['toBe'](![]),expect(getTemplateParamFileLayer('retail/vertical-handmade'))['toEqual']({});});});
@@ -1 +1 @@
1
- import{toBase58}from'@wowok/wowok';import{DataType,newDb}from'pg-mem';import{afterEach,beforeEach,describe,expect,it}from'vitest';import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createProjectionApi}from'./server.js';const digest=toBase58(new Uint8Array(0x20)['fill'](0x7)),objectId='0x14'+'01'['repeat'](0x1f);describe('projection\x20read-only\x20API',()=>{let a,b,c,d;beforeEach(async()=>{const e=newDb();e['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:f}=e['adapters']['createPg']();a=new PostgresProjectionStore(new f(),0x10),b=new PostgresSyncStore(new f()),await a['migrate'](),await b['migrate'](),await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-1','payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'json+bcs-v1','payload_json':{'name':'Indexed\x20service','stock':0x3},'checkpoint':'100','tx_digest':digest,'state':'active','observed_at':'2026-10-24T00:00:00.000Z'});const g=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'100'});await b['savePage']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId'],'cursor':null,'checkpoint':'100','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId']}),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(i=>c['listen'](0x0,'127.0.0.1',i));const h=c['address']();d='http://127.0.0.1:'+h['port'];}),afterEach(async()=>{await new Promise((e,f)=>{c['close'](g=>g?f(g):e());}),await a['close'](),await b['close']();}),it('returns\x20projection\x20and\x20persisted\x20sync\x20status',async()=>{const e=await fetch(d+'/v1/status'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f)['toMatchObject']({'chain_id':'chain_a','read_only':!![],'projection':{'active_objects':0x1,'coverage':{'complete':![]}},'sync':[{'state':'complete','pages':0x1,'objects':0x1}],'head':null,'freshness':null,'cdc':[]}),expect(f['watermarks'])['toEqual']([{'verified_kind':'Service','max_checkpoint':'100','active_objects':0x1}]);}),it('publishes\x20every\x20CDC\x20cursor\x20with\x20its\x20distance\x20from\x20head',async()=>{await b['setCdcCheckpoint']('chain_a','Service','100'),await b['setCdcCheckpoint']('chain_a','Demand','90');const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'head':{'read':async()=>({'checkpoint':'200','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await(await fetch('http://127.0.0.1:'+f['port']+'/v1/status'))['json']();expect(g['cdc'])['toEqual']([{'kind':'Demand','checkpoint':'90','updated_at':expect['any'](String),'behind_head':'110'},{'kind':'Service','checkpoint':'100','updated_at':expect['any'](String),'behind_head':'100'}]);}finally{await new Promise((h,i)=>{e['close'](j=>j?i(j):h());});}}),it('reports\x20chain-head\x20lag\x20and\x20staleness\x20when\x20a\x20probe\x20is\x20configured',async()=>{const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleLag':0x3,'head':{'read':async()=>({'checkpoint':'105','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await fetch('http://127.0.0.1:'+f['port']+'/v1/status'),h=await g['json']();expect(h['head'])['toMatchObject']({'checkpoint':'105','source':'probe'}),expect(h['freshness'])['toMatchObject']({'head_checkpoint':'105','projection_checkpoint':'100','head_lag':'5','stale':!![]}),expect(h['freshness']['projection_age_seconds'])['toBe'](0x0),expect(h['freshness']['version_observed_at'])['toBe']('2026-10-24T00:00:00.000Z');}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('scores\x20freshness\x20off\x20the\x20last\x20confirmed\x20round,\x20not\x20off\x20the\x20last\x20version\x20change',async()=>{const e=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'200'});await b['savePage']({'chainId':e['chainId'],'stream':e['stream'],'runId':e['runId'],'cursor':null,'checkpoint':'200','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':e['chainId'],'stream':e['stream'],'runId':e['runId']});const f=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleAgeSec':0x1,'head':{'read':async()=>({'checkpoint':'210','observed_at':new Date()['toISOString'](),'source':'probe'})}});await new Promise(h=>f['listen'](0x0,'127.0.0.1',h));const g=f['address']();try{const h=await(await fetch('http://127.0.0.1:'+g['port']+'/v1/status'))['json']();expect(h['freshness'])['toMatchObject']({'projection_checkpoint':'200','head_lag':'10','version_checkpoint':'100','version_observed_at':'2026-10-24T00:00:00.000Z','stale':![]}),expect(h['freshness']['projection_age_seconds'])['toBeLessThan'](0x3c);}finally{await new Promise((i,j)=>{f['close'](k=>k?j(k):i());});}}),it('splits\x20quarantined\x20facts\x20into\x20blocking\x20and\x20superseded',async()=>{const e=await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-other','payload_hash':'0x'+'42'['repeat'](0x20),'payload_format':'json+bcs-v1','checkpoint':'150','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});expect(e['status'])['toBe']('conflict');const f=await a['apply']({'chain_id':'chain_a','object_id':'0x14'+'02'['repeat'](0x1f),'object_version':'7','move_type':'0x9::unknown::Unknown','owner_kind':'Shared','payload_uri':'test://raw/unknown-1','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'json+bcs-v1','checkpoint':'160','tx_digest':digest,'state':'active','observed_at':'2026-10-24T02:00:00.000Z'});expect(f['status'])['toBe']('quarantined');const g=await(await fetch(d+'/v1/status'))['json']();expect(g['quarantine']['blocking'])['toBe'](0x1),expect(g['quarantine']['entries']['map'](h=>[h['reason_code'],h['blocking']]))['toEqual']([['UNSUPPORTED_OR_INVALID_MOVE_TYPE',!![]],['CONFLICTING_OBJECT_VERSION',![]]]),expect(g['quarantine']['entries'][0x1]['object_id'])['toBe'](objectId);}),it('calls\x20a\x20projection\x20stale\x20by\x20age\x20even\x20when\x20it\x20sits\x20on\x20the\x20chain\x20head',async()=>{for(const g of await b['status']('chain_a')){await b['fail'](g['chainId'],g['stream'],g['runId'],'simulated\x20timer\x20outage');}const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleAgeSec':0x1,'head':{'read':async()=>({'checkpoint':'100','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(h=>e['listen'](0x0,'127.0.0.1',h));const f=e['address']();try{const h=await(await fetch('http://127.0.0.1:'+f['port']+'/v1/status'))['json']();expect(h['freshness'])['toMatchObject']({'head_lag':'0','stale':!![]}),expect(h['projection']['observed_at'])['toBe']('2026-10-24T00:00:00.000Z');}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('lists\x20current\x20objects\x20with\x20coverage\x20and\x20version\x20metadata',async()=>{const e=await fetch(d+'/v1/objects?kind=Service&limit=1'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f['objects'])['toHaveLength'](0x1),expect(f['objects'][0x0])['toMatchObject']({'objectId':objectId,'objectVersion':'1','verifiedKind':'Service','payloadJson':{'name':'Indexed\x20service','stock':0x3}}),expect(f['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(e['headers']['get']('cache-control'))['toBe']('no-store');}),it('rejects\x20invalid\x20selectors\x20without\x20exposing\x20internal\x20errors',async()=>{const e=await fetch(d+'/v1/objects?kind=Unknown'),f=await fetch(d+'/v1/objects?cursor=invalid'),g=await fetch(d+'/v1/objects?shard_count=16');expect(e['status'])['toBe'](0x190),expect(f['status'])['toBe'](0x190),expect(g['status'])['toBe'](0x190),expect(await e['json']())['toEqual']({'error':{'code':'BAD_REQUEST','message':'Unknown\x20object\x20kind:\x20Unknown'}});}),it('exposes\x20graph\x20edges\x20with\x20orphan\x20annotation',async()=>{const e='0x15'+'02'['repeat'](0x1f);await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'2','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-2','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':{'machine':e,'name':'Indexed\x20service'},'checkpoint':'101','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});const f=await fetch(d+'/v1/edges?src='+objectId),g=await f['json']();expect(f['status'])['toBe'](0xc8),expect(g)['toMatchObject']({'direction':'out','object_id':objectId,'orphan_count':0x1}),expect(g['edges'])['toEqual']([{'src':objectId,'srcKind':'Service','edge':'machine','dst':e,'dstKind':'Machine','objectVersion':'2','dstProjected':![]}]);const h=await fetch(d+'/v1/edges?dst='+e),i=await h['json']();expect(h['status'])['toBe'](0xc8),expect(i['direction'])['toBe']('in'),expect(i['edges'][0x0])['toMatchObject']({'src':objectId,'edge':'machine'});const j=await fetch(d+'/v1/edges'),k=await fetch(d+'/v1/edges?src=invalid');expect(j['status'])['toBe'](0x190),expect(k['status'])['toBe'](0x190);}),it('has\x20no\x20write\x20or\x20catch-all\x20endpoints',async()=>{const e=await fetch(d+'/v1/objects',{'method':'POST','body':'{}'}),f=await fetch(d+'/v1/unknown');expect(e['status'])['toBe'](0x195),expect(e['headers']['get']('allow'))['toBe']('GET'),expect(f['status'])['toBe'](0x194);});}),describe('match\x20API',()=>{let a,b,c,d;const e=j=>'0x14'+j['repeat'](0x1f),f=e('01'),g=e('02'),h=e('03');function i(j,k,l){return{'chain_id':'chain_a','object_id':j,'object_version':k,'move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/'+j+'-'+k,'payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':l,'checkpoint':'100','tx_digest':toBase58(new Uint8Array(0x20)['fill'](0x7)),'state':'active','observed_at':'2026-10-24T00:00:00.000Z'};}beforeEach(async()=>{const j=newDb();j['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:k}=j['adapters']['createPg']();a=new PostgresProjectionStore(new k(),0x10),b=new PostgresSyncStore(new k()),await a['migrate'](),await b['migrate'](),await a['apply'](i(f,'1',{'description':'Exclusive\x20beat\x20license\x20for\x20hip\x20hop\x20producers','location':'remote','sales':[{'fields':{'name':'Beat\x20License','price':'6000000000','wip_hash':'0xabc'}}],'arbitrations':['0x12'+'04'['repeat'](0x1f)],'compensation_fund':'1000000000','machine':'0x15'+'05'['repeat'](0x1f),'um':'0x24'+'06'['repeat'](0x1f),'bPublished':!![],'bPaused':![]})),await a['apply'](i(g,'1',{'description':'Coffee\x20shop\x20interior\x20mural\x20painting','location':'Shanghai','sales':[{'fields':{'name':'Mural','price':'15000000000'}}],'arbitrations':[],'compensation_fund':'0','bPublished':!![],'bPaused':![]})),await a['apply'](i(h,'1',{'description':'Beat\x20store\x20on\x20holiday','sales':[{'fields':{'name':'Beat\x20Pack','price':'1000000000'}}],'bPublished':!![],'bPaused':!![]})),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(l=>c['listen'](0x0,'127.0.0.1',l)),d='http://127.0.0.1:'+c['address']()['port'];}),afterEach(async()=>{await new Promise((j,k)=>{c['close'](l=>l?k(l):j());}),await a['close'](),await b['close']();}),it('matches\x20materialized\x20facets\x20end-to-end\x20with\x20honest\x20coverage',async()=>{const j=new URLSearchParams({'kind':'Service','q':'beat\x20license','capabilities':'has_arbitration','budget':'10','limit':'10'}),k=await fetch(d+'/v1/match?'+j),l=await k['json']();expect(k['status'])['toBe'](0xc8),expect(l['chain_id'])['toBe']('chain_a'),expect(l['policy_version'])['toBe']('public-baseline-1'),expect(l['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(l['recall'])['toMatchObject']({'live_set':0x3,'gated':0x2,'merged':0x2,'channels_active':['structured','bm25']}),expect(l['candidates']['map'](o=>o['object_id']))['toEqual']([f,g]);const m=l['candidates'][0x0];expect(m['server_evaluation']['policy_version'])['toBe']('public-baseline-1'),expect(m['server_evaluation']['total'])['toBe'](0x64),expect(m['server_evaluation']['unknown_rules']['some'](o=>o['startsWith']('trust:')))['toBe'](!![]),expect(m['public_features']['capabilities'])['toContain']('has_refund_path');const n=l['candidates'][0x1];expect(n['server_evaluation']['red_flags'])['toEqual'](['price_over_budget','missing_capability:has_arbitration']);}),it('rejects\x20invalid\x20match\x20parameters',async()=>{const j=['/v1/match','/v1/match?kind=Arb','/v1/match?kind=Service&capabilities=has_wings','/v1/match?kind=Service&budget=abc','/v1/match?kind=Service&budget=1.2345678901','/v1/match?kind=Service&budget=-5','/v1/match?kind=Service&limit=0','/v1/match?kind=Service&limit=101','/v1/match?kind=Service&recall_limit=1001'];for(const k of j){const l=await fetch(''+d+k);expect(l['status'],k)['toBe'](0x190),expect((await l['json']())['error']['code'])['toBe']('BAD_REQUEST');}});});
1
+ import{toBase58}from'@wowok/wowok';import{DataType,newDb}from'pg-mem';import{afterEach,beforeEach,describe,expect,it}from'vitest';import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createProjectionApi}from'./server.js';const digest=toBase58(new Uint8Array(0x20)['fill'](0x7)),objectId='0x14'+'01'['repeat'](0x1f);describe('projection\x20read-only\x20API',()=>{let a,b,c,d;beforeEach(async()=>{const e=newDb();e['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:f}=e['adapters']['createPg']();a=new PostgresProjectionStore(new f(),0x10),b=new PostgresSyncStore(new f()),await a['migrate'](),await b['migrate'](),await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-1','payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'json+bcs-v1','payload_json':{'name':'Indexed\x20service','stock':0x3},'checkpoint':'100','tx_digest':digest,'state':'active','observed_at':'2026-10-24T00:00:00.000Z'});const g=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'100'});await b['savePage']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId'],'cursor':null,'checkpoint':'100','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId']}),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(i=>c['listen'](0x0,'127.0.0.1',i));const h=c['address']();d='http://127.0.0.1:'+h['port'];}),afterEach(async()=>{await new Promise((e,f)=>{c['close'](g=>g?f(g):e());}),await a['close'](),await b['close']();}),it('returns\x20projection\x20and\x20persisted\x20sync\x20status',async()=>{const e=await fetch(d+'/v1/status'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f)['toMatchObject']({'chain_id':'chain_a','read_only':!![],'projection':{'active_objects':0x1,'coverage':{'complete':![]}},'sync':[{'state':'complete','pages':0x1,'objects':0x1}],'head':null,'freshness':null,'cdc':[]}),expect(f['watermarks'])['toEqual']([{'verified_kind':'Service','max_checkpoint':'100','active_objects':0x1}]);}),it('publishes\x20every\x20CDC\x20cursor\x20with\x20its\x20distance\x20from\x20head',async()=>{await b['setCdcCheckpoint']('chain_a','Service','100'),await b['setCdcCheckpoint']('chain_a','Demand','90');const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'head':{'read':async()=>({'checkpoint':'200','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await(await fetch('http://127.0.0.1:'+f['port']+'/v1/status'))['json']();expect(g['cdc'])['toEqual']([{'kind':'Demand','checkpoint':'90','updated_at':expect['any'](String),'behind_head':'110'},{'kind':'Service','checkpoint':'100','updated_at':expect['any'](String),'behind_head':'100'}]);}finally{await new Promise((h,i)=>{e['close'](j=>j?i(j):h());});}}),it('reports\x20chain-head\x20lag\x20and\x20staleness\x20when\x20a\x20probe\x20is\x20configured',async()=>{const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleLag':0x3,'head':{'read':async()=>({'checkpoint':'105','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await fetch('http://127.0.0.1:'+f['port']+'/v1/status'),h=await g['json']();expect(h['head'])['toMatchObject']({'checkpoint':'105','source':'probe'}),expect(h['freshness'])['toMatchObject']({'head_checkpoint':'105','projection_checkpoint':'100','head_lag':'5','stale':!![]}),expect(h['freshness']['projection_age_seconds'])['toBe'](0x0),expect(h['freshness']['version_observed_at'])['toBe']('2026-10-24T00:00:00.000Z');}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('scores\x20freshness\x20off\x20the\x20last\x20confirmed\x20round,\x20not\x20off\x20the\x20last\x20version\x20change',async()=>{const e=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'200'});await b['savePage']({'chainId':e['chainId'],'stream':e['stream'],'runId':e['runId'],'cursor':null,'checkpoint':'200','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':e['chainId'],'stream':e['stream'],'runId':e['runId']});const f=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleAgeSec':0x1,'head':{'read':async()=>({'checkpoint':'210','observed_at':new Date()['toISOString'](),'source':'probe'})}});await new Promise(h=>f['listen'](0x0,'127.0.0.1',h));const g=f['address']();try{const h=await(await fetch('http://127.0.0.1:'+g['port']+'/v1/status'))['json']();expect(h['freshness'])['toMatchObject']({'projection_checkpoint':'200','head_lag':'10','version_checkpoint':'100','version_observed_at':'2026-10-24T00:00:00.000Z','stale':![]}),expect(h['freshness']['projection_age_seconds'])['toBeLessThan'](0x3c);}finally{await new Promise((i,j)=>{f['close'](k=>k?j(k):i());});}}),it('splits\x20quarantined\x20facts\x20into\x20blocking\x20and\x20superseded',async()=>{const e=await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-other','payload_hash':'0x'+'42'['repeat'](0x20),'payload_format':'json+bcs-v1','checkpoint':'150','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});expect(e['status'])['toBe']('conflict');const f=await a['apply']({'chain_id':'chain_a','object_id':'0x14'+'02'['repeat'](0x1f),'object_version':'7','move_type':'0x9::unknown::Unknown','owner_kind':'Shared','payload_uri':'test://raw/unknown-1','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'json+bcs-v1','checkpoint':'160','tx_digest':digest,'state':'active','observed_at':'2026-10-24T02:00:00.000Z'});expect(f['status'])['toBe']('quarantined');const g=await(await fetch(d+'/v1/status'))['json']();expect(g['quarantine']['blocking'])['toBe'](0x1),expect(g['quarantine']['entries']['map'](h=>[h['reason_code'],h['blocking']]))['toEqual']([['UNSUPPORTED_OR_INVALID_MOVE_TYPE',!![]],['CONFLICTING_OBJECT_VERSION',![]]]),expect(g['quarantine']['entries'][0x1]['object_id'])['toBe'](objectId);}),it('calls\x20a\x20projection\x20stale\x20by\x20age\x20even\x20when\x20it\x20sits\x20on\x20the\x20chain\x20head',async()=>{for(const g of await b['status']('chain_a')){await b['fail'](g['chainId'],g['stream'],g['runId'],'simulated\x20timer\x20outage');}const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleAgeSec':0x1,'head':{'read':async()=>({'checkpoint':'100','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(h=>e['listen'](0x0,'127.0.0.1',h));const f=e['address']();try{const h=await(await fetch('http://127.0.0.1:'+f['port']+'/v1/status'))['json']();expect(h['freshness'])['toMatchObject']({'head_lag':'0','stale':!![]}),expect(h['projection']['observed_at'])['toBe']('2026-10-24T00:00:00.000Z');}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('lists\x20current\x20objects\x20with\x20coverage\x20and\x20version\x20metadata',async()=>{const e=await fetch(d+'/v1/objects?kind=Service&limit=1'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f['objects'])['toHaveLength'](0x1),expect(f['objects'][0x0])['toMatchObject']({'objectId':objectId,'objectVersion':'1','verifiedKind':'Service','payloadJson':{'name':'Indexed\x20service','stock':0x3}}),expect(f['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(e['headers']['get']('cache-control'))['toBe']('no-store');}),it('rejects\x20invalid\x20selectors\x20without\x20exposing\x20internal\x20errors',async()=>{const e=await fetch(d+'/v1/objects?kind=Unknown'),f=await fetch(d+'/v1/objects?cursor=invalid'),g=await fetch(d+'/v1/objects?shard_count=16');expect(e['status'])['toBe'](0x190),expect(f['status'])['toBe'](0x190),expect(g['status'])['toBe'](0x190),expect(await e['json']())['toEqual']({'error':{'code':'BAD_REQUEST','message':'Unknown\x20object\x20kind:\x20Unknown'}});}),it('exposes\x20graph\x20edges\x20with\x20orphan\x20annotation',async()=>{const e='0x15'+'02'['repeat'](0x1f);await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'2','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-2','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':{'machine':e,'name':'Indexed\x20service'},'checkpoint':'101','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});const f=await fetch(d+'/v1/edges?src='+objectId),g=await f['json']();expect(f['status'])['toBe'](0xc8),expect(g)['toMatchObject']({'direction':'out','object_id':objectId,'orphan_count':0x1}),expect(g['edges'])['toEqual']([{'src':objectId,'srcKind':'Service','edge':'machine','dst':e,'dstKind':'Machine','objectVersion':'2','dstProjected':![]}]);const h=await fetch(d+'/v1/edges?dst='+e),i=await h['json']();expect(h['status'])['toBe'](0xc8),expect(i['direction'])['toBe']('in'),expect(i['edges'][0x0])['toMatchObject']({'src':objectId,'edge':'machine'});const j=await fetch(d+'/v1/edges'),k=await fetch(d+'/v1/edges?src=invalid');expect(j['status'])['toBe'](0x190),expect(k['status'])['toBe'](0x190);}),it('has\x20no\x20write\x20or\x20catch-all\x20endpoints',async()=>{const e=await fetch(d+'/v1/objects',{'method':'POST','body':'{}'}),f=await fetch(d+'/v1/unknown');expect(e['status'])['toBe'](0x195),expect(e['headers']['get']('allow'))['toBe']('GET'),expect(f['status'])['toBe'](0x194);});}),describe('match\x20API',()=>{let a,b,c,d;const e=j=>'0x14'+j['repeat'](0x1f),f=e('01'),g=e('02'),h=e('03');function i(j,k,l){return{'chain_id':'chain_a','object_id':j,'object_version':k,'move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/'+j+'-'+k,'payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':l,'checkpoint':'100','tx_digest':toBase58(new Uint8Array(0x20)['fill'](0x7)),'state':'active','observed_at':'2026-10-24T00:00:00.000Z'};}beforeEach(async()=>{const j=newDb();j['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:k}=j['adapters']['createPg']();a=new PostgresProjectionStore(new k(),0x10),b=new PostgresSyncStore(new k()),await a['migrate'](),await b['migrate'](),await a['apply'](i(f,'1',{'description':'Exclusive\x20beat\x20license\x20for\x20hip\x20hop\x20producers','location':'remote','sales':[{'fields':{'name':'Beat\x20License','price':'6000000000','wip_hash':'0xabc'}}],'arbitrations':['0x12'+'04'['repeat'](0x1f)],'compensation_fund':'1000000000','machine':'0x15'+'05'['repeat'](0x1f),'um':'0x24'+'06'['repeat'](0x1f),'bPublished':!![],'bPaused':![]})),await a['apply'](i(g,'1',{'description':'Coffee\x20shop\x20interior\x20mural\x20painting','location':'Shanghai','sales':[{'fields':{'name':'Mural','price':'15000000000'}}],'arbitrations':[],'compensation_fund':'0','bPublished':!![],'bPaused':![]})),await a['apply'](i(h,'1',{'description':'Beat\x20store\x20on\x20holiday','sales':[{'fields':{'name':'Beat\x20Pack','price':'1000000000'}}],'bPublished':!![],'bPaused':!![]})),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(l=>c['listen'](0x0,'127.0.0.1',l)),d='http://127.0.0.1:'+c['address']()['port'];}),afterEach(async()=>{await new Promise((j,k)=>{c['close'](l=>l?k(l):j());}),await a['close'](),await b['close']();}),it('matches\x20materialized\x20facets\x20end-to-end\x20with\x20honest\x20coverage',async()=>{const j=new URLSearchParams({'kind':'Service','q':'beat\x20license','capabilities':'has_arbitration','budget':'10','limit':'10'}),k=await fetch(d+'/v1/match?'+j),l=await k['json']();expect(k['status'])['toBe'](0xc8),expect(l['chain_id'])['toBe']('chain_a'),expect(l['policy_version'])['toBe']('public-baseline-1'),expect(l['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(l['recall'])['toMatchObject']({'live_set':0x3,'gated':0x2,'merged':0x2,'channels_active':['structured','bm25']}),expect(l['candidates']['map'](o=>o['object_id']))['toEqual']([f,g]);const m=l['candidates'][0x0];expect(m['server_evaluation']['policy_version'])['toBe']('public-baseline-1'),expect(m['server_evaluation']['total'])['toBe'](0x64),expect(m['server_evaluation']['unknown_rules']['some'](o=>o['startsWith']('trust:')))['toBe'](!![]),expect(m['public_features']['capabilities'])['toContain']('has_refund_path');const n=l['candidates'][0x1];expect(n['server_evaluation']['red_flags'])['toEqual'](['price_over_budget','missing_capability:has_arbitration']);}),it('rejects\x20invalid\x20match\x20parameters',async()=>{const j=['/v1/match','/v1/match?kind=Arb','/v1/match?kind=Service&capabilities=has_wings','/v1/match?kind=Service&budget=abc','/v1/match?kind=Service&budget=1.2345678901','/v1/match?kind=Service&budget=-5','/v1/match?kind=Service&limit=0','/v1/match?kind=Service&limit=101','/v1/match?kind=Service&recall_limit=1001'];for(const k of j){const l=await fetch(''+d+k);expect(l['status'],k)['toBe'](0x190),expect((await l['json']())['error']['code'])['toBe']('BAD_REQUEST');}});}),describe('projection\x20aggregate\x20API\x20(S17-C\x20F-RQD2-06\x20cross-order\x20view)',()=>{let a,b,c,d;const e='0x14'+'aa'['repeat'](0x1f),f='0x14'+'bb'['repeat'](0x1f),g='0x15'+'cc'['repeat'](0x1f),h='0x12'+'dd'['repeat'](0x1f),i='0x00'+'11'['repeat'](0x1f),j='0x00'+'22'['repeat'](0x1f),k=o=>'0x16'+String(o)['padStart'](0x2,'0')['repeat'](0x1f),l=toBase58(new Uint8Array(0x20)['fill'](0x9));async function m(n,o){await a['apply']({'chain_id':'chain_a','object_id':n,'object_version':'1','move_type':'0x2::order::Order<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/'+n,'payload_hash':'0x'+'42'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':{'service':o['service'],...o['machine']?{'machine':o['machine']}:{},'amount':o['amount'],'owner':o['owner'],'claimed_by':o['claimed_by']??null,'time':0x1a18a4d1565},'checkpoint':'200','tx_digest':l,'state':'active','observed_at':'2026-10-31T00:00:00.000Z'});}beforeEach(async()=>{const n=newDb();n['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:o}=n['adapters']['createPg']();a=new PostgresProjectionStore(new o(),0x10),b=new PostgresSyncStore(new o()),await a['migrate'](),await b['migrate'](),await m(k(0x1),{'service':e,'amount':'6000000000','owner':i}),await m(k(0x2),{'service':e,'amount':'6000000000','owner':j}),await m(k(0x3),{'service':e,'amount':'6000000000','owner':i,'claimed_by':h}),await m(k(0x4),{'service':f,'machine':g,'amount':'1000000000','owner':j}),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(p=>c['listen'](0x0,'127.0.0.1',p)),d='http://127.0.0.1:'+c['address']()['port'];}),afterEach(async()=>{await new Promise((n,o)=>{c['close'](p=>p?o(p):n());}),await a['close'](),await b['close']();}),it('aggregates\x20orders\x20per\x20service\x20with\x20totals\x20and\x20the\x20coverage\x20watermark',async()=>{const n=await fetch(d+'/v1/aggregate?kind=Order'),o=await n['json']();expect(n['status'])['toBe'](0xc8),expect(o)['toMatchObject']({'chain_id':'chain_a','kind':'Order','group':'service','group_id':null,'metric':'amount','exclude_claimed':![],'rows':[{'group_id':e,'count':0x3,'metric_sum':'18000000000','max_checkpoint':'200'},{'group_id':f,'count':0x1,'metric_sum':'1000000000','max_checkpoint':'200'}],'totals':{'count':0x4,'metric_sum':'19000000000'},'truncated':![]}),expect(o['coverage'])['toMatchObject']({'mode':'known_objects','chain_id':'chain_a'});}),it('answers\x20the\x20target\x20check:\x20single\x20group\x20with\x20claimed\x20orders\x20excluded',async()=>{const n=new URLSearchParams({'kind':'Order','group_id':e,'exclude_claimed':'1'}),o=await(await fetch(d+'/v1/aggregate?'+n))['json']();expect(o['rows'])['toEqual']([{'group_id':e,'count':0x2,'metric_sum':'12000000000','max_checkpoint':'200'}]),expect(o['totals'])['toEqual']({'count':0x2,'metric_sum':'12000000000'});}),it('aggregates\x20by\x20the\x20owner\x20dimension',async()=>{const n=await(await fetch(d+'/v1/aggregate?kind=Order&group=owner'))['json']();expect(n['rows'])['toEqual']([{'group_id':i,'count':0x2,'metric_sum':'12000000000','max_checkpoint':'200'},{'group_id':j,'count':0x2,'metric_sum':'7000000000','max_checkpoint':'200'}]);}),it('returns\x20an\x20empty\x20honest\x20aggregate\x20when\x20nothing\x20is\x20projected',async()=>{const n=newDb();n['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:o}=n['adapters']['createPg'](),p=new PostgresProjectionStore(new o(),0x10);await p['migrate']();try{const q=createProjectionApi({'chainId':'chain_a','projection':p,'sync':b});await new Promise(s=>q['listen'](0x0,'127.0.0.1',s));const r=q['address']()['port'];try{const s=await(await fetch('http://127.0.0.1:'+r+'/v1/aggregate?kind=Order'))['json']();expect(s['rows'])['toEqual']([]),expect(s['totals'])['toEqual']({'count':0x0,'metric_sum':'0'}),expect(s['coverage'])['toMatchObject']({'chain_id':'chain_a'});}finally{await new Promise((t,u)=>{q['close'](v=>v?u(v):t());});}}finally{await p['close']();}}),it('rejects\x20invalid\x20aggregate\x20parameters',async()=>{const n=['/v1/aggregate','/v1/aggregate?kind=Arb','/v1/aggregate?kind=Order&group=progress','/v1/aggregate?kind=Order&metric=allocation','/v1/aggregate?kind=Order&group_id=not-an-address','/v1/aggregate?kind=Order&exclude_claimed=maybe','/v1/aggregate?kind=Order&limit=0','/v1/aggregate?kind=Order&limit=1001'];for(const o of n){const p=await fetch(''+d+o);expect(p['status'],o)['toBe'](0x190),expect((await p['json']())['error']['code'])['toBe']('BAD_REQUEST');}});});
@@ -1 +1 @@
1
- import{createServer}from'node:http';import{WOW_OBJECT_TYPE_TAGS,wowAddressToBytes}from'@wowok/wowok';import{KNOWN_CAPABILITIES,runMatch}from'./match.js';function json(a,b,c){a['writeHead'](b,{'Content-Type':'application/json;\x20charset=utf-8','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'}),a['end'](JSON['stringify'](c));}function badRequest(a,b){json(a,0x190,{'error':{'code':'BAD_REQUEST','message':b}});}const WOW_DECIMALS=0x9;function parseWowToWei(a){const b=/^(\d+)(?:\.(\d{1,9}))?$/['exec'](a['trim']());if(!b)return null;const c=(b[0x2]??'')['padEnd'](WOW_DECIMALS,'0');return(BigInt(b[0x1])*BigInt(0xa**WOW_DECIMALS)+BigInt(c))['toString']();}function parsePositiveInt(a){return/^\d+$/['test'](a['trim']())?Number(a['trim']()):null;}export function createProjectionApi(a){if(!a['chainId'])throw new Error('chainId\x20is\x20required');const b=a['staleLag']??0x0;if(!Number['isInteger'](b)||b<0x0)throw new Error('Invalid\x20staleLag');const c=a['staleAgeSec']??0x0;if(!Number['isInteger'](c)||c<0x0)throw new Error('Invalid\x20staleAgeSec');return createServer(async(d,e)=>{try{if(d['method']!=='GET'){e['setHeader']('Allow','GET'),json(e,0x195,{'error':{'code':'METHOD_NOT_ALLOWED','message':'GET\x20required'}});return;}const f=new URL(d['url']??'/','http://localhost');if(f['pathname']==='/v1/status'){const [g,h,i,j,k,l]=await Promise['all']([a['projection']['status'](a['chainId']),a['sync']['status'](a['chainId']),a['projection']['watermarks'](a['chainId']),a['head']?a['head']['read']():Promise['resolve'](null),a['sync']['cdcCursors'](a['chainId']),a['projection']['quarantineQueue'](a['chainId'])]);let m=g['max_checkpoint'],n=g['observed_at'];for(const p of h){if(p['state']!=='complete'||!p['checkpoint'])continue;(m===null||BigInt(p['checkpoint'])>BigInt(m))&&(m=p['checkpoint']);const r=p['updatedAt'];r&&(n===null||Date['parse'](r)>Date['parse'](n))&&(n=r);}let o=null;if(j?.['checkpoint']!==null&&j?.['checkpoint']!==undefined&&m!==null){const s=BigInt(j['checkpoint'])-BigInt(m),t=n===null?null:Math['max'](0x0,Math['floor']((Date['now']()-Date['parse'](n))/0x3e8));o={'head_checkpoint':j['checkpoint'],'projection_checkpoint':m,'head_lag':(s>0x0n?s:0x0n)['toString'](),'projection_age_seconds':t,'version_checkpoint':g['max_checkpoint'],'version_observed_at':g['observed_at'],'stale':b>0x0&&s>BigInt(b)||c>0x0&&t!==null&&t>c};}json(e,0xc8,{'chain_id':a['chainId'],'read_only':!![],'generated_at':new Date()['toISOString'](),'projection':g,'sync':h,'watermarks':i,'head':j,'freshness':o,'cdc':k['map'](u=>({...u,'behind_head':j?.['checkpoint']===null||j?.['checkpoint']===undefined?null:((()=>{const v=BigInt(j['checkpoint'])-BigInt(u['checkpoint']);return(v>0x0n?v:0x0n)['toString']();})())})),'quarantine':{'blocking':l['filter'](u=>u['blocking'])['length'],'entries':l}});return;}if(f['pathname']==='/v1/objects'){const u=f['searchParams']['get']('kind')??undefined;if(u&&!(u in WOW_OBJECT_TYPE_TAGS)){badRequest(e,'Unknown\x20object\x20kind:\x20'+u);return;}const v=f['searchParams']['get']('cursor')??undefined;if(v)try{wowAddressToBytes(v);}catch{badRequest(e,'Invalid\x20object\x20cursor');return;}const w=f['searchParams']['get']('limit'),x=w===null?undefined:Number(w);if(x!==undefined&&(!Number['isInteger'](x)||x<0x1||x>0x3e8)){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}const y=f['searchParams']['get']('shard_count'),z=f['searchParams']['get']('shard_index');if(y===null!==(z===null)){badRequest(e,'shard_count\x20and\x20shard_index\x20must\x20be\x20provided\x20together');return;}const A=y===null||z===null?undefined:{'count':Number(y),'index':Number(z)};if(A&&(!Number['isInteger'](A['count'])||A['count']<0x1||!Number['isInteger'](A['index'])||A['index']<0x0||A['index']>=A['count'])){badRequest(e,'Invalid\x20shard\x20selector');return;}const B=await a['projection']['listCurrent']({'chainId':a['chainId'],'kind':u,'cursor':v,'limit':x,'shard':A});json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),...B});return;}if(f['pathname']==='/v1/edges'){const C=f['searchParams']['get']('src'),D=f['searchParams']['get']('dst');if(C===null===(D===null)){badRequest(e,'Provide\x20exactly\x20one\x20of\x20src\x20or\x20dst');return;}const E=C??D;try{wowAddressToBytes(E);}catch{badRequest(e,'Invalid\x20object\x20address');return;}const F=C!==null?await a['projection']['edgesFrom'](a['chainId'],E):await a['projection']['edgesTo'](a['chainId'],E);json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'direction':C!==null?'out':'in','object_id':E['toLowerCase'](),'edges':F,'orphan_count':F['filter'](G=>!G['dstProjected'])['length']});return;}if(f['pathname']==='/v1/match'){const G=f['searchParams']['get']('kind');if(G!=='Service'&&G!=='Demand'){badRequest(e,'kind\x20must\x20be\x20\x27Service\x27\x20or\x20\x27Demand\x27');return;}const H=f['searchParams']['get']('q')??undefined,I=f['searchParams']['get']('location')??undefined,J=f['searchParams']['get']('industry')??undefined;let K;const L=f['searchParams']['get']('budget');if(L!==null){K=parseWowToWei(L)??undefined;if(K===undefined){badRequest(e,'budget\x20must\x20be\x20a\x20non-negative\x20decimal\x20WOW\x20amount\x20(max\x209\x20fractional\x20digits)');return;}}let M;const N=f['searchParams']['get']('capabilities');if(N!==null){M=N['split'](',')['map'](a0=>a0['trim']())['filter'](a0=>a0['length']>0x0);const Z=M['filter'](a0=>!KNOWN_CAPABILITIES['includes'](a0));if(Z['length']>0x0){badRequest(e,'Unknown\x20capability:\x20'+Z['join'](',\x20')+'\x20(known:\x20'+KNOWN_CAPABILITIES['join'](',\x20')+')');return;}}let O=0x14;const P=f['searchParams']['get']('limit');if(P!==null){O=parsePositiveInt(P)??-0x1;if(!Number['isInteger'](O)||O<0x1||O>0x64){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x20100');return;}}let Q=0xc8;const R=f['searchParams']['get']('recall_limit');if(R!==null){Q=parsePositiveInt(R)??-0x1;if(!Number['isInteger'](Q)||Q<0x1||Q>0x3e8){badRequest(e,'recall_limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}}const S=f['searchParams']['get']('include_payload');let T=![];if(S!==null){if(S==='1'||S==='true')T=!![];else{if(S!=='0'&&S!=='false'){badRequest(e,'include_payload\x20must\x20be\x20one\x20of\x201,\x20true,\x200,\x20false');return;}}}const U={'kind':G,'q':H,'location':I,'industry':J,'budgetWei':K,'capabilities':M,'limit':O,'recallLimit':Q},[V,W]=await Promise['all']([a['projection']['activeFacets'](a['chainId'],G),a['projection']['status'](a['chainId'])]),X=runMatch(V,U);let Y=X['candidates'];if(T&&Y['length']>0x0){const a0=await a['projection']['currentPayloads'](a['chainId'],Y['map'](a1=>a1['object_id']));Y=Y['map'](a1=>({...a1,'payload_json':a0['get'](a1['object_id'])??null}));}json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'coverage':W['coverage'],...X,'candidates':Y});return;}json(e,0x194,{'error':{'code':'NOT_FOUND','message':'Unknown\x20endpoint'}});}catch{json(e,0x1f4,{'error':{'code':'INTERNAL_ERROR','message':'Index\x20query\x20failed'}});}});}
1
+ import{createServer}from'node:http';import{WOW_OBJECT_TYPE_TAGS,wowAddressToBytes}from'@wowok/wowok';import{KNOWN_CAPABILITIES,runMatch}from'./match.js';function json(a,b,c){a['writeHead'](b,{'Content-Type':'application/json;\x20charset=utf-8','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'}),a['end'](JSON['stringify'](c));}function badRequest(a,b){json(a,0x190,{'error':{'code':'BAD_REQUEST','message':b}});}const WOW_DECIMALS=0x9;function parseWowToWei(a){const b=/^(\d+)(?:\.(\d{1,9}))?$/['exec'](a['trim']());if(!b)return null;const c=(b[0x2]??'')['padEnd'](WOW_DECIMALS,'0');return(BigInt(b[0x1])*BigInt(0xa**WOW_DECIMALS)+BigInt(c))['toString']();}function parsePositiveInt(a){return/^\d+$/['test'](a['trim']())?Number(a['trim']()):null;}const AGGREGATE_SHAPES={'Order':{'defaultGroup':'service','groups':['service','machine','owner'],'defaultMetric':'amount','metrics':['amount']}};export function createProjectionApi(a){if(!a['chainId'])throw new Error('chainId\x20is\x20required');const b=a['staleLag']??0x0;if(!Number['isInteger'](b)||b<0x0)throw new Error('Invalid\x20staleLag');const c=a['staleAgeSec']??0x0;if(!Number['isInteger'](c)||c<0x0)throw new Error('Invalid\x20staleAgeSec');return createServer(async(d,e)=>{try{if(d['method']!=='GET'){e['setHeader']('Allow','GET'),json(e,0x195,{'error':{'code':'METHOD_NOT_ALLOWED','message':'GET\x20required'}});return;}const f=new URL(d['url']??'/','http://localhost');if(f['pathname']==='/v1/status'){const [g,h,i,j,k,l]=await Promise['all']([a['projection']['status'](a['chainId']),a['sync']['status'](a['chainId']),a['projection']['watermarks'](a['chainId']),a['head']?a['head']['read']():Promise['resolve'](null),a['sync']['cdcCursors'](a['chainId']),a['projection']['quarantineQueue'](a['chainId'])]);let m=g['max_checkpoint'],n=g['observed_at'];for(const p of h){if(p['state']!=='complete'||!p['checkpoint'])continue;(m===null||BigInt(p['checkpoint'])>BigInt(m))&&(m=p['checkpoint']);const r=p['updatedAt'];r&&(n===null||Date['parse'](r)>Date['parse'](n))&&(n=r);}let o=null;if(j?.['checkpoint']!==null&&j?.['checkpoint']!==undefined&&m!==null){const s=BigInt(j['checkpoint'])-BigInt(m),t=n===null?null:Math['max'](0x0,Math['floor']((Date['now']()-Date['parse'](n))/0x3e8));o={'head_checkpoint':j['checkpoint'],'projection_checkpoint':m,'head_lag':(s>0x0n?s:0x0n)['toString'](),'projection_age_seconds':t,'version_checkpoint':g['max_checkpoint'],'version_observed_at':g['observed_at'],'stale':b>0x0&&s>BigInt(b)||c>0x0&&t!==null&&t>c};}json(e,0xc8,{'chain_id':a['chainId'],'read_only':!![],'generated_at':new Date()['toISOString'](),'projection':g,'sync':h,'watermarks':i,'head':j,'freshness':o,'cdc':k['map'](u=>({...u,'behind_head':j?.['checkpoint']===null||j?.['checkpoint']===undefined?null:((()=>{const v=BigInt(j['checkpoint'])-BigInt(u['checkpoint']);return(v>0x0n?v:0x0n)['toString']();})())})),'quarantine':{'blocking':l['filter'](u=>u['blocking'])['length'],'entries':l}});return;}if(f['pathname']==='/v1/objects'){const u=f['searchParams']['get']('kind')??undefined;if(u&&!(u in WOW_OBJECT_TYPE_TAGS)){badRequest(e,'Unknown\x20object\x20kind:\x20'+u);return;}const v=f['searchParams']['get']('cursor')??undefined;if(v)try{wowAddressToBytes(v);}catch{badRequest(e,'Invalid\x20object\x20cursor');return;}const w=f['searchParams']['get']('limit'),x=w===null?undefined:Number(w);if(x!==undefined&&(!Number['isInteger'](x)||x<0x1||x>0x3e8)){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}const y=f['searchParams']['get']('shard_count'),z=f['searchParams']['get']('shard_index');if(y===null!==(z===null)){badRequest(e,'shard_count\x20and\x20shard_index\x20must\x20be\x20provided\x20together');return;}const A=y===null||z===null?undefined:{'count':Number(y),'index':Number(z)};if(A&&(!Number['isInteger'](A['count'])||A['count']<0x1||!Number['isInteger'](A['index'])||A['index']<0x0||A['index']>=A['count'])){badRequest(e,'Invalid\x20shard\x20selector');return;}const B=await a['projection']['listCurrent']({'chainId':a['chainId'],'kind':u,'cursor':v,'limit':x,'shard':A});json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),...B});return;}if(f['pathname']==='/v1/edges'){const C=f['searchParams']['get']('src'),D=f['searchParams']['get']('dst');if(C===null===(D===null)){badRequest(e,'Provide\x20exactly\x20one\x20of\x20src\x20or\x20dst');return;}const E=C??D;try{wowAddressToBytes(E);}catch{badRequest(e,'Invalid\x20object\x20address');return;}const F=C!==null?await a['projection']['edgesFrom'](a['chainId'],E):await a['projection']['edgesTo'](a['chainId'],E);json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'direction':C!==null?'out':'in','object_id':E['toLowerCase'](),'edges':F,'orphan_count':F['filter'](G=>!G['dstProjected'])['length']});return;}if(f['pathname']==='/v1/match'){const G=f['searchParams']['get']('kind');if(G!=='Service'&&G!=='Demand'){badRequest(e,'kind\x20must\x20be\x20\x27Service\x27\x20or\x20\x27Demand\x27');return;}const H=f['searchParams']['get']('q')??undefined,I=f['searchParams']['get']('location')??undefined,J=f['searchParams']['get']('industry')??undefined;let K;const L=f['searchParams']['get']('budget');if(L!==null){K=parseWowToWei(L)??undefined;if(K===undefined){badRequest(e,'budget\x20must\x20be\x20a\x20non-negative\x20decimal\x20WOW\x20amount\x20(max\x209\x20fractional\x20digits)');return;}}let M;const N=f['searchParams']['get']('capabilities');if(N!==null){M=N['split'](',')['map'](a0=>a0['trim']())['filter'](a0=>a0['length']>0x0);const Z=M['filter'](a0=>!KNOWN_CAPABILITIES['includes'](a0));if(Z['length']>0x0){badRequest(e,'Unknown\x20capability:\x20'+Z['join'](',\x20')+'\x20(known:\x20'+KNOWN_CAPABILITIES['join'](',\x20')+')');return;}}let O=0x14;const P=f['searchParams']['get']('limit');if(P!==null){O=parsePositiveInt(P)??-0x1;if(!Number['isInteger'](O)||O<0x1||O>0x64){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x20100');return;}}let Q=0xc8;const R=f['searchParams']['get']('recall_limit');if(R!==null){Q=parsePositiveInt(R)??-0x1;if(!Number['isInteger'](Q)||Q<0x1||Q>0x3e8){badRequest(e,'recall_limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}}const S=f['searchParams']['get']('include_payload');let T=![];if(S!==null){if(S==='1'||S==='true')T=!![];else{if(S!=='0'&&S!=='false'){badRequest(e,'include_payload\x20must\x20be\x20one\x20of\x201,\x20true,\x200,\x20false');return;}}}const U={'kind':G,'q':H,'location':I,'industry':J,'budgetWei':K,'capabilities':M,'limit':O,'recallLimit':Q},[V,W]=await Promise['all']([a['projection']['activeFacets'](a['chainId'],G),a['projection']['status'](a['chainId'])]),X=runMatch(V,U);let Y=X['candidates'];if(T&&Y['length']>0x0){const a0=await a['projection']['currentPayloads'](a['chainId'],Y['map'](a1=>a1['object_id']));Y=Y['map'](a1=>({...a1,'payload_json':a0['get'](a1['object_id'])??null}));}json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'coverage':W['coverage'],...X,'candidates':Y});return;}if(f['pathname']==='/v1/aggregate'){const a1=f['searchParams']['get']('kind')??'',a2=AGGREGATE_SHAPES[a1];if(!a2){badRequest(e,'Unknown\x20aggregate\x20kind:\x20'+(a1||'(missing)')+'\x20(known:\x20'+Object['keys'](AGGREGATE_SHAPES)['join'](',\x20')+')');return;}const a3=f['searchParams']['get']('group')??a2['defaultGroup'];if(!a2['groups']['includes'](a3)){badRequest(e,'Unknown\x20group\x20field:\x20'+a3+'\x20(known\x20for\x20'+a1+':\x20'+a2['groups']['join'](',\x20')+')');return;}const a4=f['searchParams']['get']('metric')??a2['defaultMetric'];if(!a2['metrics']['includes'](a4)){badRequest(e,'Unknown\x20metric\x20field:\x20'+a4+'\x20(known\x20for\x20'+a1+':\x20'+a2['metrics']['join'](',\x20')+')');return;}let a5;const a6=f['searchParams']['get']('group_id');if(a6!==null){try{wowAddressToBytes(a6);}catch{badRequest(e,'Invalid\x20group_id\x20address');return;}a5=a6;}const a7=f['searchParams']['get']('exclude_claimed');let a8=![];if(a7!==null){if(a7==='1'||a7==='true')a8=!![];else{if(a7!=='0'&&a7!=='false'){badRequest(e,'exclude_claimed\x20must\x20be\x20one\x20of\x201,\x20true,\x200,\x20false');return;}}}let a9=0x32;const aa=f['searchParams']['get']('limit');if(aa!==null){a9=parsePositiveInt(aa)??-0x1;if(!Number['isInteger'](a9)||a9<0x1||a9>0x3e8){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}}const [ab,ac]=await Promise['all']([a['projection']['aggregate'](a['chainId'],{'chainId':a['chainId'],'group':a3,'groupId':a5,'metric':a4,'excludeClaimed':a8,'limit':a9}),a['projection']['status'](a['chainId'])]);json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'kind':a1,'group':a3,'group_id':a5??null,'metric':a4,'exclude_claimed':a8,...ab,'coverage':ac['coverage']});return;}json(e,0x194,{'error':{'code':'NOT_FOUND','message':'Unknown\x20endpoint'}});}catch{json(e,0x1f4,{'error':{'code':'INTERNAL_ERROR','message':'Index\x20query\x20failed'}});}});}
@@ -1,6 +1,6 @@
1
1
  import { type WowTypedObjectKind } from "@wowok/wowok";
2
2
  import { Pool } from "pg";
3
- import type { ApplyProjectionResult, CurrentObjectPage, GraphEdgeView, ObjectFacetRow, ObjectVersionFact, ProjectionStatus, ProjectionWatermark, QuarantineEntry, RecordReconciliationOptions, RecordReconciliationResult, ReconciliationGeneration } from "./types.js";
3
+ import type { AggregateAnswer, AggregateOptions, ApplyProjectionResult, CurrentObjectPage, GraphEdgeView, ObjectFacetRow, ObjectVersionFact, ProjectionStatus, ProjectionWatermark, QuarantineEntry, RecordReconciliationOptions, RecordReconciliationResult, ReconciliationGeneration } from "./types.js";
4
4
  export interface ListCurrentObjectsOptions {
5
5
  chainId: string;
6
6
  kind?: WowTypedObjectKind;
@@ -40,6 +40,7 @@ export declare class PostgresProjectionStore {
40
40
  }>;
41
41
  activeFacets(chainId: string, kind?: string): Promise<ObjectFacetRow[]>;
42
42
  currentPayloads(chainId: string, objectIds: string[]): Promise<Map<string, Record<string, unknown> | null>>;
43
+ aggregate(chainId: string, options: AggregateOptions): Promise<AggregateAnswer>;
43
44
  recordReconciliation(options: RecordReconciliationOptions): Promise<RecordReconciliationResult>;
44
45
  reconciliationSummary(chainId: string): Promise<ReconciliationGeneration[]>;
45
46
  private reconciledThrough;
@@ -1 +1 @@
1
- import{createHash}from'node:crypto';import{isDeepStrictEqual}from'node:util';import{WOW_OBJECT_TYPE_TAGS,fromBase58,fromHex,toHex,wowAddressToBytes}from'@wowok/wowok';import{Pool}from'pg';import{extractGraphEdges}from'./edges.js';import{extractFacets,FACET_VERSION}from'./facets.js';import{parseObjectVersionFact}from'./facts.js';import{projectObjectVersion}from'./project.js';import{PROJECTION_SCHEMA_SQL}from'./schema.js';function addressBytes(a){return Buffer['from'](wowAddressToBytes(a));}function hashBytes(a){return Buffer['from'](fromHex(a['replace'](/^0x/,'')));}function digestBytes(a){return Buffer['from'](fromBase58(a));}function hexBytes(a){return'0x'+toHex(a);}function numberValue(a){return Number(a);}function isoValue(a){if(a===null||a===undefined)return null;const b=a instanceof Date?a:new Date(String(a));return Number['isNaN'](b['getTime']())?null:b['toISOString']();}function coverage(a,b,c,d){return{'mode':'known_objects','complete':![],'truncated':c,'total_enumerated':b,'chain_id':a,'reconciled_through':d,'degraded_reasons':[...d===null?['RECONCILIATION_REQUIRED']:[],...c?['ENUMERATION_TRUNCATED']:[]]};}function sameRawVersion(a,b){const c=a['owner_address']?hexBytes(a['owner_address']):undefined,d=a['previous_version']===null||a['previous_version']===undefined?undefined:BigInt(String(a['previous_version']));return a['move_type']===b['moveType']&&a['owner_kind']===b['ownerKind']&&c===b['ownerAddress']&&a['payload_uri']===b['payloadUri']&&a['payload_format']===b['payloadFormat']&&(b['payloadJson']===undefined||a['payload_json_present']===!![]&&isDeepStrictEqual(a['payload_json']??null,b['payloadJson']))&&hexBytes(a['payload_hash'])==='0x'+b['payloadHash']['replace'](/^0x/,'')['toLowerCase']()&&Buffer['from'](a['tx_digest'])['equals'](digestBytes(b['txDigest']))&&d===b['previousVersion']&&a['state']===b['state'];}function canAttachJson(a,b){return b['payloadJson']!==undefined&&a['payload_json_present']!==!![]&&sameRawVersion(a,{...b,'payloadJson':undefined});}export class PostgresProjectionStore{['pool'];['shardCount'];constructor(a,b=0x100){this['pool']=a,this['shardCount']=b;if(!Number['isInteger'](b)||b<0x1||b>0xffff)throw new Error('Invalid\x20shard\x20count:\x20'+b);}static['fromDatabaseUrl'](a,b=0x100){return new PostgresProjectionStore(new Pool({'connectionString':a}),b);}async['migrate'](){await this['pool']['query'](PROJECTION_SCHEMA_SQL);}async['close'](){await this['pool']['end']();}async['apply'](a){return this['applyFact'](parseObjectVersionFact(a));}async['applyFact'](a){const b=await this['pool']['connect']();try{await b['query']('BEGIN');const c=await this['applyWithClient'](b,a);return await b['query']('COMMIT'),c;}catch(d){await b['query']('ROLLBACK');throw d;}finally{b['release']();}}async['applyWithClient'](a,b){const c=projectObjectVersion(b,this['shardCount']),d=createHash('sha256')['update'](b['chainId']+':'+b['objectId'])['digest']();await a['query']('SELECT\x20pg_advisory_xact_lock($1,\x20$2)',[d['readInt32BE'](0x0),d['readInt32BE'](0x4)]);const e=[b['chainId'],addressBytes(b['objectId']),b['objectVersion']['toString']()],f=await a['query']('SELECT\x20*\x20FROM\x20object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20object_version=$3',e);if(f['rows']['length']>0x0){if(!sameRawVersion(f['rows'][0x0],b)){if(canAttachJson(f['rows'][0x0],b)){await this['attachJson'](a,e,b);const k=await a['query']('SELECT\x20verified_kind,\x20object_version::TEXT\x20AS\x20object_version\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20state=\x27active\x27',[b['chainId'],addressBytes(b['objectId'])]);return k['rows'][0x0]?.['verified_kind']&&BigInt(k['rows'][0x0]['object_version'])<=b['objectVersion']&&(await this['syncGraphEdges'](a,b,k['rows'][0x0]['verified_kind']),await this['syncFacets'](a,b,k['rows'][0x0]['verified_kind'])),{'status':'duplicate','currentVersion':b['objectVersion']['toString']()};}return await this['quarantine'](a,b,'CONFLICTING_OBJECT_VERSION'),{'status':'conflict','reasonCode':'CONFLICTING_OBJECT_VERSION'};}return{'status':'duplicate','currentVersion':b['objectVersion']['toString']()};}await a['query']('INSERT\x20INTO\x20object_version\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20kind_hint,\x20object_version,\x20move_type,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20owner_kind,\x20owner_address,\x20payload_uri,\x20payload_hash,\x20payload_format,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20payload_json,\x20payload_json_present,\x20checkpoint,\x20tx_digest,\x20previous_version,\x20state,\x20observed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id,\x20object_version)\x20DO\x20NOTHING',[b['chainId'],addressBytes(b['objectId']),c['kindHint'],b['objectVersion']['toString'](),b['moveType'],b['ownerKind'],b['ownerAddress']?addressBytes(b['ownerAddress']):null,b['payloadUri'],hashBytes(b['payloadHash']),b['payloadFormat'],b['payloadJson']===undefined?null:JSON['stringify'](b['payloadJson']),b['payloadJson']!==undefined,b['checkpoint']['toString'](),digestBytes(b['txDigest']),b['previousVersion']?.['toString']()??null,b['state'],b['observedAt']['toISOString']()]);const g=await a['query']('SELECT\x20*\x20FROM\x20object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20object_version=$3',e);if(!sameRawVersion(g['rows'][0x0],b))return await this['quarantine'](a,b,'CONFLICTING_OBJECT_VERSION'),{'status':'conflict','reasonCode':'CONFLICTING_OBJECT_VERSION'};if(c['quarantineReason']||c['verifiedKind']===null||c['shardIndex']===null){const l=c['quarantineReason']??'INVALID_OBJECT_PROJECTION';return await this['quarantine'](a,b,l),{'status':'quarantined','reasonCode':l};}const h=await a['query']('SELECT\x20MAX(object_version)::TEXT\x20AS\x20max\x20FROM\x20object_version\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[b['chainId'],addressBytes(b['objectId'])]);if(h['rows'][0x0]['max']!==null&&BigInt(h['rows'][0x0]['max'])>b['objectVersion']){const m=await a['query']('SELECT\x20object_version\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[b['chainId'],addressBytes(b['objectId'])]);return await this['quarantine'](a,b,'OUT_OF_ORDER_OBJECT_VERSION'),{'status':'stale','currentVersion':m['rows'][0x0]?.['object_version']===undefined?undefined:String(m['rows'][0x0]['object_version']),'reasonCode':'OUT_OF_ORDER_OBJECT_VERSION'};}await a['query']('INSERT\x20INTO\x20object_current\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20kind_hint,\x20object_version,\x20move_type,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verified_kind,\x20shard_count,\x20shard_index,\x20checkpoint,\x20state,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20payload_hash,\x20updated_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20kind_hint=EXCLUDED.kind_hint,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20object_version=EXCLUDED.object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20move_type='+'EXCLUDED.'+'move_type,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verified_kind=EXCLUDED.verified_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20shard_count=EXCLUDED.shard_count,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20shard_index=EXCLUDED.shard_index,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20checkpoint=EXCLUDED.checkpoint,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20state=EXCLUDED.state,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20payload_hash=EXCLUDED.payload_hash,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20updated_at=EXCLUDED.updated_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20EXCLUDED.object_version\x20>\x20object_current.object_version',[b['chainId'],addressBytes(b['objectId']),c['kindHint'],b['objectVersion']['toString'](),b['moveType'],c['verifiedKind'],c['shardCount'],c['shardIndex'],b['checkpoint']['toString'](),b['state'],hashBytes(b['payloadHash']),b['observedAt']['toISOString']()]);const i=await a['query']('SELECT\x20object_version\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[b['chainId'],addressBytes(b['objectId'])]),j=i['rows'][0x0]?.['object_version'];if(j===undefined)throw new Error('Current\x20object\x20projection\x20missing\x20after\x20conditional\x20upsert');if(BigInt(j)>b['objectVersion'])return await this['quarantine'](a,b,'OUT_OF_ORDER_OBJECT_VERSION'),{'status':'stale','currentVersion':String(j),'reasonCode':'OUT_OF_ORDER_OBJECT_VERSION'};if(BigInt(j)===b['objectVersion'])return await this['syncGraphEdges'](a,b,c['verifiedKind']),await this['syncFacets'](a,b,c['verifiedKind']),{'status':'applied','currentVersion':String(j)};throw new Error('Current\x20object\x20version\x20is\x20behind\x20the\x20applied\x20raw\x20version');}async['syncGraphEdges'](a,b,c){if(!c)return;const d=extractGraphEdges(c,b['objectId'],b['payloadJson']),e=addressBytes(b['objectId']);await a['query']('DELETE\x20FROM\x20graph_edge\x20WHERE\x20chain_id=$1\x20AND\x20src=$2',[b['chainId'],e]);for(const f of d){await a['query']('INSERT\x20INTO\x20graph_edge\x20(chain_id,\x20src,\x20src_kind,\x20edge,\x20dst,\x20dst_kind,\x20object_version)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20src,\x20edge,\x20dst)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20src_kind=EXCLUDED.src_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20dst_kind=EXCLUDED.dst_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20object_version=EXCLUDED.object_version',[b['chainId'],e,f['srcKind'],f['edge'],addressBytes(f['dst']),f['dstKind'],b['objectVersion']['toString']()]);}}async['syncFacets'](a,b,c){if(!c)return;const d=addressBytes(b['objectId']),e=extractFacets(c,b['objectId'],b['payloadJson']);if(!e){await a['query']('DELETE\x20FROM\x20object_facet\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[b['chainId'],d]);return;}await a['query']('INSERT\x20INTO\x20object_facet\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20verified_kind,\x20facet_version,\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry,\x20industry_confidence,\x20location,\x20price_min,\x20price_max,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20capabilities,\x20published,\x20paused,\x20name_tokens,\x20text_tokens,\x20keywords,\x20computed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verified_kind=EXCLUDED.verified_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20facet_version=EXCLUDED.facet_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20object_version=EXCLUDED.object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry=EXCLUDED.industry,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry_confidence=EXCLUDED.industry_confidence,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20location=EXCLUDED.location,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20price_min=EXCLUDED.price_min,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20price_max=EXCLUDED.price_max,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20capabilities=EXCLUDED.capabilities,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20published=EXCLUDED.published,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20paused=EXCLUDED.paused,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20name_tokens=EXCLUDED.name_tokens,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20text_tokens=EXCLUDED.text_tokens,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20keywords=EXCLUDED.keywords,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20computed_at=EXCLUDED.computed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20EXCLUDED.object_version\x20>=\x20object_facet.object_version',[b['chainId'],d,e['verifiedKind'],FACET_VERSION,b['objectVersion']['toString'](),e['industry'],e['industryConfidence'],e['location'],e['priceMin'],e['priceMax'],e['capabilities'],e['published'],e['paused'],e['nameTokens'],e['textTokens'],e['keywords'],new Date()['toISOString']()]);}async['attachJson'](a,b,c){await a['query']('UPDATE\x20object_version\x20SET\x20payload_json=$4,\x20payload_json_present=TRUE\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20object_version=$3\x20AND\x20payload_json_present=FALSE',[...b,c['payloadJson']===null?'null':JSON['stringify'](c['payloadJson'])]);}async['quarantine'](a,b,c){await a['query']('INSERT\x20INTO\x20quarantine\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20object_version,\x20reason_code,\x20raw_ref,\x20first_seen\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id,\x20object_version,\x20reason_code)\x20DO\x20NOTHING',[b['chainId'],addressBytes(b['objectId']),b['objectVersion']['toString'](),c,b['payloadUri'],b['observedAt']['toISOString']()]);}async['liveSetVersions'](a,b){const c=await this['pool']['query']('SELECT\x20object_id,\x20object_version::TEXT\x20AS\x20object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20verified_kind=$2\x20AND\x20state=\x27active\x27',[a,b]),d=new Map();for(const e of c['rows']){d['set'](hexBytes(e['object_id']),String(e['object_version']));}return d;}async['markTombstone'](a,b){const c=await this['pool']['connect']();try{await c['query']('BEGIN');const d=await c['query']('UPDATE\x20object_current\x20SET\x20state=\x27deleted\x27,\x20updated_at=$3\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20state=\x27active\x27',[a,addressBytes(b),new Date()['toISOString']()]);return await c['query']('DELETE\x20FROM\x20graph_edge\x20WHERE\x20chain_id=$1\x20AND\x20src=$2',[a,addressBytes(b)]),await c['query']('DELETE\x20FROM\x20object_facet\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[a,addressBytes(b)]),await c['query']('COMMIT'),(d['rowCount']??0x0)>0x0;}catch(e){await c['query']('ROLLBACK');throw e;}finally{c['release']();}}async['markTombstoneIfKind'](a,b,c){const d=await this['pool']['connect']();try{await d['query']('BEGIN');const e=await d['query']('UPDATE\x20object_current\x20SET\x20state=\x27deleted\x27,\x20updated_at=$4\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20state=\x27active\x27\x20AND\x20verified_kind=$3',[a,addressBytes(b),c,new Date()['toISOString']()]);return(e['rowCount']??0x0)>0x0&&(await d['query']('DELETE\x20FROM\x20graph_edge\x20WHERE\x20chain_id=$1\x20AND\x20src=$2',[a,addressBytes(b)]),await d['query']('DELETE\x20FROM\x20object_facet\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[a,addressBytes(b)])),await d['query']('COMMIT'),(e['rowCount']??0x0)>0x0;}catch(f){await d['query']('ROLLBACK');throw f;}finally{d['release']();}}async['edgesFrom'](a,b){const c=await this['pool']['query']('SELECT\x20g.src_kind,\x20g.edge,\x20g.dst,\x20g.dst_kind,\x20g.object_version::TEXT\x20AS\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(c.object_id\x20IS\x20NOT\x20NULL)\x20AS\x20dst_projected\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20graph_edge\x20g\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LEFT\x20JOIN\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20c.chain_id=g.chain_id\x20AND\x20c.object_id=g.dst\x20AND\x20c.state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20g.chain_id=$1\x20AND\x20g.src=$2\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20g.edge,\x20g.dst',[a,addressBytes(b)]);return c['rows']['map'](d=>({'src':b['toLowerCase'](),'srcKind':d['src_kind'],'edge':d['edge'],'dst':hexBytes(d['dst']),'dstKind':d['dst_kind'],'objectVersion':d['object_version'],'dstProjected':d['dst_projected']}));}async['edgesTo'](a,b){const c=await this['pool']['query']('SELECT\x20g.src,\x20g.src_kind,\x20g.edge,\x20g.dst_kind,\x20g.object_version::TEXT\x20AS\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(c.object_id\x20IS\x20NOT\x20NULL)\x20AS\x20src_projected\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20graph_edge\x20g\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LEFT\x20JOIN\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20c.chain_id=g.chain_id\x20AND\x20c.object_id=g.src\x20AND\x20c.state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20g.chain_id=$1\x20AND\x20g.dst=$2\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20g.src_kind,\x20g.src',[a,addressBytes(b)]);return c['rows']['map'](d=>({'src':hexBytes(d['src']),'srcKind':d['src_kind'],'edge':d['edge'],'dst':b['toLowerCase'](),'dstKind':d['dst_kind'],'objectVersion':d['object_version'],'dstProjected':d['src_projected']}));}async['backfillGraphEdges'](a){const b=await this['pool']['query']('SELECT\x20c.object_id,\x20c.verified_kind,\x20v.payload_json\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20v.chain_id=c.chain_id\x20AND\x20v.object_id=c.object_id\x20AND\x20v.object_version=c.object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20c.chain_id=$1\x20AND\x20c.state=\x27active\x27\x20AND\x20v.payload_json\x20IS\x20NOT\x20NULL',[a]),c=await this['pool']['connect']();let d=0x0;try{await c['query']('BEGIN');for(const e of b['rows']){const f=hexBytes(e['object_id']),g=extractGraphEdges(e['verified_kind'],f,e['payload_json']);await c['query']('DELETE\x20FROM\x20graph_edge\x20WHERE\x20chain_id=$1\x20AND\x20src=$2',[a,e['object_id']]);for(const h of g){await c['query']('INSERT\x20INTO\x20graph_edge\x20(chain_id,\x20src,\x20src_kind,\x20edge,\x20dst,\x20dst_kind,\x20object_version)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,$2,$3,$4,$5,$6,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(SELECT\x20object_version\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2))',[a,e['object_id'],h['srcKind'],h['edge'],addressBytes(h['dst']),h['dstKind']]);}d+=g['length'];}await c['query']('COMMIT');}catch(i){await c['query']('ROLLBACK');throw i;}finally{c['release']();}return{'objects':b['rows']['length'],'edges':d};}async['backfillFacets'](a){const b=await this['pool']['query']('SELECT\x20c.object_id,\x20c.verified_kind,\x20c.object_version::TEXT\x20AS\x20object_version,\x20v.payload_json\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20v.chain_id=c.chain_id\x20AND\x20v.object_id=c.object_id\x20AND\x20v.object_version=c.object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20c.chain_id=$1\x20AND\x20c.state=\x27active\x27\x20AND\x20v.payload_json\x20IS\x20NOT\x20NULL',[a]),c=await this['pool']['connect']();let d=0x0;try{await c['query']('BEGIN');for(const e of b['rows']){const f=hexBytes(e['object_id']),g=extractFacets(e['verified_kind'],f,e['payload_json']);if(!g){await c['query']('DELETE\x20FROM\x20object_facet\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[a,e['object_id']]);continue;}await c['query']('INSERT\x20INTO\x20object_facet\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20verified_kind,\x20facet_version,\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry,\x20industry_confidence,\x20location,\x20price_min,\x20price_max,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20capabilities,\x20published,\x20paused,\x20name_tokens,\x20text_tokens,\x20keywords,\x20computed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verified_kind=EXCLUDED.verified_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20facet_version=EXCLUDED.facet_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20object_version=EXCLUDED.object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry=EXCLUDED.industry,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry_confidence=EXCLUDED.industry_confidence,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20location=EXCLUDED.location,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20price_min=EXCLUDED.price_min,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20price_max=EXCLUDED.price_max,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20capabilities=EXCLUDED.capabilities,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20published=EXCLUDED.published,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20paused=EXCLUDED.paused,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20name_tokens=EXCLUDED.name_tokens,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20text_tokens=EXCLUDED.text_tokens,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20keywords=EXCLUDED.keywords,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20computed_at=EXCLUDED.computed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20EXCLUDED.object_version\x20>=\x20object_facet.object_version',[a,e['object_id'],g['verifiedKind'],FACET_VERSION,e['object_version'],g['industry'],g['industryConfidence'],g['location'],g['priceMin'],g['priceMax'],g['capabilities'],g['published'],g['paused'],g['nameTokens'],g['textTokens'],g['keywords'],new Date()['toISOString']()]),d+=0x1;}await c['query']('COMMIT');}catch(h){await c['query']('ROLLBACK');throw h;}finally{c['release']();}return{'objects':b['rows']['length'],'facets':d};}async['activeFacets'](a,b){const c=[a];let d='';b&&(c['push'](b),d='\x20AND\x20c.verified_kind=$'+c['length']);const e=await this['pool']['query']('SELECT\x20f.object_id,\x20f.verified_kind,\x20f.object_version::TEXT\x20AS\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20f.facet_version,\x20f.industry,\x20f.industry_confidence,\x20f.location,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20f.price_min,\x20f.price_max,\x20f.capabilities,\x20f.published,\x20f.paused,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20f.name_tokens,\x20f.text_tokens,\x20f.keywords,\x20c.checkpoint::TEXT\x20AS\x20checkpoint\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_facet\x20f\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20c.chain_id=f.chain_id\x20AND\x20c.object_id=f.object_id\x20AND\x20c.state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20f.chain_id=$1'+d+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20f.object_id',c);return e['rows']['map'](f=>({'objectId':hexBytes(f['object_id']),'verifiedKind':f['verified_kind'],'objectVersion':f['object_version'],'facetVersion':f['facet_version'],'industry':f['industry'],'industryConfidence':Number(f['industry_confidence']),'location':f['location'],'priceMin':f['price_min'],'priceMax':f['price_max'],'capabilities':f['capabilities']??[],'published':f['published'],'paused':f['paused'],'nameTokens':f['name_tokens']??[],'textTokens':f['text_tokens']??[],'keywords':f['keywords']??[],'checkpoint':f['checkpoint']}));}async['currentPayloads'](a,b){const c=new Map();if(b['length']===0x0)return c;const d=[a],e=b['map'](g=>{return d['push'](addressBytes(g)),'$'+d['length'];}),f=await this['pool']['query']('SELECT\x20c.object_id,\x20v.payload_json\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20v.chain_id=c.chain_id\x20AND\x20v.object_id=c.object_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20AND\x20v.object_version=c.object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20c.chain_id=$1\x20AND\x20c.state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20AND\x20c.object_id\x20IN\x20('+e['join'](',\x20')+')',d);for(const g of f['rows']){c['set'](hexBytes(g['object_id']),g['payload_json']??null);}return c;}async['recordReconciliation'](a){const b=a['missing']['length'],c=a['extra']['length'],d=a['versionDrift']['length'],e=a['error']||b>0x0||c>0x0||d>0x0?'fail':'pass',f=new Date()['toISOString'](),g=await this['pool']['connect']();try{await g['query']('BEGIN'),await g['query']('INSERT\x20INTO\x20reconciliation_run\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20kind,\x20run_id,\x20live_set_checkpoint,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20missing,\x20extra,\x20version_drift,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20missing_count,\x20extra_count,\x20version_drift_count,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20repaired_missing,\x20repaired_drift,\x20tombstoned,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verdict,\x20live_count,\x20projection_active,\x20generation,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20reconciled_through,\x20started_at,\x20completed_at,\x20error\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4::bigint,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14::text,$15,$16,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(SELECT\x20generation\x20FROM\x20projection_generation\x20WHERE\x20chain_id=$1\x20AND\x20kind=$2),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20CASE\x20WHEN\x20$14::text=\x27pass\x27\x20THEN\x20$4::bigint\x20ELSE\x20NULL\x20END,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20$17,$18,$19)',[a['chainId'],a['kind'],a['runId'],a['liveSetCheckpoint'],a['missing'],a['extra'],a['versionDrift'],a['preDiff']['missing'],a['preDiff']['extra'],a['preDiff']['versionDrift'],a['repairs']['missing'],a['repairs']['drift'],a['repairs']['tombstoned'],e,a['liveCount'],a['projectionActive'],f,f,a['error']??null]);let h=null,i=null;if(e==='pass'){const j=await g['query']('INSERT\x20INTO\x20projection_generation\x20(chain_id,\x20kind,\x20generation,\x20reconciled_through,\x20updated_at)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,$2,1,$3,$4)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20kind)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20generation=projection_generation.generation+1,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20reconciled_through=EXCLUDED.reconciled_through,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20updated_at=EXCLUDED.updated_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20RETURNING\x20generation',[a['chainId'],a['kind'],a['liveSetCheckpoint'],new Date()['toISOString']()]);h=Number(j['rows'][0x0]['generation']),i=a['liveSetCheckpoint'];}return await g['query']('UPDATE\x20reconciliation_run\x20SET\x20generation=$4,\x20reconciled_through=$5\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20kind=$2\x20AND\x20run_id=$3',[a['chainId'],a['kind'],a['runId'],h,i]),await g['query']('COMMIT'),{'runId':a['runId'],'verdict':e,'generation':h,'reconciledThrough':i};}catch(k){await g['query']('ROLLBACK');throw k;}finally{g['release']();}}async['reconciliationSummary'](a){if(!a)throw new Error('chainId\x20is\x20required');const b=await this['pool']['query']('SELECT\x20kind,\x20generation,\x20reconciled_through::TEXT\x20AS\x20reconciled_through,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verdict,\x20completed_at,\x20missing_count,\x20extra_count,\x20version_drift_count\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20reconciliation_run\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20completed_at\x20IS\x20NOT\x20NULL\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20completed_at\x20DESC,\x20run_id\x20DESC',[a]),c=new Map();for(const d of b['rows']){if(c['has'](d['kind']))continue;c['set'](d['kind'],{'kind':d['kind'],'generation':Number(d['generation']??0x0),'reconciled_through':d['reconciled_through'],'verdict':d['verdict'],'completed_at':new Date(d['completed_at'])['toISOString'](),'missing_count':Number(d['missing_count']),'extra_count':Number(d['extra_count']),'version_drift_count':Number(d['version_drift_count'])});}return[...c['values']()]['sort']((e,f)=>e['kind']['localeCompare'](f['kind']));}async['reconciledThrough'](a,b){const c=b?await this['pool']['query']('SELECT\x20MIN(reconciled_through)::TEXT\x20AS\x20reconciled_through\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20projection_generation\x20WHERE\x20chain_id=$1\x20AND\x20kind=$2',[a,b]):await this['pool']['query']('SELECT\x20MIN(reconciled_through)::TEXT\x20AS\x20reconciled_through\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20projection_generation\x20WHERE\x20chain_id=$1',[a]);return c['rows'][0x0]?.['reconciled_through']??null;}async['status'](a){if(!a)throw new Error('chainId\x20is\x20required');const [b,c,d,e,f,g,h,i]=await Promise['all']([this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20count\x20FROM\x20object_version\x20WHERE\x20chain_id=$1',[a]),this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20count\x20FROM\x20object_current\x20WHERE\x20chain_id=$1',[a]),this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20count\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20state=\x27active\x27',[a]),this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20count\x20FROM\x20quarantine\x20WHERE\x20chain_id=$1',[a]),this['pool']['query']('SELECT\x20MAX(checkpoint)::TEXT\x20AS\x20max\x20FROM\x20object_current\x20WHERE\x20chain_id=$1',[a]),this['pool']['query']('SELECT\x20MAX(updated_at)\x20AS\x20max\x20FROM\x20object_current\x20WHERE\x20chain_id=$1',[a]),this['reconciliationSummary'](a),this['reconciledThrough'](a)]),j=numberValue(d['rows'][0x0]['count']);return{'chain_id':a,'raw_versions':numberValue(b['rows'][0x0]['count']),'current_objects':numberValue(c['rows'][0x0]['count']),'active_objects':j,'quarantined_versions':numberValue(e['rows'][0x0]['count']),'max_checkpoint':f['rows'][0x0]['max'],'observed_at':isoValue(g['rows'][0x0]['max']),'coverage':coverage(a,j,![],i),'reconciliations':h};}async['watermarks'](a){if(!a)throw new Error('chainId\x20is\x20required');const b=await this['pool']['query']('SELECT\x20verified_kind,\x20MAX(checkpoint)::TEXT\x20AS\x20max,\x20COUNT(*)::TEXT\x20AS\x20count\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20GROUP\x20BY\x20verified_kind\x20ORDER\x20BY\x20verified_kind',[a]);return b['rows']['map'](c=>({'verified_kind':c['verified_kind'],'max_checkpoint':c['max'],'active_objects':numberValue(c['count'])}));}async['quarantineQueue'](a,b=0x32){if(!a)throw new Error('chainId\x20is\x20required');if(!Number['isInteger'](b)||b<0x1||b>0x1f4)throw new Error('Invalid\x20quarantine\x20limit:\x20'+b);const c=await this['pool']['query']('SELECT\x20q.object_id,\x20q.object_version::TEXT\x20AS\x20object_version,\x20q.reason_code,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20q.first_seen,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20c.object_version::TEXT\x20AS\x20current_version,\x20c.verified_kind\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20quarantine\x20q\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LEFT\x20JOIN\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20c.chain_id=q.chain_id\x20AND\x20c.object_id=q.object_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20q.chain_id=$1\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20q.first_seen\x20DESC\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LIMIT\x20$2',[a,String(b)]),d=c['rows']['map'](e=>{return{'object_id':e['object_id']instanceof Uint8Array?hexBytes(e['object_id'])['toLowerCase']():null,'object_version':e['object_version'],'reason_code':e['reason_code'],'first_seen':isoValue(e['first_seen']),'current_version':e['current_version'],'verified_kind':e['verified_kind'],'blocking':e['current_version']===null||BigInt(e['object_version'])>BigInt(e['current_version'])};});return d['sort']((e,f)=>e['blocking']===f['blocking']?0x0:e['blocking']?-0x1:0x1)['slice'](0x0,b);}async['listCurrent'](a){if(!a['chainId'])throw new Error('chainId\x20is\x20required');if(a['kind']&&!(a['kind']in WOW_OBJECT_TYPE_TAGS))throw new Error('Unknown\x20object\x20kind:\x20'+a['kind']);const b=a['limit']??0x64;if(!Number['isInteger'](b)||b<0x1||b>0x3e8)throw new Error('Invalid\x20list\x20limit:\x20'+b);if(a['shard']){const {count:i,index:j}=a['shard'];if(!Number['isInteger'](i)||i<0x1||!Number['isInteger'](j)||j<0x0||j>=i)throw new Error('Invalid\x20shard\x20selector');}const c=[a['chainId']],d=['c.chain_id=$1','c.state=\x27active\x27'];a['kind']&&(c['push'](a['kind']),d['push']('c.verified_kind=$'+c['length']));a['shard']&&(c['push'](a['shard']['count'],a['shard']['index']),d['push']('c.shard_count=$'+(c['length']-0x1)),d['push']('c.shard_index=$'+c['length']));a['cursor']&&(c['push'](addressBytes(a['cursor'])),d['push']('c.object_id>$'+c['length']));c['push'](b+0x1);const e=await this['pool']['query']('SELECT\x20c.*,\x20v.payload_uri,\x20v.payload_format,\x20v.payload_json,\x20v.owner_kind,\x20v.owner_address\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x20ON\x20v.chain_id=c.chain_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20AND\x20v.object_id=c.object_id\x20AND\x20v.object_version=c.object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20'+d['join']('\x20AND\x20')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20c.object_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LIMIT\x20$'+c['length'],c),f=e['rows']['length']>b,g=e['rows']['slice'](0x0,b),h=await this['reconciledThrough'](a['chainId'],a['kind']);return{'objects':g['map'](k=>({'objectId':hexBytes(k['object_id']),'objectVersion':String(k['object_version']),'kindHint':k['kind_hint'],'verifiedKind':k['verified_kind'],'shardCount':k['shard_count'],'shardIndex':k['shard_index'],'moveType':k['move_type'],'checkpoint':String(k['checkpoint']),'state':k['state'],'payloadHash':hexBytes(k['payload_hash']),'payloadUri':k['payload_uri'],'payloadFormat':k['payload_format'],'payloadJson':k['payload_json']??null,'ownerKind':k['owner_kind'],'ownerAddress':k['owner_address']?hexBytes(k['owner_address']):undefined,'updatedAt':new Date(k['updated_at'])['toISOString']()})),'next_cursor':f?hexBytes(g[g['length']-0x1]['object_id']):null,'coverage':coverage(a['chainId'],g['length'],f,h)};}}
1
+ import{createHash}from'node:crypto';import{isDeepStrictEqual}from'node:util';import{WOW_OBJECT_TYPE_TAGS,fromBase58,fromHex,toHex,wowAddressToBytes}from'@wowok/wowok';import{Pool}from'pg';import{extractGraphEdges}from'./edges.js';import{extractFacets,FACET_VERSION}from'./facets.js';import{parseObjectVersionFact}from'./facts.js';import{projectObjectVersion}from'./project.js';import{PROJECTION_SCHEMA_SQL}from'./schema.js';function addressBytes(a){return Buffer['from'](wowAddressToBytes(a));}function hashBytes(a){return Buffer['from'](fromHex(a['replace'](/^0x/,'')));}function digestBytes(a){return Buffer['from'](fromBase58(a));}function hexBytes(a){return'0x'+toHex(a);}function numberValue(a){return Number(a);}function isoValue(a){if(a===null||a===undefined)return null;const b=a instanceof Date?a:new Date(String(a));return Number['isNaN'](b['getTime']())?null:b['toISOString']();}function coverage(a,b,c,d){return{'mode':'known_objects','complete':![],'truncated':c,'total_enumerated':b,'chain_id':a,'reconciled_through':d,'degraded_reasons':[...d===null?['RECONCILIATION_REQUIRED']:[],...c?['ENUMERATION_TRUNCATED']:[]]};}function sameRawVersion(a,b){const c=a['owner_address']?hexBytes(a['owner_address']):undefined,d=a['previous_version']===null||a['previous_version']===undefined?undefined:BigInt(String(a['previous_version']));return a['move_type']===b['moveType']&&a['owner_kind']===b['ownerKind']&&c===b['ownerAddress']&&a['payload_uri']===b['payloadUri']&&a['payload_format']===b['payloadFormat']&&(b['payloadJson']===undefined||a['payload_json_present']===!![]&&isDeepStrictEqual(a['payload_json']??null,b['payloadJson']))&&hexBytes(a['payload_hash'])==='0x'+b['payloadHash']['replace'](/^0x/,'')['toLowerCase']()&&Buffer['from'](a['tx_digest'])['equals'](digestBytes(b['txDigest']))&&d===b['previousVersion']&&a['state']===b['state'];}function canAttachJson(a,b){return b['payloadJson']!==undefined&&a['payload_json_present']!==!![]&&sameRawVersion(a,{...b,'payloadJson':undefined});}export class PostgresProjectionStore{['pool'];['shardCount'];constructor(a,b=0x100){this['pool']=a,this['shardCount']=b;if(!Number['isInteger'](b)||b<0x1||b>0xffff)throw new Error('Invalid\x20shard\x20count:\x20'+b);}static['fromDatabaseUrl'](a,b=0x100){return new PostgresProjectionStore(new Pool({'connectionString':a}),b);}async['migrate'](){await this['pool']['query'](PROJECTION_SCHEMA_SQL);}async['close'](){await this['pool']['end']();}async['apply'](a){return this['applyFact'](parseObjectVersionFact(a));}async['applyFact'](a){const b=await this['pool']['connect']();try{await b['query']('BEGIN');const c=await this['applyWithClient'](b,a);return await b['query']('COMMIT'),c;}catch(d){await b['query']('ROLLBACK');throw d;}finally{b['release']();}}async['applyWithClient'](a,b){const c=projectObjectVersion(b,this['shardCount']),d=createHash('sha256')['update'](b['chainId']+':'+b['objectId'])['digest']();await a['query']('SELECT\x20pg_advisory_xact_lock($1,\x20$2)',[d['readInt32BE'](0x0),d['readInt32BE'](0x4)]);const e=[b['chainId'],addressBytes(b['objectId']),b['objectVersion']['toString']()],f=await a['query']('SELECT\x20*\x20FROM\x20object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20object_version=$3',e);if(f['rows']['length']>0x0){if(!sameRawVersion(f['rows'][0x0],b)){if(canAttachJson(f['rows'][0x0],b)){await this['attachJson'](a,e,b);const k=await a['query']('SELECT\x20verified_kind,\x20object_version::TEXT\x20AS\x20object_version\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20state=\x27active\x27',[b['chainId'],addressBytes(b['objectId'])]);return k['rows'][0x0]?.['verified_kind']&&BigInt(k['rows'][0x0]['object_version'])<=b['objectVersion']&&(await this['syncGraphEdges'](a,b,k['rows'][0x0]['verified_kind']),await this['syncFacets'](a,b,k['rows'][0x0]['verified_kind'])),{'status':'duplicate','currentVersion':b['objectVersion']['toString']()};}return await this['quarantine'](a,b,'CONFLICTING_OBJECT_VERSION'),{'status':'conflict','reasonCode':'CONFLICTING_OBJECT_VERSION'};}return{'status':'duplicate','currentVersion':b['objectVersion']['toString']()};}await a['query']('INSERT\x20INTO\x20object_version\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20kind_hint,\x20object_version,\x20move_type,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20owner_kind,\x20owner_address,\x20payload_uri,\x20payload_hash,\x20payload_format,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20payload_json,\x20payload_json_present,\x20checkpoint,\x20tx_digest,\x20previous_version,\x20state,\x20observed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id,\x20object_version)\x20DO\x20NOTHING',[b['chainId'],addressBytes(b['objectId']),c['kindHint'],b['objectVersion']['toString'](),b['moveType'],b['ownerKind'],b['ownerAddress']?addressBytes(b['ownerAddress']):null,b['payloadUri'],hashBytes(b['payloadHash']),b['payloadFormat'],b['payloadJson']===undefined?null:JSON['stringify'](b['payloadJson']),b['payloadJson']!==undefined,b['checkpoint']['toString'](),digestBytes(b['txDigest']),b['previousVersion']?.['toString']()??null,b['state'],b['observedAt']['toISOString']()]);const g=await a['query']('SELECT\x20*\x20FROM\x20object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20object_version=$3',e);if(!sameRawVersion(g['rows'][0x0],b))return await this['quarantine'](a,b,'CONFLICTING_OBJECT_VERSION'),{'status':'conflict','reasonCode':'CONFLICTING_OBJECT_VERSION'};if(c['quarantineReason']||c['verifiedKind']===null||c['shardIndex']===null){const l=c['quarantineReason']??'INVALID_OBJECT_PROJECTION';return await this['quarantine'](a,b,l),{'status':'quarantined','reasonCode':l};}const h=await a['query']('SELECT\x20MAX(object_version)::TEXT\x20AS\x20max\x20FROM\x20object_version\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[b['chainId'],addressBytes(b['objectId'])]);if(h['rows'][0x0]['max']!==null&&BigInt(h['rows'][0x0]['max'])>b['objectVersion']){const m=await a['query']('SELECT\x20object_version\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[b['chainId'],addressBytes(b['objectId'])]);return await this['quarantine'](a,b,'OUT_OF_ORDER_OBJECT_VERSION'),{'status':'stale','currentVersion':m['rows'][0x0]?.['object_version']===undefined?undefined:String(m['rows'][0x0]['object_version']),'reasonCode':'OUT_OF_ORDER_OBJECT_VERSION'};}await a['query']('INSERT\x20INTO\x20object_current\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20kind_hint,\x20object_version,\x20move_type,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verified_kind,\x20shard_count,\x20shard_index,\x20checkpoint,\x20state,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20payload_hash,\x20updated_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20kind_hint=EXCLUDED.kind_hint,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20object_version=EXCLUDED.object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20move_type='+'EXCLUDED.'+'move_type,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verified_kind=EXCLUDED.verified_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20shard_count=EXCLUDED.shard_count,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20shard_index=EXCLUDED.shard_index,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20checkpoint=EXCLUDED.checkpoint,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20state=EXCLUDED.state,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20payload_hash=EXCLUDED.payload_hash,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20updated_at=EXCLUDED.updated_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20EXCLUDED.object_version\x20>\x20object_current.object_version',[b['chainId'],addressBytes(b['objectId']),c['kindHint'],b['objectVersion']['toString'](),b['moveType'],c['verifiedKind'],c['shardCount'],c['shardIndex'],b['checkpoint']['toString'](),b['state'],hashBytes(b['payloadHash']),b['observedAt']['toISOString']()]);const i=await a['query']('SELECT\x20object_version\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[b['chainId'],addressBytes(b['objectId'])]),j=i['rows'][0x0]?.['object_version'];if(j===undefined)throw new Error('Current\x20object\x20projection\x20missing\x20after\x20conditional\x20upsert');if(BigInt(j)>b['objectVersion'])return await this['quarantine'](a,b,'OUT_OF_ORDER_OBJECT_VERSION'),{'status':'stale','currentVersion':String(j),'reasonCode':'OUT_OF_ORDER_OBJECT_VERSION'};if(BigInt(j)===b['objectVersion'])return await this['syncGraphEdges'](a,b,c['verifiedKind']),await this['syncFacets'](a,b,c['verifiedKind']),{'status':'applied','currentVersion':String(j)};throw new Error('Current\x20object\x20version\x20is\x20behind\x20the\x20applied\x20raw\x20version');}async['syncGraphEdges'](a,b,c){if(!c)return;const d=extractGraphEdges(c,b['objectId'],b['payloadJson']),e=addressBytes(b['objectId']);await a['query']('DELETE\x20FROM\x20graph_edge\x20WHERE\x20chain_id=$1\x20AND\x20src=$2',[b['chainId'],e]);for(const f of d){await a['query']('INSERT\x20INTO\x20graph_edge\x20(chain_id,\x20src,\x20src_kind,\x20edge,\x20dst,\x20dst_kind,\x20object_version)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20src,\x20edge,\x20dst)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20src_kind=EXCLUDED.src_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20dst_kind=EXCLUDED.dst_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20object_version=EXCLUDED.object_version',[b['chainId'],e,f['srcKind'],f['edge'],addressBytes(f['dst']),f['dstKind'],b['objectVersion']['toString']()]);}}async['syncFacets'](a,b,c){if(!c)return;const d=addressBytes(b['objectId']),e=extractFacets(c,b['objectId'],b['payloadJson']);if(!e){await a['query']('DELETE\x20FROM\x20object_facet\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[b['chainId'],d]);return;}await a['query']('INSERT\x20INTO\x20object_facet\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20verified_kind,\x20facet_version,\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry,\x20industry_confidence,\x20location,\x20price_min,\x20price_max,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20capabilities,\x20published,\x20paused,\x20name_tokens,\x20text_tokens,\x20keywords,\x20computed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verified_kind=EXCLUDED.verified_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20facet_version=EXCLUDED.facet_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20object_version=EXCLUDED.object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry=EXCLUDED.industry,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry_confidence=EXCLUDED.industry_confidence,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20location=EXCLUDED.location,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20price_min=EXCLUDED.price_min,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20price_max=EXCLUDED.price_max,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20capabilities=EXCLUDED.capabilities,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20published=EXCLUDED.published,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20paused=EXCLUDED.paused,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20name_tokens=EXCLUDED.name_tokens,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20text_tokens=EXCLUDED.text_tokens,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20keywords=EXCLUDED.keywords,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20computed_at=EXCLUDED.computed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20EXCLUDED.object_version\x20>=\x20object_facet.object_version',[b['chainId'],d,e['verifiedKind'],FACET_VERSION,b['objectVersion']['toString'](),e['industry'],e['industryConfidence'],e['location'],e['priceMin'],e['priceMax'],e['capabilities'],e['published'],e['paused'],e['nameTokens'],e['textTokens'],e['keywords'],new Date()['toISOString']()]);}async['attachJson'](a,b,c){await a['query']('UPDATE\x20object_version\x20SET\x20payload_json=$4,\x20payload_json_present=TRUE\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20object_version=$3\x20AND\x20payload_json_present=FALSE',[...b,c['payloadJson']===null?'null':JSON['stringify'](c['payloadJson'])]);}async['quarantine'](a,b,c){await a['query']('INSERT\x20INTO\x20quarantine\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20object_version,\x20reason_code,\x20raw_ref,\x20first_seen\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id,\x20object_version,\x20reason_code)\x20DO\x20NOTHING',[b['chainId'],addressBytes(b['objectId']),b['objectVersion']['toString'](),c,b['payloadUri'],b['observedAt']['toISOString']()]);}async['liveSetVersions'](a,b){const c=await this['pool']['query']('SELECT\x20object_id,\x20object_version::TEXT\x20AS\x20object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20verified_kind=$2\x20AND\x20state=\x27active\x27',[a,b]),d=new Map();for(const e of c['rows']){d['set'](hexBytes(e['object_id']),String(e['object_version']));}return d;}async['markTombstone'](a,b){const c=await this['pool']['connect']();try{await c['query']('BEGIN');const d=await c['query']('UPDATE\x20object_current\x20SET\x20state=\x27deleted\x27,\x20updated_at=$3\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20state=\x27active\x27',[a,addressBytes(b),new Date()['toISOString']()]);return await c['query']('DELETE\x20FROM\x20graph_edge\x20WHERE\x20chain_id=$1\x20AND\x20src=$2',[a,addressBytes(b)]),await c['query']('DELETE\x20FROM\x20object_facet\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[a,addressBytes(b)]),await c['query']('COMMIT'),(d['rowCount']??0x0)>0x0;}catch(e){await c['query']('ROLLBACK');throw e;}finally{c['release']();}}async['markTombstoneIfKind'](a,b,c){const d=await this['pool']['connect']();try{await d['query']('BEGIN');const e=await d['query']('UPDATE\x20object_current\x20SET\x20state=\x27deleted\x27,\x20updated_at=$4\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2\x20AND\x20state=\x27active\x27\x20AND\x20verified_kind=$3',[a,addressBytes(b),c,new Date()['toISOString']()]);return(e['rowCount']??0x0)>0x0&&(await d['query']('DELETE\x20FROM\x20graph_edge\x20WHERE\x20chain_id=$1\x20AND\x20src=$2',[a,addressBytes(b)]),await d['query']('DELETE\x20FROM\x20object_facet\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[a,addressBytes(b)])),await d['query']('COMMIT'),(e['rowCount']??0x0)>0x0;}catch(f){await d['query']('ROLLBACK');throw f;}finally{d['release']();}}async['edgesFrom'](a,b){const c=await this['pool']['query']('SELECT\x20g.src_kind,\x20g.edge,\x20g.dst,\x20g.dst_kind,\x20g.object_version::TEXT\x20AS\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(c.object_id\x20IS\x20NOT\x20NULL)\x20AS\x20dst_projected\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20graph_edge\x20g\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LEFT\x20JOIN\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20c.chain_id=g.chain_id\x20AND\x20c.object_id=g.dst\x20AND\x20c.state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20g.chain_id=$1\x20AND\x20g.src=$2\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20g.edge,\x20g.dst',[a,addressBytes(b)]);return c['rows']['map'](d=>({'src':b['toLowerCase'](),'srcKind':d['src_kind'],'edge':d['edge'],'dst':hexBytes(d['dst']),'dstKind':d['dst_kind'],'objectVersion':d['object_version'],'dstProjected':d['dst_projected']}));}async['edgesTo'](a,b){const c=await this['pool']['query']('SELECT\x20g.src,\x20g.src_kind,\x20g.edge,\x20g.dst_kind,\x20g.object_version::TEXT\x20AS\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(c.object_id\x20IS\x20NOT\x20NULL)\x20AS\x20src_projected\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20graph_edge\x20g\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LEFT\x20JOIN\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20c.chain_id=g.chain_id\x20AND\x20c.object_id=g.src\x20AND\x20c.state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20g.chain_id=$1\x20AND\x20g.dst=$2\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20g.src_kind,\x20g.src',[a,addressBytes(b)]);return c['rows']['map'](d=>({'src':hexBytes(d['src']),'srcKind':d['src_kind'],'edge':d['edge'],'dst':b['toLowerCase'](),'dstKind':d['dst_kind'],'objectVersion':d['object_version'],'dstProjected':d['src_projected']}));}async['backfillGraphEdges'](a){const b=await this['pool']['query']('SELECT\x20c.object_id,\x20c.verified_kind,\x20v.payload_json\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20v.chain_id=c.chain_id\x20AND\x20v.object_id=c.object_id\x20AND\x20v.object_version=c.object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20c.chain_id=$1\x20AND\x20c.state=\x27active\x27\x20AND\x20v.payload_json\x20IS\x20NOT\x20NULL',[a]),c=await this['pool']['connect']();let d=0x0;try{await c['query']('BEGIN');for(const e of b['rows']){const f=hexBytes(e['object_id']),g=extractGraphEdges(e['verified_kind'],f,e['payload_json']);await c['query']('DELETE\x20FROM\x20graph_edge\x20WHERE\x20chain_id=$1\x20AND\x20src=$2',[a,e['object_id']]);for(const h of g){await c['query']('INSERT\x20INTO\x20graph_edge\x20(chain_id,\x20src,\x20src_kind,\x20edge,\x20dst,\x20dst_kind,\x20object_version)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,$2,$3,$4,$5,$6,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(SELECT\x20object_version\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2))',[a,e['object_id'],h['srcKind'],h['edge'],addressBytes(h['dst']),h['dstKind']]);}d+=g['length'];}await c['query']('COMMIT');}catch(i){await c['query']('ROLLBACK');throw i;}finally{c['release']();}return{'objects':b['rows']['length'],'edges':d};}async['backfillFacets'](a){const b=await this['pool']['query']('SELECT\x20c.object_id,\x20c.verified_kind,\x20c.object_version::TEXT\x20AS\x20object_version,\x20v.payload_json\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20v.chain_id=c.chain_id\x20AND\x20v.object_id=c.object_id\x20AND\x20v.object_version=c.object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20c.chain_id=$1\x20AND\x20c.state=\x27active\x27\x20AND\x20v.payload_json\x20IS\x20NOT\x20NULL',[a]),c=await this['pool']['connect']();let d=0x0;try{await c['query']('BEGIN');for(const e of b['rows']){const f=hexBytes(e['object_id']),g=extractFacets(e['verified_kind'],f,e['payload_json']);if(!g){await c['query']('DELETE\x20FROM\x20object_facet\x20WHERE\x20chain_id=$1\x20AND\x20object_id=$2',[a,e['object_id']]);continue;}await c['query']('INSERT\x20INTO\x20object_facet\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20object_id,\x20verified_kind,\x20facet_version,\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry,\x20industry_confidence,\x20location,\x20price_min,\x20price_max,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20capabilities,\x20published,\x20paused,\x20name_tokens,\x20text_tokens,\x20keywords,\x20computed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20object_id)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verified_kind=EXCLUDED.verified_kind,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20facet_version=EXCLUDED.facet_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20object_version=EXCLUDED.object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry=EXCLUDED.industry,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20industry_confidence=EXCLUDED.industry_confidence,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20location=EXCLUDED.location,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20price_min=EXCLUDED.price_min,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20price_max=EXCLUDED.price_max,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20capabilities=EXCLUDED.capabilities,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20published=EXCLUDED.published,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20paused=EXCLUDED.paused,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20name_tokens=EXCLUDED.name_tokens,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20text_tokens=EXCLUDED.text_tokens,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20keywords=EXCLUDED.keywords,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20computed_at=EXCLUDED.computed_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20EXCLUDED.object_version\x20>=\x20object_facet.object_version',[a,e['object_id'],g['verifiedKind'],FACET_VERSION,e['object_version'],g['industry'],g['industryConfidence'],g['location'],g['priceMin'],g['priceMax'],g['capabilities'],g['published'],g['paused'],g['nameTokens'],g['textTokens'],g['keywords'],new Date()['toISOString']()]),d+=0x1;}await c['query']('COMMIT');}catch(h){await c['query']('ROLLBACK');throw h;}finally{c['release']();}return{'objects':b['rows']['length'],'facets':d};}async['activeFacets'](a,b){const c=[a];let d='';b&&(c['push'](b),d='\x20AND\x20c.verified_kind=$'+c['length']);const e=await this['pool']['query']('SELECT\x20f.object_id,\x20f.verified_kind,\x20f.object_version::TEXT\x20AS\x20object_version,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20f.facet_version,\x20f.industry,\x20f.industry_confidence,\x20f.location,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20f.price_min,\x20f.price_max,\x20f.capabilities,\x20f.published,\x20f.paused,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20f.name_tokens,\x20f.text_tokens,\x20f.keywords,\x20c.checkpoint::TEXT\x20AS\x20checkpoint\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_facet\x20f\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20c.chain_id=f.chain_id\x20AND\x20c.object_id=f.object_id\x20AND\x20c.state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20f.chain_id=$1'+d+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20f.object_id',c);return e['rows']['map'](f=>({'objectId':hexBytes(f['object_id']),'verifiedKind':f['verified_kind'],'objectVersion':f['object_version'],'facetVersion':f['facet_version'],'industry':f['industry'],'industryConfidence':Number(f['industry_confidence']),'location':f['location'],'priceMin':f['price_min'],'priceMax':f['price_max'],'capabilities':f['capabilities']??[],'published':f['published'],'paused':f['paused'],'nameTokens':f['name_tokens']??[],'textTokens':f['text_tokens']??[],'keywords':f['keywords']??[],'checkpoint':f['checkpoint']}));}async['currentPayloads'](a,b){const c=new Map();if(b['length']===0x0)return c;const d=[a],e=b['map'](g=>{return d['push'](addressBytes(g)),'$'+d['length'];}),f=await this['pool']['query']('SELECT\x20c.object_id,\x20v.payload_json\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20v.chain_id=c.chain_id\x20AND\x20v.object_id=c.object_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20AND\x20v.object_version=c.object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20c.chain_id=$1\x20AND\x20c.state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20AND\x20c.object_id\x20IN\x20('+e['join'](',\x20')+')',d);for(const g of f['rows']){c['set'](hexBytes(g['object_id']),g['payload_json']??null);}return c;}async['aggregate'](a,b){if(!a)throw new Error('chainId\x20is\x20required');const c=[a,b['group'],b['metric']],d='(v.payload_json->>$2)',e='(v.payload_json->>$3)::numeric',f=['c.chain_id=$1','c.state=\x27active\x27',d+'\x20IS\x20NOT\x20NULL'];b['groupId']!==undefined&&(c['push'](b['groupId']),f['push'](d+'\x20=\x20$'+c['length']));b['excludeClaimed']&&f['push']('(v.payload_json->>\x27claimed_by\x27)\x20IS\x20NULL');const g=f['join']('\x20AND\x20'),h='\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x20ON\x20v.chain_id=c.chain_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20AND\x20v.object_id=c.object_id\x20AND\x20v.object_version=c.object_version',i=await this['pool']['query']('SELECT\x20'+d+'\x20AS\x20group_id,\x20COUNT(*)::TEXT\x20AS\x20count,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20COALESCE(SUM('+e+'),\x200)::TEXT\x20AS\x20metric_sum,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20MAX(c.checkpoint)::TEXT\x20AS\x20max_checkpoint\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+h+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20'+g+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20GROUP\x20BY\x20'+d+'\x20ORDER\x20BY\x20'+d+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LIMIT\x20$'+(c['length']+0x1),[...c,b['limit']+0x1]),j=await this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20total_count,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20COALESCE(SUM('+e+'),\x200)::TEXT\x20AS\x20metric_sum\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+h+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20'+g,c),k=i['rows']['length']>b['limit'];return{'rows':i['rows']['slice'](0x0,b['limit'])['map'](l=>({'group_id':l['group_id'],'count':Number(l['count']),'metric_sum':l['metric_sum'],'max_checkpoint':l['max_checkpoint']})),'totals':{'count':Number(j['rows'][0x0]?.['total_count']??'0'),'metric_sum':j['rows'][0x0]?.['metric_sum']??'0'},'truncated':k};}async['recordReconciliation'](a){const b=a['missing']['length'],c=a['extra']['length'],d=a['versionDrift']['length'],e=a['error']||b>0x0||c>0x0||d>0x0?'fail':'pass',f=new Date()['toISOString'](),g=await this['pool']['connect']();try{await g['query']('BEGIN'),await g['query']('INSERT\x20INTO\x20reconciliation_run\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20chain_id,\x20kind,\x20run_id,\x20live_set_checkpoint,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20missing,\x20extra,\x20version_drift,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20missing_count,\x20extra_count,\x20version_drift_count,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20repaired_missing,\x20repaired_drift,\x20tombstoned,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verdict,\x20live_count,\x20projection_active,\x20generation,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20reconciled_through,\x20started_at,\x20completed_at,\x20error\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20)\x20VALUES\x20($1,$2,$3,$4::bigint,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14::text,$15,$16,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(SELECT\x20generation\x20FROM\x20projection_generation\x20WHERE\x20chain_id=$1\x20AND\x20kind=$2),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20CASE\x20WHEN\x20$14::text=\x27pass\x27\x20THEN\x20$4::bigint\x20ELSE\x20NULL\x20END,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20$17,$18,$19)',[a['chainId'],a['kind'],a['runId'],a['liveSetCheckpoint'],a['missing'],a['extra'],a['versionDrift'],a['preDiff']['missing'],a['preDiff']['extra'],a['preDiff']['versionDrift'],a['repairs']['missing'],a['repairs']['drift'],a['repairs']['tombstoned'],e,a['liveCount'],a['projectionActive'],f,f,a['error']??null]);let h=null,i=null;if(e==='pass'){const j=await g['query']('INSERT\x20INTO\x20projection_generation\x20(chain_id,\x20kind,\x20generation,\x20reconciled_through,\x20updated_at)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,$2,1,$3,$4)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20CONFLICT\x20(chain_id,\x20kind)\x20DO\x20UPDATE\x20SET\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20generation=projection_generation.generation+1,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20reconciled_through=EXCLUDED.reconciled_through,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20updated_at=EXCLUDED.updated_at\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20RETURNING\x20generation',[a['chainId'],a['kind'],a['liveSetCheckpoint'],new Date()['toISOString']()]);h=Number(j['rows'][0x0]['generation']),i=a['liveSetCheckpoint'];}return await g['query']('UPDATE\x20reconciliation_run\x20SET\x20generation=$4,\x20reconciled_through=$5\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20kind=$2\x20AND\x20run_id=$3',[a['chainId'],a['kind'],a['runId'],h,i]),await g['query']('COMMIT'),{'runId':a['runId'],'verdict':e,'generation':h,'reconciledThrough':i};}catch(k){await g['query']('ROLLBACK');throw k;}finally{g['release']();}}async['reconciliationSummary'](a){if(!a)throw new Error('chainId\x20is\x20required');const b=await this['pool']['query']('SELECT\x20kind,\x20generation,\x20reconciled_through::TEXT\x20AS\x20reconciled_through,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20verdict,\x20completed_at,\x20missing_count,\x20extra_count,\x20version_drift_count\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20reconciliation_run\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20completed_at\x20IS\x20NOT\x20NULL\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20completed_at\x20DESC,\x20run_id\x20DESC',[a]),c=new Map();for(const d of b['rows']){if(c['has'](d['kind']))continue;c['set'](d['kind'],{'kind':d['kind'],'generation':Number(d['generation']??0x0),'reconciled_through':d['reconciled_through'],'verdict':d['verdict'],'completed_at':new Date(d['completed_at'])['toISOString'](),'missing_count':Number(d['missing_count']),'extra_count':Number(d['extra_count']),'version_drift_count':Number(d['version_drift_count'])});}return[...c['values']()]['sort']((e,f)=>e['kind']['localeCompare'](f['kind']));}async['reconciledThrough'](a,b){const c=b?await this['pool']['query']('SELECT\x20MIN(reconciled_through)::TEXT\x20AS\x20reconciled_through\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20projection_generation\x20WHERE\x20chain_id=$1\x20AND\x20kind=$2',[a,b]):await this['pool']['query']('SELECT\x20MIN(reconciled_through)::TEXT\x20AS\x20reconciled_through\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20projection_generation\x20WHERE\x20chain_id=$1',[a]);return c['rows'][0x0]?.['reconciled_through']??null;}async['status'](a){if(!a)throw new Error('chainId\x20is\x20required');const [b,c,d,e,f,g,h,i]=await Promise['all']([this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20count\x20FROM\x20object_version\x20WHERE\x20chain_id=$1',[a]),this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20count\x20FROM\x20object_current\x20WHERE\x20chain_id=$1',[a]),this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20count\x20FROM\x20object_current\x20WHERE\x20chain_id=$1\x20AND\x20state=\x27active\x27',[a]),this['pool']['query']('SELECT\x20COUNT(*)::TEXT\x20AS\x20count\x20FROM\x20quarantine\x20WHERE\x20chain_id=$1',[a]),this['pool']['query']('SELECT\x20MAX(checkpoint)::TEXT\x20AS\x20max\x20FROM\x20object_current\x20WHERE\x20chain_id=$1',[a]),this['pool']['query']('SELECT\x20MAX(updated_at)\x20AS\x20max\x20FROM\x20object_current\x20WHERE\x20chain_id=$1',[a]),this['reconciliationSummary'](a),this['reconciledThrough'](a)]),j=numberValue(d['rows'][0x0]['count']);return{'chain_id':a,'raw_versions':numberValue(b['rows'][0x0]['count']),'current_objects':numberValue(c['rows'][0x0]['count']),'active_objects':j,'quarantined_versions':numberValue(e['rows'][0x0]['count']),'max_checkpoint':f['rows'][0x0]['max'],'observed_at':isoValue(g['rows'][0x0]['max']),'coverage':coverage(a,j,![],i),'reconciliations':h};}async['watermarks'](a){if(!a)throw new Error('chainId\x20is\x20required');const b=await this['pool']['query']('SELECT\x20verified_kind,\x20MAX(checkpoint)::TEXT\x20AS\x20max,\x20COUNT(*)::TEXT\x20AS\x20count\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20chain_id=$1\x20AND\x20state=\x27active\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20GROUP\x20BY\x20verified_kind\x20ORDER\x20BY\x20verified_kind',[a]);return b['rows']['map'](c=>({'verified_kind':c['verified_kind'],'max_checkpoint':c['max'],'active_objects':numberValue(c['count'])}));}async['quarantineQueue'](a,b=0x32){if(!a)throw new Error('chainId\x20is\x20required');if(!Number['isInteger'](b)||b<0x1||b>0x1f4)throw new Error('Invalid\x20quarantine\x20limit:\x20'+b);const c=await this['pool']['query']('SELECT\x20q.object_id,\x20q.object_version::TEXT\x20AS\x20object_version,\x20q.reason_code,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20q.first_seen,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20c.object_version::TEXT\x20AS\x20current_version,\x20c.verified_kind\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20quarantine\x20q\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LEFT\x20JOIN\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ON\x20c.chain_id=q.chain_id\x20AND\x20c.object_id=q.object_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20q.chain_id=$1\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20q.first_seen\x20DESC\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LIMIT\x20$2',[a,String(b)]),d=c['rows']['map'](e=>{return{'object_id':e['object_id']instanceof Uint8Array?hexBytes(e['object_id'])['toLowerCase']():null,'object_version':e['object_version'],'reason_code':e['reason_code'],'first_seen':isoValue(e['first_seen']),'current_version':e['current_version'],'verified_kind':e['verified_kind'],'blocking':e['current_version']===null||BigInt(e['object_version'])>BigInt(e['current_version'])};});return d['sort']((e,f)=>e['blocking']===f['blocking']?0x0:e['blocking']?-0x1:0x1)['slice'](0x0,b);}async['listCurrent'](a){if(!a['chainId'])throw new Error('chainId\x20is\x20required');if(a['kind']&&!(a['kind']in WOW_OBJECT_TYPE_TAGS))throw new Error('Unknown\x20object\x20kind:\x20'+a['kind']);const b=a['limit']??0x64;if(!Number['isInteger'](b)||b<0x1||b>0x3e8)throw new Error('Invalid\x20list\x20limit:\x20'+b);if(a['shard']){const {count:i,index:j}=a['shard'];if(!Number['isInteger'](i)||i<0x1||!Number['isInteger'](j)||j<0x0||j>=i)throw new Error('Invalid\x20shard\x20selector');}const c=[a['chainId']],d=['c.chain_id=$1','c.state=\x27active\x27'];a['kind']&&(c['push'](a['kind']),d['push']('c.verified_kind=$'+c['length']));a['shard']&&(c['push'](a['shard']['count'],a['shard']['index']),d['push']('c.shard_count=$'+(c['length']-0x1)),d['push']('c.shard_index=$'+c['length']));a['cursor']&&(c['push'](addressBytes(a['cursor'])),d['push']('c.object_id>$'+c['length']));c['push'](b+0x1);const e=await this['pool']['query']('SELECT\x20c.*,\x20v.payload_uri,\x20v.payload_format,\x20v.payload_json,\x20v.owner_kind,\x20v.owner_address\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20object_current\x20c\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20JOIN\x20object_version\x20v\x20ON\x20v.chain_id=c.chain_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20AND\x20v.object_id=c.object_id\x20AND\x20v.object_version=c.object_version\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20'+d['join']('\x20AND\x20')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ORDER\x20BY\x20c.object_id\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20LIMIT\x20$'+c['length'],c),f=e['rows']['length']>b,g=e['rows']['slice'](0x0,b),h=await this['reconciledThrough'](a['chainId'],a['kind']);return{'objects':g['map'](k=>({'objectId':hexBytes(k['object_id']),'objectVersion':String(k['object_version']),'kindHint':k['kind_hint'],'verifiedKind':k['verified_kind'],'shardCount':k['shard_count'],'shardIndex':k['shard_index'],'moveType':k['move_type'],'checkpoint':String(k['checkpoint']),'state':k['state'],'payloadHash':hexBytes(k['payload_hash']),'payloadUri':k['payload_uri'],'payloadFormat':k['payload_format'],'payloadJson':k['payload_json']??null,'ownerKind':k['owner_kind'],'ownerAddress':k['owner_address']?hexBytes(k['owner_address']):undefined,'updatedAt':new Date(k['updated_at'])['toISOString']()})),'next_cursor':f?hexBytes(g[g['length']-0x1]['object_id']):null,'coverage':coverage(a['chainId'],g['length'],f,h)};}}
@@ -78,6 +78,28 @@ export interface GraphEdgeView {
78
78
  objectVersion: string;
79
79
  dstProjected: boolean;
80
80
  }
81
+ export interface AggregateOptions {
82
+ chainId: string;
83
+ group: string;
84
+ groupId?: string;
85
+ metric: string;
86
+ excludeClaimed: boolean;
87
+ limit: number;
88
+ }
89
+ export interface AggregateRow {
90
+ group_id: string;
91
+ count: number;
92
+ metric_sum: string;
93
+ max_checkpoint: string;
94
+ }
95
+ export interface AggregateAnswer {
96
+ rows: AggregateRow[];
97
+ totals: {
98
+ count: number;
99
+ metric_sum: string;
100
+ };
101
+ truncated: boolean;
102
+ }
81
103
  export interface ObjectFacetRow {
82
104
  objectId: string;
83
105
  verifiedKind: string;
@@ -6,9 +6,8 @@ export declare class GraphQLCdcSource implements CdcSource {
6
6
  private readonly graphql;
7
7
  private readonly snapshot;
8
8
  private readonly rpc;
9
- private readonly network;
10
9
  private readonly expectedChainId;
11
- constructor(graphql: WowGraphQLClient, snapshot: GraphQLSnapshotSource, rpc: WowClient, network: ENTRYPOINT, expectedChainId: string);
10
+ constructor(graphql: WowGraphQLClient, snapshot: GraphQLSnapshotSource, rpc: WowClient, expectedChainId: string);
12
11
  static forNetwork(network: ENTRYPOINT, expectedChainId: string): GraphQLCdcSource;
13
12
  head(): Promise<CdcHead>;
14
13
  readChanges(after: string, before: string, kind: string): Promise<CdcChangeBatch>;