@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
package/README.md CHANGED
@@ -4,7 +4,7 @@ This package provides the native TypeScript Laser SDK for Apache Iggy. [LaserDat
4
4
 
5
5
  This prerelease targets Node 22.14 or later. Bun, Deno, and browsers are not supported because the Apache Iggy transport uses Node TCP and TLS APIs.
6
6
 
7
- > The current release is `0.5.3`. The wire contract and public API use semantic versioning. Before `1.0.0`, minor releases can contain breaking changes.
7
+ > The current release is `0.6.0`. The wire contract and public API use semantic versioning. Before `1.0.0`, minor releases can contain breaking changes.
8
8
 
9
9
  **Filter before the network.** Consumer filters select records on the server so each reader receives only its matching subset of a topic and its partitions. The shared CDC example delivers **4 of 240 records** and saves **98.5% of payload transfer**. It preserves original payloads and offsets, supports exact-width typed headers, and acknowledges only completed work. See the [Consumer Filters guide](https://docs.laserdata.cloud/laser-sdk/consumer-filters) and the [three-language examples](https://github.com/laserdata/laser-sdk/tree/main/examples).
10
10
 
@@ -24,20 +24,20 @@ import { Laser } from "@laserdata/laser-sdk"
24
24
  await using laser = await Laser.connect(
25
25
  process.env.LASER_CONNECTION_STRING ?? "iggy:iggy@127.0.0.1:8090"
26
26
  )
27
- const topic = laser.stream("commerce").topic("orders")
27
+ const topic = laser.stream("fleet").topic("readings")
28
28
  await topic.ensure(4)
29
- const committed = await topic.publish().json({ id: "order-1", total: 42 }).send()
29
+ const committed = await topic.publish().json({ host: "node-7", cpu: 82 }).send()
30
30
  console.log(committed.confirmations)
31
31
 
32
32
  const records = await (await topic.replay()).poll()
33
- console.log(`read ${records.length} order(s)`)
33
+ console.log(`read ${records.length} reading(s)`)
34
34
  ```
35
35
 
36
36
  Use a `user:password@host:port` connection string. The SDK supplies the Apache Iggy TCP scheme. Select a stream with `laser.stream(name)` and a topic with `.topic(name)`. `Laser.connectWithStream()` selects a default for the shorter `laser.topic(name)` form. It does not restrict stream access.
37
37
 
38
38
  `Laser.connectEnv()` reads `LASER_CONNECTION_STRING` and optional `LASER_STREAM`. `Laser.local()` uses the default local server. `Laser.builder()` accepts a connection string, separate credentials, or an Apache Iggy client. For an injected client, select whether Laser SDK owns or borrows it.
39
39
 
40
- For owned connections, the SDK retries initial connections and reconnects dropped sockets. The default is unlimited retries at one-second intervals. Set `reconnection_retries` to a non-negative integer to limit retries. Set `reconnection_interval` to a duration such as `250ms`, `1s`, or `1m`. The caller controls the lifecycle and reconnect policy of an injected client.
40
+ For owned connections, the SDK retries a failed dial and reconnects dropped sockets, by default without limit at one-second intervals. The 30-second connect budget stops the retries of the initial connection. Add `reconnection_retries` to the connection string with a non-negative integer to limit retries, and `reconnection_interval` with a duration such as `250ms`, `1s`, or `1m`, for example `iggy:iggy@127.0.0.1:8090?reconnection_retries=5&reconnection_interval=250ms`. The caller controls the lifecycle and reconnect policy of an injected client.
41
41
 
42
42
  The TypeScript SDK uses Iggy's native VSR transport for owned and injected clients.
43
43
 
@@ -46,10 +46,11 @@ The TypeScript SDK uses Iggy's native VSR transport for owned and injected clien
46
46
  `laser.stream(name).topic(name)` addresses any stream. `laser.topic(name)` is the default-stream shortcut. Topics support:
47
47
 
48
48
  - raw, JSON, CBOR, MessagePack, Avro, Protobuf, and JSON Schema records
49
- - exact headers, metadata, indexes, projection and schema IDs, inline payload, claim-check, routing keys, explicit partitions, and heterogeneous batches
50
- - direct producers with bounded retry and explicit batching
49
+ - exact headers, indexes, projection and schema IDs, inline payload, claim-check, routing keys, explicit partitions, and heterogeneous batches
50
+ - direct producers with bounded retry, explicit batching, and stream and topic creation on the first send (`createStream`, `createTopic`, `partitions`)
51
+ - a size-and-time batching publisher through `topic.batching()`
51
52
  - standalone and consumer-group readers with first, last, next, offset, or timestamp starts
52
- - automatic or explicit offset commits, replay, cancellation, and bounded `nextWithin()` waits
53
+ - the ten Rust commit policies through `commitPolicy`, such as `{ kind: "disabled" }` for manual commits, explicit `commit`, `storeOffset`, `deleteOffset`, and `lastStoredOffset`, replay, cancellation, and bounded `nextWithin()` waits that fail with `TimeoutError`
53
54
 
54
55
  Delivery is at least once, so records can repeat. Ordering applies within each selected partition. Make external effects idempotent, which means safe to repeat. For operations that require a lease holder token, use fenced managed coordination.
55
56
 
@@ -57,31 +58,33 @@ Producers and publish builders return `SendMessagesResponse`. A confirmation ide
57
58
 
58
59
  ## Runtime-checked records
59
60
 
60
- TypeScript types do not exist at runtime. A typed topic therefore takes a codec that checks decoded values. A generic type parameter alone cannot check incoming bytes.
61
+ TypeScript types do not exist at runtime. A typed topic therefore takes a codec that checks decoded values. A generic type parameter alone cannot check incoming bytes. The `Json`, `Cbor`, `Msgpack`, and `Bson` codec classes take an optional decode check, and a custom `Codec<T>` declares its `contentType` with `encode` and `decode`.
61
62
 
62
63
  ```ts
63
- import { jsonCodec } from "@laserdata/laser-sdk"
64
+ import { Json } from "@laserdata/laser-sdk"
64
65
 
65
- interface Order {
66
- readonly id: string
67
- readonly total: number
66
+ interface Reading {
67
+ readonly host: string
68
+ readonly cpu: number
68
69
  }
69
70
 
70
- const orderCodec = jsonCodec<Order>((value) => {
71
- if (typeof value !== "object" || value === null) throw new TypeError("order must be an object")
72
- const order = value as Record<string, unknown>
73
- if (typeof order.id !== "string" || typeof order.total !== "number") {
74
- throw new TypeError("order fields are invalid")
71
+ const readingCodec = new Json<Reading>((value) => {
72
+ if (typeof value !== "object" || value === null)
73
+ throw new TypeError("a reading must be an object")
74
+ const reading = value as Record<string, unknown>
75
+ if (typeof reading.host !== "string" || typeof reading.cpu !== "number") {
76
+ throw new TypeError("reading fields are invalid")
75
77
  }
76
- return { id: order.id, total: order.total }
78
+ return { host: reading.host, cpu: reading.cpu }
77
79
  })
78
80
 
79
- const orders = laser.stream("commerce").topic("orders").json(orderCodec)
80
- await orders.publish({ id: "order-1", total: 42 })
81
+ const readings = laser.stream("fleet").topic("readings").json(readingCodec)
82
+ await readings.publish({ host: "node-7", cpu: 82 })
81
83
 
82
- const reader = await orders.records("orders-export")
83
- const record = await reader.nextWithin(1_000)
84
- console.log(record?.value)
84
+ const reader = await readings.records("readings-export")
85
+ for await (const item of reader.stream()) {
86
+ if (item.kind === "record") console.log(item.record.value)
87
+ }
85
88
  ```
86
89
 
87
90
  Registered Avro, Protobuf, and JSON Schema topics compile their writer schema once. They reject invalid values before sending and attach the schema ID. Reads decode through the same schema.
@@ -95,29 +98,31 @@ The root client provides queries, projections, schemas, key-value state, forks,
95
98
  ```ts
96
99
  import { graphNodeEntity, queryResultValue, typedValueDiagnosticText } from "@laserdata/laser-sdk"
97
100
 
98
- const paid = await laser.query("orders_v1").whereEq("status", "paid").limit(20).fetch()
99
- for (const row of paid.rows) {
100
- const total = queryResultValue(paid, row, "total")
101
- console.log(total === undefined ? "missing" : typedValueDiagnosticText(total))
101
+ const degraded = await laser.query("readings_v1").whereEq("status", "degraded").limit(20).fetch()
102
+ for (const row of degraded.rows) {
103
+ const cpu = queryResultValue(degraded, row, "cpu")
104
+ console.log(cpu === undefined ? "missing" : typedValueDiagnosticText(cpu))
102
105
  }
103
106
 
104
- const key = new TextEncoder().encode("user:42")
105
- const session = { cart: ["sku-1"] }
106
- await laser.kv("sessions").set(key).json(session).ttl(300_000_000n).send()
107
- const stored = await laser.kv("sessions").get(key)
107
+ const key = new TextEncoder().encode("service:auth")
108
+ await laser.kv("config").set(key).json({ log_level: "debug" }).ttl(300_000_000n).send()
109
+ const stored = await laser.kv("config").get(key)
108
110
 
109
- const checkout = graphNodeEntity("Service", "checkout")
110
- const nearby = await laser.graph("ops").neighbors(checkout.id, "out", undefined, 2)
111
+ const auth = graphNodeEntity("Service", "auth")
112
+ const nearby = await laser.graph("ops").neighbors(auth.id, "out", undefined, 2)
111
113
  ```
112
114
 
113
115
  `result.fields` defines the ordered result schema. Each `row.values` entry matches the field at the same position. Tagged values preserve numeric widths, decimal precision, timestamps, UUIDs, bytes, nested values, and nullability. Use `queryResultValue()` to select a field by name. Use `typedValueDiagnosticText()` for stable display text.
114
116
 
115
- The first page can use an offset. Later pages use the `nextCursor` supplied by the server. `hasMore` is true exactly when that cursor is present. `fetchAll()` follows these cursors. Each page contains at most 1000 rows.
117
+ The first page can use an offset. Later pages use the `result.page.nextCursor` supplied by the server. `result.page.hasMore` is true exactly when that cursor is present. `fetchAll()` follows these cursors. Each page contains at most 1000 rows.
116
118
 
117
- A query has a stable execution identity and absolute deadline. `status()` and `cancel()` use dedicated managed commands and fail locally when the deployment does not advertise those capabilities:
119
+ A query has a stable execution identity and an absolute deadline, 30 seconds after the request was built unless you set `deadlineMicros(epochMicros)` or the relative `deadline(milliseconds)`. `status()` and `cancel()` use dedicated managed commands and fail locally when the deployment does not advertise those capabilities. `laser.executeQuery(query)`, `queryPage(executionId, cursor, deadlineMicros)`, `queryStatus(executionId)`, and `cancelQuery(executionId)` are the lower-level forms:
118
120
 
119
121
  ```ts
120
- const request = laser.query("orders_v1").filterGte("total", 100).deadlineMicros(deadlineMicros)
122
+ const request = laser
123
+ .query("readings_v1")
124
+ .filterGte("cpu", { kind: "int", value: 90 })
125
+ .deadline(10_000)
121
126
  const page = await request.fetch()
122
127
  const status = await request.status()
123
128
  if (status.state === "running") await request.cancel()
@@ -129,7 +134,7 @@ Lakehouse queries name one destination generation and can select a retained snap
129
134
  const historical = await laser
130
135
  .queryLakehouse(destinationId, destinationGeneration)
131
136
  .atSnapshot(snapshotId)
132
- .filterEq("customer_id", "alice")
137
+ .filterEq("host_id", { kind: "string", value: "node-7" })
133
138
  .limit(100)
134
139
  .fetch()
135
140
 
@@ -143,7 +148,7 @@ Use `laser.destinations()` for destination declarations and explicit query route
143
148
  ```ts
144
149
  const destinations = laser.destinations()
145
150
  const page = await destinations.list("linearizable", {}, undefined, 50)
146
- const routes = await destinations.queryRoutes("potentially_stale", "orders", undefined, 50)
151
+ const routes = await destinations.queryRoutes("potentially_stale", "readings", undefined, 50)
147
152
  const current = await destinations.get(destinationId, "linearizable")
148
153
  ```
149
154
 
@@ -170,19 +175,21 @@ Accessors select operations without performing I/O. Methods such as `send()`, `f
170
175
 
171
176
  A replay cursor saves offsets only after all partition reads succeed. A failed or canceled poll leaves them unchanged. Each request reads at most 10,000 messages. Further polls resume from the saved offsets. The TypeScript cursor stream continues waiting for new records until it is stopped.
172
177
 
173
- Durable memory can use the default audit topic through `laser.memory(namespace)`, an existing isolated topic through `laser.memoryOnTopic(topic)`, or a configured topic:
178
+ Durable memory can use the default audit topic through `laser.memory(namespace)`, an existing isolated topic through `laser.memoryOnTopic(topic)`, or a configured topic. Each form needs a stream, from `Laser.connectWithStream()` or `withDefaultStream()`. `memoryTopic(topic).stream(name)` and `memoryOnTopic(topic, stream)` name one directly:
174
179
 
175
180
  ```ts
176
181
  const incidents = await laser.memoryTopic("incidents").partitions(4).ttl(86_400_000).build()
177
182
 
178
- await incidents.remember(new TextEncoder().encode("checkout uses the read replica")).send()
183
+ await incidents.remember(new TextEncoder().encode("auth uses the read replica")).send()
179
184
  ```
180
185
 
181
- TypeScript duration inputs use milliseconds. `noExpiry()` keeps the raw memory history until ordinary topic retention removes it.
186
+ Memory topic and consumer duration inputs use milliseconds. KV `ttl` and `expire` take a lifetime and `expireAt` takes an absolute time, all as microsecond `bigint` values. `noExpiry()` keeps the raw memory history until ordinary topic retention removes it.
182
187
 
183
- **Filter before the network.** Configure a consumer group's policy once. Its ordinary consumers and page readers then receive the selected records with their original payloads, headers and offsets. The shared CDC feed delivers **4 of 240 records**, saving **98.5% of payload transfer**. An unbound group receives all records without payload decoding.
188
+ Configure a consumer group's policy once. Its ordinary consumers and page readers then receive the selected records with their original payloads, headers and offsets. An unbound group receives all records without payload decoding.
184
189
 
185
190
  ```ts
191
+ import { ConsumerFilter, FilterExpr } from "@laserdata/laser-sdk"
192
+
186
193
  const safeMode = ConsumerFilter.json(
187
194
  FilterExpr.all([
188
195
  FilterExpr.pred("table", "eq", "satellites"),
@@ -195,13 +202,11 @@ const group = topic.consumerGroup("anomaly-desk")
195
202
  await group.create({ filter: safeMode }) // Run once during setup.
196
203
 
197
204
  // Every consumer instance needs only the group name or the returned group ID.
198
- const consumer = await group.consumer({ batchLength: 100, autoCommit: false })
205
+ const consumer = await group.consumer({ batchLength: 100, commitPolicy: { kind: "disabled" } })
199
206
  try {
200
- const record = await consumer.nextWithin(15_000)
201
- if (record !== null) {
202
- console.log(record.partitionId, record.offset, record.payload)
203
- await consumer.commit(record)
204
- }
207
+ const record = await consumer.nextWithin(15_000) // TimeoutError when nothing matched in time
208
+ console.log(record.position.partitionId, record.position.offset, record.json())
209
+ await consumer.commit(record)
205
210
  } finally {
206
211
  await consumer.shutdown()
207
212
  }
@@ -213,7 +218,7 @@ For batch handling, build `await group.reader().count(100).maxExamined(1000).bui
213
218
 
214
219
  `group.filter()` provides `configure`, `get`, `revisions`, `revise`, `setRevisionEnabled`, `release`, `delete`, `preview` and `test`. `delete()` removes the group's own filter with every revision and releases the group first. Use `configureAs(operationId, policy)` when setup must resume with the same operation ID after a lost reply. `topic.consumerGroupId(id)` addresses the same saved group by numeric ID. Catalog failures, denied reads and paused revisions never broaden into unfiltered delivery. Original Apache Iggy uses native group consumption, while an older managed server without group-aware reads returns an explicit upgrade error.
215
220
 
216
- Filters support JSON, CBOR, Avro, Protobuf and typed headers. `CompiledFilter.compile(filter).evaluate(record)` checks records locally with exact integers. `ConsumerFilter.withFaultPolicy`, `withForeignPolicy` and `withMismatchPolicy` control invalid records. Passed invalid records and unfiltered records have `evaluated` false. Malformed headers set `headersMalformed` without discarding valid entries or the payload. Server refusals throw `FilterExecutionError`, and fault or oversized stops throw `FilterStopError` with the stop reason. See the [Consumer Filters guide](https://docs.laserdata.cloud/laser-sdk/consumer-filters) and the [three-language examples](https://github.com/laserdata/laser-sdk/tree/main/examples).
221
+ Filters support JSON, CBOR, Avro, Protobuf and typed headers. `CompiledFilter.compile(filter).evaluate(record)` checks records locally with exact integers. `ConsumerFilter.withFaultPolicy`, `withForeignPolicy` and `withMismatchPolicy` control invalid records. Passed invalid records and unfiltered records have `evaluated` false. Malformed headers set `headersMalformed` without discarding valid entries or the payload. Server refusals throw `FilterExecutionError`. A fault stop throws `FilterFaultError` with its `reason`, and an oversized stop throws `FilterOversizedRecordError`. `filterReason(error)` reads the reason from any of them. See the [Consumer Filters guide](https://docs.laserdata.cloud/laser-sdk/consumer-filters) and the [three-language examples](https://github.com/laserdata/laser-sdk/tree/main/examples).
217
222
 
218
223
  ## Agents and coordination
219
224
 
@@ -221,7 +226,7 @@ The agent layer adds record origins, typed AGDX messages, routing, discovery, re
221
226
 
222
227
  Sessions group one agent's conversation through `laser.sessions().create(id)`. `append(kind, data)` records a turn, and `context()` returns typed turns for a model. Turn kinds are `instruction`, `response`, `model.response`, `tool.call`, `tool.result`, and `human.input`. `memory().search(query)` searches memory scoped to the conversation.
223
228
 
224
- A checkpoint records the next offset for each topic partition. `checkpoint()`, `turnsAt`, `turnsSince`, `stateAt`, and `replay` support reads and state reconstruction around those saved offsets. `Checkpoint.fromJSON(JSON.stringify(checkpoint))` restores a saved checkpoint. `laser.sessions({ stream, topics, memoryNamespace, contextTurns, contextTokens })` configures the stream, topics, memory namespace, and context limits.
229
+ A checkpoint records the next offset for each topic partition. `checkpoint()`, `turnsAt`, `turnsSince`, `stateAt`, and `replay` support reads and state reconstruction around those saved offsets. `Checkpoint.fromJSON(JSON.stringify(checkpoint))` restores a saved checkpoint. `laser.sessions(new SessionConfig().stream(name).topic(kind, topic).memoryNamespace(ns).contextTurns(n).contextTokens(n))` configures the stream, topics, memory namespace, and context limits. Each turn kind needs a distinct topic.
225
230
 
226
231
  The root package provides context, snapshots, memory, governance, intent records, signing, delegation, A2A, MCP, AG-UI, and edge authorization. A configured verifier rejects unsigned or invalid replies for contracts, shared reply readers, and `requestInput`. It binds signatures to the observed headers and server timestamp. An agent with a signing key signs its `respond` and `respondInput` replies. `KvKeyRegistry` manages versioned keys through the platform. The SDK records model-call metadata but does not call a model.
227
232
 
@@ -233,10 +238,11 @@ await using handle = Agent.builder()
233
238
  .listenOn(AgentTopic.Commands)
234
239
  .respondOn(AgentTopic.Responses)
235
240
  .handler({
236
- handle(message, context) {
237
- return context.respond(message.payload)
241
+ handle(message, ctx) {
242
+ return ctx.respond(message.payload)
238
243
  }
239
244
  })
245
+ .build()
240
246
  .spawn(laser)
241
247
 
242
248
  await handle.ready()
@@ -249,50 +255,70 @@ Waiting operations accept `AbortSignal` or an explicit timeout where their contr
249
255
 
250
256
  SDK failures extend `LaserError` and carry a stable `kind`. Separate subclasses identify configuration, timeout, cancellation, unknown mutation outcomes, unsupported operations, encoding, transport, policy, and signature failures. Catch a specific subclass when it needs different recovery. Otherwise, report the base error and its cause.
251
257
 
258
+ A failed publish throws `PublishFailedError` with the `stream`, `topic`, the `committed` confirmations, and the `unconfirmed` records. `publishCause()` reaches the original failure, so an `instanceof TransportError` check around a publish no longer matches. The classifiers mirror the Rust `LaserError` methods and answer through any publish wrapping: `isPermissionDenied`, `isUnsupported`, `isNotFound`, `isUnavailable`, `isNotLeader`, `isStale`, `isVersionSkew`, `isVersionConflict`, `isAmbiguousMutation`, `isStreamOrTopicNotFound`, `isNoCapableAgent`, `isLeaseLost`, `isFenceViolation`, `isBudgetExceeded`, `isQuarantined`, `isRetryable`, `filterReason`, `iggyErrorCode`, and `code`, which returns the unified result code. Routing failures throw `NoCapableAgentError`, `NoInboxError`, or `RoutePrincipalMismatchError`. Invalid identifiers throw `IdError` and malformed provenance headers throw `ProvenanceError`. Payloads are `Uint8Array`, so `TextEncoder` and `TextDecoder` convert text.
259
+
252
260
  `Laser.connect*()` owns its Apache Iggy client. `Laser.builder()` can own or borrow an injected client. `Laser`, `Producer`, `Consumer`, and `AgentHandle` support `await using`. Their `close()` and `shutdown()` methods are safe to repeat. `close()` on any `Laser` view ends the shared connection for every view. Disposing a scoped view with `await using` leaves the root connection open.
253
261
 
254
- ## Package exports
262
+ ## Connect timeout
255
263
 
256
- - `@laserdata/laser-sdk` is the ordinary application surface
257
- - `@laserdata/laser-sdk/full` adds the complete native wire namespace
258
- - `@laserdata/laser-sdk/testing` provides clocks, stores, fake transports, factories, observers, and bounded eventually checks
259
- - `@laserdata/laser-sdk/opentelemetry` adapts the observer seam to OpenTelemetry
264
+ Connecting gives up after 30 seconds. Set another budget in milliseconds with `Laser.builder().connectTimeout()` or the `LASER_CONNECT_TIMEOUT_MS` environment variable. Explicit configuration overrides the variable. The budget covers the TCP dial, the TLS handshake, the login, and the capability probe. An expired budget rejects with a `TimeoutError` that says whether the server never accepted the connection or never answered the login. `laser.stream(name).delete()` removes a stream you no longer need, and `laser.close()` ends the shared connection. See [connect timeout and cleanup](../../docs/connect-timeout.md).
260
265
 
261
- `laser.iggyClient()` is the Apache Iggy escape hatch for native administrative or transport operations that Laser does not wrap.
266
+ ## Publish recovery
262
267
 
263
- ## Examples and verification
268
+ Publish attempts default to 60 seconds with three retries. Retry delays start at 250 milliseconds, double after each failure, and stop increasing at 30 seconds. Set them with `publishTimeout`, `publishMaxRetries`, and `publishRetryBackoff` on `Laser.builder()`, or with `LASER_PUBLISH_TIMEOUT_MS`, `LASER_PUBLISH_MAX_RETRIES`, and `LASER_PUBLISH_RETRY_BACKOFF_MS`. Explicit configuration overrides the variables. Exhausted retries reject with a `PublishFailedError`, so check `committed` before resending. A batching publisher from `topic.batching()` keeps a failed timer flush until `send()`, `flush()`, or `close()` reports it. See [publish recovery and outage handling](../../docs/publish-recovery.md).
264
269
 
265
- The examples in [`examples/typescript`](../../examples/typescript/README.md) cover nine focused operations and nine larger applications. The shared scenarios under [`bdd/scenarios`](../../bdd/scenarios) describe behavior across clients.
270
+ ## Consumer filter groups and offsets
266
271
 
267
- ```sh
268
- npm ci
269
- npm run verify
270
- ```
272
+ **Provision a filtered group once, then consume by its ID.** The filter API supports create-and-bind setup, numeric group selection, and revision pause/resume. Use separate groups for A/B revisions so their offsets remain independent. A fresh named consumer using `Next` starts at the first retained record. Ordinary consumers auto-commit each polled batch before delivery by default, so a later consumer can resume after records the application did not process. Disable auto-commit and commit after successful processing when that matters. Filtered readers use explicit acknowledgments, and keep at most 1024 unacknowledged record-bearing pages per partition by default, set with `maxUnackedPages`, so a reader that never acknowledges stops at that bound instead of growing without limit. Unnamed TypeScript consumers have isolated identities and default to no automatic commit. Use a stable name to resume durable progress. See the [Consumer Filters guide](https://docs.laserdata.cloud/laser-sdk/consumer-filters).
271
273
 
272
- `verify` runs style, formatting, lint, dependency-boundary, type, build, API, unit, wire, coverage, license, and package tests. Integration and shared BDD tests run separately against the versioned native Iggy server.
274
+ Avro and Protobuf filters use registered writer schemas, immutable schema IDs in the filter, and the `agdx.sid` header on each record. Headers-only filters work with any payload format. Filtering preserves original bytes and offsets.
273
275
 
274
- ## Security and license
276
+ For an application checkpoint inside a filtered page, call `reader.ackThrough(record)` after persisting the checkpoint and processing all preceding records on that partition. Later records in the same page stay pending. Use `ackPage` when the whole page is complete.
275
277
 
276
- Report security issues through the repository security policy. The package is Apache-2.0 licensed. Apache and Apache Iggy are trademarks of the Apache Software Foundation.
278
+ Consumer-filter patterns use the server's bounded Rust regex engine. TypeScript validates structure and lets the server decide regex syntax. A local `CompiledFilter` refuses regex predicates, because only the server's engine defines their meaning. A filter permits four compiled glob or regex predicates, with a 256 KiB program budget each. Enabling `localGuard(true)` on a reader whose filter has regex predicates throws a `ConfigError` instead of skipping verification. Guards verify unevaluated records under the server's reported decoder bounds and the applicable pass policy.
277
279
 
278
- ## Connect timeout
280
+ ## 0.6.0 additions
279
281
 
280
- Connecting gives up after 30 seconds. Set another budget with the Rust `connect_timeout` builder method, the Python `connect_timeout_ms` connect argument, or the TypeScript `connectTimeout` builder method. The environment variable is `LASER_CONNECT_TIMEOUT_MS`, and explicit configuration overrides it. The budget covers the TCP dial, the TLS handshake, the login, and the capability probe. An expired budget returns a timeout error that says whether the server never accepted the connection or never answered the login. `stream(name).delete()` removes a stream you no longer need, and `close()` ends the shared connection.
282
+ These match the Rust and Python surfaces:
281
283
 
282
- See [connect timeout and cleanup](../../docs/connect-timeout.md).
284
+ - Producer options `batchLength`, `lingerMs`, `maxTopicBytes`, `unlimitedTopicSize`, and `background`. In background mode a send returns once its records are buffered, and `shutdown()` drains the buffer, closes, and reports a background send failure.
285
+ - `QueryRequest.atSnapshot(id)`, `atTimestampMicros(ts)`, and `rowsTyped(codec)`.
286
+ - `MemoryHandle.backend`, `AgentScope.contract(router)`, and `SwappableGovernor.current()`.
287
+ - Capability helpers `isOpenOnly`, `servesConsistency`, `isReady`, `readinessReasons`, `enabledBackends`, and `unreadyBackends`.
288
+ - `AgdxSend.claimCheck(store, thresholdBytes)` moves a body at or over the threshold to the blob store before signing.
289
+ - `ConversationId.asU128()` returns the raw 128-bit ULID value.
290
+ - `MemoryHandle.consolidate` and `ScopedMemory.consolidate` take `{ summarizer, pruneSummarized }` to fold `message` items into one summary per conversation and to forget the folded items.
291
+ - `filterCapsEvaluates(filters, evaluatorVersion, codec)` tells whether the server evaluates a filter exactly as this build does.
292
+ - `KeyRecord.keyId()` returns the 8-byte identifier of the record's public key.
293
+ - `MemoryHandler` wraps an agent handler, and `autoRemember(kind)` remembers each handled message under its conversation.
294
+ - `cardIsFresh`, `cardServes`, and `cardAvailableFor` check the freshness, the skills, and the advertised health of a registered card.
295
+ - `new ProjectionBuilder(id)`, `new ProjectionBindingBuilder()`, and `new IndexSchemaBuilder()` build projection declarations with the Rust defaults.
296
+ - `laser.fork(id)` returns a `ForkHandle` whose `id` names the fork.
283
297
 
284
- ## Publish recovery
298
+ ## 0.6.0 breaking changes
285
299
 
286
- Publish attempts default to 60 seconds with three retries. Retry delays start at 250 milliseconds, double after each failure, and stop increasing at 30 seconds. Configure these values through the client builder or connect arguments. The corresponding environment variables are `LASER_PUBLISH_TIMEOUT_MS`, `LASER_PUBLISH_MAX_RETRIES`, and `LASER_PUBLISH_RETRY_BACKOFF_MS`. Explicit configuration overrides these variables. Exhausted retries return an error for the application to handle.
300
+ 0.6.0 changes several TypeScript signatures. A publish that gives up throws `PublishFailedError` around the original error, `Consumer.nextWithin` throws `TimeoutError` instead of returning `null`, and `Kv.expire` takes a lifetime while `expireAt` takes an absolute time. `ConsolidationReport` reports `summarized`, `reweighted`, `pruned`, and `derived`, and `Consolidator.consolidate(scope, signal?)` no longer receives a memory argument. Fork row embeddings take numbers. The [client behavior guide](../../docs/client-behavior.md) lists every change with its replacement.
287
301
 
288
- See [publish recovery and outage handling](../../docs/publish-recovery.md).
302
+ ## Package exports
289
303
 
290
- ## Consumer filter groups and offsets
304
+ - `@laserdata/laser-sdk` is the ordinary application surface
305
+ - `@laserdata/laser-sdk/full` adds the native `wire` namespace
306
+ - `@laserdata/laser-sdk/testing` provides `TestClock`, `InMemoryStore`, and the `agentMessage` and `agentCtx` factories for handler tests
307
+ - `@laserdata/laser-sdk/opentelemetry` adapts the observer seam to OpenTelemetry
291
308
 
292
- **Provision a filtered group once, then consume by its ID.** The filter API supports create-and-bind setup, numeric group selection, and revision pause/resume. Use separate groups for A/B revisions so their offsets remain independent. A fresh named consumer using `Next` starts at the first retained record. Ordinary consumers auto-commit each polled batch before delivery by default, so a later consumer can resume after records the application did not process. Disable auto-commit and commit after successful processing when that matters. Filtered readers use explicit acknowledgments, and keep at most 1024 unacknowledged record-bearing pages per partition by default, set with `maxUnackedPages`, so a reader that never acknowledges stops at that bound instead of growing without limit. Unnamed TypeScript consumers have isolated identities and default to no automatic commit. Use a stable name to resume durable progress. See the [Consumer Filters guide](https://docs.laserdata.cloud/laser-sdk/consumer-filters).
309
+ `laser.client` (a property) is the Apache Iggy escape hatch for native administrative or transport operations that Laser does not wrap.
310
+
311
+ ## Examples and verification
293
312
 
294
- **Filter fields inside JSON, CBOR, Avro, and Protobuf payloads on the server.** Avro and Protobuf use registered writer schemas, immutable schema IDs in the filter, and the `agdx.sid` header on each record. **Headers-only filters work with any payload format.** Filtering preserves original bytes and offsets. See the [Consumer Filters guide](https://docs.laserdata.cloud/laser-sdk/consumer-filters) for codec profiles and examples.
313
+ The examples in [`examples/typescript`](../../examples/typescript/README.md) cover nine focused operations and nine larger applications. The shared scenarios under [`bdd/scenarios`](../../bdd/scenarios) describe behavior across clients.
295
314
 
296
- For an application checkpoint inside a filtered page, call `reader.ackThrough(record)` after persisting the checkpoint and processing all preceding records on that partition. Later records in the same page stay pending. Use `ackPage` when the whole page is complete. Regex predicates reject an enabled TypeScript local guard instead of silently skipping verification.
315
+ ```sh
316
+ npm ci
317
+ npm run verify
318
+ ```
297
319
 
298
- Consumer-filter patterns use the server's bounded Rust regex engine. TypeScript validates structure and lets the server decide regex syntax. A local `CompiledFilter` refuses regex predicates, because only the server's engine defines their meaning. A filter permits four compiled glob or regex predicates, with a 256 KiB program budget each. Local guards reject regex filters explicitly. Guards verify unevaluated records under the server's reported decoder bounds and the applicable pass policy.
320
+ `verify` runs formatting, lint, dependency-boundary, type, build, API, unit, wire, coverage, license, and package tests. Integration and shared BDD tests run separately against the versioned native Iggy server.
321
+
322
+ ## Security and license
323
+
324
+ Report security issues through the repository security policy. The package is Apache-2.0 licensed. Apache and Apache Iggy are trademarks of the Apache Software Foundation.
@@ -1,6 +1,7 @@
1
+ import { type BlobStore } from "../blob.js";
1
2
  import { type BytesLike } from "../client/bytes.js";
2
3
  import type { LaserTransport } from "../iggy/apache-iggy.js";
3
- import { type UlidSource } from "../runtime/ulid.js";
4
+ import type { UlidSource } from "../runtime/ulid.js";
4
5
  import { type KeyRegistry, type SigningKey } from "../signing.js";
5
6
  import { type AgentId as SdkAgentId, type ConversationId as SdkConversationId } from "../types/ids.js";
6
7
  import { type AgentEnvelope, type AgentErrorBody, type IdempotencyKey, type TaskState, type TokenUsage } from "../wire/agent.js";
@@ -10,9 +11,7 @@ import type { Value } from "../wire/value.js";
10
11
  export declare const DEFAULT_CHUNK_FLUSH_BYTES = 512;
11
12
  export declare const DEFAULT_CHUNK_LINGER_MS = 20;
12
13
  export declare const MAX_CHUNK_BODY_BYTES: number;
13
- export type AgdxLogPosition = LogPosition;
14
14
  export interface Agdx {
15
- readonly topicName: string;
16
15
  command(correlation: CorrelationId, body: BytesLike): AgdxSend;
17
16
  respond(correlation: CorrelationId, body: BytesLike): AgdxSend;
18
17
  emit(body: BytesLike): AgdxSend;
@@ -39,6 +38,12 @@ export interface AgdxSend {
39
38
  contentType(contentType: ContentType): this;
40
39
  body(body: BytesLike): this;
41
40
  signedBy(key: SigningKey): this;
41
+ /**
42
+ * Externalizes a body at or over `thresholdBytes` to `store` at send and
43
+ * replaces it with the body reference capsule (content type `ref`). Applied
44
+ * before signing, so a signature covers the capsule the log carries.
45
+ */
46
+ claimCheck(store: BlobStore, thresholdBytes: number): this;
42
47
  send(): Promise<RecordId | undefined>;
43
48
  }
44
49
  export interface AgdxStream {
@@ -1 +1 @@
1
- {"version":3,"file":"agdx.d.ts","sourceRoot":"","sources":["../../src/agent/agdx.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agdx.d.ts","sourceRoot":"","sources":["../../src/agent/agdx.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
+ import { checkIn } from "../blob.js";
1
2
  import { ownedBytes } from "../client/bytes.js";
2
3
  import { CancelledError, InvalidError, RejectedError, TimeoutError } from "../client/errors.js";
3
- import { mintUlidValue } from "../runtime/ulid.js";
4
4
  import {} from "../signing.js";
5
5
  import { decodeAgentMessage } from "./reliable-consumer.js";
6
- import {} from "../types/ids.js";
7
- import { AgentKind, chunkEnvelope, commandEnvelope, decodeAgentErrorBody, encodeAgentErrorBody, errorEnvelope, eventEnvelope, responseEnvelope, parseAgentId, statusEnvelope, validateAgentEnvelope, withCause, withCorrelation, withDeadlineMicros, withIdempotencyKey, withMetadata, withOperation, withTarget, withTaskState, withTool, withUsage } from "../wire/agent.js";
6
+ import { MintUlid } from "../types/ids.js";
7
+ import { AgentKind, chunkEnvelope, commandEnvelope, decodeAgentErrorBody, encodeAgentErrorBody, errorEnvelope, eventEnvelope, responseEnvelope, statusEnvelope, validateAgentEnvelope, withCause, withCorrelation, withDeadlineMicros, withIdempotencyKey, withMetadata, withOperation, withTarget, withTaskState, withTool, withUsage } from "../wire/agent.js";
8
8
  import { canonicalAgentRecord } from "../wire/agent-record.js";
9
9
  import { decodeOne, encodeNamed, expectMap } from "../wire/cbor.js";
10
10
  import { AGENT_OP_VERSION } from "../wire/codes.js";
@@ -33,9 +33,6 @@ function delay(ms, signal) {
33
33
  signal?.addEventListener("abort", onAbort, { once: true });
34
34
  });
35
35
  }
36
- function wireAgentId(agent) {
37
- return parseAgentId(agent.asString());
38
- }
39
36
  function u32FromLittleEndian(header) {
40
37
  if (header.bytes.byteLength !== 4)
41
38
  throw new InvalidError("AGDX u32 header must be 4 bytes");
@@ -70,13 +67,13 @@ function assemble(envelope, contentType) {
70
67
  };
71
68
  }
72
69
  function mintRecordId(source) {
73
- return RecordId.fromU128(mintUlidValue(source));
70
+ return MintUlid.mint(RecordId, source);
74
71
  }
75
72
  function mintCorrelationId(source) {
76
- return CorrelationId.fromU128(mintUlidValue(source));
73
+ return MintUlid.mint(CorrelationId, source);
77
74
  }
78
75
  function mintChannelId(source) {
79
- return ChannelId.fromU128(mintUlidValue(source));
76
+ return MintUlid.mint(ChannelId, source);
80
77
  }
81
78
  class AgdxReplyReader {
82
79
  transport;
@@ -224,19 +221,31 @@ class AgdxClient {
224
221
  await this.transport.sendMessagesWithHeaders(this.streamName, this.topicName, [message], this.conversationId.toString());
225
222
  return envelope.record;
226
223
  }
227
- async prepare(envelope, contentType, signingKey) {
224
+ async prepare(envelope, contentType, signingKey, claimCheck) {
228
225
  const body = this.govern === undefined
229
226
  ? envelope.body
230
227
  : await this.govern(envelope, signingKey !== undefined);
231
- const governed = body === envelope.body ? envelope : { ...envelope, body };
228
+ let prepared = body === envelope.body ? envelope : { ...envelope, body };
229
+ let preparedType = contentType;
230
+ // Claim-check runs after governance and before signing, so the signature
231
+ // covers the capsule the log carries.
232
+ if (claimCheck !== undefined) {
233
+ const checked = await checkIn(claimCheck.store, claimCheck.thresholdBytes, prepared.body);
234
+ prepared = { ...prepared, body: checked.payload };
235
+ if (checked.contentType !== undefined)
236
+ preparedType = checked.contentType;
237
+ }
232
238
  if (signingKey === undefined)
233
- return governed;
239
+ return { envelope: prepared, contentType: preparedType };
234
240
  return {
235
- ...governed,
236
- signature: signingKey.signWithContext(governed, {
237
- contentType: contentTypeCode(contentType),
238
- agentVersion: AGENT_OP_VERSION
239
- })
241
+ envelope: {
242
+ ...prepared,
243
+ signature: signingKey.signWithContext(prepared, {
244
+ contentType: contentTypeCode(preparedType),
245
+ agentVersion: AGENT_OP_VERSION
246
+ })
247
+ },
248
+ contentType: preparedType
240
249
  };
241
250
  }
242
251
  assemble(envelope, contentType) {
@@ -250,7 +259,7 @@ class AgdxClient {
250
259
  }
251
260
  }
252
261
  export function createAgdx(transport, streamName, topicName, source, conversation, ulidSource, govern, verifier) {
253
- return new AgdxClient(transport, streamName, topicName, parseAgentId(source.asString()), ConversationId.parse(conversation.toString()), ulidSource, govern, verifier);
262
+ return new AgdxClient(transport, streamName, topicName, source.wireId(), ConversationId.parse(conversation.toString()), ulidSource, govern, verifier);
254
263
  }
255
264
  class AgdxSendBuilder {
256
265
  agdx;
@@ -258,12 +267,13 @@ class AgdxSendBuilder {
258
267
  contentTypeValue = ContentType.Raw;
259
268
  sent = false;
260
269
  signingKey;
270
+ claimCheckValue;
261
271
  constructor(agdx, envelope) {
262
272
  this.agdx = agdx;
263
273
  this.envelope = envelope;
264
274
  }
265
275
  withTarget(target) {
266
- this.envelope = withTarget(this.envelope, wireAgentId(target));
276
+ this.envelope = withTarget(this.envelope, target.wireId());
267
277
  return this;
268
278
  }
269
279
  withCause(cause, causeAt) {
@@ -318,12 +328,19 @@ class AgdxSendBuilder {
318
328
  this.signingKey = key;
319
329
  return this;
320
330
  }
331
+ claimCheck(store, thresholdBytes) {
332
+ if (!Number.isSafeInteger(thresholdBytes) || thresholdBytes < 0) {
333
+ throw new InvalidError("claim-check threshold must be a non-negative safe integer");
334
+ }
335
+ this.claimCheckValue = { store, thresholdBytes };
336
+ return this;
337
+ }
321
338
  async send() {
322
339
  if (this.sent)
323
340
  throw new InvalidError("an AGDX send can only be performed once");
324
341
  this.sent = true;
325
- const envelope = await this.agdx.prepare(this.envelope, this.contentTypeValue, this.signingKey);
326
- return this.agdx.publish(envelope, this.contentTypeValue);
342
+ const prepared = await this.agdx.prepare(this.envelope, this.contentTypeValue, this.signingKey, this.claimCheckValue);
343
+ return this.agdx.publish(prepared.envelope, prepared.contentType);
327
344
  }
328
345
  }
329
346
  class AgdxStreamWriter {
@@ -354,7 +371,7 @@ class AgdxStreamWriter {
354
371
  return this;
355
372
  }
356
373
  withTarget(target) {
357
- this.target = wireAgentId(target);
374
+ this.target = target.wireId();
358
375
  return this;
359
376
  }
360
377
  contentType(contentType) {