@laserdata/laser-sdk 0.5.3 → 0.6.0

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 (356) hide show
  1. package/README.md +105 -79
  2. package/dist/agent/agdx.d.ts +8 -3
  3. package/dist/agent/agdx.d.ts.map +1 -1
  4. package/dist/agent/agdx.js +39 -22
  5. package/dist/agent/agdx.js.map +1 -1
  6. package/dist/agent/builder.d.ts +25 -15
  7. package/dist/agent/builder.d.ts.map +1 -1
  8. package/dist/agent/builder.js +103 -59
  9. package/dist/agent/builder.js.map +1 -1
  10. package/dist/agent/context.d.ts +3 -6
  11. package/dist/agent/context.d.ts.map +1 -1
  12. package/dist/agent/context.js +17 -9
  13. package/dist/agent/context.js.map +1 -1
  14. package/dist/agent/contract.d.ts +2 -2
  15. package/dist/agent/contract.d.ts.map +1 -1
  16. package/dist/agent/contract.js +10 -6
  17. package/dist/agent/contract.js.map +1 -1
  18. package/dist/agent/memory-handler.d.ts +25 -0
  19. package/dist/agent/memory-handler.d.ts.map +1 -0
  20. package/dist/agent/memory-handler.js +43 -0
  21. package/dist/agent/memory-handler.js.map +1 -0
  22. package/dist/agent/registry.d.ts +3 -10
  23. package/dist/agent/registry.d.ts.map +1 -1
  24. package/dist/agent/registry.js +22 -19
  25. package/dist/agent/registry.js.map +1 -1
  26. package/dist/agent/reliable-consumer.d.ts +19 -9
  27. package/dist/agent/reliable-consumer.d.ts.map +1 -1
  28. package/dist/agent/reliable-consumer.js +193 -54
  29. package/dist/agent/reliable-consumer.js.map +1 -1
  30. package/dist/agent/replies.d.ts +6 -0
  31. package/dist/agent/replies.d.ts.map +1 -1
  32. package/dist/agent/replies.js +55 -4
  33. package/dist/agent/replies.js.map +1 -1
  34. package/dist/agent/router.d.ts +1 -1
  35. package/dist/agent/router.d.ts.map +1 -1
  36. package/dist/agent/router.js +5 -19
  37. package/dist/agent/router.js.map +1 -1
  38. package/dist/agent/scope.d.ts +7 -3
  39. package/dist/agent/scope.d.ts.map +1 -1
  40. package/dist/agent/scope.js +11 -1
  41. package/dist/agent/scope.js.map +1 -1
  42. package/dist/agent/timer.d.ts +6 -0
  43. package/dist/agent/timer.d.ts.map +1 -0
  44. package/dist/agent/timer.js +21 -0
  45. package/dist/agent/timer.js.map +1 -0
  46. package/dist/agent/workflow.d.ts +16 -19
  47. package/dist/agent/workflow.d.ts.map +1 -1
  48. package/dist/agent/workflow.js +17 -6
  49. package/dist/agent/workflow.js.map +1 -1
  50. package/dist/blob.d.ts +2 -3
  51. package/dist/blob.d.ts.map +1 -1
  52. package/dist/blob.js.map +1 -1
  53. package/dist/bridges/a2a.d.ts +34 -23
  54. package/dist/bridges/a2a.d.ts.map +1 -1
  55. package/dist/bridges/a2a.js +29 -19
  56. package/dist/bridges/a2a.js.map +1 -1
  57. package/dist/bridges/hops.d.ts +1 -1
  58. package/dist/bridges/hops.d.ts.map +1 -1
  59. package/dist/bridges/hops.js +1 -1
  60. package/dist/bridges/hops.js.map +1 -1
  61. package/dist/bridges/mcp.d.ts +27 -7
  62. package/dist/bridges/mcp.d.ts.map +1 -1
  63. package/dist/bridges/mcp.js +24 -9
  64. package/dist/bridges/mcp.js.map +1 -1
  65. package/dist/client/bytes.d.ts +5 -0
  66. package/dist/client/bytes.d.ts.map +1 -1
  67. package/dist/client/bytes.js +15 -0
  68. package/dist/client/bytes.js.map +1 -1
  69. package/dist/client/capabilities.d.ts +25 -13
  70. package/dist/client/capabilities.d.ts.map +1 -1
  71. package/dist/client/capabilities.js +145 -123
  72. package/dist/client/capabilities.js.map +1 -1
  73. package/dist/client/error-classify.d.ts +57 -0
  74. package/dist/client/error-classify.d.ts.map +1 -0
  75. package/dist/client/error-classify.js +347 -0
  76. package/dist/client/error-classify.js.map +1 -0
  77. package/dist/client/errors.d.ts +113 -40
  78. package/dist/client/errors.d.ts.map +1 -1
  79. package/dist/client/errors.js +191 -53
  80. package/dist/client/errors.js.map +1 -1
  81. package/dist/client/internals.d.ts +1 -0
  82. package/dist/client/internals.d.ts.map +1 -1
  83. package/dist/client/internals.js +1 -0
  84. package/dist/client/internals.js.map +1 -1
  85. package/dist/client/laser.d.ts +62 -46
  86. package/dist/client/laser.d.ts.map +1 -1
  87. package/dist/client/laser.js +206 -120
  88. package/dist/client/laser.js.map +1 -1
  89. package/dist/client/managed.d.ts +3 -0
  90. package/dist/client/managed.d.ts.map +1 -1
  91. package/dist/client/managed.js +70 -3
  92. package/dist/client/managed.js.map +1 -1
  93. package/dist/context-scope.d.ts +25 -9
  94. package/dist/context-scope.d.ts.map +1 -1
  95. package/dist/context-scope.js +36 -9
  96. package/dist/context-scope.js.map +1 -1
  97. package/dist/context.d.ts +33 -16
  98. package/dist/context.d.ts.map +1 -1
  99. package/dist/context.js +174 -95
  100. package/dist/context.js.map +1 -1
  101. package/dist/conversation-state.d.ts +1 -1
  102. package/dist/conversation-state.d.ts.map +1 -1
  103. package/dist/conversation-state.js +35 -16
  104. package/dist/conversation-state.js.map +1 -1
  105. package/dist/govern.d.ts +24 -5
  106. package/dist/govern.d.ts.map +1 -1
  107. package/dist/govern.js +116 -28
  108. package/dist/govern.js.map +1 -1
  109. package/dist/iggy/apache-iggy.d.ts +59 -56
  110. package/dist/iggy/apache-iggy.d.ts.map +1 -1
  111. package/dist/iggy/apache-iggy.js +300 -137
  112. package/dist/iggy/apache-iggy.js.map +1 -1
  113. package/dist/index.d.ts +97 -65
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +49 -30
  116. package/dist/index.js.map +1 -1
  117. package/dist/intent.d.ts +16 -2
  118. package/dist/intent.d.ts.map +1 -1
  119. package/dist/intent.js +50 -18
  120. package/dist/intent.js.map +1 -1
  121. package/dist/managed/coordination.d.ts +82 -0
  122. package/dist/managed/coordination.d.ts.map +1 -0
  123. package/dist/managed/coordination.js +367 -0
  124. package/dist/managed/coordination.js.map +1 -0
  125. package/dist/managed/destinations.d.ts +4 -3
  126. package/dist/managed/destinations.d.ts.map +1 -1
  127. package/dist/managed/destinations.js +29 -13
  128. package/dist/managed/destinations.js.map +1 -1
  129. package/dist/managed/filters.d.ts +5 -5
  130. package/dist/managed/filters.d.ts.map +1 -1
  131. package/dist/managed/filters.js +39 -22
  132. package/dist/managed/filters.js.map +1 -1
  133. package/dist/managed/forks.d.ts +8 -11
  134. package/dist/managed/forks.d.ts.map +1 -1
  135. package/dist/managed/forks.js +33 -13
  136. package/dist/managed/forks.js.map +1 -1
  137. package/dist/managed/graph.d.ts +1 -4
  138. package/dist/managed/graph.d.ts.map +1 -1
  139. package/dist/managed/graph.js +5 -3
  140. package/dist/managed/graph.js.map +1 -1
  141. package/dist/managed/kv.d.ts +26 -14
  142. package/dist/managed/kv.d.ts.map +1 -1
  143. package/dist/managed/kv.js +88 -61
  144. package/dist/managed/kv.js.map +1 -1
  145. package/dist/managed/projections.d.ts +5 -8
  146. package/dist/managed/projections.d.ts.map +1 -1
  147. package/dist/managed/projections.js +22 -2
  148. package/dist/managed/projections.js.map +1 -1
  149. package/dist/managed/query.d.ts +20 -6
  150. package/dist/managed/query.d.ts.map +1 -1
  151. package/dist/managed/query.js +97 -24
  152. package/dist/managed/query.js.map +1 -1
  153. package/dist/managed/runs.d.ts +2 -4
  154. package/dist/managed/runs.d.ts.map +1 -1
  155. package/dist/managed/runs.js +9 -1
  156. package/dist/managed/runs.js.map +1 -1
  157. package/dist/managed/watch.d.ts +2 -4
  158. package/dist/managed/watch.d.ts.map +1 -1
  159. package/dist/managed/watch.js +9 -1
  160. package/dist/managed/watch.js.map +1 -1
  161. package/dist/memory/handle.d.ts +75 -22
  162. package/dist/memory/handle.d.ts.map +1 -1
  163. package/dist/memory/handle.js +232 -58
  164. package/dist/memory/handle.js.map +1 -1
  165. package/dist/memory/log-memory.d.ts +24 -12
  166. package/dist/memory/log-memory.d.ts.map +1 -1
  167. package/dist/memory/log-memory.js +214 -100
  168. package/dist/memory/log-memory.js.map +1 -1
  169. package/dist/memory/topic.d.ts +2 -2
  170. package/dist/memory/topic.d.ts.map +1 -1
  171. package/dist/memory/topic.js +7 -5
  172. package/dist/memory/topic.js.map +1 -1
  173. package/dist/memory/types.d.ts +41 -5
  174. package/dist/memory/types.d.ts.map +1 -1
  175. package/dist/memory/types.js +44 -18
  176. package/dist/memory/types.js.map +1 -1
  177. package/dist/memory/vector-memory.d.ts +8 -6
  178. package/dist/memory/vector-memory.d.ts.map +1 -1
  179. package/dist/memory/vector-memory.js +65 -34
  180. package/dist/memory/vector-memory.js.map +1 -1
  181. package/dist/memory.d.ts +6 -5
  182. package/dist/memory.d.ts.map +1 -1
  183. package/dist/memory.js +4 -4
  184. package/dist/memory.js.map +1 -1
  185. package/dist/provenance/agent-topic.d.ts +3 -1
  186. package/dist/provenance/agent-topic.d.ts.map +1 -1
  187. package/dist/provenance/agent-topic.js +3 -1
  188. package/dist/provenance/agent-topic.js.map +1 -1
  189. package/dist/provenance/provenance.d.ts +3 -3
  190. package/dist/provenance/provenance.d.ts.map +1 -1
  191. package/dist/provenance/provenance.js +30 -18
  192. package/dist/provenance/provenance.js.map +1 -1
  193. package/dist/runtime/clock.d.ts +3 -0
  194. package/dist/runtime/clock.d.ts.map +1 -1
  195. package/dist/runtime/clock.js +16 -3
  196. package/dist/runtime/clock.js.map +1 -1
  197. package/dist/schema-codecs.d.ts +7 -3
  198. package/dist/schema-codecs.d.ts.map +1 -1
  199. package/dist/schema-codecs.js +80 -12
  200. package/dist/schema-codecs.js.map +1 -1
  201. package/dist/session.d.ts +27 -18
  202. package/dist/session.d.ts.map +1 -1
  203. package/dist/session.js +95 -37
  204. package/dist/session.js.map +1 -1
  205. package/dist/signing.d.ts +11 -5
  206. package/dist/signing.d.ts.map +1 -1
  207. package/dist/signing.js +64 -21
  208. package/dist/signing.js.map +1 -1
  209. package/dist/snapshot.d.ts +10 -2
  210. package/dist/snapshot.d.ts.map +1 -1
  211. package/dist/snapshot.js +62 -28
  212. package/dist/snapshot.js.map +1 -1
  213. package/dist/state-store.d.ts +1 -1
  214. package/dist/state-store.d.ts.map +1 -1
  215. package/dist/state-store.js.map +1 -1
  216. package/dist/stream/batching.d.ts +81 -0
  217. package/dist/stream/batching.d.ts.map +1 -0
  218. package/dist/stream/batching.js +210 -0
  219. package/dist/stream/batching.js.map +1 -0
  220. package/dist/stream/bson.d.ts +3 -0
  221. package/dist/stream/bson.d.ts.map +1 -0
  222. package/dist/stream/bson.js +245 -0
  223. package/dist/stream/bson.js.map +1 -0
  224. package/dist/stream/codecs.d.ts +58 -6
  225. package/dist/stream/codecs.d.ts.map +1 -1
  226. package/dist/stream/codecs.js +143 -59
  227. package/dist/stream/codecs.js.map +1 -1
  228. package/dist/stream/consumer-group.d.ts +13 -10
  229. package/dist/stream/consumer-group.d.ts.map +1 -1
  230. package/dist/stream/consumer-group.js +91 -31
  231. package/dist/stream/consumer-group.js.map +1 -1
  232. package/dist/stream/consumer-start.d.ts +17 -0
  233. package/dist/stream/consumer-start.d.ts.map +1 -0
  234. package/dist/stream/consumer-start.js +2 -0
  235. package/dist/stream/consumer-start.js.map +1 -0
  236. package/dist/stream/consumer.d.ts +166 -24
  237. package/dist/stream/consumer.d.ts.map +1 -1
  238. package/dist/stream/consumer.js +451 -68
  239. package/dist/stream/consumer.js.map +1 -1
  240. package/dist/stream/cursor.d.ts +5 -12
  241. package/dist/stream/cursor.d.ts.map +1 -1
  242. package/dist/stream/cursor.js +34 -8
  243. package/dist/stream/cursor.js.map +1 -1
  244. package/dist/stream/header-value.d.ts +61 -15
  245. package/dist/stream/header-value.d.ts.map +1 -1
  246. package/dist/stream/header-value.js.map +1 -1
  247. package/dist/stream/message.d.ts +17 -0
  248. package/dist/stream/message.d.ts.map +1 -0
  249. package/dist/stream/message.js +9 -0
  250. package/dist/stream/message.js.map +1 -0
  251. package/dist/stream/producer.d.ts +127 -11
  252. package/dist/stream/producer.d.ts.map +1 -1
  253. package/dist/stream/producer.js +401 -36
  254. package/dist/stream/producer.js.map +1 -1
  255. package/dist/stream/publish.d.ts +6 -15
  256. package/dist/stream/publish.d.ts.map +1 -1
  257. package/dist/stream/publish.js +18 -28
  258. package/dist/stream/publish.js.map +1 -1
  259. package/dist/stream/record.d.ts +4 -6
  260. package/dist/stream/record.d.ts.map +1 -1
  261. package/dist/stream/record.js +4 -3
  262. package/dist/stream/record.js.map +1 -1
  263. package/dist/stream/routing.d.ts +12 -0
  264. package/dist/stream/routing.d.ts.map +1 -1
  265. package/dist/stream/routing.js +6 -1
  266. package/dist/stream/routing.js.map +1 -1
  267. package/dist/stream/stream.d.ts +1 -4
  268. package/dist/stream/stream.d.ts.map +1 -1
  269. package/dist/stream/stream.js +5 -1
  270. package/dist/stream/stream.js.map +1 -1
  271. package/dist/stream/topic.d.ts +22 -23
  272. package/dist/stream/topic.d.ts.map +1 -1
  273. package/dist/stream/topic.js +90 -30
  274. package/dist/stream/topic.js.map +1 -1
  275. package/dist/stream/typed-topic.d.ts +9 -13
  276. package/dist/stream/typed-topic.d.ts.map +1 -1
  277. package/dist/stream/typed-topic.js +25 -10
  278. package/dist/stream/typed-topic.js.map +1 -1
  279. package/dist/swarm.d.ts +0 -1
  280. package/dist/swarm.d.ts.map +1 -1
  281. package/dist/swarm.js +1 -0
  282. package/dist/swarm.js.map +1 -1
  283. package/dist/testing.d.ts +3 -3
  284. package/dist/testing.d.ts.map +1 -1
  285. package/dist/testing.js +3 -3
  286. package/dist/testing.js.map +1 -1
  287. package/dist/types/ids.d.ts +17 -2
  288. package/dist/types/ids.d.ts.map +1 -1
  289. package/dist/types/ids.js +34 -14
  290. package/dist/types/ids.js.map +1 -1
  291. package/dist/wire/agent.d.ts +22 -0
  292. package/dist/wire/agent.d.ts.map +1 -1
  293. package/dist/wire/agent.js +80 -25
  294. package/dist/wire/agent.js.map +1 -1
  295. package/dist/wire/authz.d.ts +35 -1
  296. package/dist/wire/authz.d.ts.map +1 -1
  297. package/dist/wire/authz.js +45 -15
  298. package/dist/wire/authz.js.map +1 -1
  299. package/dist/wire/cbor.d.ts.map +1 -1
  300. package/dist/wire/cbor.js +13 -2
  301. package/dist/wire/cbor.js.map +1 -1
  302. package/dist/wire/checkpoint.d.ts +17 -12
  303. package/dist/wire/checkpoint.d.ts.map +1 -1
  304. package/dist/wire/checkpoint.js +28 -3
  305. package/dist/wire/checkpoint.js.map +1 -1
  306. package/dist/wire/control.d.ts +82 -0
  307. package/dist/wire/control.d.ts.map +1 -1
  308. package/dist/wire/control.js +219 -0
  309. package/dist/wire/control.js.map +1 -1
  310. package/dist/wire/filter-eval.d.ts +41 -7
  311. package/dist/wire/filter-eval.d.ts.map +1 -1
  312. package/dist/wire/filter-eval.js +26 -28
  313. package/dist/wire/filter-eval.js.map +1 -1
  314. package/dist/wire/filter.d.ts +51 -17
  315. package/dist/wire/filter.d.ts.map +1 -1
  316. package/dist/wire/filter.js +99 -10
  317. package/dist/wire/filter.js.map +1 -1
  318. package/dist/wire/fork.d.ts +14 -1
  319. package/dist/wire/fork.d.ts.map +1 -1
  320. package/dist/wire/fork.js +19 -8
  321. package/dist/wire/fork.js.map +1 -1
  322. package/dist/wire/graph.d.ts +3 -0
  323. package/dist/wire/graph.d.ts.map +1 -1
  324. package/dist/wire/graph.js +18 -4
  325. package/dist/wire/graph.js.map +1 -1
  326. package/dist/wire/hello.d.ts +4 -1
  327. package/dist/wire/hello.d.ts.map +1 -1
  328. package/dist/wire/hello.js +13 -3
  329. package/dist/wire/hello.js.map +1 -1
  330. package/dist/wire/index.d.ts +4 -1
  331. package/dist/wire/index.d.ts.map +1 -1
  332. package/dist/wire/index.js +4 -1
  333. package/dist/wire/index.js.map +1 -1
  334. package/dist/wire/kv.d.ts +37 -2
  335. package/dist/wire/kv.d.ts.map +1 -1
  336. package/dist/wire/kv.js +36 -18
  337. package/dist/wire/kv.js.map +1 -1
  338. package/dist/wire/query.d.ts +6 -0
  339. package/dist/wire/query.d.ts.map +1 -1
  340. package/dist/wire/query.js +38 -12
  341. package/dist/wire/query.js.map +1 -1
  342. package/dist/wire/schema.d.ts +29 -6
  343. package/dist/wire/schema.d.ts.map +1 -1
  344. package/dist/wire/schema.js +61 -26
  345. package/dist/wire/schema.js.map +1 -1
  346. package/dist/wire/snapshot.js +1 -1
  347. package/dist/wire/snapshot.js.map +1 -1
  348. package/dist/wire/value.d.ts +10 -2
  349. package/dist/wire/value.d.ts.map +1 -1
  350. package/dist/wire/value.js +29 -3
  351. package/dist/wire/value.js.map +1 -1
  352. package/package.json +2 -3
  353. package/dist/stream/polling-strategy.d.ts +0 -14
  354. package/dist/stream/polling-strategy.d.ts.map +0 -1
  355. package/dist/stream/polling-strategy.js +0 -2
  356. package/dist/stream/polling-strategy.js.map +0 -1
@@ -10,18 +10,19 @@ import { Workflow } from "../agent/workflow.js";
10
10
  import { aguiEvents, publishStateDelta, publishStateSnapshot, reconstructState } from "../bridges/agui.js";
11
11
  import { AgentScope } from "../agent/scope.js";
12
12
  import { ChunkAssembler } from "../agent/assembler.js";
13
- import { AgentRegistry, ClientMetadataRequest, encodePresenceInput, newRegistryCache } from "../agent/registry.js";
13
+ import { AgentRegistry, ClientMetadataRequest, encodePresence, newRegistryCache } from "../agent/registry.js";
14
14
  import { AsyncOnce } from "../runtime/async-once.js";
15
15
  import { Stream } from "../stream/stream.js";
16
16
  import { ContextScope } from "../context-scope.js";
17
17
  import { Sessions } from "../session.js";
18
- import { ActionKind, GovernorState, encodePolicyEvidence, decodePolicyEvidence, POLICY_DECISION_OPERATION } from "../govern.js";
18
+ import { ActionKind, GovernorState, encodePolicyEvidence, POLICY_DECISION_OPERATION } from "../govern.js";
19
19
  import { MemoryBackend, MemoryHandle } from "../memory/handle.js";
20
20
  import { MemoryTopicBuilder } from "../memory/topic.js";
21
21
  import { NOOP_OBSERVER } from "../observe.js";
22
22
  import { executeBatch } from "../managed/batch.js";
23
- import { Fork } from "../managed/forks.js";
23
+ import { ForkHandle } from "../managed/forks.js";
24
24
  import { Kv } from "../managed/kv.js";
25
+ import { LeaseCoordinator } from "../managed/coordination.js";
25
26
  import { Bindings, Projections, Schemas } from "../managed/projections.js";
26
27
  import { QueryRequest } from "../managed/query.js";
27
28
  import { Destinations } from "../managed/destinations.js";
@@ -30,7 +31,7 @@ import { GraphHandle } from "../managed/graph.js";
30
31
  import { Runs } from "../managed/runs.js";
31
32
  import { Watch } from "../managed/watch.js";
32
33
  import { AGDX_HELLO_CODE, AGDX_SET_CLIENT_METADATA_CODE, CONTROL_OP_VERSION, QUERY_OP_VERSION } from "../wire/codes.js";
33
- import { QueryCancelCommand, QueryCommand, QueryStatusCommand } from "../wire/commands.js";
34
+ import { QueryCancelCommand, QueryCommand, QueryPageCommand, QueryStatusCommand } from "../wire/commands.js";
34
35
  import { encodeControlEnvelope } from "../wire/control.js";
35
36
  import { decodeBackendAnnounce } from "../wire/hello.js";
36
37
  import { AgentId, ConversationId } from "../types/ids.js";
@@ -43,27 +44,27 @@ import { AgentTopic } from "../provenance/agent-topic.js";
43
44
  import { encodeProvenanceHeaders, provenancePartitionKey } from "../provenance/provenance.js";
44
45
  import { CHANGES_TOPIC, CONTROL_TOPIC, DLQ_TOPIC, OPS_STREAM } from "../wire/topics.js";
45
46
  import { encodeNamed } from "../wire/cbor.js";
46
- import { ConfigError, NoStreamError, PresenceConflictError, QueryExecutionError, InvalidError, TimeoutError, UnsupportedError } from "./errors.js";
47
+ import { ConfigError, NoStreamError, PresenceConflictError, QueryExecutionError, ProtocolError, InvalidError, TimeoutError, UnsupportedError } from "./errors.js";
47
48
  import { executeManaged } from "./managed.js";
48
49
  import { INTERNAL_GOVERN, INTERNAL_REPLY_HUB, INTERNAL_TRANSPORT, INTERNAL_VERIFIER } from "./internals.js";
49
- import { OPEN_CAPABILITIES, managedCapabilitiesFrom, mergeCapabilities, isReady, servesConsistency } from "./capabilities.js";
50
+ import { OPEN_CAPABILITIES, advertisedTopology, managedCapabilitiesFrom, mergeCapabilities, isReady, servesConsistency } from "./capabilities.js";
50
51
  const LOCAL_CONNECTION_STRING = "iggy:iggy@127.0.0.1:8090";
51
52
  // The Iggy error code a server answers an unknown command with.
52
53
  const INVALID_COMMAND = 3;
53
54
  const DEFAULT_TOPOLOGY = {
54
55
  opsStream: OPS_STREAM,
55
56
  controlTopic: CONTROL_TOPIC,
56
- deadLetterTopic: DLQ_TOPIC,
57
+ dlqTopic: DLQ_TOPIC,
57
58
  changesTopic: CHANGES_TOPIC
58
59
  };
59
60
  const NO_TOPOLOGY_OVERRIDES = {
60
61
  opsStream: false,
61
62
  controlTopic: false,
62
- deadLetterTopic: false,
63
+ dlqTopic: false,
63
64
  changesTopic: false
64
65
  };
65
66
  export class LaserBuilder {
66
- create;
67
+ connectWith;
67
68
  connectOptionsValue = {};
68
69
  publishOptionsValue = {};
69
70
  connectionStringValue;
@@ -78,8 +79,12 @@ export class LaserBuilder {
78
79
  verifierValue;
79
80
  topologyValue = DEFAULT_TOPOLOGY;
80
81
  topologyOverridesValue = NO_TOPOLOGY_OVERRIDES;
81
- constructor(create) {
82
- this.create = create;
82
+ constructor(connectWith) {
83
+ this.connectWith = connectWith;
84
+ }
85
+ /** @internal */
86
+ static create(connectWith) {
87
+ return new LaserBuilder(connectWith);
83
88
  }
84
89
  /**
85
90
  * Budget for the initial connect: TCP dial, TLS handshake, login, and the managed capability probe. An expired budget rejects with `TimeoutError` naming the stage that stalled. Default: 30 seconds, or `LASER_CONNECT_TIMEOUT_MS`.
@@ -109,19 +114,15 @@ export class LaserBuilder {
109
114
  return this;
110
115
  }
111
116
  credentials(username, password) {
112
- this.credentialsValue = { kind: "usernamePassword", username, password };
113
- return this;
114
- }
115
- token(value) {
116
- this.credentialsValue = { kind: "token", token: value };
117
+ this.credentialsValue = { username, password };
117
118
  return this;
118
119
  }
119
- iggyClient(client, options = {}) {
120
+ client(client, options = {}) {
120
121
  this.clientValue = client;
121
122
  this.ownershipValue = options.ownership ?? "borrowed";
122
123
  return this;
123
124
  }
124
- defaultStream(value) {
125
+ stream(value) {
125
126
  this.defaultStreamValue = value;
126
127
  return this;
127
128
  }
@@ -151,9 +152,9 @@ export class LaserBuilder {
151
152
  this.topologyOverridesValue = { ...this.topologyOverridesValue, controlTopic: true };
152
153
  return this;
153
154
  }
154
- deadLetterTopic(value) {
155
- this.topologyValue = { ...this.topologyValue, deadLetterTopic: value };
156
- this.topologyOverridesValue = { ...this.topologyOverridesValue, deadLetterTopic: true };
155
+ dlqTopic(value) {
156
+ this.topologyValue = { ...this.topologyValue, dlqTopic: value };
157
+ this.topologyOverridesValue = { ...this.topologyOverridesValue, dlqTopic: true };
157
158
  return this;
158
159
  }
159
160
  changesTopic(value) {
@@ -161,15 +162,17 @@ export class LaserBuilder {
161
162
  this.topologyOverridesValue = { ...this.topologyOverridesValue, changesTopic: true };
162
163
  return this;
163
164
  }
164
- connect() {
165
+ /** Connects with the configured settings. A configuration conflict
166
+ * rejects before any I/O, like every other failure of the connect. */
167
+ async connect() {
165
168
  const modes = Number(this.connectionStringValue !== undefined) +
166
169
  Number(this.addressValue !== undefined) +
167
170
  Number(this.clientValue !== undefined);
168
171
  if (modes > 1) {
169
- throw new ConfigError("connectionString(), address(), and iggyClient() are mutually exclusive");
172
+ throw new ConfigError("connectionString(), address(), and client() are mutually exclusive");
170
173
  }
171
174
  if (this.credentialsValue !== undefined && this.addressValue === undefined) {
172
- throw new ConfigError("credentials() and token() require address()");
175
+ throw new ConfigError("credentials() requires address()");
173
176
  }
174
177
  if (this.addressValue !== undefined) {
175
178
  const { host, port } = this.addressValue;
@@ -180,14 +183,14 @@ export class LaserBuilder {
180
183
  const topologyEntries = [
181
184
  ["opsStream", this.topologyValue.opsStream],
182
185
  ["controlTopic", this.topologyValue.controlTopic],
183
- ["deadLetterTopic", this.topologyValue.deadLetterTopic],
186
+ ["dlqTopic", this.topologyValue.dlqTopic],
184
187
  ["changesTopic", this.topologyValue.changesTopic]
185
188
  ];
186
189
  for (const [name, value] of topologyEntries) {
187
190
  if (value.length === 0)
188
191
  throw new ConfigError(`${name} must not be empty`);
189
192
  }
190
- return this.create({
193
+ return this.connectWith({
191
194
  connectOptions: connectOptions(this.connectOptionsValue),
192
195
  publishOptions: publishOptions(this.publishOptionsValue),
193
196
  ...(this.connectionStringValue !== undefined
@@ -208,10 +211,13 @@ export class LaserBuilder {
208
211
  }
209
212
  }
210
213
  export { INTERNAL_GOVERN, INTERNAL_REPLY_HUB, INTERNAL_TRANSPORT, INTERNAL_VERIFIER } from "./internals.js";
211
- function newSharedState() {
214
+ // `connectionString` is the string the client dialed, absent for an injected
215
+ // client, which has nothing to dial a coordination connection with.
216
+ function newSharedState(connectionString) {
212
217
  return {
213
218
  registryCaches: new Map(),
214
219
  replyHubs: new Map(),
220
+ leases: LeaseCoordinator.forConnection(connectionString),
215
221
  announcedTopology: DEFAULT_TOPOLOGY
216
222
  };
217
223
  }
@@ -244,7 +250,7 @@ function actionKind(kind) {
244
250
  }
245
251
  function metadataString(envelope, key) {
246
252
  const value = envelope.metadata?.get(key);
247
- return value?.kind === "string" ? value.value : undefined;
253
+ return value?.kind === "str" ? value.value : undefined;
248
254
  }
249
255
  function metadataActionFields(envelope) {
250
256
  const onBehalfOf = metadataString(envelope, METADATA_DELEGATED_BY);
@@ -319,10 +325,10 @@ export class Laser {
319
325
  ? this.configuredTopology.controlTopic
320
326
  : this.shared.announcedTopology.controlTopic;
321
327
  }
322
- get deadLetterTopic() {
323
- return this.topologyOverrides.deadLetterTopic
324
- ? this.configuredTopology.deadLetterTopic
325
- : this.shared.announcedTopology.deadLetterTopic;
328
+ get dlqTopic() {
329
+ return this.topologyOverrides.dlqTopic
330
+ ? this.configuredTopology.dlqTopic
331
+ : this.shared.announcedTopology.dlqTopic;
326
332
  }
327
333
  get changesTopic() {
328
334
  return this.topologyOverrides.changesTopic
@@ -330,32 +336,29 @@ export class Laser {
330
336
  : this.shared.announcedTopology.changesTopic;
331
337
  }
332
338
  static builder() {
333
- return new LaserBuilder(async (options) => {
339
+ return LaserBuilder.create(async (options) => {
334
340
  const deadline = Date.now() + options.connectOptions.timeoutMs;
335
341
  let transport;
342
+ let dialed;
336
343
  if (options.client !== undefined) {
337
344
  transport = await ApacheIggyTransport.fromClient(options.client, options.ownership, options.publishOptions, deadline);
338
345
  }
339
346
  else if (options.address !== undefined) {
340
- const credentials = options.credentials ?? {
341
- kind: "usernamePassword",
342
- username: "iggy",
343
- password: "iggy"
344
- };
345
- const userInfo = credentials.kind === "token"
346
- ? encodeURIComponent(credentials.token)
347
- : `${encodeURIComponent(credentials.username)}:${encodeURIComponent(credentials.password)}`;
347
+ const credentials = options.credentials ?? { username: "iggy", password: "iggy" };
348
+ const userInfo = `${encodeURIComponent(credentials.username)}:${encodeURIComponent(credentials.password)}`;
348
349
  const authorityHost = options.address.host.includes(":")
349
350
  ? `[${options.address.host.replace(/^\[|\]$/g, "")}]`
350
351
  : options.address.host;
351
- transport = await ApacheIggyTransport.connect(`iggy://${userInfo}@${authorityHost}:${String(options.address.port)}`, options.publishOptions, deadline);
352
+ dialed = `iggy://${userInfo}@${authorityHost}:${String(options.address.port)}`;
353
+ transport = await ApacheIggyTransport.connect(dialed, options.publishOptions, deadline);
352
354
  }
353
355
  else {
354
- transport = await ApacheIggyTransport.connect(options.connectionString ?? LOCAL_CONNECTION_STRING, options.publishOptions, deadline);
356
+ dialed = options.connectionString ?? LOCAL_CONNECTION_STRING;
357
+ transport = await ApacheIggyTransport.connect(dialed, options.publishOptions, deadline);
355
358
  }
356
359
  const laser = new Laser(transport, options.defaultStream, options.capabilities === undefined
357
360
  ? new AsyncOnce()
358
- : AsyncOnce.resolved(options.capabilities), newSharedState(), options.observer, options.governor === undefined
361
+ : AsyncOnce.resolved(options.capabilities), newSharedState(dialed), options.observer, options.governor === undefined
359
362
  ? undefined
360
363
  : new GovernorState(options.governor.policy, options.governor.mode, undefined, options.governor.retention), options.verifier, options.topology, options.topologyOverrides, options.capabilities ?? OPEN_CAPABILITIES);
361
364
  if (options.capabilities === undefined)
@@ -363,15 +366,14 @@ export class Laser {
363
366
  return laser;
364
367
  });
365
368
  }
366
- static fromIggyClient(client, options = {}) {
367
- const builder = Laser.builder()
368
- .iggyClient(client, options.ownership === undefined ? {} : { ownership: options.ownership })
369
- .capabilities(options.capabilities ?? OPEN_CAPABILITIES);
370
- if (options.defaultStream !== undefined)
371
- builder.defaultStream(options.defaultStream);
372
- if (options.observer !== undefined)
373
- builder.observer(options.observer);
374
- return builder.connect();
369
+ /**
370
+ * Wrap a connected, logged-in Apache Iggy client with no default stream.
371
+ * Chain `withDefaultStream`, `withCapabilities`, or `withObserver` to
372
+ * configure the handle. A `borrowed` client (the default) stays open when
373
+ * the handle closes, an `owned` one closes with it.
374
+ */
375
+ static fromClient(client, options = {}) {
376
+ return Laser.builder().client(client, options).capabilities(OPEN_CAPABILITIES).connect();
375
377
  }
376
378
  /**
377
379
  * Connect using an Iggy connection string. Connecting gives up after 30 seconds, or `LASER_CONNECT_TIMEOUT_MS`, with a `TimeoutError` that says whether the server never accepted the connection or never answered the login. Use `Laser.builder().connectTimeout()` for another budget.
@@ -379,14 +381,14 @@ export class Laser {
379
381
  static async connect(connectionString) {
380
382
  const deadline = Date.now() + connectOptions().timeoutMs;
381
383
  const transport = await ApacheIggyTransport.connect(connectionString, undefined, deadline);
382
- const laser = new Laser(transport, undefined, new AsyncOnce(), newSharedState());
384
+ const laser = new Laser(transport, undefined, new AsyncOnce(), newSharedState(connectionString));
383
385
  await laser.probeCapabilitiesBefore(deadline);
384
386
  return laser;
385
387
  }
386
388
  static async connectWithStream(connectionString, stream) {
387
389
  const deadline = Date.now() + connectOptions().timeoutMs;
388
390
  const transport = await ApacheIggyTransport.connect(connectionString, undefined, deadline);
389
- const laser = new Laser(transport, stream, new AsyncOnce(), newSharedState());
391
+ const laser = new Laser(transport, stream, new AsyncOnce(), newSharedState(connectionString));
390
392
  await laser.probeCapabilitiesBefore(deadline);
391
393
  return laser;
392
394
  }
@@ -406,15 +408,48 @@ export class Laser {
406
408
  withDefaultStream(stream) {
407
409
  return new Laser(this.transport, stream, this.capabilitiesOnce, this.shared, this.observer, this.governor, this.verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, this.capabilityOverride, false);
408
410
  }
411
+ /** A clone whose managed operations use `opsStream` instead of the ops
412
+ * stream the deployment announced. The connection is shared. */
413
+ withOpsStream(opsStream) {
414
+ return this.withTopology({ opsStream });
415
+ }
416
+ /** A clone whose control commands publish to `controlTopic` on the ops
417
+ * stream. The connection is shared. */
418
+ withControlTopic(controlTopic) {
419
+ return this.withTopology({ controlTopic });
420
+ }
421
+ /** A clone whose dead-letter capsules publish to `dlqTopic` on the ops
422
+ * stream. The connection is shared. */
423
+ withDlqTopic(dlqTopic) {
424
+ return this.withTopology({ dlqTopic });
425
+ }
426
+ /** A clone whose change-feed records are read from `changesTopic` on the ops
427
+ * stream. The connection is shared. */
428
+ withChangesTopic(changesTopic) {
429
+ return this.withTopology({ changesTopic });
430
+ }
431
+ withTopology(override) {
432
+ const topology = {
433
+ opsStream: this.opsStream,
434
+ controlTopic: this.controlTopic,
435
+ dlqTopic: this.dlqTopic,
436
+ changesTopic: this.changesTopic,
437
+ ...override
438
+ };
439
+ const overrides = {
440
+ opsStream: this.topologyOverrides.opsStream || override.opsStream !== undefined,
441
+ controlTopic: this.topologyOverrides.controlTopic || override.controlTopic !== undefined,
442
+ dlqTopic: this.topologyOverrides.dlqTopic || override.dlqTopic !== undefined,
443
+ changesTopic: this.topologyOverrides.changesTopic || override.changesTopic !== undefined
444
+ };
445
+ return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, this.observer, this.governor, this.verifier, topology, overrides, this.configuredCapabilities, this.capabilityOverride, false);
446
+ }
409
447
  withCapabilities(capabilities) {
410
448
  return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, this.observer, this.governor, this.verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, capabilities, false);
411
449
  }
412
450
  withGovernor(governor, mode, retention = {}) {
413
451
  return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, this.observer, new GovernorState(governor, mode, undefined, retention), this.verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, this.capabilityOverride, false);
414
452
  }
415
- withVerifier(verifier) {
416
- return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, this.observer, this.governor, verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, this.capabilityOverride, false);
417
- }
418
453
  withObserver(observer) {
419
454
  return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, observer, this.governor, this.verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, this.capabilityOverride, false);
420
455
  }
@@ -481,7 +516,9 @@ export class Laser {
481
516
  if (isReady(capabilities))
482
517
  return capabilities;
483
518
  if (capabilities.backends.length === 0) {
484
- throw new UnsupportedError("server has no managed backend descriptors");
519
+ throw new UnsupportedError("server has no managed backend descriptors", {
520
+ surface: "readiness"
521
+ });
485
522
  }
486
523
  if (Date.now() >= deadline) {
487
524
  throw new TimeoutError("timed out waiting for managed backend readiness", {
@@ -492,41 +529,45 @@ export class Laser {
492
529
  }
493
530
  }
494
531
  applyAdvertisedTopology(capabilities) {
495
- const topology = capabilities.topology;
532
+ const topology = advertisedTopology(capabilities);
496
533
  if (topology === undefined)
497
534
  return;
498
535
  this.shared.announcedTopology = {
499
536
  opsStream: topology.opsStream,
500
537
  controlTopic: topology.controlTopic,
501
- deadLetterTopic: topology.dlqTopic,
538
+ dlqTopic: topology.dlqTopic,
502
539
  changesTopic: topology.changesTopic
503
540
  };
504
541
  }
542
+ /** @internal */
505
543
  [INTERNAL_TRANSPORT]() {
506
544
  return this.transport;
507
545
  }
546
+ /** @internal */
508
547
  [INTERNAL_VERIFIER]() {
509
548
  return this.verifier;
510
549
  }
550
+ /** @internal */
511
551
  [INTERNAL_REPLY_HUB](topic) {
512
552
  return this.replyHub(topic);
513
553
  }
554
+ /** @internal */
514
555
  [INTERNAL_GOVERN](action) {
515
556
  if (this.governor === undefined)
516
557
  return Promise.resolve(action.payload.slice());
517
558
  return this.governor.govern(action, (evidence) => this.emitPolicyEvidence(action.stream, evidence));
518
559
  }
519
- get iggyClient() {
560
+ get client() {
520
561
  return this.transport.iggyClient;
521
562
  }
522
563
  stream(name) {
523
- return new Stream(this.transport, name, (stream, topic, payload, provenance) => this[INTERNAL_GOVERN]({
564
+ return Stream.create(this.transport, name, (stream, topic, payload, provenance) => this[INTERNAL_GOVERN]({
524
565
  kind: ActionKind.Publish,
525
566
  stream,
526
567
  topic,
527
- ...(provenance?.agent !== undefined ? { source: provenance.agent.asString() } : {}),
568
+ ...(provenance?.agent !== undefined ? { source: provenance.agent.asStr() } : {}),
528
569
  ...(provenance?.targetAgentId !== undefined
529
- ? { target: provenance.targetAgentId.asString() }
570
+ ? { target: provenance.targetAgentId.asStr() }
530
571
  : {}),
531
572
  ...(provenance !== undefined ? { conversation: provenance.conversationId } : {}),
532
573
  ...(provenance?.correlationId !== undefined
@@ -575,13 +616,13 @@ export class Laser {
575
616
  }), this.verifier);
576
617
  }
577
618
  agent(id) {
578
- return new AgentScope(this, id);
619
+ return AgentScope.create(this, id);
579
620
  }
580
621
  contract(router) {
581
- return new ContractBuilder(this, router);
622
+ return ContractBuilder.create(this, router);
582
623
  }
583
624
  workflow(name) {
584
- return new Workflow(this, name);
625
+ return Workflow.create(this, name);
585
626
  }
586
627
  publishStateSnapshot(topic, source, conversation, state) {
587
628
  return publishStateSnapshot(this, topic, source, conversation, state);
@@ -602,13 +643,13 @@ export class Laser {
602
643
  return scatterReport(this, source, selector, payload, inboxRoute, deadlineMs);
603
644
  }
604
645
  context(conversation) {
605
- return new ContextScope(this, conversation);
646
+ return ContextScope.create(this, conversation);
606
647
  }
607
648
  /** The session accessor: one conversation seen as typed turns, a model-ready
608
649
  * context, scoped memory, and checkpointed replay. Built on `context`, so a
609
650
  * session is never a second store. */
610
- sessions(options) {
611
- return new Sessions(this, options);
651
+ sessions(config) {
652
+ return Sessions.create(this, config);
612
653
  }
613
654
  memory(namespace) {
614
655
  return this.memoryWith(namespace, MemoryBackend.Auto);
@@ -619,7 +660,7 @@ export class Laser {
619
660
  }
620
661
  /** Configures a durable memory topic before opening it. */
621
662
  memoryTopic(topic) {
622
- return new MemoryTopicBuilder(this, topic);
663
+ return MemoryTopicBuilder.create(this, topic);
623
664
  }
624
665
  memoryWith(namespace, backend, embedder) {
625
666
  return backend === MemoryBackend.Vector
@@ -646,15 +687,15 @@ export class Laser {
646
687
  ...(provenance.correlationId !== undefined
647
688
  ? { correlation: provenance.correlationId }
648
689
  : {}),
649
- ...(provenance.agent !== undefined ? { agent: provenance.agent.asString() } : {})
690
+ ...(provenance.agent !== undefined ? { agent: provenance.agent.asStr() } : {})
650
691
  }, async () => {
651
692
  const governedPayload = await this[INTERNAL_GOVERN]({
652
693
  kind: ActionKind.Send,
653
694
  stream,
654
695
  topic,
655
- ...(provenance.agent !== undefined ? { source: provenance.agent.asString() } : {}),
696
+ ...(provenance.agent !== undefined ? { source: provenance.agent.asStr() } : {}),
656
697
  ...(provenance.targetAgentId !== undefined
657
- ? { target: provenance.targetAgentId.asString() }
698
+ ? { target: provenance.targetAgentId.asStr() }
658
699
  : {}),
659
700
  conversation: provenance.conversationId,
660
701
  ...(provenance.correlationId !== undefined
@@ -673,19 +714,6 @@ export class Laser {
673
714
  await this.transport.sendMessageWithHeaders(stream, topic, governedPayload, headers, provenancePartitionKey(provenance));
674
715
  });
675
716
  }
676
- async policyEvidence(conversation) {
677
- const messages = await this.context(conversation).fetch([AgentTopic.Audit], Number.MAX_SAFE_INTEGER);
678
- return messages.flatMap((message) => {
679
- if (message.envelope?.operation !== POLICY_DECISION_OPERATION)
680
- return [];
681
- try {
682
- return [decodePolicyEvidence(message.envelope.body)];
683
- }
684
- catch {
685
- return [];
686
- }
687
- });
688
- }
689
717
  async emitPolicyEvidence(stream, evidence) {
690
718
  const conversation = evidence.conversation === undefined
691
719
  ? ConversationId.parse("00000000000000000000000000")
@@ -706,10 +734,10 @@ export class Laser {
706
734
  };
707
735
  }
708
736
  async reassembleChannel(conversation, topic, channel) {
709
- const cursor = await this.topic(topic).replay({ batchSize: 1_000 });
737
+ const cursor = (await this.topic(topic).replay()).batch(1_000);
710
738
  const envelopes = [];
711
739
  for (;;) {
712
- const records = await cursor.poll();
740
+ const records = await cursor.pollRecords();
713
741
  if (records.length === 0)
714
742
  break;
715
743
  for (const record of records) {
@@ -735,7 +763,9 @@ export class Laser {
735
763
  async consumed(target, at) {
736
764
  if (this.transport.resolveStreamTopicNames === undefined ||
737
765
  this.transport.getConsumerOffset === undefined) {
738
- throw new UnsupportedError("the active Iggy transport cannot resolve consumer offsets");
766
+ throw new UnsupportedError("the active Iggy transport cannot resolve consumer offsets", {
767
+ surface: "stream"
768
+ });
739
769
  }
740
770
  const names = await this.transport.resolveStreamTopicNames(at.streamId, at.topicId);
741
771
  if (names === undefined) {
@@ -744,7 +774,7 @@ export class Laser {
744
774
  const consumer = target.kind === "group"
745
775
  ? {
746
776
  kind: "group",
747
- name: typeof target.name === "string" ? target.name : target.name.asString()
777
+ name: typeof target.name === "string" ? target.name : target.name.asStr()
748
778
  }
749
779
  : { kind: "consumer", name: target.name };
750
780
  const offset = await this.transport.getConsumerOffset(names.stream, names.topic, consumer, at.partitionId);
@@ -756,7 +786,9 @@ export class Laser {
756
786
  }
757
787
  async redriveDeadLetter(capsule) {
758
788
  if (this.transport.resolveStreamTopicNames === undefined) {
759
- throw new UnsupportedError("the active Iggy transport cannot resolve dead-letter sources");
789
+ throw new UnsupportedError("the active Iggy transport cannot resolve dead-letter sources", {
790
+ surface: "stream"
791
+ });
760
792
  }
761
793
  const source = capsule.source;
762
794
  const names = await this.transport.resolveStreamTopicNames(source.streamId, source.topicId);
@@ -787,7 +819,7 @@ export class Laser {
787
819
  const correlationId = provenance.correlationId ?? ConversationId.new().toString();
788
820
  const correlated = { ...provenance, correlationId };
789
821
  const hub = await this.replyHub(replyTopic);
790
- const ticket = hub.subscribe(correlationId, correlated.targetAgentId?.asString());
822
+ const ticket = hub.subscribe(correlationId, correlated.targetAgentId?.asStr());
791
823
  try {
792
824
  await this.sendAgent(requestTopic, payload, correlated);
793
825
  }
@@ -798,16 +830,16 @@ export class Laser {
798
830
  return ticket.wait(timeoutMs, signal);
799
831
  }
800
832
  clientMetadata() {
801
- return new ClientMetadataRequest(this.transport);
833
+ return ClientMetadataRequest.create(this.transport);
802
834
  }
803
835
  async advertisePresence(presence) {
804
- const requested = presence.agent.asString();
836
+ const requested = AgentId.new(presence.agent).asStr();
805
837
  const advertised = this.shared.advertisedAgent;
806
838
  if (advertised !== undefined && advertised !== requested) {
807
839
  throw new PresenceConflictError(advertised, requested);
808
840
  }
809
841
  this.shared.advertisedAgent = requested;
810
- await this.managedTransport().sendManaged(AGDX_SET_CLIENT_METADATA_CODE, encodePresenceInput(presence));
842
+ await this.managedTransport().sendManaged(AGDX_SET_CLIENT_METADATA_CODE, encodePresence(presence));
811
843
  }
812
844
  async clearPresence() {
813
845
  await this.managedTransport().sendManaged(AGDX_SET_CLIENT_METADATA_CODE, new Uint8Array());
@@ -822,7 +854,7 @@ export class Laser {
822
854
  this.shared.registryCaches.set(stream, cache);
823
855
  }
824
856
  const cursor = await this.topic(AgentTopic.Registry).replay();
825
- return new AgentRegistry(cursor, cache, () => this.clientMetadata(), undefined, this.verifier);
857
+ return AgentRegistry.create(cursor, cache, () => this.clientMetadata(), undefined, this.verifier);
826
858
  }
827
859
  async publishCard(source, card) {
828
860
  validateAgentCard(card);
@@ -850,7 +882,7 @@ export class Laser {
850
882
  await this.topic(AgentTopic.Registry).ensure(1);
851
883
  let fact = this.agdx(AgentTopic.Registry, operator, ConversationId.new())
852
884
  .status(operation)
853
- .body(new TextEncoder().encode(agent.asString()));
885
+ .body(new TextEncoder().encode(agent.asStr()));
854
886
  if (key !== undefined)
855
887
  fact = fact.signedBy(key);
856
888
  await fact.send();
@@ -879,13 +911,18 @@ export class Laser {
879
911
  return this.queryTarget({ kind: "operational", index });
880
912
  }
881
913
  queryTarget(target) {
882
- return new QueryRequest(target, (query) => this.executeQuery(query), (executionId) => this.queryStatus(executionId), (executionId) => this.cancelQuery(executionId));
914
+ return QueryRequest.create(target, (query) => this.executeQuery(query), (executionId) => this.queryStatus(executionId), (executionId) => this.cancelQuery(executionId));
883
915
  }
884
916
  queryLakehouse(destinationId, destinationGeneration) {
885
917
  return this.queryTarget({ kind: "lakehouse", destinationId, destinationGeneration });
886
918
  }
887
919
  destinations() {
888
- return new Destinations(this.managedTransport(), () => this.capabilities());
920
+ return Destinations.create(this.managedTransport(), () => this.capabilities());
921
+ }
922
+ /** Sends one checkpoint request envelope, the deep form behind every
923
+ * `destinations()` mutation. */
924
+ executeCheckpoint(request) {
925
+ return this.destinations().executeCheckpoint(request);
889
926
  }
890
927
  // What a consumer group needs to reach its filter policy and read through
891
928
  // the partition primaries.
@@ -910,11 +947,12 @@ export class Laser {
910
947
  : {}),
911
948
  ...(transport.connectsNodes !== undefined ? { connectsNodes: transport.connectsNodes } : {})
912
949
  },
913
- capabilities: () => this.capabilities()
950
+ capabilities: () => this.capabilities(),
951
+ refreshCapabilities: () => this.refreshCapabilities()
914
952
  };
915
953
  }
916
954
  kv(namespace) {
917
- return new Kv(this.managedTransport(), () => this.capabilities(), namespace);
955
+ return Kv.create(this.managedTransport(), () => this.capabilities(), namespace, this.shared.leases);
918
956
  }
919
957
  async kvNamespaces() {
920
958
  return Kv.namespaces(this.managedTransport(), () => this.capabilities());
@@ -924,28 +962,28 @@ export class Laser {
924
962
  return executeBatch(this.managedTransport(), capabilities, ops);
925
963
  }
926
964
  fork(forkId) {
927
- return new Fork(this.managedTransport(), () => this.capabilities(), forkId);
965
+ return ForkHandle.create(this.managedTransport(), () => this.capabilities(), forkId);
928
966
  }
929
967
  async forks() {
930
- return Fork.forks(this.managedTransport(), () => this.capabilities());
968
+ return ForkHandle.forks(this.managedTransport(), () => this.capabilities());
931
969
  }
932
970
  projections() {
933
- return new Projections(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
971
+ return Projections.create(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
934
972
  }
935
973
  bindings() {
936
- return new Bindings((command) => this.publishControl(command));
974
+ return Bindings.create((command) => this.publishControl(command));
937
975
  }
938
976
  schemas() {
939
- return new Schemas(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
977
+ return Schemas.create(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
940
978
  }
941
979
  runs() {
942
- return new Runs(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
980
+ return Runs.create(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
943
981
  }
944
982
  watch() {
945
- return new Watch(() => this.capabilities(), (options) => this.stream(this.opsStream).topic(this.changesTopic).replay(options));
983
+ return Watch.create(() => this.capabilities(), () => this.stream(this.opsStream).topic(this.changesTopic).replay());
946
984
  }
947
985
  graph(name) {
948
- return new GraphHandle(this.managedTransport(), () => this.capabilities(), name);
986
+ return GraphHandle.create(this.managedTransport(), () => this.capabilities(), name);
949
987
  }
950
988
  async whoami() {
951
989
  return whoami(this.managedTransport(), await this.capabilities());
@@ -982,49 +1020,96 @@ export class Laser {
982
1020
  .topic(this.controlTopic)
983
1021
  .send(payload, { key: new TextEncoder().encode("control") });
984
1022
  }
1023
+ /** Executes a pre-built `Query` and returns the raw paged result. Most
1024
+ * callers want `query(index)...fetch()` instead. Needs `laser-plane` in Laser
1025
+ * Stack or LaserData Cloud, otherwise it fails with `UnsupportedError`. */
985
1026
  async executeQuery(query) {
986
1027
  const capabilities = await this.capabilities();
987
1028
  if (query.text !== undefined && !capabilities.query.keyword) {
988
- throw new UnsupportedError("keyword query is not served by this deployment");
1029
+ throw new UnsupportedError("keyword query is not served by this deployment", {
1030
+ surface: "query",
1031
+ feature: "keyword"
1032
+ });
989
1033
  }
990
1034
  if (!servesConsistency(capabilities, query.consistency)) {
991
- throw new UnsupportedError(`${query.consistency} query consistency is not served by this deployment`);
1035
+ throw new UnsupportedError(`${query.consistency} query consistency is not served by this deployment`, { surface: "query", feature: "consistency" });
992
1036
  }
993
1037
  const reply = await executeManaged(this.managedTransport(), capabilities, QueryCommand, {
994
1038
  v: QUERY_OP_VERSION,
995
1039
  query
996
1040
  });
997
- if (reply.kind === "ok")
1041
+ if (reply.kind === "ok") {
1042
+ if (reply.result.context.executionId.asU128() !== query.executionId.asU128()) {
1043
+ throw new ProtocolError("query reply execution id does not match the request");
1044
+ }
998
1045
  return reply.result;
999
- if (reply.error.kind === "unsupported") {
1000
- throw new UnsupportedError(reply.error.message);
1001
1046
  }
1002
1047
  throw new QueryExecutionError(`query failed: ${reply.error.kind}`, reply.error);
1003
1048
  }
1049
+ /** Retrieves the next cursor page of an executing query. Needs the
1050
+ * `cursorPaging` capability. */
1051
+ async queryPage(executionId, cursor, deadlineMicros) {
1052
+ const capabilities = await this.capabilities();
1053
+ if (!capabilities.query.cursorPaging) {
1054
+ throw new UnsupportedError("query cursor paging is not advertised by this deployment", {
1055
+ surface: "query",
1056
+ feature: "cursor_paging"
1057
+ });
1058
+ }
1059
+ const reply = await executeManaged(this.managedTransport(), capabilities, QueryPageCommand, {
1060
+ v: QUERY_OP_VERSION,
1061
+ executionId,
1062
+ cursor,
1063
+ deadlineMicros
1064
+ });
1065
+ if (reply.kind === "ok") {
1066
+ if (reply.result.context.executionId.asU128() !== executionId.asU128()) {
1067
+ throw new ProtocolError("query reply execution id does not match the request");
1068
+ }
1069
+ return reply.result;
1070
+ }
1071
+ throw new QueryExecutionError(`query page failed: ${reply.error.kind}`, reply.error);
1072
+ }
1073
+ /** Reads the current state of an executing or recently completed query. */
1004
1074
  async queryStatus(executionId) {
1005
1075
  const capabilities = await this.capabilities();
1006
1076
  if (!capabilities.query.executionStatus) {
1007
- throw new UnsupportedError("query execution status is not served by this deployment");
1077
+ throw new UnsupportedError("query execution status is not served by this deployment", {
1078
+ surface: "query",
1079
+ feature: "execution_status"
1080
+ });
1008
1081
  }
1009
1082
  const reply = await executeManaged(this.managedTransport(), capabilities, QueryStatusCommand, {
1010
1083
  v: QUERY_OP_VERSION,
1011
1084
  executionId
1012
1085
  });
1013
- if (reply.kind === "ok")
1086
+ if (reply.kind === "ok") {
1087
+ if (reply.status.executionId.asU128() !== executionId.asU128()) {
1088
+ throw new ProtocolError("query status execution id does not match the request");
1089
+ }
1014
1090
  return reply.status;
1091
+ }
1015
1092
  throw new QueryExecutionError(`query status failed: ${reply.error.kind}`, reply.error);
1016
1093
  }
1094
+ /** Cancels an executing query by its unguessable identity. */
1017
1095
  async cancelQuery(executionId) {
1018
1096
  const capabilities = await this.capabilities();
1019
1097
  if (!capabilities.query.cancellation) {
1020
- throw new UnsupportedError("query cancellation is not served by this deployment");
1098
+ throw new UnsupportedError("query cancellation is not served by this deployment", {
1099
+ surface: "query",
1100
+ feature: "cancellation"
1101
+ });
1021
1102
  }
1022
1103
  const reply = await executeManaged(this.managedTransport(), capabilities, QueryCancelCommand, {
1023
1104
  v: QUERY_OP_VERSION,
1024
1105
  executionId
1025
1106
  });
1026
- if (reply.kind === "ok")
1107
+ if (reply.kind === "ok") {
1108
+ if (reply.status.executionId.asU128() !== executionId.asU128()) {
1109
+ throw new ProtocolError("query status execution id does not match the request");
1110
+ }
1027
1111
  return reply.status;
1112
+ }
1028
1113
  throw new QueryExecutionError(`query cancellation failed: ${reply.error.kind}`, reply.error);
1029
1114
  }
1030
1115
  /** Closes owned transport resources. Safe to call more than once. */
@@ -1036,6 +1121,7 @@ export class Laser {
1036
1121
  }, () => undefined);
1037
1122
  }
1038
1123
  this.shared.replyHubs.clear();
1124
+ await this.shared.leases.close();
1039
1125
  await closeProducerStatistics(this.transport);
1040
1126
  await this.observe("laser.close", { operation: "close" }, () => this.transport.close());
1041
1127
  })();