@naniteninja/profile-comparison-lib 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Profile Comparison Library
2
2
 
3
- 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.
3
+ Angular library that renders a side-by-side profile comparison (two profile images, a central draggable shape, and semantically aligned interest lists). It is a **thin client** the library sends user config to a backend and displays the payload it returns. No API keys or key-entry modals live in the library.
4
4
 
5
- **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"**.
5
+ **You need a backend** that implements the profile comparison API (e.g. the **profile-comparison-server** repo). By default the component points at the real deployed backend. Set `[backendMode]="BackendMode.Mock"` to use `localhost:3000` during development.
6
6
 
7
7
  ---
8
8
 
@@ -11,255 +11,150 @@ Angular library that renders a side-by-side profile comparison (two profile imag
11
11
  ### 1. Install
12
12
 
13
13
  ```bash
14
- npm install @naniteninja/profile-comparison-lib @tensorflow/tfjs @tensorflow-models/universal-sentence-encoder
14
+ npm install @naniteninja/profile-comparison-lib
15
15
  ```
16
16
 
17
- ### 2. Wire up the module and backend URL
17
+ ### 2. Wire up the module
18
18
 
19
19
  ```typescript
20
20
  import { NgModule } from '@angular/core';
21
21
  import { HttpClientModule } from '@angular/common/http';
22
- import {
23
- ProfileComparisonLibModule,
24
- PROFILE_COMPARISON_API_BASE_URL,
25
- } from '@naniteninja/profile-comparison-lib';
22
+ import { ProfileComparisonLibModule } from '@naniteninja/profile-comparison-lib';
26
23
 
27
24
  @NgModule({
28
25
  imports: [HttpClientModule, ProfileComparisonLibModule],
29
- providers: [
30
- { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'http://localhost:3000/api' },
31
- ],
32
26
  })
33
27
  export class AppModule {}
34
28
  ```
35
29
 
36
30
  ### 3. Add the component to a template
37
31
 
32
+ Minimal — uses the real deployed backend with all edges faded:
33
+
34
+ ```html
35
+ <lib-profile-comparison [config]="profileConfig"></lib-profile-comparison>
36
+ ```
37
+
38
+ During development, point at a local backend:
39
+
40
+ ```html
41
+ <lib-profile-comparison
42
+ [config]="profileConfig"
43
+ [backendMode]="BackendMode.Mock"
44
+ ></lib-profile-comparison>
45
+ ```
46
+
47
+ Or supply a fully custom URL (overrides `backendMode`):
48
+
38
49
  ```html
39
50
  <lib-profile-comparison
40
51
  [config]="profileConfig"
41
- [fadeAllEdges]="false"
52
+ [backendUrl]="'https://my-custom-api.example.com/api'"
53
+ ></lib-profile-comparison>
54
+ ```
55
+
56
+ Full example with all inputs and outputs:
57
+
58
+ ```html
59
+ <lib-profile-comparison
60
+ [config]="profileConfig"
61
+ [backendMode]="backendMode"
62
+ [backendUrl]="customUrl"
63
+ [fadeAllEdges]="true"
42
64
  (matrixDataChange)="onMatrixData($event)"
43
65
  (rawLLMOutputChange)="onRawLLM($event)"
44
66
  (viewProfileClick)="onViewProfile($event)"
45
67
  ></lib-profile-comparison>
46
68
  ```
47
69
 
48
- ### 4. Provide config data in the component
70
+ ### 4. Component class
49
71
 
50
72
  ```typescript
51
- import { IProfileConfig } from '@naniteninja/profile-comparison-lib';
52
-
53
- profileConfig: IProfileConfig = {
54
- person1Interests: [
55
- 'Gaming', 'Programming', 'AI/ML', 'Startups',
56
- 'Blockchain', 'Cybersecurity', 'Web Development', 'Data Science',
57
- ],
58
- person2Interests: [
59
- 'AI machine learning', 'Mobile Games', 'Hardware',
60
- 'Data Science', 'Entrepreneurship', 'Design Thinking', 'Blockchain',
61
- ],
62
- person3Interests: ['Board Games', 'Machine Learning'],
63
- user1Image: './assets/user1.jpg', // data URL or asset path
64
- user2Image: './assets/user2.jpg',
65
- };
66
-
67
- onMatrixData(data: any) { console.log('Matrix:', data); }
68
- onRawLLM(raw: string) { console.log('LLM:', raw); }
69
- onViewProfile(e: { side: 'left' | 'right' }) {
70
- console.log('View profile:', e.side);
73
+ import { Component } from '@angular/core';
74
+ import { IProfileConfig, IMatrixData, BackendMode } from '@naniteninja/profile-comparison-lib';
75
+
76
+ @Component({ /* ... */ })
77
+ export class AppComponent {
78
+ readonly BackendMode = BackendMode; // expose enum to template
79
+
80
+ backendMode = BackendMode.Real;
81
+ customUrl: string | null = null;
82
+
83
+ profileConfig: IProfileConfig = {
84
+ person1Interests: [
85
+ 'Gaming', 'Programming', 'AI/ML', 'Startups',
86
+ 'Blockchain', 'Cybersecurity', 'Web Development', 'Data Science',
87
+ ],
88
+ person2Interests: [
89
+ 'AI machine learning', 'Mobile Games', 'Hardware',
90
+ 'Data Science', 'Entrepreneurship', 'Design Thinking', 'Blockchain',
91
+ ],
92
+ person3Interests: ['Board Games', 'Machine Learning'],
93
+ user1Image: './assets/user1.jpg', // data-URL or asset path
94
+ user2Image: './assets/user2.jpg',
95
+ };
96
+
97
+ onMatrixData(data: IMatrixData) { console.log('Matrix:', data); }
98
+ onRawLLM(raw: string) { console.log('LLM:', raw); }
99
+ onViewProfile(e: { side: 'left' | 'right' }) {
100
+ console.log('View profile:', e.side);
101
+ }
71
102
  }
72
103
  ```
73
104
 
74
- ### 5. Start the backend and run
105
+ ### 5. Run
75
106
 
76
107
  ```bash
77
- # Terminal 1 — backend (profile-comparison-server repo)
78
- cd ../profile-comparison-server && npm install && npm start
79
-
80
- # Terminal 2 — your app
81
108
  ng serve
82
109
  ```
83
110
 
84
- The 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.
85
-
86
- ---
87
-
88
- ## Quickstart
89
-
90
- 1. **Install the package and peer dependencies** (including TensorFlow; required for Vite and other bundlers):
91
-
92
- ```bash
93
- npm install @naniteninja/profile-comparison-lib @angular/core@^20 @angular/common@^20 @tensorflow/tfjs @tensorflow-models/universal-sentence-encoder
94
- ```
95
-
96
- 2. **Provide the backend URL**
97
-
98
- In `app.config.ts` (or `AppModule`):
99
-
100
- ```typescript
101
- import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib';
102
-
103
- providers: [
104
- { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' },
105
- ]
106
- ```
107
-
108
- Or with a factory (e.g. runtime toggle between backends):
109
-
110
- ```typescript
111
- providers: [{
112
- provide: PROFILE_COMPARISON_API_BASE_URL,
113
- useFactory: (backendUrl: BackendUrlService) => () => backendUrl.getBaseUrl(),
114
- deps: [BackendUrlService],
115
- }]
116
- ```
117
-
118
- 3. **Use the component**
119
-
120
- Import the module and add the component to a template:
121
-
122
- ```typescript
123
- import { ProfileComparisonLibModule } from '@naniteninja/profile-comparison-lib';
124
- ```
111
+ If using `BackendMode.Mock`, start the local backend first:
125
112
 
126
- ```html
127
- <lib-profile-comparison [config]="config"></lib-profile-comparison>
128
- ```
129
-
130
- ---
131
-
132
- ## What the element looks like
133
-
134
- When you use `<lib-profile-comparison>` in another Angular app you get:
135
-
136
- - **Side-by-side profile comparison**: two profile images (left and right) with a central draggable “shape” and aligned interest lists between them.
137
- - **Main regions**: left image, right image, center shape with text, loading indicator when a request is in progress.
138
- - **Action**: “View Profile” on each side; the component emits `viewProfileClick` with `{ side: 'left' | 'right' }` so the host can route or act.
139
-
140
- No key-entry modals or API key inputs appear in the library; all keys and third-party API calls live on your backend.
141
-
142
- ---
143
-
144
- ## Full setup (copy-paste)
145
-
146
- 1. Create or open an Angular app (Angular ^20.0.0).
147
-
148
- 2. Install the library and peer dependencies (TensorFlow is required for dependency optimization in Vite etc.):
149
-
150
- ```bash
151
- npm install @naniteninja/profile-comparison-lib @angular/core@^20 @angular/common@^20 @tensorflow/tfjs @tensorflow-models/universal-sentence-encoder
152
- ```
153
-
154
- 3. Add the backend URL provider in `app.config.ts`:
155
-
156
- ```typescript
157
- import { ApplicationConfig } from '@angular/core';
158
- import { provideHttpClient } from '@angular/common/http';
159
- import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib';
160
-
161
- export const appConfig: ApplicationConfig = {
162
- providers: [
163
- provideHttpClient(),
164
- { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' },
165
- ],
166
- };
167
- ```
168
-
169
- Or in `AppModule`:
170
-
171
- ```typescript
172
- import { PROFILE_COMPARISON_API_BASE_URL } from '@naniteninja/profile-comparison-lib';
173
-
174
- @NgModule({
175
- providers: [
176
- { provide: PROFILE_COMPARISON_API_BASE_URL, useValue: 'https://your-backend.com/api' },
177
- ],
178
- })
179
- export class AppModule {}
180
- ```
181
-
182
- 4. Import the module where you use the component:
183
-
184
- ```typescript
185
- import { ProfileComparisonLibModule } from '@naniteninja/profile-comparison-lib';
186
-
187
- @NgModule({
188
- imports: [ProfileComparisonLibModule, ...],
189
- })
190
- export class YourModule {}
191
- ```
192
-
193
- 5. Add the component to a template with required `[config]`:
194
-
195
- ```html
196
- <lib-profile-comparison
197
- [config]="config"
198
- [fadeAllEdges]="fadeAllEdges"
199
- (matrixDataChange)="onMatrixData($event)"
200
- (rawLLMOutputChange)="onRawLLMOutput($event)"
201
- (viewProfileClick)="onViewProfile($event)"
202
- ></lib-profile-comparison>
203
- ```
204
-
205
- 6. Run the app and ensure your backend is reachable at the URL you provided.
113
+ ```bash
114
+ cd ../profile-comparison-server && npm install && npm start # listens on :3000
115
+ ```
206
116
 
207
117
  ---
208
118
 
209
- ## Inputs and outputs
119
+ ## Inputs
210
120
 
211
- ### Inputs
121
+ | Input | Type | Default | Description |
122
+ |-------|------|---------|-------------|
123
+ | `config` | `IProfileConfig` | *required* | Profile data (interests, images) for the comparison. |
124
+ | `backendMode` | `BackendMode` | `BackendMode.Real` (0) | `Real` = deployed backend, `Mock` = `localhost:3000`. |
125
+ | `backendUrl` | `string \| null` | `null` | When non-empty, overrides `backendMode` entirely. |
126
+ | `fadeAllEdges` | `boolean` | `true` | Fade the outer edges of the profile area. |
212
127
 
213
- - **`config`** (required) — `IProfileConfig`:
128
+ ## Outputs
214
129
 
215
- ```json
216
- {
217
- "person1Interests": ["Gaming", "Programming", "AI/ML"],
218
- "person2Interests": ["AI machine learning", "Mobile Games", "Data Science"],
219
- "person3Interests": ["Board Games", "Machine Learning"],
220
- "user1Image": "data:image/jpeg;base64,...",
221
- "user2Image": "data:image/jpeg;base64,..."
222
- }
223
- ```
130
+ All outputs are optional — bind only what you need.
224
131
 
225
- `user1Image` and `user2Image` can be data URLs or URLs; the library sends them to the backend as needed.
132
+ | Output | Type | Description |
133
+ |--------|------|-------------|
134
+ | `matrixDataChange` | `IMatrixData` | Legend, headers, and rows for the similarity matrix. |
135
+ | `rawLLMOutputChange` | `string` | Raw LLM output from the backend (if any). |
136
+ | `viewProfileClick` | `{ side: 'left' \| 'right' }` | Emitted when the user clicks "View Profile". |
226
137
 
227
- - **`fadeAllEdges`** (optional) — `boolean`, default `false`. When true, fades the outer edges of the profile area.
138
+ ## BackendMode enum
228
139
 
229
- ### Outputs
230
-
231
- - **`matrixDataChange`** — `IMatrixData`: legend, headers, and rows for the similarity matrix.
232
-
233
- Example payload:
234
-
235
- ```json
236
- {
237
- "legend": [{ "abbr": "Gam", "full": "Gaming" }, { "abbr": "Pro", "full": "Programming" }],
238
- "headers": ["Gam", "Pro", "AI/ML"],
239
- "rows": [
240
- { "label": "Gam", "values": ["1.00", "0.2", "0.5"] },
241
- { "label": "Pro", "values": ["0.2", "1.00", "0.8"] }
242
- ]
243
- }
244
- ```
245
-
246
- - **`rawLLMOutputChange`** — `string`: raw LLM output from the backend (if any).
140
+ ```typescript
141
+ import { BackendMode } from '@naniteninja/profile-comparison-lib';
247
142
 
248
- - **`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.
143
+ BackendMode.Real // 0deployed backend (default)
144
+ BackendMode.Mock // 1 — localhost:3000
145
+ ```
249
146
 
250
- Example:
147
+ ### URL resolution priority
251
148
 
252
- ```typescript
253
- onViewProfile(payload: { side: 'left' | 'right' }) {
254
- this.router.navigate(['/profile', payload.side]);
255
- }
256
- ```
149
+ 1. `backendUrl` input (if non-empty)
150
+ 2. `backendMode` enum mapping
151
+ 3. Legacy `PROFILE_COMPARISON_API_BASE_URL` injection token (backward compatible)
257
152
 
258
153
  ---
259
154
 
260
155
  ## Backend API contract
261
156
 
262
- 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.
157
+ The library calls `POST {baseUrl}/profile/compare-full` with body `{ config: IProfileConfig }`. The backend returns a display payload (face results, aligned lists, center item, matrix data, raw LLM output). See the **profile-comparison-server** repo and the `IComparisonPayload` interface for the response shape.
263
158
 
264
159
  ---
265
160
 
@@ -269,4 +164,4 @@ The library calls your backend at `POST {baseUrl}/profile/compare-full` with bod
269
164
  ng build profile-comparison-lib
270
165
  ```
271
166
 
272
- Output 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`).
167
+ Output is in `dist/profile-comparison-lib/` (FESM bundles, typings, package.json). Peer dependencies: Angular `^20.0.0`.