Overview
In-house audience & affinity intelligence for AbsoluteJS apps — the ownable parts of what an audience-intelligence SaaS sells, run on your own provider and embedding model.
@absolutejs/audiencev0.0.4alphaCommerce & GrowthPsychographic inference, affinity profiles, and measured audience-overlap scores on your own AI provider.
In-house audience and affinity intelligence — the ownable parts of what an audience-intelligence SaaS sells, run on your own provider and embedding model. Every primitive is a pure function of typed input plus an injected AI call, and affinity work also takes an injected embed call, so the package never picks a provider or an embedding model. Pairs naturally with @absolutejs/partnership, which follows the same injection pattern.
bun add @absolutejs/audienceIn-house audience & affinity intelligence for AbsoluteJS apps — the ownable parts of what an audience-intelligence SaaS sells, run on your own provider and embedding model.
inferPsychographics — communication style, values, and motivations of a
person or brand from public signals (the "how to approach them" layer).
profileAffinity — a structured interest/brand affinity profile, embedded
into a vector.
affinityOverlap — a measured audience-overlap score between two profiles
(cosine of their embedded affinities) plus shared topics/brands. Pure, no model call.
cosineSimilarity — the underlying vector math, exported.
Like @absolutejs/partnership, every primitive is a pure function of typed input plus an injected AI call. Affinity work also takes an injected embed call, so the package never picks a provider or an embedding model — your app supplies both, with its own metering and caching.
For a cheap inline path (no affinity extraction), embed two short descriptor strings yourself and call cosineSimilarity directly.
inferPsychographics derives the communication style, values, and motivations of a person or brand from public signals — the "how to approach them" layer.
profileAffinity extracts a structured interest/brand affinity profile and embeds it into a vector via your injected embed call.
affinityOverlap returns a measured audience-overlap score (cosine of two embedded affinity profiles) plus shared topics and brands — pure, no model call.
Your app supplies generateObject and embed through AudienceContext, keeping provider choice, metering, and caching in your own code.
cosineSimilarity is exported directly for a cheap inline path: embed two short descriptor strings yourself and compare.
Outcomes
In-house audience & affinity intelligence for AbsoluteJS apps — the ownable parts of what an audience-intelligence SaaS sells, run on your own provider and embedding model.
For a cheap inline path (no affinity extraction), embed two short descriptor strings yourself and call cosineSimilarity directly.
Hardening checklist
Follow in order
Working example for Wiring.
import type { AudienceContext, GenerateObject } from "@absolutejs/audience";
import { meteredGenerateObjectAI } from "./usage/meteredAI";
import { aiProvider } from "./integrations/aiProvider";
import { embedTexts } from "./integrations/ragStore";
export const audienceCtx = (userSub?: string | null): AudienceContext => ({
embed: (texts) => embedTexts(texts, "passage"),
generateObject: ((req) =>
meteredGenerateObjectAI({ ...req, provider: aiProvider, userSub })) as GenerateObject,
});Working example for Measuring audience overlap.
import { profileAffinity, affinityOverlap } from "@absolutejs/audience";
const me = await profileAffinity({ name: "Me", signals: { niche, offer } }, audienceCtx());
const them = await profileAffinity({ name: company, signals: { summary, industry } }, audienceCtx());
const { score, sharedTopics, rationale } = affinityOverlap(me, them);
// score ∈ [0,1] — a *measured* overlap to use wherever you'd otherwise
// have an LLM guess (e.g. a Trust & Fit "audience overlap" dimension).Build an AudienceContext from whatever you already use for structured generation and embeddings, extract two affinity profiles, then compare them without another model call.
import type { AudienceContext } from '@absolutejs/audience';
import { affinityOverlap, profileAffinity } from '@absolutejs/audience';
const ctx: AudienceContext = {
embed: (texts) => embedTexts(texts, 'passage'),
generateObject: (req) => generateObjectAI({ ...req, provider })
};
const me = await profileAffinity(
{ name: 'Me', signals: { niche, offer } },
ctx
);
const them = await profileAffinity(
{ name: company, signals: { industry, summary } },
ctx
);
const { rationale, score, sharedTopics } = affinityOverlap(me, them);
// score ∈ [0,1] — a measured overlap, not an LLM guess.Source adapters implement the AudienceSource contract against third-party audience-intelligence APIs (Apache-2.0), putting measured data behind the same interface as the derived, own-it primitives.
Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.
These playbooks show where this package fits, how to verify the combined system, and what changes before production.
Current package surface
Import surface · click to copy