npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@voyant-travel/commerce

v0.19.0

Published

`@voyant-travel/commerce` defines the narrow commercial decision Interface and owns the quote-time markets, pricing, promotions, and sellability runtime sources.

Readme

Commerce

@voyant-travel/commerce defines the narrow commercial decision Interface and owns the quote-time markets, pricing, promotions, and sellability runtime sources.

The root call is:

const decision = await evaluator.evaluateCommercialDecision(input)

The question it answers is: can this buyer or channel buy this Catalog Item or vertical item, for this date, party, market, channel, and currency, and at what price?

Public Surface

The package intentionally exposes the Commerce Interface from the root:

  • createCommercialDecisionEvaluator(...)
  • evaluateCommercialDecision(input, context)
  • createCommerceAdapterRegistry(...)
  • recordCommercialSnapshot(decision, target, repository)
  • createCommerceHonoModules()
  • createCommerceStorefrontOfferResolvers()
  • decision, adapter, trace, pricing, promotion, FX, and snapshot types

Pricing, markets, promotions, and sellability source folders are internal organization behind the root Commerce API. Public runtime consumers import from @voyant-travel/commerce or @voyant-travel/commerce/schema.

React/admin consumers should prefer @voyant-travel/commerce-react for Commerce-owned UI wiring. That package owns the reusable Markets, Pricing, Promotions, and Sellability React/admin source under owner-path subpaths:

  • @voyant-travel/commerce-react/markets
  • @voyant-travel/commerce-react/pricing
  • @voyant-travel/commerce-react/promotions
  • @voyant-travel/commerce-react/promotions/admin
  • @voyant-travel/commerce-react/sellability

Runtime Mounting

Templates should declare one Commerce runtime entry and expand it through createCommerceHonoModules():

const modules = createCommerceHonoModules()

The returned modules preserve the existing route prefixes:

  • /v1/pricing and /v1/public/pricing
  • /v1/markets
  • /v1/sellability
  • /v1/admin/promotions

This keeps route compatibility while moving template runtime wiring to the Commerce Module.

Input

CommercialDecisionInput carries:

  • item: a Catalog Item or vertical item reference. Operated inventory and sourced verticals both enter Commerce through this item reference.
  • date: the local service date being priced and sold.
  • party: traveler counts and optional unit counts.
  • currency: requested sell currency.
  • market, channel, and buyer: commercial context.
  • promotionCodes: requested promotion codes.
  • idempotencyKey: optional caller key used to replay the same decision or snapshot target without minting conflicting evidence. When supplied, Commerce derives the decision id from this key instead of the evaluation clock.
  • requestedAt: optional clock value for deterministic evaluation tests and replay.

Output

CommercialDecision returns:

  • status and buyable: buyable, unbuyable, or error.
  • reason: canonical unbuyable or error code and details.
  • pricing: currency, minor-unit totals, components, tax/fee facts, and source price facts.
  • fx: requested currency, source currency, rate, rate set, and provider handle when conversion was applied.
  • promotions: applied and rejected promotions, requested codes, total discount, and stacking facts.
  • availability and sellability: capacity and policy facts supplied by the selected adapter.
  • traces: applied, skipped, blocked, and error rule traces. Rule ids, market facts, promotion ids, FX facts, and adapter calls belong here.
  • handles: adapter, provider, source, live quote, offer, or reservation handles. Commerce records these handles but does not import source-native fare tables.
  • validFrom and validUntil: validity bounds for using the decision.

Error Modes

Unsupported items return an unbuyable decision with unsupported_item. Commerce did not find a registered adapter for the item.

Adapter lookup ambiguity returns an error decision with adapter_ambiguous. Registry misuse, such as duplicate adapter ids, throws CommercialDecisionError during registration.

Adapter execution failures return an error decision with adapter_failed. The decision includes the selected adapter handle and an error trace.

Malformed adapter output returns an error decision with adapter_invalid_result. A buyable decision must include pricing facts.

Side Effects

evaluateCommercialDecision is side-effect-free from Commerce's perspective. It may call registered adapters, and those adapters may read operational or source state, but the call must not create offers, orders, reservations, holds, snapshots, ledgers, or audit records.

Persisted evidence is explicit:

await recordCommercialSnapshot(decision, target, repository)

The snapshot repository owns writes and idempotency enforcement for its storage backend. Commerce passes the decision, target, and idempotency key through a separate snapshot command instead of writing during evaluation.

Adapter Registration

Optional Inventory, vertical modules, and source integrations register price-availability adapters at boot:

const evaluator = createCommercialDecisionEvaluator()

evaluator.registerPriceAvailabilityAdapter(operatedInventoryAdapter)
evaluator.registerPriceAvailabilityAdapter(cruiseSourceAdapter)

An adapter declares id, kind, supports(input), and evaluate(input, context). Inventory is just another adapter kind; Commerce does not depend on Product or Inventory schemas to evaluate sourced or vertical items.