@naniteninja/profile-comparison-lib 1.0.3 → 1.0.6
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 +167 -272
- package/fesm2022/naniteninja-profile-comparison-lib.mjs +352 -1039
- package/fesm2022/naniteninja-profile-comparison-lib.mjs.map +1 -1
- package/index.d.ts +77 -75
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -1,272 +1,167 @@
|
|
|
1
|
-
# Profile Comparison Library
|
|
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
|
|
4
|
-
|
|
5
|
-
**You need a backend** that implements the profile comparison API (e.g. the **profile-comparison-server** repo).
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Quick start (copy-paste)
|
|
10
|
-
|
|
11
|
-
### 1. Install
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install @naniteninja/profile-comparison-lib
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### 2. Wire up the module
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
import { NgModule } from '@angular/core';
|
|
21
|
-
import { HttpClientModule } from '@angular/common/http';
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
]
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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.
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
## Inputs and outputs
|
|
210
|
-
|
|
211
|
-
### Inputs
|
|
212
|
-
|
|
213
|
-
- **`config`** (required) — `IProfileConfig`:
|
|
214
|
-
|
|
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
|
-
```
|
|
224
|
-
|
|
225
|
-
`user1Image` and `user2Image` can be data URLs or URLs; the library sends them to the backend as needed.
|
|
226
|
-
|
|
227
|
-
- **`fadeAllEdges`** (optional) — `boolean`, default `false`. When true, fades the outer edges of the profile area.
|
|
228
|
-
|
|
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).
|
|
247
|
-
|
|
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.
|
|
249
|
-
|
|
250
|
-
Example:
|
|
251
|
-
|
|
252
|
-
```typescript
|
|
253
|
-
onViewProfile(payload: { side: 'left' | 'right' }) {
|
|
254
|
-
this.router.navigate(['/profile', payload.side]);
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
## Backend API contract
|
|
261
|
-
|
|
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.
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
## Building the library
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
ng build profile-comparison-lib
|
|
270
|
-
```
|
|
271
|
-
|
|
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`).
|
|
1
|
+
# Profile Comparison Library
|
|
2
|
+
|
|
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
|
+
|
|
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
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Quick start (copy-paste)
|
|
10
|
+
|
|
11
|
+
### 1. Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @naniteninja/profile-comparison-lib
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 2. Wire up the module
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { NgModule } from '@angular/core';
|
|
21
|
+
import { HttpClientModule } from '@angular/common/http';
|
|
22
|
+
import { ProfileComparisonLibModule } from '@naniteninja/profile-comparison-lib';
|
|
23
|
+
|
|
24
|
+
@NgModule({
|
|
25
|
+
imports: [HttpClientModule, ProfileComparisonLibModule],
|
|
26
|
+
})
|
|
27
|
+
export class AppModule {}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 3. Add the component to a template
|
|
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
|
+
|
|
49
|
+
```html
|
|
50
|
+
<lib-profile-comparison
|
|
51
|
+
[config]="profileConfig"
|
|
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"
|
|
64
|
+
(matrixDataChange)="onMatrixData($event)"
|
|
65
|
+
(rawLLMOutputChange)="onRawLLM($event)"
|
|
66
|
+
(viewProfileClick)="onViewProfile($event)"
|
|
67
|
+
></lib-profile-comparison>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 4. Component class
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
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
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 5. Run
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
ng serve
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
If using `BackendMode.Mock`, start the local backend first:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
cd ../profile-comparison-server && npm install && npm start # listens on :3000
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Inputs
|
|
120
|
+
|
|
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. |
|
|
127
|
+
|
|
128
|
+
## Outputs
|
|
129
|
+
|
|
130
|
+
All outputs are optional — bind only what you need.
|
|
131
|
+
|
|
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". |
|
|
137
|
+
|
|
138
|
+
## BackendMode enum
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { BackendMode } from '@naniteninja/profile-comparison-lib';
|
|
142
|
+
|
|
143
|
+
BackendMode.Real // 0 — deployed backend (default)
|
|
144
|
+
BackendMode.Mock // 1 — localhost:3000
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### URL resolution priority
|
|
148
|
+
|
|
149
|
+
1. `backendUrl` input (if non-empty)
|
|
150
|
+
2. `backendMode` enum mapping
|
|
151
|
+
3. Legacy `PROFILE_COMPARISON_API_BASE_URL` injection token (backward compatible)
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Backend API contract
|
|
156
|
+
|
|
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.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Building the library
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
ng build profile-comparison-lib
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Output is in `dist/profile-comparison-lib/` (FESM bundles, typings, package.json). Peer dependencies: Angular `^20.0.0`.
|