mq-bridge-py-basic 0.3.10__tar.gz → 0.4.0__tar.gz

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 (293) hide show
  1. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/dependabot.yml +10 -1
  2. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/node.yml +6 -0
  3. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/test-matrix.yml +2 -2
  4. mq_bridge_py_basic-0.4.0/CHANGELOG.md +182 -0
  5. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/CLAUDE.md +3 -2
  6. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/Cargo.lock +130 -76
  7. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/Cargo.toml +21 -7
  8. mq_bridge_py_basic-0.3.10/python/mq-bridge-py/README.md → mq_bridge_py_basic-0.4.0/PKG-INFO +67 -0
  9. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/README.md +60 -198
  10. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/benches/performance_bench.rs +145 -72
  11. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0/docs}/ARCHITECTURE.md +15 -2
  12. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0/docs}/CONFIGURATION.md +38 -2
  13. mq_bridge_py_basic-0.4.0/docs/DELIVERY.md +454 -0
  14. mq_bridge_py_basic-0.4.0/docs/EXTENDING.md +457 -0
  15. mq_bridge_py_basic-0.4.0/docs/PLUGINS.md +309 -0
  16. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0/docs}/REFERENCE.md +58 -9
  17. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/mq-bridge.schema.json +99 -26
  18. mq_bridge_py_basic-0.4.0/mq_bridge/__init__.py +88 -0
  19. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/mq_bridge/__init__.pyi +59 -0
  20. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/mq_bridge/config.pyi +10 -2
  21. mq_bridge_py_basic-0.4.0/mq_bridge/plugin_packaging.py +90 -0
  22. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/pyproject.toml +3 -0
  23. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/Cargo.toml +4 -2
  24. mq_bridge_py_basic-0.3.10/PKG-INFO → mq_bridge_py_basic-0.4.0/python/mq-bridge-py/README.md +40 -24
  25. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/pyproject-basic.toml +3 -0
  26. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/src/lib.rs +795 -3
  27. mq_bridge_py_basic-0.4.0/python/mq-bridge-py/tests/test_custom_endpoint.py +444 -0
  28. mq_bridge_py_basic-0.4.0/python/mq-bridge-py/tests/test_plugin_package.py +32 -0
  29. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/tests/test_public_api.py +4 -0
  30. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/uv.lock +126 -1
  31. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/canonical_message.rs +8 -0
  32. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/grpc.proto +3 -0
  33. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/grpc.rs +1085 -110
  34. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/mod.rs +34 -23
  35. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/mongodb/consumer.rs +0 -352
  36. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/mongodb/mod.rs +29 -9
  37. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/mongodb/publisher.rs +52 -18
  38. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/mongodb/readers.rs +51 -19
  39. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/mongodb/tests.rs +30 -9
  40. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/object_store.rs +41 -7
  41. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/mod.rs +1 -1
  42. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/zeromq/mod.rs +42 -13
  43. mq_bridge_py_basic-0.4.0/src/endpoints/zeromq/omq.rs +712 -0
  44. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/zeromq/zmq.rs +18 -2
  45. mq_bridge_py_basic-0.4.0/src/extensions.rs +162 -0
  46. mq_bridge_py_basic-0.4.0/src/lib.rs +187 -0
  47. mq_bridge_py_basic-0.4.0/src/middleware/id.rs +320 -0
  48. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/mod.rs +11 -1
  49. mq_bridge_py_basic-0.4.0/src/models/builders.rs +958 -0
  50. mq_bridge_py_basic-0.4.0/src/models/defaults.rs +247 -0
  51. mq_bridge_py_basic-0.4.0/src/models/secrets.rs +500 -0
  52. mq_bridge_py_basic-0.4.0/src/models/serde_support.rs +661 -0
  53. mq_bridge_py_basic-0.4.0/src/models/tests.rs +681 -0
  54. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/models.rs +93 -2644
  55. mq_bridge_py_basic-0.4.0/src/plugin/conformance.rs +323 -0
  56. mq_bridge_py_basic-0.4.0/src/plugin/endpoint.rs +548 -0
  57. mq_bridge_py_basic-0.4.0/src/plugin/message.rs +147 -0
  58. mq_bridge_py_basic-0.4.0/src/plugin/middleware.rs +365 -0
  59. mq_bridge_py_basic-0.4.0/src/plugin/mod.rs +349 -0
  60. mq_bridge_py_basic-0.4.0/src/plugin/sdk.rs +1156 -0
  61. mq_bridge_py_basic-0.4.0/src/plugin/test_support.rs +131 -0
  62. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/route.rs +165 -29
  63. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/support/interpolation.rs +74 -15
  64. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/support/mod.rs +4 -1
  65. mq_bridge_py_basic-0.4.0/src/support/plugin_abi.rs +705 -0
  66. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/test_utils.rs +48 -0
  67. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/traits.rs +92 -17
  68. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/mongodb.rs +184 -29
  69. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/route.rs +5 -4
  70. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration_test.rs +20 -7
  71. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/ref_test.rs +4 -2
  72. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/reference_docs_test.rs +25 -15
  73. mq_bridge_py_basic-0.3.10/CHANGELOG.md +0 -76
  74. mq_bridge_py_basic-0.3.10/mq_bridge/__init__.py +0 -25
  75. mq_bridge_py_basic-0.3.10/src/endpoints/zeromq/omq.rs +0 -373
  76. mq_bridge_py_basic-0.3.10/src/extensions.rs +0 -37
  77. mq_bridge_py_basic-0.3.10/src/lib.rs +0 -85
  78. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  79. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  80. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  81. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/benchmark.yml +0 -0
  82. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/ci.yml +0 -0
  83. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/ibm-mq.yml +0 -0
  84. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/publish-node.yml +0 -0
  85. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/publish-python.yml +0 -0
  86. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/python.yml +0 -0
  87. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.github/workflows/release.yml +0 -0
  88. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/.gitignore +0 -0
  89. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/CONTRIBUTING.md +0 -0
  90. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/LICENSE +0 -0
  91. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/LICENSE.python +0 -0
  92. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/SECURITY.md +0 -0
  93. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/benches/ETL_BENCHMARKS.md +0 -0
  94. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/benches/router_bench.rs +0 -0
  95. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/benches/zeromq_backends.rs +0 -0
  96. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/bindings-common/Cargo.toml +0 -0
  97. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/bindings-common/src/lib.rs +0 -0
  98. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/bindings-common/src/logging.rs +0 -0
  99. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/build.rs +0 -0
  100. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/deny.toml +0 -0
  101. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/examples/ipc_worker_queue.yaml +0 -0
  102. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/mq_bridge/config.py +0 -0
  103. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/mq_bridge/py.typed +0 -0
  104. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/package-lock.json +0 -0
  105. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/LICENSE.python +0 -0
  106. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
  107. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/example.py +0 -0
  108. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/examples/bench_memory.py +0 -0
  109. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
  110. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/examples/consume_pull.py +0 -0
  111. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/examples/dlt_source.py +0 -0
  112. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/examples/json_route.py +0 -0
  113. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/examples/memory.yaml +0 -0
  114. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/examples/raw_route.py +0 -0
  115. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/pyproject-reduced.toml +0 -0
  116. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/scripts/gen_config_types.py +0 -0
  117. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/tests/test_config_types.py +0 -0
  118. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/tests/test_logging.py +0 -0
  119. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/tests/test_packaging.py +0 -0
  120. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
  121. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/python/mq-bridge-py/tests/test_routes.py +0 -0
  122. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/analysis/benches/metadata_bench.rs +0 -0
  123. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
  124. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
  125. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/analysis/http/http_flamegraph.py +0 -0
  126. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
  127. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/analysis/http/run_http_ladder.sh +0 -0
  128. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/ci/format_bench_output.sh +0 -0
  129. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/httparena/README.md +0 -0
  130. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
  131. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
  132. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/httparena/frameworks/mq-bridge-py/server.py +0 -0
  133. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
  134. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
  135. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
  136. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
  137. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/techempower/README.md +0 -0
  138. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/techempower/postgres.yml +0 -0
  139. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/techempower/seed.sql +0 -0
  140. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/techempower/verify.sh +0 -0
  141. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/the-benchmarker/README.md +0 -0
  142. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
  143. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
  144. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
  145. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/checkpoint.rs +0 -0
  146. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/command_handler.rs +0 -0
  147. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/amqp.rs +0 -0
  148. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/aws.rs +0 -0
  149. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/clickhouse.rs +0 -0
  150. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/file/mod.rs +0 -0
  151. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/file/tests.rs +0 -0
  152. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/http/mod.rs +0 -0
  153. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/http/publisher.rs +0 -0
  154. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/http/stream.rs +0 -0
  155. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/http/tests.rs +0 -0
  156. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/ibm_mq.rs +0 -0
  157. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/kafka.rs +0 -0
  158. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/memory/endpoint.rs +0 -0
  159. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/memory/framed.rs +0 -0
  160. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/memory/ipc_unix.rs +0 -0
  161. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/memory/ipc_windows.rs +0 -0
  162. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/memory/memory_transport.rs +0 -0
  163. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/memory/mod.rs +0 -0
  164. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/memory/transport.rs +0 -0
  165. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/mongodb/dedup.rs +0 -0
  166. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/mqtt.rs +0 -0
  167. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/nats.rs +0 -0
  168. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/poll.rs +0 -0
  169. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/VENDORED.md +0 -0
  170. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/mod.rs +0 -0
  171. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
  172. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
  173. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
  174. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
  175. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/pgoutput/values.rs +0 -0
  176. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/replication.rs +0 -0
  177. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/postgres/state.rs +0 -0
  178. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/redis_streams.rs +0 -0
  179. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/sled.rs +0 -0
  180. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/sqlx/dedup.rs +0 -0
  181. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/sqlx/mod.rs +0 -0
  182. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/sqlx/tests.rs +0 -0
  183. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/fanout.rs +0 -0
  184. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/null.rs +0 -0
  185. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/reader.rs +0 -0
  186. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/request.rs +0 -0
  187. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/response.rs +0 -0
  188. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/static_endpoint.rs +0 -0
  189. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/stream_buffer.rs +0 -0
  190. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/structural/switch.rs +0 -0
  191. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/websocket.rs +0 -0
  192. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/endpoints/zeromq/codec.rs +0 -0
  193. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/errors.rs +0 -0
  194. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/event_handler.rs +0 -0
  195. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/event_store.rs +0 -0
  196. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/buffer.rs +0 -0
  197. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/compression.rs +0 -0
  198. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/cookie_jar.rs +0 -0
  199. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/deduplication.rs +0 -0
  200. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/delay.rs +0 -0
  201. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/dlq.rs +0 -0
  202. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/encryption.rs +0 -0
  203. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/limiter.rs +0 -0
  204. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/metrics.rs +0 -0
  205. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/random_panic.rs +0 -0
  206. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/retry.rs +0 -0
  207. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/transform/coerce.rs +0 -0
  208. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/transform/compiled.rs +0 -0
  209. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/transform/error.rs +0 -0
  210. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/transform/mod.rs +0 -0
  211. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/transform/path.rs +0 -0
  212. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/transform/schema.rs +0 -0
  213. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/transform/tests.rs +0 -0
  214. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/middleware/weak_join.rs +0 -0
  215. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/outcomes.rs +0 -0
  216. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/publisher.rs +0 -0
  217. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/response.rs +0 -0
  218. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/support/base64_engine.rs +0 -0
  219. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/support/compression.rs +0 -0
  220. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/support/connection_registry.rs +0 -0
  221. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/support/crypto.rs +0 -0
  222. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/support/crypto_envelope.rs +0 -0
  223. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/support/source_ranges.rs +0 -0
  224. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/src/type_handler.rs +0 -0
  225. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/README.md +0 -0
  226. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/armature_integration.rs +0 -0
  227. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/amqp.rs +0 -0
  228. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/aws.rs +0 -0
  229. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/clickhouse.rs +0 -0
  230. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/config.toml +0 -0
  231. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/amqp.yml +0 -0
  232. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/aws.yml +0 -0
  233. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/clickhouse.yml +0 -0
  234. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
  235. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
  236. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
  237. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
  238. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
  239. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/ibm_mq.yml +0 -0
  240. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
  241. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/kafka-tls.yml +0 -0
  242. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/kafka.yml +0 -0
  243. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mariadb.yml +0 -0
  244. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
  245. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
  246. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mongodb.yml +0 -0
  247. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mosquitto.conf +0 -0
  248. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
  249. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
  250. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mq_init.mqsc +0 -0
  251. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
  252. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mqtt.yml +0 -0
  253. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
  254. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/mysql.yml +0 -0
  255. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/nats.yml +0 -0
  256. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/object_store.yml +0 -0
  257. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/postgres.yml +0 -0
  258. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
  259. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/docker-compose/redis.yml +0 -0
  260. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/file.rs +0 -0
  261. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/grpc.rs +0 -0
  262. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/grpc_tls.rs +0 -0
  263. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/http.rs +0 -0
  264. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/http_tls.rs +0 -0
  265. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/ibm_mq.rs +0 -0
  266. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/ibm_mq_tls.rs +0 -0
  267. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/ipc.rs +0 -0
  268. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/kafka.rs +0 -0
  269. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/kafka_tls.rs +0 -0
  270. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/logic_test.rs +0 -0
  271. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/mariadb.rs +0 -0
  272. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/memory.rs +0 -0
  273. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/mod.rs +0 -0
  274. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/mongodb_raw.rs +0 -0
  275. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/mongodb_tls.rs +0 -0
  276. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/mqtt.rs +0 -0
  277. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/mysql.rs +0 -0
  278. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/nats.rs +0 -0
  279. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/object_store.rs +0 -0
  280. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/performance_static.rs +0 -0
  281. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/postgres.rs +0 -0
  282. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/postgres_cdc.rs +0 -0
  283. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/redis_streams.rs +0 -0
  284. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/scripts/gen_certs.sh +0 -0
  285. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/sqlite.rs +0 -0
  286. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/tls_helpers.rs +0 -0
  287. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/websocket.rs +0 -0
  288. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/integration/zeromq.rs +0 -0
  289. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/memory_leak_test.rs +0 -0
  290. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/sqlite_test.rs +0 -0
  291. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/tls_example.rs +0 -0
  292. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/unit_tests.md +0 -0
  293. {mq_bridge_py_basic-0.3.10 → mq_bridge_py_basic-0.4.0}/tests/websocket_test.rs +0 -0
@@ -7,5 +7,14 @@ version: 2
7
7
  updates:
8
8
  - package-ecosystem: "cargo" # See documentation for possible values
9
9
  directory: "/" # Location of package manifests
10
+ target-branch: "dev"
10
11
  schedule:
11
- interval: "weekly"
12
+ interval: "monthly"
13
+ groups:
14
+ minor-and-patch:
15
+ applies-to: version-updates
16
+ patterns:
17
+ - "*"
18
+ update-types:
19
+ - "minor"
20
+ - "patch"
@@ -48,6 +48,9 @@ jobs:
48
48
  test:
49
49
  name: Node binding smoke test
50
50
  runs-on: ubuntu-latest
51
+ # Backstop only; the tests carry their own tighter cap. Keep this above a
52
+ # cold-cache `cargo check` + `napi build`, which the step timeouts don't cover.
53
+ timeout-minutes: 30
51
54
  steps:
52
55
  - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
53
56
  with:
@@ -86,6 +89,9 @@ jobs:
86
89
  working-directory: node/mq-bridge-node
87
90
  run: npm run build:ci
88
91
 
92
+ # A leaked ThreadsafeFunction keeps the event loop alive and the suite
93
+ # never exits; cap it here rather than burning the whole job budget.
89
94
  - name: Run Node tests
90
95
  working-directory: node/mq-bridge-node
96
+ timeout-minutes: 5
91
97
  run: npm test
@@ -2,9 +2,9 @@ name: Test Matrix
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [main, develop]
5
+ branches: [main, dev]
6
6
  pull_request:
7
- branches: [main, develop]
7
+ branches: [main, dev]
8
8
 
9
9
  env:
10
10
  CARGO_TERM_COLOR: always
@@ -0,0 +1,182 @@
1
+ # Changelog
2
+
3
+ All notable changes to `mq-bridge`. Newest first.
4
+
5
+ ## 0.4.0
6
+
7
+ ### Breaking
8
+
9
+ - **Changed defaults.** Four defaults were chosen for safety or speed rather than history.
10
+ Set the field explicitly to keep the old behaviour:
11
+ - `batch_size` is **512** instead of 1. Batches fill opportunistically — the consumer waits
12
+ for one message and takes whatever else is already there — so this raises throughput
13
+ without adding idle latency. It does widen the blast radius of a failed batch, and
14
+ nothing caps a batch by bytes, so lower it on routes carrying large payloads.
15
+ - MongoDB `consume` defaults to **`capture_all`** instead of `consumer`. The old default
16
+ claimed, re-fetched and **deleted** each document, so pointing a route at a collection to
17
+ read it destroyed it — and it only ever worked on collections written by the mq-bridge
18
+ MongoDB publisher. `capture_all` is non-destructive, reads arbitrary collections, and is
19
+ ~5x faster. On a replica set it snapshots, then follows the change stream; a one-shot
20
+ `exit_on_empty` / `--drain` job finishes once that stream goes quiet.
21
+ **`capture_all` and `capture_new` now require a replica set** (a single-node one is enough)
22
+ and refuse to start without one. `capture_all` used to fall back to paging `_id` forward on
23
+ a standalone `mongod`; that reader only ever matches ids above its high-water mark, so any
24
+ document a concurrent writer commits below it was dropped — silently, with no error and no
25
+ gap in the delivery count. On a standalone server use the new `consume: snapshot`, or
26
+ `consume: consumer` for a work queue.
27
+ - MongoDB `consume: subscriber` and the `MongoDbSubscriber` type are **removed**. It polled
28
+ `seq > last_seq` and advanced the watermark to the highest seq it saw, so a batch whose seq
29
+ block was reserved first but committed second was skipped for good — the same silent loss as
30
+ above, and present on a replica set too. Once a replica set is required it is also redundant:
31
+ `consume: capture_new` without a `cursor_id` is ephemeral fan-out from now on, and reads
32
+ arbitrary collections rather than only the bridge's own wrapped documents. The deprecated
33
+ `change_stream: true` boolean now resolves to `capture_new` instead of `subscriber`.
34
+ - ZeroMQ `format` defaults to **`raw_framed`** instead of `json`: binary-safe payloads with
35
+ a JSON metadata frame in front, so headers still travel. This is a wire-format change —
36
+ a 0.4 peer and a 0.3 peer no longer interoperate on the same socket unless one sets
37
+ `format: json`.
38
+ - ZeroMQ `backend` defaults to **`try_omq`**, which uses the faster omq backend when the
39
+ `zeromq-omq` feature is compiled in and falls back to `zmq` otherwise. Naming `omq` or
40
+ `zmq` explicitly still makes that backend a hard requirement.
41
+ - `extensions::register_endpoint_factory` and `register_middleware_factory` return
42
+ `anyhow::Result<()>` instead of `()`, and registering a name that is already taken is now an
43
+ error instead of silently replacing the previous factory. A duplicate name meant one of the
44
+ two registrations was quietly ignored, which is impossible to diagnose from a route that then
45
+ behaves like the wrong endpoint. Existing callers add `?` or `.unwrap()`; anything that relied
46
+ on re-registering the same name must pick distinct names.
47
+
48
+ ### Added
49
+
50
+ - MongoDB `consume: snapshot` — a one-shot, non-destructive read that pages the collection by
51
+ `_id` and ends the route on drain. It needs no replica set, reads arbitrary collections, and is
52
+ the supported way to read a standalone `mongod` without deleting anything. Its contract is
53
+ deliberately narrow: it delivers what exists when the run starts, and it is **not** a tail.
54
+ `cursor_id` is rejected at startup — resuming above a stored `_id` would skip whatever a
55
+ concurrent writer commits below that mark, and `_id` is assigned client-side before the insert,
56
+ so it does not follow commit order. Incremental reads need commit order, i.e. the oplog, i.e. a
57
+ replica set.
58
+ - gRPC consumers can call arbitrary unary and server-streaming services without generated
59
+ Rust clients. Point an endpoint at a compiled protobuf `FileDescriptorSet`, name the
60
+ service and method, and provide the request as JSON; responses are decoded dynamically
61
+ with `prost-reflect` and emitted using protobuf's canonical JSON representation. The
62
+ existing generated `mqbridge.Bridge` protocol remains the default.
63
+ - The omq ZeroMQ backend covers **REQ/REP** as well as PUSH/PULL and PUB/SUB, so the whole
64
+ `zeromq` endpoint surface — including request-reply — works on either backend. REQ exchanges
65
+ are serialised and bounded by `request_timeout_ms`, and a timed-out socket is rebuilt rather
66
+ than reused, because ZMTP requires strict send/recv alternation.
67
+ - Custom endpoints and middleware can be written in Python and Node.js, not just Rust —
68
+ `register_endpoint` / `register_middleware` in both bindings, with the same batch, ack and
69
+ request-reply semantics as a Rust `CustomEndpointFactory`. See [EXTENDING.md](docs/EXTENDING.md).
70
+ - Native endpoint plugins. An endpoint can live in its own crate and package and be loaded
71
+ into any mq-bridge process at runtime — `mq_bridge::plugin::load_endpoint_plugin(path)` in
72
+ Rust, `mq_bridge.load_endpoint_plugin(path)` in Python, `loadEndpointPlugin(path)` in
73
+ Node.js — so a broker's dependencies stay out of curated mq-bridge builds while every
74
+ language runs the same implementation and delivery semantics. The `plugin` feature (part of
75
+ `full` and `portable`) provides the loader; `plugin-sdk` provides the authoring side:
76
+ `export_endpoint_plugin!`, which exports an ordinary `CustomEndpointFactory` through the
77
+ stable C ABI with no handwritten `unsafe`, and a conformance suite to run against the
78
+ endpoint both linked directly and loaded as a plugin. A plugin can provide a
79
+ middleware too (`export_middleware_plugin!`, or `middleware:` alongside an
80
+ endpoint): it returns one entry per message — `None` drops it — while the
81
+ wrapper around the endpoint stays on the host side, so nothing calls back
82
+ across the boundary. See [PLUGINS.md](docs/PLUGINS.md).
83
+
84
+ ### Fixed
85
+
86
+ - The built-in `mqbridge.Bridge` gRPC transport now commits messages with real ACK/NACK
87
+ RPCs instead of a no-op. Embedded publishers wait for downstream processing to commit
88
+ before receiving an ACK, and unacknowledged subscription messages are retained in memory
89
+ and redelivered to the same `consumer_id`. This provides at-least-once delivery while the
90
+ server process is running; durable restart recovery and exactly-once processing still
91
+ require persistent state or downstream deduplication by message ID. Arbitrary dynamic
92
+ services retain the delivery semantics of their own API because protobuf descriptors do
93
+ not define a generic acknowledgement operation.
94
+ Retention is capped (1024 messages per subscriber, 64 subscribers per route, oldest
95
+ evicted first) so a consumer that never acknowledges cannot grow the server without bound.
96
+ `consumer_id` defaults to a fresh id per consumer rather than to the topic, so competing
97
+ consumers on one topic no longer share a retention set; set it explicitly to be
98
+ redelivered unacknowledged messages after a reconnect.
99
+ - A **non-retryable handler failure no longer discards the rest of its batch**. The default
100
+ `Handler::handle_many` aborted the remaining messages after any failure; for retryable and
101
+ connection errors that is right (the batch is nacked and redelivered together), but a
102
+ non-retryable message is dropped and never redelivered, so every healthy message behind it
103
+ was silently lost. How many depended purely on `batch_size` — at the old default of 1 the
104
+ collateral was zero, which is why this went unnoticed. The behaviour now matches what
105
+ `CommandPublisher::send_batch` already documented and tested.
106
+ - ZeroMQ REQ/REP with `format: raw` or `raw_framed` decoded the reply using that format, but the
107
+ REP side always answers with a JSON array of canonical messages, so the caller got one message
108
+ whose payload was the JSON text instead of the decoded replies. Both backends now decode replies
109
+ as JSON. This was invisible while `json` was the default format.
110
+
111
+ ## 0.3.10
112
+
113
+
114
+ ### Changed
115
+
116
+ - DLQ and output middleware now run around the publish step, not inside the handler, so a
117
+ handler failure is no longer retried by the output chain. The tradeoff: a handler failure
118
+ now skips the output middleware entirely, so `dlq` on the output endpoint cannot capture
119
+ it — only publish failures reach the DLQ. Put a `dlq` on the input endpoint to catch
120
+ handler failures.
121
+ - Errors carry their full cause chain instead of only the outermost context.
122
+ - `deduplication` on an **output** endpoint is now a startup error instead of a warning and a
123
+ silent no-op. Move it to the route's input endpoint.
124
+ - `limiter` paces a single `send_batch` by its own message count, so one large batch is no
125
+ longer a free burst. Sustained throughput is unchanged.
126
+ - A `message_id` that is neither a UUID nor a `u128` is hashed to a stable id rather than
127
+ making the whole JSON envelope unparseable.
128
+
129
+ ### Performance
130
+
131
+ - **Kafka consumer**: a long-lived prefetch task reads librdkafka continuously into a bounded
132
+ channel, instead of rebuilding the stream inside every `receive_batch`. librdkafka only keeps
133
+ requesting records while its queue is drained, so every pause the pipeline took — a transform,
134
+ a slow sink — was also a pause in fetching, and the fetch rate collapsed to well under what the
135
+ broker could serve. Batch offsets are also recorded once per partition rather than once per
136
+ message, which was O(n²) in the batch and allocated two `CString`s per record.
137
+ Kafka → transform → file: **192,854 → 824,983 rows/s** on the 1M-row, four-partition
138
+ benchmark, from 0.35x to 1.51x Arroyo on identical output. A 16,384-message passthrough
139
+ batch went from 11.5s to 2.2s, and from 10.4s to 0.9s of CPU.
140
+ - **Postgres / sqlx**: `test_before_acquire(false)` on the pool, zero-copy row encoding via
141
+ a prebuilt `JsonRowSchema`, and prebuilt first/next page queries on the cursor path.
142
+ - **Command handler**: `send_batch` no longer loops per-message `send()` (≈8x on batched routes).
143
+ - **File**: single-pass byte-array decode, faster CSV writes, compression sniffing.
144
+ - **Deduplication**: the two-phase reserve/commit no longer writes to the store twice per
145
+ message. Reservations are held in memory — sled takes an exclusive file lock on its directory,
146
+ so a claim only ever has to be visible to this process — leaving one write per message, on
147
+ commit.
148
+
149
+ ### Fixed
150
+
151
+ - `insert_query` batch inserts dropped anything but a bare token from the `VALUES` tuple, so
152
+ `decode(${payload:x}, 'base64')` and casts were silently discarded — a binary (`bytea`)
153
+ column could not be written. The batch path now keeps the user's SQL and falls back to
154
+ iterative inserts when the tuple contains an expression.
155
+ - A payload string containing an embedded NUL byte was dropped by the driver and stored as
156
+ SQL `NULL` while the route reported success. It is now rejected as non-retryable.
157
+ - Database errors were rendered twice, because `sqlx` errors already display their own
158
+ source. Cause chains now skip a link an earlier one already contains.
159
+ - `cookie_jar`'s `inject_metadata` resolved only a bare stored name, so the namespaced
160
+ `cookie.<name>` / `value.<name>` spelling that `export_metadata_prefix` reports back
161
+ injected nothing. Both spellings now work.
162
+ - MQTT publishes are confirmed by PUBACK/PUBCOMP and guarded against session resets, which
163
+ took chaos-test message loss to zero.
164
+ - Postgres CDC advances its replication slot durably on shutdown instead of leaving the
165
+ feedback unflushed.
166
+ - `deduplication` could silently drop a message after a crash. The reservation was written to
167
+ the store *before* the message was processed, so a redelivery arriving within the 5s pending
168
+ TTL was classified as a duplicate and acked — without ever having been written to the sink.
169
+ Reservations are now in-memory and die with the process, so the redelivery is reprocessed.
170
+ - A Kafka record with no value — a tombstone, which is ordinary traffic on a compacted topic —
171
+ failed the whole batch. Its offset was never committed, so the route reconnected onto the same
172
+ record forever: one tombstone wedged the consumer permanently, and a compacted topic could not
173
+ be consumed at all. Tombstones now arrive as an empty payload flagged `mqb.kafka.tombstone`.
174
+ - `--drain` on a Kafka source could report success having copied only part of a topic, or none
175
+ of it. An idle wait was taken to mean "source exhausted", but an idle channel means nothing on
176
+ its own: before the first fetch lands, or in an ordinary gap between fetches, it looks exactly
177
+ the same as the end of the data. The shorter the idle timeout the more went missing — at 1ms a
178
+ 1,000,000-row topic landed 0 rows, and the copy still exited successfully. A drain now
179
+ completes only once every assigned partition has reached the offset it held when the drain
180
+ began, and lands all 1,000,000 rows at every idle timeout including 0.
181
+ - Drain no longer hangs on an empty source, and reconnect attempts are bounded.
182
+ - CSV reader handles quoted newlines; file endpoints fail fast on an unopenable path.
@@ -1,8 +1,8 @@
1
1
  # mq-bridge Project Context
2
2
 
3
3
  > **Looking for what middleware or structural endpoints exist, and how to configure them?**
4
- > [REFERENCE.md](REFERENCE.md) is the complete, authoritative list — every middleware
5
- > (`retry`, `dlq`, `transform`, `deduplication`, `weak_join`, `buffer`, `limiter`, `delay`,
4
+ > [REFERENCE.md](docs/REFERENCE.md) is the complete, authoritative list — every middleware
5
+ > (`retry`, `dlq`, `transform`, `id`, `deduplication`, `weak_join`, `buffer`, `limiter`, `delay`,
6
6
  > `cookie_jar`, `encryption`, `compression`, `metrics`, `random_panic`, `custom`) and every structural endpoint (`ref`,
7
7
  > `fanout`, `switch`, `request`, `response`, `reader`, `static`, `stream_buffer`, `null`,
8
8
  > `custom`), each with its fields, defaults, and a working YAML example. Do not infer these
@@ -79,6 +79,7 @@ src/
79
79
  │ ├── delay.rs # Artificial delay
80
80
  │ ├── dlq.rs # Dead-letter queue
81
81
  │ ├── encryption.rs # AEAD payload encryption
82
+ │ ├── id.rs # Replay-stable business identity into `mqb.id`
82
83
  │ ├── limiter.rs # Throughput limiting (msg/s)
83
84
  │ ├── metrics.rs # Metrics collection
84
85
  │ ├── random_panic.rs # Testing middleware