Skip to content

SQLite contract

Knocker’s language bindings are thin runtime surfaces over the same loadable SQLite extension. Curated receive(...) calls delegate to shared Rust/SQLite code, and queue/lifecycle operations go through SQLite functions exposed by the extension.

This page is the contract underneath the bindings. You usually do not need to write raw SQL in app code, but it is useful for understanding, debugging, and proving that every binding is doing the same thing.

.load ./target/release/libknocker_ext
SELECT knocker_bootstrap();
SELECT knocker_endpoint_upsert(
'stripe',
'/webhooks/stripe',
'stripe',
1
);
SELECT knocker_receive(
'stripe',
'stripe',
json_array('whsec_...'),
json_object('tolerance_s', 300),
'POST',
:headers_json,
:body_blob,
:query_json,
NULL,
NULL,
NULL,
NULL,
'knocker.events',
3
) AS result_json;

result_json contains the verification and storage outcome, including the HTTP status code your route should return.

FunctionPurpose
knocker_bootstrap()Creates Knocker and Honker tables in the current SQLite database.
knocker_endpoint_upsert(name, path, provider, enabled)Registers or updates an endpoint row.
knocker_receive(...)Verifies a curated provider request, stores a delivery, and creates/correlates an event.
knocker_ingest(...)Stores a trusted delivery when verification happened elsewhere.
knocker_mark_processing(event_id, attempt_count)Moves an event into processing during a worker transaction.
knocker_mark_handled(event_id, duration_ms)Marks an event handled and records attempt history.
knocker_mark_failed(event_id, attempt_count, error, terminal, duration_ms)Records retry/dead-letter state after a handler failure.
knocker_mark_ignored(event_id, duration_ms)Operator-ignore transition.
knocker_replay(event_id, queue_name, max_attempts)Re-enqueues a handled event using its canonical event body.
knocker_requeue(event_id, queue_name, max_attempts)Re-enqueues failed, dead, or ignored events.
knocker_prune_events(statuses_json, older_than, limit, queue_name)Bounded event pruning with audit rows.
knocker_prune_orphan_deliveries(older_than, limit, queue_name)Bounded orphan delivery pruning with audit rows.
knocker_run_retention_pass(...)One bounded retention pass for events and orphan deliveries.

Worker claiming and acknowledgement use Honker functions such as honker_claim_batch(...), honker_ack(...), honker_retry(...), and honker_fail(...). Bindings wrap those with endpoint/event-type handler dispatch, rollback behavior, and long-running worker loops.

Every binding in this section proves the same SQLite-contract baseline:

  • open/bootstrap
  • endpoint registration
  • trusted ingest
  • provider-verified receive(...) for curated providers through the shared SQLite extension
  • endpoint and event-type-specific handler registration, with endpoint fallback
  • one-shot and long-running worker-processing paths
  • handler access to the same SQLite transaction used for Knocker’s event transition and queue acknowledgement
  • handler-failure rollback before retry/dead-letter bookkeeping
  • get_event
  • list_events
  • delivery reads
  • replay
  • requeue
  • ignore
  • replay_delivery
  • retention pass/loop helpers
  • prune/audit reads

Bindings load or package the Knocker SQLite extension directly. They are not framework adapters and they do not wrap separate Honker language packages; queue operations go through shared SQLite functions exposed by the extension.

Curated provider names are the same across bindings: stripe, github, shopify, slack, postmark, resend, paddle, lemon-squeezy, standard-webhooks, clerk, twilio, sendgrid, linear, meta, discord, zendesk, intercom, hubspot, token-header, bearer-token, and basic-auth. See Verified ingress for provider-specific options and caveats.

Repo-level commands:

Terminal window
make test-node
make test-bun
make test-go
make test-elixir
make test-python
make test-ruby

make test runs the full Rust, Bun, Elixir, Go, Node, Python, and Ruby suite together.