@merchbase/http-client
v7.0.0
Published
Typed tRPC client for MerchBase Core
Readme
@merchbase/http-client
Typed tRPC client for MerchBase Core.
Usage
import {
createMerchbaseClient,
createMerchbaseRealtimeClient,
} from '@merchbase/http-client';
const client = createMerchbaseClient({
baseUrl: 'http://localhost:8080',
apiKey: 'mb_live_xxx',
});
const products = await client.products.search.query({
query: 'cat shirt',
exactFilters: {
marketplace: { in: ['US', 'GB'] },
status: { in: ['LIVE'], notIn: ['REJECTED'] },
},
limit: 25,
offset: 0,
});Read durable history, then continue without a list/subscribe gap:
Event names use product.* for seller product and commercial facts and
system.* for Core, account, sync, and operation history.
const page = await client.events.list.query({
types: [
'product.sale.recorded',
'product.sale.reversed',
'product.details-changed',
'product.status-changed',
],
limit: 50,
});
const realtime = createMerchbaseRealtimeClient({
baseUrl: 'http://localhost:8080',
apiKey: 'mb_live_xxx',
});
const stopEvents = realtime.events.watch(
{ cursor: page.watchCursor },
{
onData: (event) => {
// Delivery is at least once. Persist cursor and upsert by stable event.id.
// Product change events use schemaVersion 1 and typed previous/current values.
console.log(event.cursor, event.type, event.payload);
},
},
);
stopEvents();
await realtime.close();The websocket client uses tracked cursors on reconnect and suppresses recently replayed event ids with bounded memory. Cursors are opaque; store and return them unchanged.
On Node runtimes without a global WebSocket, pass a compatible implementation
through the realtime client's WebSocket option. The MerchBase CLI supplies
its declared Node implementation automatically.
Request a product thumbnail and subscribe for the Core websocket update:
const thumbnailRealtime = createMerchbaseRealtimeClient({
baseUrl: 'http://localhost:8080',
apiKey: 'mb_live_xxx',
});
const unsubscribe = thumbnailRealtime.products.thumbnails.watch(
{},
{
onData: (event) => {
console.log(event.thumbnailState, event.thumbnailUrl);
},
},
);
const product = await client.products.get.query({
asin: 'B000TEST',
marketplace: 'US',
requestThumbnail: true,
});
unsubscribe();
await thumbnailRealtime.close();Repo smoke test:
MERCHBASE_API_KEY=mb_live_xxx \
MERCHBASE_PRODUCT_ASIN=B000TEST \
MERCHBASE_MARKETPLACE=US \
bun run scripts/smoke-product-thumbnail.tsCheck the shared readiness gate before calling endpoints that depend on synced setup data:
import {
getPublicApiReadiness,
getPublicApiReadinessGate,
} from '@merchbase/http-client';
const setup = await client.setup.status.query();
const gate = getPublicApiReadinessGate('api.public.products.sync');
if (gate) {
const readiness = getPublicApiReadiness({
path: 'api.public.products.sync',
setupStatus: setup,
});
}