urja-client
v0.2.0
Published
Type-safe URL builders + React ThemeProvider for Urja — the Insights by Omkar Visual API. Zero-runtime: every helper returns a cacheable URL ready for <img src>, <link href>, or fetch().
Maintainers
Readme
urja-client
Type-safe URL builders and a React <VisualThemeProvider> for
Urja — the Insights by Omkar Visual API.
Zero runtime fetch. Every helper returns a string URL ready for
<img src>, <link href>, or fetch().
Install
npm install urja-client
# or
pnpm add urja-clientReact is a peer dependency used only by <VisualThemeProvider>. The
URL builders work without React.
URL builders
import {
buildCharacterUrl,
buildSceneUrl,
buildPricingCardUrl,
buildUmbrellaHeroUrl,
buildEffectUrl,
buildIllustrateUrl,
buildPPPBannerUrl,
buildPaletteUrl,
buildTokensUrl,
buildFontsUrl,
buildMotionUrl,
} from "urja-client";
// Character render
const src = buildCharacterUrl({
pose: "listening",
mood: "attentive",
size: 256,
motion: "static",
});
// Pricing-card atmosphere for a /pricing tile
const bg = buildPricingCardUrl({ product: "netra", tier: "max" });
// Umbrella-hero backdrop for the apex pricing page
const hero = buildUmbrellaHeroUrl({ motion: "drift" });
// Pinned token stylesheet
const tokens = buildTokensUrl({
format: "css",
layer: "semantic",
version: "1.4.0",
});
// Staging / local dev
const local = buildCharacterUrl({
baseUrl: "http://localhost:3000",
pose: "resting",
});Every builder accepts an optional baseUrl. Default is the production
host. Undefined / empty option values are dropped from the query string.
React ThemeProvider
import { VisualThemeProvider } from "urja-client";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<VisualThemeProvider
tokensVersion="1.4.0"
tokenLayer="both"
fontFamilies={["display", "sans"]}
motionSet="all"
>
{children}
</VisualThemeProvider>
);
}On mount, <VisualThemeProvider> injects three deduped
<link rel="stylesheet"> tags into document.head:
/api/v1/tokens?format=css&layer=<both|atoms|semantic>[&version=…]/api/v1/fonts?format=css&families=…/api/v1/motion?format=css&set=<base|all|character>
Each link gets a data-tuffys-visual="tokens|fonts|motion" marker so:
- Re-mounting the provider is a no-op (same
hrefis skipped). - Unmounting only removes the links this component added.
- Devtools tell you at a glance what the provider is managing.
The provider is SSR-safe — useEffect runs only on the client. For
above-the-fold work where hydration delay matters, emit matching
<link rel="stylesheet"> tags directly in your document head and
keep the provider — the dedupe keeps things clean.
Imperative injector
Non-React hosts (or one-off scripts):
import { injectVisualTheme } from "urja-client";
const dispose = injectVisualTheme({
baseUrl: "http://localhost:3000",
tokensVersion: "1.4.0",
fontFamilies: ["display", "sans"],
motionSet: "all",
});
// later
dispose();Pinning
Pass tokensVersion to pin the token surface. Supported versions today:
1.0.0·1.1.0·1.2.0·1.3.0·1.4.0
Unknown versions yield a 400 on the initial stylesheet load; the page
falls back to host-defined CSS. Prefer pinning in production — it
insulates you from silent token renames in future surfaces.
Status
v0.1.0 — mirrored from tuffys-visual-api/lib/client/urls.ts.
Ready to publish; the source repo's scaffold stays the canonical
working copy until the package cuts its first public tag.
Publishing
cd packages/urja-client
npm login # once per machine
npm publish --access publicprepublishOnly runs typecheck → test → build — an unclean tree
blocks publish. The publishConfig.access = "public" in
package.json means unscoped packages publish as public (npm's
default for scoped names is private).
License
MIT — see LICENSE.
