mq-bridge-basic 0.4.17__tar.gz → 0.4.19__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 (384) hide show
  1. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/docs.yml +4 -0
  2. mq_bridge_basic-0.4.17/CLAUDE.md → mq_bridge_basic-0.4.19/AGENTS.md +24 -38
  3. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/CHANGELOG.md +309 -0
  4. mq_bridge_basic-0.4.19/CLAUDE.md +1 -0
  5. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/Cargo.lock +6 -4
  6. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/Cargo.toml +15 -8
  7. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/PKG-INFO +9 -2
  8. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/README.md +30 -7
  9. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/PLUGINS.md +100 -6
  10. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/REFERENCE.md +157 -12
  11. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/include/cbindgen.toml +3 -1
  12. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/include/mq_bridge_plugin.h +23 -2
  13. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/include/mq_bridge_plugin_helpers.h +13 -2
  14. mq_bridge_basic-0.4.19/llms.txt +87 -0
  15. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/mq-bridge.schema.json +952 -121
  16. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/mq_bridge/config.py +38 -0
  17. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/mq_bridge/config.pyi +152 -0
  18. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/pyproject.toml +8 -1
  19. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/pyproject-basic.toml +8 -1
  20. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_packaging.py +1 -0
  21. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/checkpoint.rs +2 -0
  22. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/aws.rs +1 -1
  23. mq_bridge_basic-0.4.19/src/endpoints/file/csv_dialect.rs +322 -0
  24. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/file/mod.rs +567 -151
  25. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/file/tests.rs +456 -39
  26. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/publisher.rs +5 -1
  27. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/server.rs +8 -10
  28. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/http/publisher.rs +4 -14
  29. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/http/tests.rs +45 -0
  30. mq_bridge_basic-0.4.19/src/endpoints/http_bulk/auth.rs +583 -0
  31. mq_bridge_basic-0.4.19/src/endpoints/http_bulk/consumer.rs +710 -0
  32. mq_bridge_basic-0.4.19/src/endpoints/http_bulk/mod.rs +241 -0
  33. mq_bridge_basic-0.4.19/src/endpoints/http_bulk/presets.rs +776 -0
  34. mq_bridge_basic-0.4.19/src/endpoints/http_bulk/publisher.rs +1467 -0
  35. mq_bridge_basic-0.4.19/src/endpoints/http_bulk/query.rs +429 -0
  36. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/kafka.rs +53 -6
  37. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/memory/endpoint.rs +39 -46
  38. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mod.rs +110 -4
  39. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/publisher.rs +3 -1
  40. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/readers.rs +6 -7
  41. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mqtt.rs +23 -3
  42. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/nats.rs +14 -14
  43. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/object_store.rs +222 -28
  44. mq_bridge_basic-0.4.19/src/endpoints/sqlx/columns.rs +597 -0
  45. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/sqlx/mod.rs +281 -61
  46. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/sqlx/tests.rs +316 -0
  47. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/reader.rs +27 -3
  48. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/static_endpoint.rs +33 -1
  49. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/extensions.rs +45 -2
  50. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/lib.rs +34 -0
  51. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/mod.rs +515 -131
  52. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/tests.rs +298 -4
  53. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/compression.rs +26 -4
  54. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/dlq.rs +16 -5
  55. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/encryption.rs +7 -4
  56. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/filter.rs +63 -4
  57. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/lookup.rs +52 -2
  58. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/mod.rs +57 -26
  59. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/transform/schema.rs +2 -1
  60. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/transform/tests.rs +2 -0
  61. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/models/builders.rs +2 -0
  62. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/models/defaults.rs +20 -0
  63. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/models/secrets.rs +137 -0
  64. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/models/serde_support.rs +74 -0
  65. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/models/tests.rs +112 -0
  66. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/models.rs +468 -11
  67. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/outcomes.rs +44 -0
  68. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/endpoint.rs +26 -3
  69. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/sdk.rs +80 -22
  70. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/test_support.rs +172 -0
  71. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/route.rs +248 -33
  72. mq_bridge_basic-0.4.19/src/support/change_op.rs +66 -0
  73. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/compression_pool.rs +1 -1
  74. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/config_schema.rs +214 -3
  75. mq_bridge_basic-0.4.19/src/support/http_status.rs +46 -0
  76. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/mod.rs +5 -1
  77. mq_bridge_basic-0.4.19/src/support/ndjson.rs +116 -0
  78. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/plugin_abi.rs +66 -2
  79. mq_bridge_basic-0.4.19/src/support/poll_job.rs +140 -0
  80. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/postgres.rs +51 -2
  81. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration_test.rs +9 -0
  82. mq_bridge_basic-0.4.17/python/mq-bridge-py-legacy/README.md +0 -11
  83. mq_bridge_basic-0.4.17/python/mq-bridge-py-legacy/pyproject.toml +0 -26
  84. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.cargo/config.toml +0 -0
  85. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.coderabbit.yaml +0 -0
  86. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.dockerignore +0 -0
  87. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  88. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  89. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  90. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/dependabot.yml +0 -0
  91. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/app.yml +0 -0
  92. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/benchmark.yml +0 -0
  93. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/build-node.yml +0 -0
  94. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/ci.yml +0 -0
  95. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/conda.yml +0 -0
  96. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/ibm-mq.yml +0 -0
  97. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/node.yml +0 -0
  98. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/publish-node.yml +0 -0
  99. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/publish-python.yml +0 -0
  100. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/python.yml +0 -0
  101. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/release.yml +0 -0
  102. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.github/workflows/test-matrix.yml +0 -0
  103. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.gitignore +0 -0
  104. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/.justfile +0 -0
  105. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/CONTRIBUTING.md +0 -0
  106. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/LICENSE +0 -0
  107. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/LICENSE-APACHE +0 -0
  108. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/LICENSE-APACHE.python +0 -0
  109. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/LICENSE-MIT +0 -0
  110. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/LICENSE-MIT.python +0 -0
  111. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/LICENSE.python +0 -0
  112. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/SECURITY.md +0 -0
  113. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/THIRD_PARTY_LICENSES.txt +0 -0
  114. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/benches/ETL_BENCHMARKS.md +0 -0
  115. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/benches/csv_to_json_bench.rs +0 -0
  116. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/benches/middleware_expr_bench.rs +0 -0
  117. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/benches/pack_bench.rs +0 -0
  118. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/benches/performance_bench.rs +0 -0
  119. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/benches/router_bench.rs +0 -0
  120. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/benches/zeromq_backends.rs +0 -0
  121. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/bindings-common/Cargo.toml +0 -0
  122. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/bindings-common/src/lib.rs +0 -0
  123. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/bindings-common/src/logging.rs +0 -0
  124. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/build.rs +0 -0
  125. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/deny.toml +0 -0
  126. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/ARCHITECTURE.md +0 -0
  127. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/CONFIGURATION.md +0 -0
  128. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/DELIVERY.md +0 -0
  129. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/EXTENDING.md +0 -0
  130. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/GRPC.md +0 -0
  131. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/THIRD_PARTY_LICENSES.md +0 -0
  132. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/docs/assets/copy-demo.png +0 -0
  133. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/c-plugin/CMakeLists.txt +0 -0
  134. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/c-plugin/README.md +0 -0
  135. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/c-plugin/legacy_ledger.c +0 -0
  136. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/c-plugin/legacy_ledger.h +0 -0
  137. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/c-plugin/legacy_parser.c +0 -0
  138. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/c-plugin/legacy_parser.h +0 -0
  139. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/c-plugin/minimal.c +0 -0
  140. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/c-plugin/plugin.c +0 -0
  141. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/examples/ipc_worker_queue.yaml +0 -0
  142. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/mq_bridge/__init__.py +0 -0
  143. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/mq_bridge/__init__.pyi +0 -0
  144. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/mq_bridge/plugin_packaging.py +0 -0
  145. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/mq_bridge/py.typed +0 -0
  146. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/package-lock.json +0 -0
  147. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/Cargo.toml +0 -0
  148. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/LICENSE-APACHE.python +0 -0
  149. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/LICENSE-MIT.python +0 -0
  150. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/LICENSE.python +0 -0
  151. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/README.md +0 -0
  152. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/THIRD_PARTY_LICENSES.txt +0 -0
  153. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
  154. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/example.py +0 -0
  155. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/IBM_MQ.md +0 -0
  156. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/bench_memory.py +0 -0
  157. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
  158. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/consume_pull.py +0 -0
  159. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/dlt_source.py +0 -0
  160. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/ibm-mq-input.py +0 -0
  161. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/json_route.py +0 -0
  162. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/memory.yaml +0 -0
  163. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/raw_route.py +0 -0
  164. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/pyproject-reduced.toml +0 -0
  165. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/scripts/gen_config_types.py +0 -0
  166. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/src/lib.rs +0 -0
  167. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_config_types.py +0 -0
  168. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_custom_endpoint.py +0 -0
  169. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_logging.py +0 -0
  170. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
  171. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_plugin_package.py +0 -0
  172. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_public_api.py +0 -0
  173. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_routes.py +0 -0
  174. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_shutdown.py +0 -0
  175. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/uv.lock +0 -0
  176. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/analysis/benches/metadata_bench.rs +0 -0
  177. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
  178. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
  179. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/analysis/http/http_flamegraph.py +0 -0
  180. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
  181. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/analysis/http/run_http_ladder.sh +0 -0
  182. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/ci/format_bench_output.sh +0 -0
  183. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/httparena/README.md +0 -0
  184. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
  185. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
  186. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/httparena/frameworks/mq-bridge-py/server.py +0 -0
  187. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/httparena/frameworks/mq-bridge-py/templates/fortunes.html +0 -0
  188. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/mqb-agent.py +0 -0
  189. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/sync-version.mjs +0 -0
  190. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
  191. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
  192. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
  193. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
  194. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/techempower/README.md +0 -0
  195. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/techempower/postgres.yml +0 -0
  196. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/techempower/seed.sql +0 -0
  197. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/techempower/verify.sh +0 -0
  198. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/the-benchmarker/README.md +0 -0
  199. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
  200. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
  201. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
  202. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/canonical_message.rs +0 -0
  203. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/command_handler.rs +0 -0
  204. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/config_file.rs +0 -0
  205. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/amqp.rs +0 -0
  206. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/clickhouse.rs +0 -0
  207. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/dir_spool/mod.rs +0 -0
  208. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/dir_spool/tests.rs +0 -0
  209. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/consumer.rs +0 -0
  210. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/dynamic.rs +0 -0
  211. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/mod.rs +0 -0
  212. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/proto/mqbridge/bridge.proto +0 -0
  213. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/tests.rs +0 -0
  214. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/http/mod.rs +0 -0
  215. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/http/stream.rs +0 -0
  216. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/ibm_mq.rs +0 -0
  217. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/memory/framed.rs +0 -0
  218. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/memory/ipc_unix.rs +0 -0
  219. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/memory/ipc_windows.rs +0 -0
  220. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/memory/memory_transport.rs +0 -0
  221. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/memory/mod.rs +0 -0
  222. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/memory/transport.rs +0 -0
  223. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/aggregate.rs +0 -0
  224. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/consumer.rs +0 -0
  225. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/dedup.rs +0 -0
  226. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/mod.rs +0 -0
  227. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/tests.rs +0 -0
  228. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/poll.rs +0 -0
  229. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/VENDORED.md +0 -0
  230. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/mod.rs +0 -0
  231. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
  232. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
  233. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
  234. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
  235. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/values.rs +0 -0
  236. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/replication.rs +0 -0
  237. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/state.rs +0 -0
  238. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/redis_streams.rs +0 -0
  239. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/sled.rs +0 -0
  240. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/sqlx/aggregate.rs +0 -0
  241. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/sqlx/dedup.rs +0 -0
  242. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/fanout.rs +0 -0
  243. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/mod.rs +0 -0
  244. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/null.rs +0 -0
  245. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/request.rs +0 -0
  246. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/response.rs +0 -0
  247. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/sequence.rs +0 -0
  248. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/stream_buffer.rs +0 -0
  249. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/structural/switch.rs +0 -0
  250. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/websocket.rs +0 -0
  251. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/zeromq/codec.rs +0 -0
  252. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/zeromq/mod.rs +0 -0
  253. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/zeromq/omq.rs +0 -0
  254. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/endpoints/zeromq/zmq.rs +0 -0
  255. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/errors.rs +0 -0
  256. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/event_handler.rs +0 -0
  257. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/event_store.rs +0 -0
  258. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/states.rs +0 -0
  259. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/store.rs +0 -0
  260. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/writer.rs +0 -0
  261. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/buffer.rs +0 -0
  262. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/cookie_jar.rs +0 -0
  263. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/deduplication/memory.rs +0 -0
  264. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/deduplication.rs +0 -0
  265. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/deferred_commit.rs +0 -0
  266. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/delay.rs +0 -0
  267. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/id.rs +0 -0
  268. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/limiter.rs +0 -0
  269. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/metrics.rs +0 -0
  270. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/otel.rs +0 -0
  271. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/pack.rs +0 -0
  272. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/random_panic.rs +0 -0
  273. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/raw_json.rs +0 -0
  274. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/retry.rs +0 -0
  275. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/timeout.rs +0 -0
  276. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/transform/coerce.rs +0 -0
  277. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/transform/compiled.rs +0 -0
  278. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/transform/error.rs +0 -0
  279. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/transform/mod.rs +0 -0
  280. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/transform/path.rs +0 -0
  281. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/middleware/weak_join.rs +0 -0
  282. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/completion.rs +0 -0
  283. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/conformance.rs +0 -0
  284. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/crash.rs +0 -0
  285. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/discovery.rs +0 -0
  286. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/forward.rs +0 -0
  287. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/host.rs +0 -0
  288. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/message.rs +0 -0
  289. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/middleware.rs +0 -0
  290. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/plugin/mod.rs +0 -0
  291. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/publisher.rs +0 -0
  292. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/response.rs +0 -0
  293. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/shutdown.rs +0 -0
  294. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/base64_engine.rs +0 -0
  295. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/compression.rs +0 -0
  296. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/connection_registry.rs +0 -0
  297. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/crypto.rs +0 -0
  298. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/crypto_envelope.rs +0 -0
  299. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/interpolation.rs +0 -0
  300. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/lookup_batch.rs +0 -0
  301. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/pack.rs +0 -0
  302. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/parallel.rs +0 -0
  303. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/parquet.rs +0 -0
  304. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/source_ranges.rs +0 -0
  305. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/support/stream_batch.rs +0 -0
  306. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/test_utils.rs +0 -0
  307. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/traits.rs +0 -0
  308. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/src/type_handler.rs +0 -0
  309. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/README.md +0 -0
  310. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/armature_integration.rs +0 -0
  311. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/compat/python/bridge_client.py +0 -0
  312. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/dedup_store_bench.rs +0 -0
  313. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/delivery_guarantee_test.rs +0 -0
  314. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/amqp.rs +0 -0
  315. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/aws.rs +0 -0
  316. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/clickhouse.rs +0 -0
  317. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/config.toml +0 -0
  318. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/amqp.yml +0 -0
  319. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/aws.yml +0 -0
  320. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/clickhouse.yml +0 -0
  321. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
  322. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
  323. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
  324. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
  325. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
  326. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm_mq.yml +0 -0
  327. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
  328. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/kafka-tls.yml +0 -0
  329. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/kafka.yml +0 -0
  330. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mariadb.yml +0 -0
  331. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
  332. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
  333. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mongodb.yml +0 -0
  334. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mosquitto.conf +0 -0
  335. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
  336. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
  337. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mq_init.mqsc +0 -0
  338. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
  339. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mqtt.yml +0 -0
  340. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
  341. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mysql.yml +0 -0
  342. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/nats.yml +0 -0
  343. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/object_store.yml +0 -0
  344. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/postgres.yml +0 -0
  345. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
  346. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/redis.yml +0 -0
  347. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/file.rs +0 -0
  348. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/grpc.rs +0 -0
  349. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/grpc_tls.rs +0 -0
  350. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/http.rs +0 -0
  351. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/http_tls.rs +0 -0
  352. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/ibm_mq.rs +0 -0
  353. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/ibm_mq_tls.rs +0 -0
  354. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/ipc.rs +0 -0
  355. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/kafka.rs +0 -0
  356. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/kafka_tls.rs +0 -0
  357. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/logic_test.rs +0 -0
  358. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/mariadb.rs +0 -0
  359. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/memory.rs +0 -0
  360. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/mod.rs +0 -0
  361. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/mongodb.rs +0 -0
  362. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/mongodb_raw.rs +0 -0
  363. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/mongodb_tls.rs +0 -0
  364. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/mqtt.rs +0 -0
  365. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/mysql.rs +0 -0
  366. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/nats.rs +0 -0
  367. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/object_store.rs +0 -0
  368. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/performance_static.rs +0 -0
  369. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/postgres_cdc.rs +0 -0
  370. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/redis_streams.rs +0 -0
  371. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/route.rs +0 -0
  372. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/scripts/gen_certs.sh +0 -0
  373. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/sqlite.rs +0 -0
  374. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/tls_helpers.rs +0 -0
  375. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/websocket.rs +0 -0
  376. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/integration/zeromq.rs +0 -0
  377. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/memory_leak_test.rs +0 -0
  378. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/otel_test.rs +0 -0
  379. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/ref_test.rs +0 -0
  380. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/reference_docs_test.rs +0 -0
  381. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/sqlite_test.rs +0 -0
  382. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/tls_example.rs +0 -0
  383. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/unit_tests.md +0 -0
  384. {mq_bridge_basic-0.4.17 → mq_bridge_basic-0.4.19}/tests/websocket_test.rs +0 -0
@@ -43,6 +43,10 @@ jobs:
43
43
  - name: Build book
44
44
  run: mdbook build apps/mq-bridge-app/dev/docs
45
45
 
46
+ # mdbook copies non-Markdown files from the book source; fail if that ever stops.
47
+ - name: Check llms.txt is published
48
+ run: test -s apps/mq-bridge-app/dev/docs/book/llms.txt
49
+
46
50
  # The benchmark dashboard lives on the gh-pages branch. Copy it into the
47
51
  # book so this workflow is the only thing that publishes to Pages.
48
52
  - name: Checkout benchmark data
@@ -3,16 +3,16 @@
3
3
  > **Looking for what middleware or structural endpoints exist, and how to configure them?**
4
4
  > [REFERENCE.md](docs/REFERENCE.md) is the complete, authoritative list — every middleware
5
5
  > (`retry`, `dlq`, `transform`, `id`, `filter`, `deduplication`, `weak_join`, `buffer`, `limiter`, `delay`,
6
- > `cookie_jar`, `encryption`, `compression`, `pack`, `unpack`, `metrics`, `otel`, `lookup`, `aggregate`, `random_panic`, `custom`) and every
6
+ > `cookie_jar`, `encryption`, `compression`, `pack`, `unpack`, `timeout`, `metrics`, `otel`, `lookup`, `aggregate`, `random_panic`, `custom`) and every
7
7
  > structural endpoint (`ref`,
8
- > `fanout`, `switch`, `request`, `response`, `reader`, `static`, `stream_buffer`, `null`,
8
+ > `fanout`, `switch`, `sequence`, `request`, `response`, `reader`, `static`, `stream_buffer`, `null`,
9
9
  > `custom`), each with its fields, defaults, and a working YAML example. Do not infer these
10
10
  > from the enum definitions in `models.rs`; the reference records the behaviour and the
11
11
  > spelling traps too. Every snippet in it is parsed by `tests/reference_docs_test.rs`.
12
12
 
13
13
  ## Project Overview
14
14
 
15
- `mq-bridge` is an asynchronous message bridging library for Rust that connects different messaging systems, data stores, and protocols. It acts as a **programmable integration layer**, allowing for transformation, filtering, handling, events, and complex routing.
15
+ `mq-bridge` is an asynchronous Rust library that moves messages and data between brokers, databases, object storage, files and HTTP. What it can do, and where each capability is documented, is in [llms.txt](llms.txt) and the README's "Capabilities at a glance" table; this file covers how to work on the engine. The app in `apps/mq-bridge-app` has its own [AGENTS.md](apps/mq-bridge-app/AGENTS.md).
16
16
 
17
17
  ## Core Architecture
18
18
 
@@ -41,7 +41,10 @@ src/
41
41
  ├── canonical_message.rs # Unified message format
42
42
  ├── traits.rs # Core traits (MessageConsumer, MessagePublisher, Handler)
43
43
  ├── models.rs # Configuration models (Route, Endpoint, Middleware)
44
+ ├── models/ # models.rs submodules: builders, defaults, secrets, serde support
45
+ ├── config_file.rs # Loading routes from YAML/JSON files
44
46
  ├── route.rs # Route execution logic (sequential/concurrent)
47
+ ├── shutdown.rs # Graceful shutdown signalling
45
48
  ├── endpoints/ # Endpoint implementations
46
49
  │ ├── mod.rs # Factory functions for creating consumers/publishers
47
50
  │ ├── amqp.rs # AMQP (RabbitMQ) consumer/publisher
@@ -49,12 +52,13 @@ src/
49
52
  │ ├── clickhouse.rs # ClickHouse sink + cursor source
50
53
  │ ├── dir_spool/ # Crash-safe directory FIFO queue (payload file + JSON sidecar)
51
54
  │ ├── file/ # File-based endpoints
52
- │ ├── grpc.rs # gRPC consumer/publisher
55
+ │ ├── grpc/ # gRPC consumer/publisher
53
56
  │ ├── http/ # HTTP consumer/publisher (+ streaming)
57
+ │ ├── http_bulk/ # Bulk JSON documents over HTTP (search engines): publisher, paged consumer, presets
54
58
  │ ├── ibm_mq.rs # IBM MQ (client loaded at runtime via dlopen)
55
59
  │ ├── kafka.rs # Kafka consumer/publisher
56
60
  │ ├── memory/ # In-memory channels + IPC transports
57
- │ ├── mongodb.rs # MongoDB consumer/publisher/change streams
61
+ │ ├── mongodb/ # MongoDB consumer/publisher/change streams
58
62
  │ ├── mqtt.rs # MQTT consumer/publisher
59
63
  │ ├── nats.rs # NATS consumer/publisher
60
64
  │ ├── object_store.rs # Cloud object storage (S3 / GCS / Azure)
@@ -68,6 +72,7 @@ src/
68
72
  │ └── structural/ # Structural endpoints (no external system)
69
73
  │ ├── fanout.rs # Broadcast to every listed endpoint
70
74
  │ ├── switch.rs # Content-based routing
75
+ │ ├── sequence.rs # Drain several inputs one after another (backfill, then stream)
71
76
  │ ├── request.rs # Request/reply call, forward the response
72
77
  │ ├── response.rs # Reply to the origin of the current request
73
78
  │ ├── reader.rs # Trigger a pull from a consumer
@@ -77,8 +82,10 @@ src/
77
82
  ├── middleware/ # Middleware implementations
78
83
  │ ├── aggregate/ # Per-key running state (sums, counters, moving averages)
79
84
  │ ├── buffer.rs # Batch accumulation
85
+ │ ├── compression.rs # Per-message payload compression
80
86
  │ ├── cookie_jar.rs # Cookie / metadata persistence across requests
81
- │ ├── deduplication.rs # Message deduplication (sled)
87
+ │ ├── deduplication.rs # Message deduplication
88
+ │ ├── deduplication/ # Dedup stores (sled, memory, SQL, MongoDB)
82
89
  │ ├── delay.rs # Artificial delay
83
90
  │ ├── deferred_commit.rs # Hold commits for batches a middleware emptied
84
91
  │ ├── dlq.rs # Dead-letter queue
@@ -89,15 +96,22 @@ src/
89
96
  │ ├── lookup.rs # Enrich from another endpoint's response
90
97
  │ ├── metrics.rs # Metrics collection
91
98
  │ ├── otel.rs # OpenTelemetry spans + traceparent propagation
99
+ │ ├── pack.rs # pack / unpack: one transport message per batch
92
100
  │ ├── random_panic.rs # Testing middleware
101
+ │ ├── raw_json.rs # Shared raw-JSON payload helpers
93
102
  │ ├── retry.rs # Exponential backoff retry
103
+ │ ├── timeout.rs # Bound each send; fail as retryable
94
104
  │ ├── transform/ # Declarative JSON mapping + schema coercion
95
105
  │ └── weak_join.rs # Correlation-keyed join
96
106
  ├── support/ # Cross-cutting helpers
97
107
  │ ├── compression.rs # gzip / lz4 / zstd
98
108
  │ ├── connection_registry.rs # Shared connection reuse
99
109
  │ ├── crypto.rs # AEAD core (used by encryption middleware + at-rest)
100
- │ └── interpolation.rs # `${namespace:selector}` templating
110
+ │ ├── interpolation.rs # `${namespace:selector}` templating
111
+ │ ├── parquet.rs # Parquet encode/decode for object_store
112
+ │ ├── source_ranges.rs # Covered-range recovery for replay-safe file/object sinks
113
+ │ ├── pack.rs # Batch envelope used by pack / unpack
114
+ │ └── plugin_abi.rs # C ABI shared by host and native plugins
101
115
  ├── command_handler.rs # Command handler wrapper
102
116
  ├── event_handler.rs # Event handler wrapper
103
117
  ├── event_store.rs # In-memory event store
@@ -105,6 +119,7 @@ src/
105
119
  ├── publisher.rs # Standalone publisher API
106
120
  ├── checkpoint.rs # Durable cursor stores (file/s3/postgres/mongodb)
107
121
  ├── extensions.rs # Custom endpoint/middleware factory registration
122
+ ├── plugin/ # Native plugin host, SDK and conformance suite
108
123
  ├── response.rs # Ergonomic response helpers
109
124
  ├── test_utils.rs # Shared test helpers
110
125
  ├── errors.rs # Error types
@@ -142,20 +157,7 @@ Routes are defined via:
142
157
  - JSON files
143
158
  - Environment variables (prefix: `MQB__`, separator: `__`)
144
159
 
145
- Example:
146
- ```yaml
147
- kafka_to_nats:
148
- concurrency: 4
149
- batch_size: 128
150
- input:
151
- kafka:
152
- topic: "orders"
153
- url: "localhost:9092"
154
- output:
155
- nats:
156
- subject: "orders.processed"
157
- url: "nats://localhost:4222"
158
- ```
160
+ The grammar and examples are in [CONFIGURATION.md](docs/CONFIGURATION.md).
159
161
 
160
162
  ### Common Patterns
161
163
 
@@ -188,20 +190,4 @@ kafka_to_nats:
188
190
 
189
191
  ### Dependencies
190
192
 
191
- - **tokio**: Async runtime
192
- - **serde**: Serialization/deserialization
193
- - **anyhow**: Error handling
194
- - **tracing**: Structured logging
195
- - **config**: Configuration management
196
- - **async-trait**: Async trait support
197
- - **uuid**: Unique identifiers (v4 and v7)
198
-
199
- Optional (feature-gated):
200
- - **rdkafka**: Kafka support
201
- - **async-nats**: NATS support
202
- - **lapin**: AMQP support
203
- - **rumqttc**: MQTT support
204
- - **mongodb**: MongoDB support
205
- - **actix/reqwest**: HTTP support
206
- - **sled**: Deduplication storage
207
- - **metrics**: Metrics collection
193
+ Dependencies and the feature that gates each optional one are in `Cargo.toml`, with comments explaining the non-obvious choices. The crate has no default features.
@@ -2,6 +2,315 @@
2
2
 
3
3
  All notable changes to `mq-bridge`. Newest first.
4
4
 
5
+ ## 0.4.19
6
+
7
+ CSV in more shapes: the reader takes other separators and quoting, and a CSV sink no longer
8
+ mixes JSON into its cells. The second is a behaviour change, listed below.
9
+
10
+ ### Added
11
+
12
+ - **CSV dialects.** `format: csv` took only comma-separated, `"`-quoted files with a header. A
13
+ `csv` block on the `file` endpoint and on an `object_store` source now sets `separator` (one
14
+ character, `tab`, `space`, hex, or `auto`), `quote` (a character or `none`), `header` and
15
+ `columns`. `separator: auto` is for sources and takes whichever of `,` `;` tab `|` occurs
16
+ most often outside quotes in the first record. That covers Excel's semicolon exports, TSV
17
+ from `mongoexport` and `psql`, and headerless dumps; the book's file page lists the setting
18
+ per tool. On the command line it is one parameter, `csv={"separator":"auto"}`.
19
+ `FileConfig` and `ObjectStoreConfig` gain the field `csv`, and `models` the types
20
+ `CsvConfig` and `CsvNested`; code that builds either struct without `..Default::default()`
21
+ needs the new field.
22
+ - **CSV to object storage.** An `object_store` sink rejected `format: csv`. It now writes each
23
+ batch as a CSV file with its own header, taken from that batch's first row, in the dialect
24
+ the `csv` block sets. Set `csv.columns` when every object must have the same columns.
25
+ - **A warning for short CSV rows.** A row with fewer fields than the header was read with the
26
+ missing ones empty and nothing said, which is what a wrong `separator` looks like. It is now
27
+ warned about once per process, as a row with too many fields already was.
28
+
29
+ - **`aggregate`: `on_error`, time-based averages, late-message detection, `read_only`.**
30
+ - `on_error: drop | fail | skip` says what happens to a message that cannot be folded.
31
+ `drop` is the default and what happened before: an input logs, acks and drops it, so an
32
+ HTTP caller gets `202`. `fail` nacks it instead (HTTP `500`). `skip` leaves out only the
33
+ entries that cannot be computed, runs the others, passes the message on and names the
34
+ skipped entries in the metadata `mqb.aggregate.skipped`. Before, one missing field in one
35
+ entry discarded the message for all entries.
36
+ - `ema`, `ema_stddev` and `ema_variance` take a half-life in place of `alpha`
37
+ (`ema(reading, 5m)`): a value counts half after that time, however many messages came.
38
+ The new `time` names the payload field with the event time (epoch seconds or
39
+ milliseconds, or RFC 3339); without it the clock is used.
40
+ - With `time`, a message older than the newest one its state has seen is folded without
41
+ decay and marked with the metadata `mqb.aggregate.late`. It is detected, not reordered.
42
+ - `read_only: true` reads the states from the `store` and never changes them, for a dry run
43
+ or a second route that only reads.
44
+ - The error for a missing field now says `is missing or not a number`.
45
+ - `AggregateMiddleware` gains the fields `time`, `on_error` and `read_only`, and `models`
46
+ the enum `AggregateOnError`; code that builds the struct without `..Default::default()`
47
+ needs the new fields.
48
+ - **Descriptive names for the file formats.** `format: raw` writes only the payload, which
49
+ for JSON payloads is plain JSON lines, while `format: json` writes the whole message
50
+ envelope; the names suggested the opposite. `payload`, `envelope_json`, `envelope_text`
51
+ and `envelope` are now accepted for `raw`, `json`, `text` and `normal`, on `file`,
52
+ `object_store` and `mongodb`. The old names keep working and are what is written back.
53
+ - **`mqb copy`: pipes, `--limit`, progress, compression by file name.**
54
+ - `-` is stdin as the source and stdout as the target (`-?format=csv` takes parameters). A
55
+ `file` source on a pipe, FIFO or terminal is read once without seeking, and its end ends
56
+ the copy, with or without `--drain`. Before, `file:///dev/stdin` failed with `Illegal seek`.
57
+ With stdout as the target the `copied …` summary goes to stderr.
58
+ - `--limit N` stops after `N` rows reached the destination; with `--filter`, `N` matching rows.
59
+ - On a terminal, a running row count is shown on stderr every two seconds.
60
+ - A `file://` path ending in `.gz`, `.zst` or `.lz4` sets `compression`; `compression=none`
61
+ overrides. A sink named `out.jsonl.gz` used to be written uncompressed.
62
+ - A copy without `--drain` now exits when its route ends by itself, on a permanent error or
63
+ the end of a stream. It used to wait for Ctrl-C.
64
+ - **SQL sink: `columns: auto` and `key`.** A SQL sink could write a record's fields into columns
65
+ only through a hand-written `insert_query`, percent-encoded on the command line, and an upsert
66
+ needed its own `ON CONFLICT` clause. With `columns: auto` each top-level JSON field goes into
67
+ the table column of the same name, and `key: id` turns the insert into an upsert, so
68
+ `mqb copy --from 'postgres://…?table=orders&cursor_column=id' --to 'postgres://…?table=orders&columns=auto&key=id'`
69
+ copies a table and can be rerun.
70
+ - The table must exist. A column a record does not name keeps its default (insert) or its
71
+ value (update). A field without a column is not written and is logged once; with
72
+ `extra_column: <name>` those fields go into that column as one JSON object.
73
+ - PostgreSQL casts each value to the column type, so `numeric`, `timestamptz`, `uuid`,
74
+ `jsonb`, enum and array columns take the text a SQL or CSV source delivers.
75
+ - `bulk_copy` works with `columns: auto`, not with `key`. `columns` cannot be combined with
76
+ `insert_query` or `auto_create_table`.
77
+ - `SqlxConfig` gains the fields `columns`, `key` and `extra_column`, and `models` the type `SqlColumns`.
78
+ - **SQL source: `timestamps: rfc3339`.** A Postgres `timestamptz` column is read in Postgres's
79
+ text form, `2026-10-04 09:15:23.923277+00`, which few other systems parse. With
80
+ `timestamps: rfc3339` a `cursor_column` source renders it in UTC as
81
+ `2026-10-04T09:15:23.923277Z`; a `timestamp` without zone gets the `T` and no offset. The
82
+ default is unchanged. `SqlxConfig` gains the field `timestamps` and `models` the type
83
+ `SqlTimestamps`.
84
+
85
+ ### Behaviour changes
86
+
87
+ - **`aggregate`: states in memory only are opt-in.** An `aggregate` without
88
+ a `store` kept its states in the process, lost on restart and wrong with two instances, and
89
+ that was the default. It now needs `consistency: single_writer` next to it; with neither a
90
+ `store` nor that, the route fails to start with an error naming both. Add
91
+ `consistency: single_writer` to a config from 0.4.17 or 0.4.18 that has no `store` to keep
92
+ what it did.
93
+ - **A CSV sink flattens nested objects.** A nested object used to be written as JSON text in
94
+ one cell, so the output of `aggregate` (`{"stats":{"n":3,"avg":2.5}}`) came out as a mix of
95
+ CSV and JSON. It now becomes one column per leaf, named by its path: `stats.n`, `stats.avg`.
96
+ **A new file gets different columns than before; a file that already has a header keeps
97
+ it.** Set `csv.nested: json` for the previous output. Arrays are still written as JSON text.
98
+ - **A drain does not wait for an endpoint.** With `exit_on_empty` (`mqb copy --drain`) a route
99
+ that failed reconnected up to ten times, 5 s apart, before it gave up: about 50 s against a
100
+ closed port, a WebSocket path that answers 404, a NATS subject outside every stream or a gRPC
101
+ topic nobody serves. It now ends on the first failure when nothing has been delivered yet,
102
+ with the endpoint's error. A drain that has delivered something keeps the ten reconnects, so
103
+ a short outage in the middle of a long copy does not end it. Routes without `exit_on_empty`
104
+ reconnect without limit, as before. Add a `retry` middleware to a drain that should wait for
105
+ its sink.
106
+ - **A CSV file that ends inside a quoted field fails a drain.** The reader took everything
107
+ after the open quote as one field and reported success. A drain now writes the records before
108
+ it and fails, naming the byte offset of the open record; a tailing route waits for the writer
109
+ to finish the record.
110
+ - **Blank lines in a line-based file are skipped.** `raw`, `json`, `text` and `normal` sources
111
+ emitted an empty line as a message with an empty payload, which a SQL or Parquet sink then
112
+ rejected. The CSV reader already skipped them. Row counts change for files with blank lines.
113
+ - **A `file` route whose source and sink are the same path is refused.** It doubled the file
114
+ under a drain and would grow it without end otherwise.
115
+ - **SQLite `has no column named` is not retried.** A sink writing to a table without the
116
+ expected columns retried for ever; it is now a non-retryable error like the same case on
117
+ Postgres and MySQL.
118
+ - **An `object_store` source on a local path that does not exist fails a drain.** It reported
119
+ `copied 0 rows`. An empty directory or cloud prefix still does. A drain of a local path also
120
+ ends after one listing instead of waiting out the idle interval.
121
+ - **NATS: a missing `subject` or `stream` stops the route.** It was retried as a connection
122
+ error until the start timeout.
123
+ - **Clearer errors and quieter logs.** A queue read on a plain SQL table names
124
+ `cursor_column`; Postgres errors no longer end in `at line N` (a line of the server's source);
125
+ a closed database port reports `Connection refused` at once; a `filter` that does not compile
126
+ lists the operators, and one with a single `=` says so; a gRPC server names the topic it has
127
+ no consumer for; the drop summary counts messages per cause; an unknown `aggregate` field
128
+ lists the built-ins; `csv` settings without `format: csv` and an `insert_query` token that
129
+ binds NULL each warn once. The WebSocket "falling back to routed mode" line is now DEBUG and
130
+ the MQTT note on restart loss INFO.
131
+
132
+ ### Fixed
133
+
134
+ - **`mqb copy --wait` reports a failed route at once.** A route that failed before it delivered
135
+ anything was retried until the wait ran out, and a later empty attempt could then report
136
+ success. `--wait` now retries only a drain that ended cleanly with nothing to copy.
137
+ - **`aggregate` with a shared `store` no longer keeps the state of a message it rejects.** A
138
+ message whose result had no place in the payload (`into: a.b` where `a` is not an object) was
139
+ counted in the store and then failed, so under `on_error: fail` every redelivery counted it
140
+ again. It now fails before any state changes, as it already did without a shared store.
141
+
142
+ ## 0.4.18
143
+
144
+ A new generic output for search engines, plus documentation and packaging work. This release
145
+ changes behaviour in several places, listed under "Behaviour changes": read that section before
146
+ upgrading.
147
+
148
+ ### Added
149
+
150
+ - **`http_bulk`: a generic bulk document endpoint for search engines.** It sends a batch as one
151
+ NDJSON or JSON-array request and deletes by id, and reads the outcome from the HTTP status,
152
+ from one result line or array entry per document, or from a polled job. An action line per
153
+ document, an envelope around the array and `gzip`/`zstd`/`lz4` request bodies are
154
+ configuration too. The target is described in configuration, so no product is named in
155
+ code; the book has tested recipes for Meilisearch, Typesense, Elasticsearch, Qdrant,
156
+ PostgREST and CouchDB. On the command line it is `http-bulk:?config_file=<yaml>` or
157
+ `http-bulk:?config=<YAML or JSON>`. As an input, `read` pages through a JSON listing by a
158
+ cursor taken from the response, from the last document, or counted as an offset; the position
159
+ is saved with `read.cursor_id` and `read.checkpoint_store` and works with `mqb copy --resume`. Reading
160
+ was run against CouchDB's change feed, Qdrant, Meilisearch and PostgREST. Behind the new
161
+ `http-bulk` feature, which `full` and `portable` include. `EndpointType` gains the variant
162
+ `HttpBulk`. A polled job has a deadline, `result.job.timeout_ms` (default 5 minutes): when it
163
+ passes, or the poll keeps failing that long, the documents of that request fail as retryable
164
+ with the job id and the last state or poll error seen.
165
+ - **`http_bulk` answers lookups in bulk.** A `query` section makes the endpoint the `from` of a
166
+ `lookup`: every message renders `request`, one HTTP request carries the whole batch
167
+ (`ndjson`, or `json_array` inside an `envelope` with a `{requests}` marker), and the answers
168
+ are matched by position in the array at `responses`, with optional pointers `value`, `found`
169
+ and `error`. It covers Elasticsearch `_msearch` and `_mget` and Qdrant's batch search. A
170
+ missing answer is `null`; an entry that reports an error makes the batch fall back to one
171
+ request per message, with a warning, so only that message fails. `query` excludes `upsert`,
172
+ `delete` and `operation`, and an output now needs `upsert` or `query`.
173
+ - **`http_bulk` authentication: OAuth2 client credentials and AWS SigV4.** `auth.oauth2`
174
+ (`token_url`, `client_id`, `client_secret`, `scope`) fetches a token, caches it, replaces it
175
+ before it expires and once more after a 401; concurrent batches share one token request.
176
+ `auth.aws_sigv4` (`region`, `service`, optional static keys, else the default credential
177
+ chain) signs each request and needs the `aws` feature. Both apply to upserts, deletes,
178
+ queries, reads and job polls; the secrets are extracted like `headers`. The `aws` feature
179
+ now depends on `aws-sigv4` directly, a crate the AWS SDK already brought in.
180
+ - **`http_bulk` partial updates.** `upsert.document` is a template around each document with a
181
+ `{document}` marker, for `ndjson` and `json_array`. The `elasticsearch` endpoint gains
182
+ `mode: update` (`{"doc":…,"doc_as_upsert":true}` behind an `update` action) and `auth`.
183
+ - **`typesense` and `elasticsearch` endpoints.** Each is an `http_bulk` output with the
184
+ requests filled in, so it takes a few fields (`url`, `collection` or `index`, `api_key`,
185
+ `operation`) and a URI of its own: `mqb copy … 'typesense://host:8108/books?api_key=…'`,
186
+ with `typesense+https://` for HTTPS. `mqb` has both built in; a library registers one with
187
+ `endpoints::http_bulk::register_preset("typesense")` and addresses it as a `custom`
188
+ endpoint. An installed plugin of the same name replaces one through `MQB_PLUGIN_OVERRIDE`.
189
+ - **The Meilisearch book page covers bulk-load speed and embeddings.** Index settings before
190
+ loading, batch sizes with measurements, pgvector columns as `_vectors`, Supabase, keeping
191
+ joined fields current and a rebuild without downtime.
192
+ - **Book pages for the plugin connectors.** Apache Pulsar, Meilisearch and the Connect plugin
193
+ (Redpanda Connect components) each have a connector page. The Connect inputs, outputs and
194
+ processors are listed with their fields, generated by `dev/scripts/gen-connect-docs.py`.
195
+ - **Warehouse recipes in the cookbook.** Loading the Parquet that `object_store` writes into
196
+ Snowflake, BigQuery and Databricks / Spark, querying it from Athena / Trino, and when to use
197
+ the ClickHouse endpoint versus `s3()`.
198
+ - **`llms.txt`.** A capability index for agents, at the repository root and published with the
199
+ book. The docs workflow fails if the book stops shipping it.
200
+ - **A Debezium recipe in the cookbook.** MySQL, MariaDB, SQL Server and Oracle change capture by
201
+ running Debezium Server beside mq-bridge, handed over by HTTP or through a broker.
202
+ - **A feature-flag table on docs.rs.** The crate docs list each Cargo feature with what it
203
+ enables, and link to the README's capabilities table.
204
+ - **Helpers for plugin authors.** A host now accepts the schema `#[derive(JsonSchema)]` gives
205
+ an enum field (`support::config_schema::flatten`), so a plugin no longer hand-writes one.
206
+ `SentBatch::from_outcomes` builds a partial result from per-message outcomes, and
207
+ `support::ndjson::chunk` frames payloads as size-limited NDJSON request bodies.
208
+ `support::http_status` classifies an HTTP status as retryable or not,
209
+ `support::poll_job::poll_until` waits for an asynchronous job to end or a deadline to pass,
210
+ `support::change_op::ChangeOp` sorts a change record into upsert, delete or truncate, and
211
+ `plugin::test_support::StubHttpServer` replaces the remote system in a test. See
212
+ [docs/PLUGINS.md](docs/PLUGINS.md#shared-helpers).
213
+ - **Plugin ABI 1.3: a loaded plugin learns how its route ended.** The host now calls
214
+ `publisher_disconnect` with the outcome before it closes a publisher, so
215
+ `disconnect_outcome()` returns `Completed`, `Stopped` or `Failed` inside a plugin's
216
+ `on_disconnect_hook`. It returned `None` there before. Plugins built for 1.0 to 1.2 load
217
+ unchanged. C plugins that use `MQB_NO_PUBLISHER` or `MQB_BLOCKING_PUBLISHER` get a stub.
218
+ - **An endpoint can ask for its own default batch size.** `mqb copy` and the MCP server's
219
+ `start_route` use the top-level schema annotation `x-mqb-default-batch-size` of a custom
220
+ output when no batch size is given. The general default stays 1,024; of the built-in
221
+ endpoints only the `meilisearch` preset declares one, 50,000.
222
+ - **Plugin repository template.** [examples/plugin-template](examples/plugin-template) holds a
223
+ working endpoint with its npm and Python packages, conda recipe, Homebrew formula script and
224
+ CI and release workflows, plus a script that renames it.
225
+
226
+ ### Changed
227
+
228
+ - **`meilisearch` in `mqb` is now built on `http_bulk`; the plugin is no longer compiled in.**
229
+ The built-in endpoint keeps the URI and the fields `url`, `api_key`, `index`, `primary_key`,
230
+ `operation`, `delete_values`, `max_request_bytes`, `compression`, the timeouts and the input
231
+ fields. It refuses `settings`, `method`, a template in `index`, `update_where`,
232
+ `update_into`, `swap_into`, `create_index`, `wait_for_task` and `task_timeout_ms` at startup
233
+ and names the `mq-bridge-meilisearch` plugin, which still has them: install it and set
234
+ `MQB_PLUGIN_OVERRIDE=meilisearch`, or build with the cargo feature `meilisearch`, which
235
+ `full` no longer includes. `delete_values` now defaults to `delete` and `d`.
236
+ - **Secret extraction covers custom endpoints and middlewares.** `extract_config_secrets` and
237
+ the app's `balanced` config security mode now move credentials out of a `custom` config, such
238
+ as a Connect, Pulsar or Meilisearch endpoint: fields named like a credential and URLs
239
+ carrying `user:pass@`. They used to stay in the config file. The cookbook's Secrets page
240
+ lists what is recognised and what is left in place.
241
+ - **Package metadata describes the ETL scope.** The crates.io, PyPI and npm descriptions,
242
+ keywords and categories now cover CDC, Parquet and object storage as well as the brokers. The
243
+ homepage points at the book instead of the repository.
244
+ - **`AGENTS.md` holds the contributor context** that was in `CLAUDE.md`, which now imports it.
245
+
246
+ ### Behaviour changes
247
+
248
+ Each of these changes what an existing setup sees. Check them before upgrading.
249
+
250
+ - **Replies carry the request's message id.** On NATS, memory and MongoDB request/reply, and on
251
+ the `static` and `reader` endpoints, a reply's `message_id` is now the request's id and no
252
+ longer the responder's. **Anything that keyed on the responder's id sees new values: a
253
+ `deduplication` on a `request` endpoint's `forward_to` starts from an empty history after the
254
+ upgrade.** `reader` keeps the pulled message's own id in the metadata `mqb.reader.message_id`.
255
+ - **Unknown fields in a `file` or `object_store` endpoint are rejected.** `file: { path: x,
256
+ fromat: raw }` used to load and run with the default format. It now fails with the field's
257
+ name, as the other endpoints did.
258
+ - **The CSV sink keeps the first row's field order.** Columns were written alphabetically, so
259
+ the column order of an existing CSV export changes. The order is read once per file.
260
+ - **The SQL cursor source emits Postgres `json`, `jsonb` and array columns as nested JSON.**
261
+ They arrived as strings: `"j":"{\"k\": 1}"` is now `"j":{"k":1}`, and `"{1,2}"` is `[1,2]`.
262
+ `numeric` stays a string, which keeps its precision.
263
+ - **`mqb copy` logs to stderr.** Only the `copied …` summary is on stdout, so a script can read
264
+ it. `MQB_LOG_STDOUT=1` puts the log lines back on stdout.
265
+ - **`mqb copy` exits 1 when rows it read could not be decrypted**, for example an `encryption`
266
+ with the wrong key. It printed `copied 0 of 1_000 rows` and exited 0. Rows a `transform`
267
+ rejects are still reported in the summary with exit 0.
268
+ - **`mqb copy` reports dead-lettered rows separately**: `copied 0 rows, dead-lettered 1_000`
269
+ where it said `copied 1_000 rows`. The exit code is still 0.
270
+ - **`mqb --config <file>` fails when the file does not exist.** It started with default
271
+ settings and waited. The implicit `config.yml` is still optional.
272
+ - **`static` as a `--drain` source emits one batch and ends.** It never ended.
273
+ - **A SQLite sink creates its database file** when the URL names no `mode`. It failed with
274
+ `unable to open database file` unless the URL carried `mode=rwc`.
275
+ - **`mqb copy --drain` stops at once on an authentication failure** (a wrong Postgres, MySQL,
276
+ RabbitMQ or Redis password, MongoDB `capture_all` without a replica set) instead of retrying
277
+ for the start window. A bridge keeps retrying, and so does an unreachable host.
278
+ - **An unreachable MQTT broker (sink) or Kafka broker (source) fails the start** after the
279
+ start window, as other endpoints do. `copy --drain` used to retry until stopped.
280
+ - **A SQL cursor source without a checkpoint continues after a reconnect** instead of reading
281
+ the table from the first row again. The position is held in memory for the life of the
282
+ route, so a restart of the process still starts over unless `--resume` or a checkpoint is set.
283
+ - **A `null` output keeps its middlewares in the app's config.** `output: { "null": null,
284
+ middlewares: [...] }` was loaded as no output at all.
285
+ - **`mqb copy` warns** when the target is `response:` and the source cannot take a reply, and
286
+ when a SQL source has neither `cursor_column` nor `delete_after_read`, which leases the rows
287
+ for a minute and leaves them in place.
288
+
289
+ ### Fixed
290
+
291
+ - **Request/reply replies are matched in batches.** A reply from a `static` responder, and from
292
+ NATS, memory and MongoDB request/reply, kept its own message id. A batch matches replies to
293
+ requests by id, so in a batch larger than one the reply was dropped and an HTTP caller got
294
+ `202 Message processed`. Replies now carry the request's id, as HTTP and SQL replies did.
295
+ - **MQTT: the first batch of a QoS 1/2 publisher is no longer sent twice.** The first CONNACK
296
+ was treated as a session reset, so the batch was reported unconfirmed, retried after 5 s and
297
+ delivered again.
298
+ - **Kafka: draining a group that is already at the end returns at once** instead of waiting out
299
+ the 30 s join timeout, and the end-of-partition event is no longer logged as an `ERROR`.
300
+ - **MongoDB: `consume: snapshot` no longer returns the bridge's own `<collection>:sequencer`
301
+ document** as a row.
302
+ - **A configuration that can never work fails at once with its reason**, instead of being
303
+ retried for the 5 s start window: an invalid filter expression, a bad encryption key, a
304
+ middleware on the wrong side, a `limiter` of 0, a directory as a file source.
305
+ - **Clearer errors.** A file sink that cannot be opened shows the OS reason; a start timeout
306
+ with no recorded cause says an endpoint was still connecting; `${payload:…}` in a `copy` URI
307
+ explains the `$%7B…%7D` spelling; the NATS publisher no longer warns that `stream` is ignored
308
+ when it is used.
309
+ - **`mqb copy` reports the rate of delivered rows** after an `unpack`, not of packs read.
310
+ - **The `compression` middleware uses every core.** Batches of 256 messages and more are
311
+ compressed and decompressed on the blocking pool, in order: zstd 316k → 1.29M rows/s, gzip
312
+ 160k → 400k, lz4 1.9M → 3.9M. The output is byte-identical.
313
+
5
314
  ## 0.4.17
6
315
 
7
316
  ### Added
@@ -0,0 +1 @@
1
+ @AGENTS.md
@@ -3689,7 +3689,7 @@ dependencies = [
3689
3689
 
3690
3690
  [[package]]
3691
3691
  name = "mq-bridge"
3692
- version = "0.4.17"
3692
+ version = "0.4.19"
3693
3693
  dependencies = [
3694
3694
  "aes-gcm",
3695
3695
  "anyhow",
@@ -3704,6 +3704,7 @@ dependencies = [
3704
3704
  "aws-config",
3705
3705
  "aws-sdk-sns",
3706
3706
  "aws-sdk-sqs",
3707
+ "aws-sigv4",
3707
3708
  "base64 0.23.1",
3708
3709
  "byteorder",
3709
3710
  "bytes",
@@ -3791,7 +3792,7 @@ dependencies = [
3791
3792
 
3792
3793
  [[package]]
3793
3794
  name = "mq-bridge-bindings-common"
3794
- version = "0.4.17"
3795
+ version = "0.4.19"
3795
3796
  dependencies = [
3796
3797
  "anyhow",
3797
3798
  "fast-uuid-v7",
@@ -3805,7 +3806,7 @@ dependencies = [
3805
3806
 
3806
3807
  [[package]]
3807
3808
  name = "mq-bridge-node"
3808
- version = "0.4.17"
3809
+ version = "0.4.19"
3809
3810
  dependencies = [
3810
3811
  "anyhow",
3811
3812
  "async-trait",
@@ -3830,6 +3831,7 @@ name = "mq-bridge-plugin-fixture"
3830
3831
  version = "0.1.0"
3831
3832
  dependencies = [
3832
3833
  "anyhow",
3834
+ "async-channel",
3833
3835
  "async-trait",
3834
3836
  "cbindgen",
3835
3837
  "libloading",
@@ -3859,7 +3861,7 @@ dependencies = [
3859
3861
 
3860
3862
  [[package]]
3861
3863
  name = "mq-bridge-py"
3862
- version = "0.4.17"
3864
+ version = "0.4.19"
3863
3865
  dependencies = [
3864
3866
  "anyhow",
3865
3867
  "async-trait",
@@ -4,12 +4,14 @@ version.workspace = true
4
4
  edition = "2021"
5
5
  authors = ["Marco Mengelkoch"]
6
6
  rust-version = "1.85" # Base crate MSRV (non-optional uuid 1.24 needs 1.85); optional amqp/mongodb/nats need Rust 1.88.
7
- description = "An asynchronous message bridging library connecting Kafka, MQTT, AMQP, NATS, MongoDB, HTTP, and more."
7
+ description = "Embeddable async ETL and messaging library: brokers (Kafka, NATS, AMQP, MQTT), databases incl. Postgres/MongoDB CDC, Parquet on S3/GCS/Azure object storage, HTTP/gRPC."
8
8
  repository = "https://github.com/marcomq/mq-bridge"
9
+ homepage = "https://marcomq.github.io/mq-bridge/"
10
+ documentation = "https://docs.rs/mq-bridge"
9
11
  license = "MIT OR Apache-2.0"
10
12
  readme = "README.md"
11
- keywords = ["messaging", "kafka", "nats", "amqp", "cqrs"]
12
- categories = ["asynchronous", "network-programming"]
13
+ keywords = ["kafka", "messaging", "etl", "cdc", "cqrs"]
14
+ categories = ["asynchronous", "network-programming", "database"]
13
15
  # Test-only proto; build.rs skips it when absent so downstream builds skip the codegen.
14
16
  # `apps/` is a sibling product, not part of the library: cargo only auto-excludes
15
17
  # the app's member crates, so the UI, book and benches would ship in the tarball.
@@ -21,7 +23,7 @@ workspace = true
21
23
  [workspace]
22
24
  members = ["bindings-common", "python/mq-bridge-py"]
23
25
  # apps/mq-bridge-app is its own workspace with its own Cargo.lock; see its manifest.
24
- exclude = ["apps"]
26
+ exclude = ["apps", "examples/plugin-template"]
25
27
  resolver = "2"
26
28
 
27
29
  # Lints that are off by default in rustc/clippy and mark code that was never meant to
@@ -38,7 +40,7 @@ dbg_macro = "warn"
38
40
  exit = "warn"
39
41
 
40
42
  [workspace.package]
41
- version = "0.4.17"
43
+ version = "0.4.19"
42
44
 
43
45
  [workspace.dependencies]
44
46
  anyhow = "1.0"
@@ -214,6 +216,9 @@ tokio-websockets = { version = "0.13", optional = true, default-features = false
214
216
  aws-config = { version = "1.10", optional = true, default-features = false, features = ["behavior-version-latest", "rt-tokio", "default-https-client"] }
215
217
  aws-sdk-sqs = { version = "1.105", optional = true, default-features = false, features = ["rt-tokio", "default-https-client"] }
216
218
  aws-sdk-sns = { version = "1.107", optional = true, default-features = false, features = ["rt-tokio", "default-https-client"] }
219
+ # Signs `http_bulk` requests (managed OpenSearch). Already in the tree through aws-config.
220
+ # A low floor: 1.6 needs aws-smithy-types 1.8, which a dependent may pin below.
221
+ aws-sigv4 = { version = "1.4", optional = true }
217
222
 
218
223
  # SQLx
219
224
  sqlx = { version = "0.9", default-features = false, features = ["runtime-tokio", "tls-rustls", "postgres", "mysql", "any", "sqlite-bundled"], optional = true }
@@ -279,7 +284,7 @@ middleware = ["metrics", "otel", "dedup", "compression", "encryption", "filter",
279
284
  # on ~19% of 17-significant-digit doubles (e.g. a Postgres `double precision` value
280
285
  # moved through a JSON payload). Enable if bit-exact float round-tripping matters.
281
286
  float-roundtrip = ["serde_json/float_roundtrip"]
282
- full-common = ["middleware", "yaml", "plugin", "mongodb", "kafka", "amqp", "nats", "mqtt", "http", "aws", "zeromq", "zeromq-omq", "redis-streams", "sled", "grpc", "sqlx", "clickhouse", "websocket", "postgres-cdc", "object-store", "parquet", "avro", "rustls-aws-lc"]
287
+ full-common = ["middleware", "yaml", "plugin", "mongodb", "kafka", "amqp", "nats", "mqtt", "http", "aws", "zeromq", "zeromq-omq", "redis-streams", "sled", "grpc", "sqlx", "clickhouse", "http-bulk", "websocket", "postgres-cdc", "object-store", "parquet", "avro", "rustls-aws-lc"]
283
288
 
284
289
  # ibm-mq (dlopen) is safe to include: it needs no IBM SDK at build, and at
285
290
  # runtime the client is loaded lazily only when an ibm-mq endpoint is opened
@@ -315,7 +320,7 @@ vendored-protoc = ["dep:protoc-bin-vendored"]
315
320
  # kafka (librdkafka), sqlx (libsqlite3-sys), grpc (protoc), ibm-mq/ibm-mq-static
316
321
  # (IBM C client). postgres-cdc is excluded too: its wire protocol is pure Rust
317
322
  # but it pulls in sqlx (C).
318
- portable = ["metrics", "otel", "dedup", "yaml", "plugin", "mongodb", "amqp", "nats", "mqtt", "http", "aws", "zeromq", "redis-streams", "clickhouse", "websocket", "object-store", "rustls-aws-lc"]
323
+ portable = ["metrics", "otel", "dedup", "yaml", "plugin", "mongodb", "amqp", "nats", "mqtt", "http", "aws", "zeromq", "redis-streams", "clickhouse", "http-bulk", "websocket", "object-store", "rustls-aws-lc"]
319
324
 
320
325
  # Functionality features
321
326
  # YAML config files for Route/Publisher::from_file and deploy_file; JSON works without it.
@@ -375,7 +380,7 @@ mongodb = ["dep:mongodb"]
375
380
  mqtt = ["rumqttc", "rustls", "tokio-rustls", "rustls-pemfile"]
376
381
  http = ["dep:arc-swap", "hyper", "hyper-util", "hyper-rustls", "http-body-util", "dep:http-body", "rustls", "tokio-rustls", "rustls-pemfile", "webpki-roots", "h2", "dep:flate2", "dep:lz4_flex", "dep:zstd"]
377
382
  websocket = ["dep:tokio-websockets"]
378
- aws = ["aws-config", "aws-sdk-sqs", "aws-sdk-sns"]
383
+ aws = ["aws-config", "aws-sdk-sqs", "aws-sdk-sns", "aws-sigv4"]
379
384
  # Runtime-loaded IBM MQ client via dlopen: builds with no SDK present; the IBM
380
385
  # redistributable client is only needed at runtime, and only if an ibm-mq
381
386
  # endpoint is actually used.
@@ -398,6 +403,8 @@ redis-streams = ["dep:redis"]
398
403
  grpc = ["tonic", "tonic-reflection", "prost", "prost-types", "prost-reflect", "tokio-stream", "tonic-prost", "tonic-prost-build", "rustls", "vendored-protoc"]
399
404
  sqlx = ["dep:sqlx"]
400
405
  clickhouse = ["dep:reqwest", "dep:flate2", "dep:lz4_flex", "dep:zstd", "dep:percent-encoding"]
406
+ # Generic bulk document sink over HTTP (search engines and similar APIs).
407
+ http-bulk = ["dep:reqwest", "dep:percent-encoding", "dep:flate2", "dep:lz4_flex", "dep:zstd"]
401
408
  # Cloud object-store checkpoint backend (S3/GCS/Azure/R2). Talks cloud REST via reqwest.
402
409
  object-store = ["dep:object_store"]
403
410
  # `format: parquet` on object_store. Column codecs reuse the `compression` crates.
@@ -1,7 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mq-bridge-basic
3
- Version: 0.4.17
3
+ Version: 0.4.19
4
4
  Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: Topic :: Database
7
+ Classifier: Topic :: System :: Networking
8
+ Classifier: Topic :: System :: Distributed Computing
9
+ Classifier: Topic :: Software Development :: Libraries
5
10
  Classifier: License :: OSI Approved :: MIT License
6
11
  Classifier: License :: OSI Approved :: Apache Software License
7
12
  Classifier: Programming Language :: Python :: 3
@@ -24,7 +29,9 @@ Keywords: messaging,tokio,pyo3,maturin,mq-bridge
24
29
  License: MIT OR Apache-2.0
25
30
  Requires-Python: >=3.9
26
31
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
27
- Project-URL: Homepage, https://github.com/marcomq/mq-bridge
32
+ Project-URL: Book, https://marcomq.github.io/mq-bridge/
33
+ Project-URL: Documentation, https://marcomq.github.io/mq-bridge/getting-started/library-quick-start.html
34
+ Project-URL: Homepage, https://marcomq.github.io/mq-bridge/
28
35
  Project-URL: Issues, https://github.com/marcomq/mq-bridge/issues
29
36
  Project-URL: Repository, https://github.com/marcomq/mq-bridge
30
37