@shipdit/convex
v0.2.0
Published
Shipd feature flags for Convex
Maintainers
Readme
@shipdit/convex
Convex component for evaluating shipd flags from a durable, reactive snapshot cache.
Install
pnpm add @shipdit/convexMount one named component instance per shipd environment:
import shipd from '@shipdit/convex/convex.config.js';
import { defineApp } from 'convex/server';
import { v } from 'convex/values';
const app = defineApp({
env: {
SHIPD_SDK_KEY: v.string(),
SHIPD_WEBHOOK_SECRET: v.string(),
SHIPD_UNSAFE_EDGE_URL: v.optional(v.string()), // Development/test only; leave unset in production.
},
});
app.use(shipd, {
name: 'shipd',
httpPrefix: '/shipd',
env: {
SHIPD_SDK_KEY: app.env.SHIPD_SDK_KEY,
SHIPD_WEBHOOK_SECRET: app.env.SHIPD_WEBHOOK_SECRET,
SHIPD_UNSAFE_EDGE_URL: app.env.SHIPD_UNSAFE_EDGE_URL,
},
});
export default app;The component fetches snapshots from https://edge.useshipd.com. The optional
SHIPD_UNSAFE_EDGE_URL env var replaces that origin for shipd development and
test environments only; it receives your SDK key, so never set it in production.
The mount above declares it in defineApp and forwards it through app.use;
both are required for a deployment variable to reach the component.
Configure shipd's snapshot webhook destination as
https://<deployment>.convex.site/shipd/webhook. Webhooks trigger an ETag-aware
refresh; a one-minute component cron provides fallback delivery.
Create a typed host helper with concrete defaults:
import { Shipd } from '@shipdit/convex';
import { components } from './_generated/api.js';
type Flags = {
checkout: { type: 'boolean'; default: false };
};
export const shipd = new Shipd<Flags>(components.shipd, {
checkout: false,
});Call the helper only from host queries/actions that have performed the
application's own authorization checks. Component functions don't inherit host
ctx.auth.
The cache never replaces a valid snapshot with a malformed or older response.
Snapshot requests time out after ten seconds. After refresh failures,
evaluations continue from the last good snapshot and status reports
stale: true. Before the first valid snapshot, and for missing or
type-mismatched flags, evaluations return the helper's configured default.
Tests using convex-test can register the component through:
import shipdTest from '@shipdit/convex/test';
shipdTest.register(t);Local example
This is not part of the monorepo pnpm dev / mise run dev servers. From the
repo root:
pnpm --filter @shipdit/convex dev:convexThat builds the package, then runs convex dev against example/convex. Set
CONVEX_DEPLOYMENT in packages/convex/.env.local (usually created by the
Convex CLI) and provide the example env vars:
npx convex env set SHIPD_SDK_KEY shipd_sdk_...
npx convex env set SHIPD_WEBHOOK_SECRET replace-after-dashboard-setupThe webhook URL is https://<deployment>.convex.site/shipd/webhook.
