@fjell/registry 4.4.52 → 4.4.54
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/package.json +4 -4
- package/API.md +0 -62
- package/GETTING_STARTED.md +0 -69
- package/build.js +0 -38
- package/docs/README.md +0 -74
- package/docs/TIMING_NODE_OPTIMIZATION.md +0 -207
- package/docs/TIMING_README.md +0 -170
- package/docs/docs.config.ts +0 -114
- package/docs/index.html +0 -26
- package/docs/package-lock.json +0 -5129
- package/docs/package.json +0 -34
- package/docs/public/404.html +0 -53
- package/docs/public/GETTING_STARTED.md +0 -69
- package/docs/public/README.md +0 -623
- package/docs/public/TIMING_NODE_OPTIMIZATION.md +0 -207
- package/docs/public/api.md +0 -62
- package/docs/public/client-api-overview.md +0 -137
- package/docs/public/configuration.md +0 -759
- package/docs/public/error-handling/README.md +0 -356
- package/docs/public/error-handling/network-errors.md +0 -485
- package/docs/public/examples/coordinates-example.ts +0 -253
- package/docs/public/examples/multi-level-keys.ts +0 -374
- package/docs/public/examples/registry-hub-coordinates-example.ts +0 -370
- package/docs/public/examples/registry-hub-types.ts +0 -437
- package/docs/public/examples/simple-example.ts +0 -250
- package/docs/public/examples-README.md +0 -241
- package/docs/public/fjell-icon.svg +0 -1
- package/docs/public/icon.png +0 -0
- package/docs/public/icon2.png +0 -0
- package/docs/public/memory-overhead.svg +0 -120
- package/docs/public/memory.md +0 -430
- package/docs/public/operations/README.md +0 -121
- package/docs/public/operations/all.md +0 -325
- package/docs/public/operations/create.md +0 -415
- package/docs/public/operations/get.md +0 -389
- package/docs/public/package.json +0 -63
- package/docs/public/pano.png +0 -0
- package/docs/public/pano2.png +0 -0
- package/docs/public/timing-range.svg +0 -176
- package/docs/public/timing.md +0 -483
- package/docs/timing-range.svg +0 -174
- package/docs/vitest.config.ts +0 -14
- package/examples/README.md +0 -241
- package/examples/coordinates-example.ts +0 -253
- package/examples/multi-level-keys.ts +0 -382
- package/examples/registry-hub-coordinates-example.ts +0 -370
- package/examples/registry-hub-types.ts +0 -437
- package/examples/registry-statistics-example.ts +0 -264
- package/examples/simple-example.ts +0 -250
- package/tsconfig.docs.json +0 -28
- package/vitest.config.ts +0 -22
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
# `get` Operation
|
|
2
|
-
|
|
3
|
-
Retrieve a single item by its key with automatic error handling and retry logic.
|
|
4
|
-
|
|
5
|
-
## Syntax
|
|
6
|
-
|
|
7
|
-
### Primary Items (PItemApi)
|
|
8
|
-
```typescript
|
|
9
|
-
async get(key: PriKey<S>): Promise<V | null>
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
### Contained Items (CItemApi)
|
|
13
|
-
```typescript
|
|
14
|
-
async get(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<V | null>
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Parameters
|
|
18
|
-
|
|
19
|
-
| Parameter | Type | Required | Description |
|
|
20
|
-
|-----------|------|----------|-------------|
|
|
21
|
-
| `key` | `PriKey<S>` or `ComKey<S, ...>` | Yes | Key identifying the item to retrieve |
|
|
22
|
-
|
|
23
|
-
### Key Types
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
// Primary Key (for PItemApi)
|
|
27
|
-
interface PriKey<S> {
|
|
28
|
-
keyType: S;
|
|
29
|
-
pk: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Composite Key (for CItemApi)
|
|
33
|
-
interface ComKey<S, L1, L2, L3, L4, L5> {
|
|
34
|
-
keyType: S;
|
|
35
|
-
pk: string;
|
|
36
|
-
l1?: LocKey<L1>;
|
|
37
|
-
l2?: LocKey<L2>;
|
|
38
|
-
// ... up to l5
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Examples
|
|
43
|
-
|
|
44
|
-
### Basic Usage
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
// Get a user by ID
|
|
48
|
-
const userKey = { keyType: 'user', pk: 'user-123' };
|
|
49
|
-
const user = await userApi.get(userKey);
|
|
50
|
-
|
|
51
|
-
if (user) {
|
|
52
|
-
console.log('Found user:', user.name);
|
|
53
|
-
} else {
|
|
54
|
-
console.log('User not found');
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Contained Items
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
// Get a task with composite key
|
|
62
|
-
const taskKey = {
|
|
63
|
-
keyType: 'task',
|
|
64
|
-
pk: 'task-456',
|
|
65
|
-
l1: { lkType: 'user', lk: 'user-123' }
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const task = await taskApi.get(taskKey);
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Error Handling
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
try {
|
|
75
|
-
const user = await userApi.get(userKey);
|
|
76
|
-
|
|
77
|
-
if (!user) {
|
|
78
|
-
console.log('User not found - this is normal');
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log('User found:', user.name);
|
|
83
|
-
|
|
84
|
-
} catch (error) {
|
|
85
|
-
if (error.code === 'NETWORK_ERROR') {
|
|
86
|
-
console.error('Network issue - operation was automatically retried');
|
|
87
|
-
} else if (error.code === 'AUTHENTICATION_ERROR') {
|
|
88
|
-
console.error('Authentication failed - check credentials');
|
|
89
|
-
} else {
|
|
90
|
-
console.error('Unexpected error:', error.message);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Null Handling Patterns
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
// Pattern 1: Explicit null check
|
|
99
|
-
const user = await userApi.get(userKey);
|
|
100
|
-
if (user === null) {
|
|
101
|
-
throw new Error('User not found');
|
|
102
|
-
}
|
|
103
|
-
// user is now typed as V (not null)
|
|
104
|
-
|
|
105
|
-
// Pattern 2: Default fallback
|
|
106
|
-
const user = await userApi.get(userKey) ?? createDefaultUser();
|
|
107
|
-
|
|
108
|
-
// Pattern 3: Optional chaining
|
|
109
|
-
const userName = (await userApi.get(userKey))?.name ?? 'Unknown';
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Return Value
|
|
113
|
-
|
|
114
|
-
Returns `Promise<V | null>`:
|
|
115
|
-
- **V**: The found item with all its properties
|
|
116
|
-
- **null**: When item is not found (404 response)
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
// Found item structure
|
|
120
|
-
const user = await userApi.get(userKey);
|
|
121
|
-
// {
|
|
122
|
-
// id: 'user-123',
|
|
123
|
-
// name: 'John Doe',
|
|
124
|
-
// email: 'john@example.com',
|
|
125
|
-
// active: true,
|
|
126
|
-
// createdAt: '2024-01-15T10:30:00Z',
|
|
127
|
-
// updatedAt: '2024-01-20T14:22:00Z',
|
|
128
|
-
// keyType: 'user'
|
|
129
|
-
// }
|
|
130
|
-
|
|
131
|
-
// Not found
|
|
132
|
-
const missingUser = await userApi.get({ keyType: 'user', pk: 'nonexistent' });
|
|
133
|
-
// null
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Performance Optimization
|
|
137
|
-
|
|
138
|
-
### Caching Strategies
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
// Simple memory cache
|
|
142
|
-
const userCache = new Map<string, User>();
|
|
143
|
-
|
|
144
|
-
async function getCachedUser(userKey: PriKey<'user'>): Promise<User | null> {
|
|
145
|
-
const cacheKey = `user:${userKey.pk}`;
|
|
146
|
-
|
|
147
|
-
// Check cache first
|
|
148
|
-
if (userCache.has(cacheKey)) {
|
|
149
|
-
return userCache.get(cacheKey)!;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Fetch from API
|
|
153
|
-
const user = await userApi.get(userKey);
|
|
154
|
-
|
|
155
|
-
// Cache the result (including null)
|
|
156
|
-
if (user) {
|
|
157
|
-
userCache.set(cacheKey, user);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return user;
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### Batch Loading
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
// Load multiple items efficiently
|
|
168
|
-
async function getUsersBatch(userKeys: PriKey<'user'>[]): Promise<(User | null)[]> {
|
|
169
|
-
// Use Promise.all for parallel requests
|
|
170
|
-
const promises = userKeys.map(key =>
|
|
171
|
-
userApi.get(key).catch(error => {
|
|
172
|
-
console.error(`Failed to load user ${key.pk}:`, error.message);
|
|
173
|
-
return null;
|
|
174
|
-
})
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
return Promise.all(promises);
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
## Advanced Patterns
|
|
182
|
-
|
|
183
|
-
### Safe Get with Type Guards
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
// Type-safe retrieval with validation
|
|
187
|
-
async function getValidUser(userKey: PriKey<'user'>): Promise<User> {
|
|
188
|
-
const user = await userApi.get(userKey);
|
|
189
|
-
|
|
190
|
-
if (!user) {
|
|
191
|
-
throw new Error(`User ${userKey.pk} not found`);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (!user.active) {
|
|
195
|
-
throw new Error(`User ${userKey.pk} is inactive`);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return user;
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Retry with Custom Logic
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
// Get with custom retry behavior
|
|
206
|
-
async function getWithRetry<T>(
|
|
207
|
-
apiCall: () => Promise<T | null>,
|
|
208
|
-
maxAttempts: number = 3,
|
|
209
|
-
delay: number = 1000
|
|
210
|
-
): Promise<T | null> {
|
|
211
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
212
|
-
try {
|
|
213
|
-
return await apiCall();
|
|
214
|
-
} catch (error) {
|
|
215
|
-
if (attempt === maxAttempts) throw error;
|
|
216
|
-
|
|
217
|
-
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
|
|
218
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
219
|
-
delay *= 2; // Exponential backoff
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Usage
|
|
226
|
-
const user = await getWithRetry(() => userApi.get(userKey));
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Get with Fallback Chain
|
|
230
|
-
|
|
231
|
-
```typescript
|
|
232
|
-
// Try multiple sources for data
|
|
233
|
-
async function getUserWithFallbacks(userId: string): Promise<User | null> {
|
|
234
|
-
const userKey = { keyType: 'user' as const, pk: userId };
|
|
235
|
-
|
|
236
|
-
// Try primary API
|
|
237
|
-
try {
|
|
238
|
-
const user = await userApi.get(userKey);
|
|
239
|
-
if (user) return user;
|
|
240
|
-
} catch (error) {
|
|
241
|
-
console.warn('Primary API failed:', error.message);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Try backup API
|
|
245
|
-
try {
|
|
246
|
-
const user = await backupUserApi.get(userKey);
|
|
247
|
-
if (user) return user;
|
|
248
|
-
} catch (error) {
|
|
249
|
-
console.warn('Backup API failed:', error.message);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Try cache
|
|
253
|
-
try {
|
|
254
|
-
const cachedUser = await getUserFromCache(userId);
|
|
255
|
-
if (cachedUser) return cachedUser;
|
|
256
|
-
} catch (error) {
|
|
257
|
-
console.warn('Cache failed:', error.message);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
## Common Use Cases
|
|
265
|
-
|
|
266
|
-
### User Profile Loading
|
|
267
|
-
|
|
268
|
-
```typescript
|
|
269
|
-
// Load user with profile data
|
|
270
|
-
async function loadUserProfile(userId: string) {
|
|
271
|
-
const userKey = { keyType: 'user' as const, pk: userId };
|
|
272
|
-
const user = await userApi.get(userKey);
|
|
273
|
-
|
|
274
|
-
if (!user) {
|
|
275
|
-
throw new Error('User not found');
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Load related data
|
|
279
|
-
const [profile, preferences, activity] = await Promise.all([
|
|
280
|
-
profileApi.get({ keyType: 'profile', pk: userId }),
|
|
281
|
-
preferencesApi.get({ keyType: 'preferences', pk: userId }),
|
|
282
|
-
activityApi.allFacet('recent-activity', { limit: 10 }, [userId])
|
|
283
|
-
]);
|
|
284
|
-
|
|
285
|
-
return {
|
|
286
|
-
user,
|
|
287
|
-
profile,
|
|
288
|
-
preferences,
|
|
289
|
-
activity
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### Resource Validation
|
|
295
|
-
|
|
296
|
-
```typescript
|
|
297
|
-
// Validate resource exists before operation
|
|
298
|
-
async function updateUserIfExists(
|
|
299
|
-
userKey: PriKey<'user'>,
|
|
300
|
-
updates: Partial<User>
|
|
301
|
-
): Promise<User | null> {
|
|
302
|
-
const user = await userApi.get(userKey);
|
|
303
|
-
|
|
304
|
-
if (!user) {
|
|
305
|
-
console.log('User not found, skipping update');
|
|
306
|
-
return null;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// User exists, proceed with update
|
|
310
|
-
return await userApi.update(userKey, updates);
|
|
311
|
-
}
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### Conditional Operations
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
// Perform operation based on item state
|
|
318
|
-
async function processUserBasedOnState(userKey: PriKey<'user'>) {
|
|
319
|
-
const user = await userApi.get(userKey);
|
|
320
|
-
|
|
321
|
-
if (!user) {
|
|
322
|
-
console.log('User not found');
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
switch (user.status) {
|
|
327
|
-
case 'pending':
|
|
328
|
-
await userApi.action(userKey, 'send-welcome-email');
|
|
329
|
-
break;
|
|
330
|
-
|
|
331
|
-
case 'active':
|
|
332
|
-
await userApi.action(userKey, 'update-last-seen');
|
|
333
|
-
break;
|
|
334
|
-
|
|
335
|
-
case 'suspended':
|
|
336
|
-
console.log('User is suspended, no action taken');
|
|
337
|
-
break;
|
|
338
|
-
|
|
339
|
-
default:
|
|
340
|
-
console.log('Unknown user status:', user.status);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
## Error Scenarios
|
|
346
|
-
|
|
347
|
-
### Network Issues
|
|
348
|
-
|
|
349
|
-
```typescript
|
|
350
|
-
// Automatic retry handles network issues
|
|
351
|
-
try {
|
|
352
|
-
const user = await userApi.get(userKey);
|
|
353
|
-
// Network errors are automatically retried
|
|
354
|
-
} catch (error) {
|
|
355
|
-
// Only non-retryable errors reach here
|
|
356
|
-
if (error.code === 'NETWORK_ERROR') {
|
|
357
|
-
// All retries exhausted
|
|
358
|
-
console.error('Network completely unavailable');
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Authorization
|
|
364
|
-
|
|
365
|
-
```typescript
|
|
366
|
-
// Handle permission issues
|
|
367
|
-
try {
|
|
368
|
-
const user = await userApi.get(userKey);
|
|
369
|
-
} catch (error) {
|
|
370
|
-
if (error.code === 'AUTHORIZATION_ERROR') {
|
|
371
|
-
console.error('Insufficient permissions to access user');
|
|
372
|
-
// Redirect to login or show error message
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
## Related Operations
|
|
378
|
-
|
|
379
|
-
- [`all`](./all.md) - Get multiple items
|
|
380
|
-
- [`one`](./one.md) - Get single item with query
|
|
381
|
-
- [`find`](./find.md) - Find items with custom finders
|
|
382
|
-
- [`create`](./create.md) - Create new items
|
|
383
|
-
- [`update`](./update.md) - Update existing items
|
|
384
|
-
|
|
385
|
-
## Next Steps
|
|
386
|
-
|
|
387
|
-
- Explore [Caching Strategies](../guides/caching.md)
|
|
388
|
-
- Learn about [Error Handling](../error-handling/README.md)
|
|
389
|
-
- Review [Performance Optimization](../guides/performance.md)
|
package/docs/public/package.json
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@fjell/registry",
|
|
3
|
-
"version": "4.4.11",
|
|
4
|
-
"keywords": [
|
|
5
|
-
"registry",
|
|
6
|
-
"fjell"
|
|
7
|
-
],
|
|
8
|
-
"license": "Apache-2.0",
|
|
9
|
-
"description": "Common Registry for Fjell",
|
|
10
|
-
"engines": {
|
|
11
|
-
"node": ">=21"
|
|
12
|
-
},
|
|
13
|
-
"main": "dist/index.cjs",
|
|
14
|
-
"module": "dist/index.js",
|
|
15
|
-
"exports": {
|
|
16
|
-
".": {
|
|
17
|
-
"types": "./dist/index.d.ts",
|
|
18
|
-
"require": "./dist/index.cjs",
|
|
19
|
-
"import": "./dist/index.js"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"type": "module",
|
|
23
|
-
"scripts": {
|
|
24
|
-
"build": "tsc --noEmit && vite build",
|
|
25
|
-
"dev": "concurrently \"tsc --watch --noEmit\" \"vite build --watch\"",
|
|
26
|
-
"lint": "eslint . --ext .ts --fix",
|
|
27
|
-
"clean": "rm -rf dist",
|
|
28
|
-
"test": "npm run lint && vitest run --coverage",
|
|
29
|
-
"test:memory:optimized": "npm run lint && NODE_OPTIONS=\"--max-old-space-size=8192 --max-semi-space-size=1024\" vitest run tests/memory.test.ts",
|
|
30
|
-
"test:timing:optimized": "npm run lint && NODE_OPTIONS=\"--max-old-space-size=8192 --max-semi-space-size=1024\" vitest run tests/timing.test.ts",
|
|
31
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
32
|
-
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"@fjell/core": "^4.4.7",
|
|
35
|
-
"@fjell/logging": "^4.4.7",
|
|
36
|
-
"deepmerge": "^4.3.1"
|
|
37
|
-
},
|
|
38
|
-
"devDependencies": {
|
|
39
|
-
"@eslint/eslintrc": "^3.3.1",
|
|
40
|
-
"@eslint/js": "^9.31.0",
|
|
41
|
-
"@swc/core": "^1.13.1",
|
|
42
|
-
"@tsconfig/recommended": "^1.0.10",
|
|
43
|
-
"@types/multer": "^2.0.0",
|
|
44
|
-
"@types/node": "^24.0.15",
|
|
45
|
-
"@typescript-eslint/eslint-plugin": "^8.37.0",
|
|
46
|
-
"@typescript-eslint/parser": "^8.37.0",
|
|
47
|
-
"@vitest/coverage-v8": "^3.2.4",
|
|
48
|
-
"concurrently": "^9.2.0",
|
|
49
|
-
"eslint": "^9.31.0",
|
|
50
|
-
"nodemon": "^3.1.10",
|
|
51
|
-
"ts-node": "^10.9.2",
|
|
52
|
-
"tsc-alias": "^1.8.16",
|
|
53
|
-
"typescript": "^5.8.3",
|
|
54
|
-
"vite": "^7.0.5",
|
|
55
|
-
"vite-plugin-dts": "^4.5.4",
|
|
56
|
-
"vite-plugin-node": "^7.0.0",
|
|
57
|
-
"vitest": "^3.2.4"
|
|
58
|
-
},
|
|
59
|
-
"repository": {
|
|
60
|
-
"type": "git",
|
|
61
|
-
"url": "git+https://github.com/getfjell/registry.git"
|
|
62
|
-
}
|
|
63
|
-
}
|
package/docs/public/pano.png
DELETED
|
Binary file
|
package/docs/public/pano2.png
DELETED
|
Binary file
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg width="1200" height="800" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
-
<style>
|
|
4
|
-
.axis { stroke: #333; stroke-width: 1; }
|
|
5
|
-
.grid { stroke: #ddd; stroke-width: 0.5; }
|
|
6
|
-
.label { font-family: Arial, sans-serif; font-size: 14px; fill: #333; }
|
|
7
|
-
.title { font-family: Arial, sans-serif; font-size: 16px; font-weight: bold; fill: #333; }
|
|
8
|
-
.subtitle { font-family: Arial, sans-serif; font-size: 12px; fill: #666; }
|
|
9
|
-
.register-mean { stroke: #e74c3c; stroke-width: 3; fill: none; }
|
|
10
|
-
.lookup-mean { stroke: #3498db; stroke-width: 3; fill: none; }
|
|
11
|
-
.register-band { fill: rgba(231, 76, 60, 0.2); stroke: #e74c3c; stroke-width: 1; }
|
|
12
|
-
.lookup-band { fill: rgba(52, 152, 219, 0.2); stroke: #3498db; stroke-width: 1; }
|
|
13
|
-
.register-dot { fill: #e74c3c; }
|
|
14
|
-
.lookup-dot { fill: #3498db; }
|
|
15
|
-
.legend { font-family: Arial, sans-serif; font-size: 12px; fill: #333; }
|
|
16
|
-
.axis-title { font-family: Arial, sans-serif; font-size: 16px; font-weight: bold; fill: #333; }
|
|
17
|
-
.metadata-title { font-family: Arial, sans-serif; font-size: 14px; font-weight: bold; fill: #333; }
|
|
18
|
-
.metadata-section { font-family: Arial, sans-serif; font-size: 14px; font-weight: bold; fill: #444; }
|
|
19
|
-
.metadata-label { font-family: Arial, sans-serif; font-size: 10px; fill: #666; }
|
|
20
|
-
.metadata-value { font-family: Arial, sans-serif; font-size: 10px; fill: #333; }
|
|
21
|
-
</style>
|
|
22
|
-
|
|
23
|
-
<!-- Background -->
|
|
24
|
-
<rect width="1200" height="800" fill="white"/>
|
|
25
|
-
|
|
26
|
-
<!-- Title -->
|
|
27
|
-
<text x="600" y="25" text-anchor="middle" class="title">Timing of Common Registry Operations</text>
|
|
28
|
-
<text x="600" y="45" text-anchor="middle" class="subtitle">Performance measurements across varying tree sizes</text>
|
|
29
|
-
|
|
30
|
-
<!-- Plot area -->
|
|
31
|
-
<g transform="translate(110,60)">
|
|
32
|
-
|
|
33
|
-
<!-- Grid lines (logarithmic scale) -->
|
|
34
|
-
<line x1="0" y1="405.47941100296094" x2="1015" y2="405.47941100296094" class="grid"/>
|
|
35
|
-
<text x="-10" y="409.47941100296094" text-anchor="end" class="label">0.05µs</text>
|
|
36
|
-
<line x1="0" y1="344.44867833493345" x2="1015" y2="344.44867833493345" class="grid"/>
|
|
37
|
-
<text x="-10" y="348.44867833493345" text-anchor="end" class="label">0.10µs</text>
|
|
38
|
-
<line x1="0" y1="283.41794566690595" x2="1015" y2="283.41794566690595" class="grid"/>
|
|
39
|
-
<text x="-10" y="287.41794566690595" text-anchor="end" class="label">0.20µs</text>
|
|
40
|
-
<line x1="0" y1="202.7397055014805" x2="1015" y2="202.7397055014805" class="grid"/>
|
|
41
|
-
<text x="-10" y="206.7397055014805" text-anchor="end" class="label">0.50µs</text>
|
|
42
|
-
<line x1="0" y1="141.708972833453" x2="1015" y2="141.708972833453" class="grid"/>
|
|
43
|
-
<text x="-10" y="145.708972833453" text-anchor="end" class="label">1.0µs</text>
|
|
44
|
-
<line x1="0" y1="80.6782401654255" x2="1015" y2="80.6782401654255" class="grid"/>
|
|
45
|
-
<text x="-10" y="84.6782401654255" text-anchor="end" class="label">2.0µs</text>
|
|
46
|
-
<line x1="0" y1="0" x2="1015" y2="0" class="grid"/>
|
|
47
|
-
<text x="-10" y="4" text-anchor="end" class="label">5.0µs</text>
|
|
48
|
-
<line x1="0" y1="0" x2="0" y2="460" class="grid"/>
|
|
49
|
-
<text x="0" y="480" text-anchor="middle" class="label">10</text>
|
|
50
|
-
<line x1="76.38636139973525" y1="0" x2="76.38636139973525" y2="460" class="grid"/>
|
|
51
|
-
<text x="76.38636139973525" y="480" text-anchor="middle" class="label">20</text>
|
|
52
|
-
<line x1="177.36363860026475" y1="0" x2="177.36363860026475" y2="460" class="grid"/>
|
|
53
|
-
<text x="177.36363860026475" y="480" text-anchor="middle" class="label">50</text>
|
|
54
|
-
<line x1="253.75" y1="0" x2="253.75" y2="460" class="grid"/>
|
|
55
|
-
<text x="253.75" y="480" text-anchor="middle" class="label">100</text>
|
|
56
|
-
<line x1="330.1363613997352" y1="0" x2="330.1363613997352" y2="460" class="grid"/>
|
|
57
|
-
<text x="330.1363613997352" y="480" text-anchor="middle" class="label">200</text>
|
|
58
|
-
<line x1="431.1136386002648" y1="0" x2="431.1136386002648" y2="460" class="grid"/>
|
|
59
|
-
<text x="431.1136386002648" y="480" text-anchor="middle" class="label">500</text>
|
|
60
|
-
<line x1="507.5" y1="0" x2="507.5" y2="460" class="grid"/>
|
|
61
|
-
<text x="507.5" y="480" text-anchor="middle" class="label">1k</text>
|
|
62
|
-
<line x1="583.8863613997353" y1="0" x2="583.8863613997353" y2="460" class="grid"/>
|
|
63
|
-
<text x="583.8863613997353" y="480" text-anchor="middle" class="label">2k</text>
|
|
64
|
-
<line x1="684.8636386002647" y1="0" x2="684.8636386002647" y2="460" class="grid"/>
|
|
65
|
-
<text x="684.8636386002647" y="480" text-anchor="middle" class="label">5k</text>
|
|
66
|
-
<line x1="761.25" y1="0" x2="761.25" y2="460" class="grid"/>
|
|
67
|
-
<text x="761.25" y="480" text-anchor="middle" class="label">10k</text>
|
|
68
|
-
<line x1="837.6363613997353" y1="0" x2="837.6363613997353" y2="460" class="grid"/>
|
|
69
|
-
<text x="837.6363613997353" y="480" text-anchor="middle" class="label">20k</text>
|
|
70
|
-
<line x1="938.6136386002647" y1="0" x2="938.6136386002647" y2="460" class="grid"/>
|
|
71
|
-
<text x="938.6136386002647" y="480" text-anchor="middle" class="label">50k</text>
|
|
72
|
-
<line x1="1015" y1="0" x2="1015" y2="460" class="grid"/>
|
|
73
|
-
<text x="1015" y="480" text-anchor="middle" class="label">100k</text>
|
|
74
|
-
<!-- Y-axis -->
|
|
75
|
-
<line x1="0" y1="0" x2="0" y2="460" class="axis"/>
|
|
76
|
-
|
|
77
|
-
<!-- X-axis -->
|
|
78
|
-
<line x1="0" y1="460" x2="1015" y2="460" class="axis"/>
|
|
79
|
-
|
|
80
|
-
<!-- Axis labels -->
|
|
81
|
-
<text x="507.5" y="510" text-anchor="middle" class="axis-title">Tree Size (items) - Log Scale</text>
|
|
82
|
-
<text transform="rotate(-90,-70,230)" x="-70" y="230" text-anchor="middle" class="axis-title">Execution Time (µs)</text>
|
|
83
|
-
<path d="M 0 148.74050590256667 L 76.38636139973525 148.7524277923311 L 177.36363860026475 148.44013071796422 L 253.75 163.96828165051454 L 330.1363613997352 162.08556246017355 L 431.1136386002648 172.30055096042298 L 507.5 164.83245476448178 L 583.8863613997353 182.97393995516205 L 684.8636386002647 169.94194464665668 L 761.25 151.0989993965061 L 837.6363613997353 160.0780931612813 L 938.6136386002647 148.48776057676235 L 1015 120.43534569475918" class="register-mean"/>
|
|
84
|
-
<path d="M 0 391.3646719514693 L 76.38636139973525 388.54139718542586 L 177.36363860026475 389.0557369024966 L 253.75 374.3747740786199 L 330.1363613997352 398.9692673319725 L 431.1136386002648 360.0500990825511 L 507.5 360.0275016662577 L 583.8863613997353 305.0657993375811 L 684.8636386002647 300.3208350816295 L 761.25 264.9832596121842 L 837.6363613997353 268.5823457977558 L 938.6136386002647 288.5555639615857 L 1015 247.60931540724576" class="lookup-mean"/>
|
|
85
|
-
<circle cx="0" cy="148.74050590256667" r="4" class="register-dot"/>
|
|
86
|
-
<circle cx="76.38636139973525" cy="148.7524277923311" r="4" class="register-dot"/>
|
|
87
|
-
<circle cx="177.36363860026475" cy="148.44013071796422" r="4" class="register-dot"/>
|
|
88
|
-
<circle cx="253.75" cy="163.96828165051454" r="4" class="register-dot"/>
|
|
89
|
-
<circle cx="330.1363613997352" cy="162.08556246017355" r="4" class="register-dot"/>
|
|
90
|
-
<circle cx="431.1136386002648" cy="172.30055096042298" r="4" class="register-dot"/>
|
|
91
|
-
<circle cx="507.5" cy="164.83245476448178" r="4" class="register-dot"/>
|
|
92
|
-
<circle cx="583.8863613997353" cy="182.97393995516205" r="4" class="register-dot"/>
|
|
93
|
-
<circle cx="684.8636386002647" cy="169.94194464665668" r="4" class="register-dot"/>
|
|
94
|
-
<circle cx="761.25" cy="151.0989993965061" r="4" class="register-dot"/>
|
|
95
|
-
<circle cx="837.6363613997353" cy="160.0780931612813" r="4" class="register-dot"/>
|
|
96
|
-
<circle cx="938.6136386002647" cy="148.48776057676235" r="4" class="register-dot"/>
|
|
97
|
-
<circle cx="1015" cy="120.43534569475918" r="4" class="register-dot"/>
|
|
98
|
-
<circle cx="0" cy="391.3646719514693" r="4" class="lookup-dot"/>
|
|
99
|
-
<circle cx="76.38636139973525" cy="388.54139718542586" r="4" class="lookup-dot"/>
|
|
100
|
-
<circle cx="177.36363860026475" cy="389.0557369024966" r="4" class="lookup-dot"/>
|
|
101
|
-
<circle cx="253.75" cy="374.3747740786199" r="4" class="lookup-dot"/>
|
|
102
|
-
<circle cx="330.1363613997352" cy="398.9692673319725" r="4" class="lookup-dot"/>
|
|
103
|
-
<circle cx="431.1136386002648" cy="360.0500990825511" r="4" class="lookup-dot"/>
|
|
104
|
-
<circle cx="507.5" cy="360.0275016662577" r="4" class="lookup-dot"/>
|
|
105
|
-
<circle cx="583.8863613997353" cy="305.0657993375811" r="4" class="lookup-dot"/>
|
|
106
|
-
<circle cx="684.8636386002647" cy="300.3208350816295" r="4" class="lookup-dot"/>
|
|
107
|
-
<circle cx="761.25" cy="264.9832596121842" r="4" class="lookup-dot"/>
|
|
108
|
-
<circle cx="837.6363613997353" cy="268.5823457977558" r="4" class="lookup-dot"/>
|
|
109
|
-
<circle cx="938.6136386002647" cy="288.5555639615857" r="4" class="lookup-dot"/>
|
|
110
|
-
<circle cx="1015" cy="247.60931540724576" r="4" class="lookup-dot"/>
|
|
111
|
-
<!-- Legend -->
|
|
112
|
-
<g transform="translate(20, 20)">
|
|
113
|
-
<rect x="0" y="0" width="190" height="80" fill="white" stroke="#ccc" stroke-width="1"/>
|
|
114
|
-
|
|
115
|
-
<!-- Register Instance Legend -->
|
|
116
|
-
<text x="10" y="20" class="legend" font-weight="bold">Register Instance</text>
|
|
117
|
-
<line x1="10" y1="30" x2="40" y2="30" class="register-mean"/>
|
|
118
|
-
<circle cx="25" cy="30" r="3" class="register-dot"/>
|
|
119
|
-
<text x="45" y="34" class="legend">Average Timing</text>
|
|
120
|
-
|
|
121
|
-
<!-- Lookup Instance Legend -->
|
|
122
|
-
<text x="10" y="55" class="legend" font-weight="bold">Lookup Instance</text>
|
|
123
|
-
<line x1="10" y1="65" x2="40" y2="65" class="lookup-mean"/>
|
|
124
|
-
<circle cx="25" cy="65" r="3" class="lookup-dot"/>
|
|
125
|
-
<text x="45" y="69" class="legend">Average Timing</text>
|
|
126
|
-
</g>
|
|
127
|
-
|
|
128
|
-
</g>
|
|
129
|
-
|
|
130
|
-
<!-- Test Metadata Section -->
|
|
131
|
-
<g transform="translate(50, 620)">
|
|
132
|
-
<!-- Left Column: System Information -->
|
|
133
|
-
<g transform="translate(20, 20)">
|
|
134
|
-
<text x="0" y="0" class="metadata-section">System Information</text>
|
|
135
|
-
|
|
136
|
-
<text x="0" y="25" class="metadata-label">Test Date:</text>
|
|
137
|
-
<text x="150" y="25" class="metadata-value">2025-07-21</text>
|
|
138
|
-
|
|
139
|
-
<text x="0" y="45" class="metadata-label">Package Version:</text>
|
|
140
|
-
<text x="150" y="45" class="metadata-value">@fjell/registry v4.4.5</text>
|
|
141
|
-
|
|
142
|
-
<text x="0" y="65" class="metadata-label">Node.js Version:</text>
|
|
143
|
-
<text x="150" y="65" class="metadata-value">v22.0.0 (darwin arm64)</text>
|
|
144
|
-
|
|
145
|
-
<text x="0" y="85" class="metadata-label">Platform:</text>
|
|
146
|
-
<text x="150" y="85" class="metadata-value">darwin arm64</text>
|
|
147
|
-
|
|
148
|
-
<text x="0" y="105" class="metadata-label">Compiler:</text>
|
|
149
|
-
<text x="150" y="105" class="metadata-value">TypeScript + Vite</text>
|
|
150
|
-
</g>
|
|
151
|
-
|
|
152
|
-
<!-- Center Column: Test Configuration -->
|
|
153
|
-
<g transform="translate(330, 20)">
|
|
154
|
-
<text x="0" y="0" class="metadata-section">Test Configuration</text>
|
|
155
|
-
|
|
156
|
-
<text x="0" y="25" class="metadata-label">Test Rounds:</text>
|
|
157
|
-
<text x="120" y="25" class="metadata-value">100 per tree size</text>
|
|
158
|
-
|
|
159
|
-
<text x="0" y="45" class="metadata-label">Iterations per Round:</text>
|
|
160
|
-
<text x="120" y="45" class="metadata-value">200 operations</text>
|
|
161
|
-
|
|
162
|
-
<text x="0" y="65" class="metadata-label">Total Measurements:</text>
|
|
163
|
-
<text x="120" y="65" class="metadata-value">20,000 per data point</text>
|
|
164
|
-
</g>
|
|
165
|
-
|
|
166
|
-
<!-- Right Column: Test Notes -->
|
|
167
|
-
<g transform="translate(600, 20)">
|
|
168
|
-
<text x="0" y="0" class="metadata-section">Test Notes</text>
|
|
169
|
-
<text x="0" y="25" class="metadata-label">• Performance measurements use Node.js performance.now() with microsecond precision</text>
|
|
170
|
-
<text x="0" y="42" class="metadata-label">• Each test includes warm-up iterations to minimize JIT compilation effects</text>
|
|
171
|
-
<text x="0" y="59" class="metadata-label">• Logging is mocked during timing tests to eliminate I/O overhead</text>
|
|
172
|
-
<text x="0" y="76" class="metadata-label">• Tests verify both mean performance and consistency (low standard deviation)</text>
|
|
173
|
-
<text x="0" y="93" class="metadata-label">• Statistical analysis ensures reliable performance measurements across all tree sizes</text>
|
|
174
|
-
</g>
|
|
175
|
-
</g>
|
|
176
|
-
</svg>
|