@naniteninja/profile-comparison-lib
v1.0.3
Published
Angular library that renders a side-by-side profile comparison (two profile images, a central draggable shape, and aligned interest lists). It is a **thin client**: you provide a backend URL; the library sends user config to your backend and displays the
Downloads
536
Keywords
Readme
Profile Comparison Library
Angular library that renders a side-by-side profile comparison (two profile images, a central draggable shape, and aligned interest lists). It is a thin client: you provide a backend URL; the library sends user config to your backend and displays the payload it returns. No API keys or key-entry modals in the library.
You need a backend that implements the profile comparison API (e.g. the profile-comparison-server repo). Provide its base URL via PROFILE_COMPARISON_API_BASE_URL. If not provided, the component shows "Configure backend".
Quick start (copy-paste)
1. Install
npm install @naniteninja/profile-comparison-lib @tensorflow/tfjs @tensorflow-models/universal-sentence-encoder2. Wire up the module and backend URL
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import {
ProfileComparisonLibModule,
PROFILE_COMPARISON_API_BASE_URL,
} from '@naniteninja/profile-comparison-lib';
@NgModule({
imports: [HttpClientModule, ProfileComparisonLibModule],
providers: [
{ provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'http://localhost:3000/api' },
],
})
export class AppModule {}3. Add the component to a template
<lib-profile-comparison
[config]="profileConfig"
[fadeAllEdges]="false"
(matrixDataChange)="onMatrixData($event)"
(rawLLMOutputChange)="onRawLLM($event)"
(viewProfileClick)="onViewProfile($event)"
></lib-profile-comparison>4. Provide config data in the component
import { IProfileConfig } from '@naniteninja/profile-comparison-lib';
profileConfig: IProfileConfig = {
person1Interests: [
'Gaming', 'Programming', 'AI/ML', 'Startups',
'Blockchain', 'Cybersecurity', 'Web Development', 'Data Science',
],
person2Interests: [
'AI machine learning', 'Mobile Games', 'Hardware',
'Data Science', 'Entrepreneurship', 'Design Thinking', 'Blockchain',
],
person3Interests: ['Board Games', 'Machine Learning'],
user1Image: './assets/user1.jpg', // data URL or asset path
user2Image: './assets/user2.jpg',
};
onMatrixData(data: any) { console.log('Matrix:', data); }
onRawLLM(raw: string) { console.log('LLM:', raw); }
onViewProfile(e: { side: 'left' | 'right' }) {
console.log('View profile:', e.side);
}5. Start the backend and run
# Terminal 1 — backend (profile-comparison-server repo)
cd ../profile-comparison-server && npm install && npm start
# Terminal 2 — your app
ng serveThe component renders two profile images with a draggable center shape, semantically aligned interest lists on each side, and a "View Profile" link per side. If the backend is unreachable, a "Configure backend" message appears instead.
Quickstart
Install the package and peer dependencies (including TensorFlow; required for Vite and other bundlers):
npm install @naniteninja/profile-comparison-lib @angular/core@^20 @angular/common@^20 @tensorflow/tfjs @tensorflow-models/universal-sentence-encoderProvide the backend URL
In
app.config.ts(orAppModule):import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib'; providers: [ { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' }, ]Or with a factory (e.g. runtime toggle between backends):
providers: [{ provide: PROFILE_COMPARISON_API_BASE_URL, useFactory: (backendUrl: BackendUrlService) => () => backendUrl.getBaseUrl(), deps: [BackendUrlService], }]Use the component
Import the module and add the component to a template:
import { ProfileComparisonLibModule } from '@naniteninja/profile-comparison-lib';<lib-profile-comparison [config]="config"></lib-profile-comparison>
What the element looks like
When you use <lib-profile-comparison> in another Angular app you get:
- Side-by-side profile comparison: two profile images (left and right) with a central draggable “shape” and aligned interest lists between them.
- Main regions: left image, right image, center shape with text, loading indicator when a request is in progress.
- Action: “View Profile” on each side; the component emits
viewProfileClickwith{ side: 'left' | 'right' }so the host can route or act.
No key-entry modals or API key inputs appear in the library; all keys and third-party API calls live on your backend.
Full setup (copy-paste)
Create or open an Angular app (Angular ^20.0.0).
Install the library and peer dependencies (TensorFlow is required for dependency optimization in Vite etc.):
npm install @naniteninja/profile-comparison-lib @angular/core@^20 @angular/common@^20 @tensorflow/tfjs @tensorflow-models/universal-sentence-encoderAdd the backend URL provider in
app.config.ts:import { ApplicationConfig } from '@angular/core'; import { provideHttpClient } from '@angular/common/http'; import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib'; export const appConfig: ApplicationConfig = { providers: [ provideHttpClient(), { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' }, ], };Or in
AppModule:import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib'; @NgModule({ providers: [ { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' }, ], }) export class AppModule {}Import the module where you use the component:
import { ProfileComparisonLibModule } from '@naniteninja/profile-comparison-lib'; @NgModule({ imports: [ProfileComparisonLibModule, ...], }) export class YourModule {}Add the component to a template with required
[config]:<lib-profile-comparison [config]="config" [fadeAllEdges]="fadeAllEdges" (matrixDataChange)="onMatrixData($event)" (rawLLMOutputChange)="onRawLLMOutput($event)" (viewProfileClick)="onViewProfile($event)" ></lib-profile-comparison>Run the app and ensure your backend is reachable at the URL you provided.
Inputs and outputs
Inputs
config(required) —IProfileConfig:{ "person1Interests": ["Gaming", "Programming", "AI/ML"], "person2Interests": ["AI machine learning", "Mobile Games", "Data Science"], "person3Interests": ["Board Games", "Machine Learning"], "user1Image": "data:image/jpeg;base64,...", "user2Image": "data:image/jpeg;base64,..." }user1Imageanduser2Imagecan be data URLs or URLs; the library sends them to the backend as needed.fadeAllEdges(optional) —boolean, defaultfalse. When true, fades the outer edges of the profile area.
Outputs
matrixDataChange—IMatrixData: legend, headers, and rows for the similarity matrix.Example payload:
{ "legend": [{ "abbr": "Gam", "full": "Gaming" }, { "abbr": "Pro", "full": "Programming" }], "headers": ["Gam", "Pro", "AI/ML"], "rows": [ { "label": "Gam", "values": ["1.00", "0.2", "0.5"] }, { "label": "Pro", "values": ["0.2", "1.00", "0.8"] } ] }rawLLMOutputChange—string: raw LLM output from the backend (if any).viewProfileClick—{ side: 'left' | 'right' }: emitted when the user clicks “View Profile” on the left or right side. Use this to navigate or open a profile page.Example:
onViewProfile(payload: { side: 'left' | 'right' }) { this.router.navigate(['/profile', payload.side]); }
Backend API contract
The library calls your backend at POST {baseUrl}/profile/compare-full with body { config: IProfileConfig }. The backend should return a display payload (face results, aligned lists, center item, matrix data, raw LLM output). See the profile-comparison-server repo and the lib interface IComparisonPayload for the response shape.
Building the library
ng build profile-comparison-libOutput is in dist/profile-comparison-lib/ (FESM, typings, package.json). Peer dependencies: Angular ^20.0.0 and TensorFlow (@tensorflow/tfjs, @tensorflow-models/universal-sentence-encoder).
