@fjell/registry 4.4.22 → 4.4.24
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/dist/index.js.map +1 -1
- package/docs/docs.config.ts +52 -2
- package/docs/index.html +9 -0
- package/docs/public/404.html +53 -0
- package/docs/public/client-api-overview.md +137 -0
- package/docs/public/configuration.md +759 -0
- package/docs/public/error-handling/README.md +356 -0
- package/docs/public/error-handling/network-errors.md +485 -0
- package/docs/public/operations/README.md +121 -0
- package/docs/public/operations/all.md +325 -0
- package/docs/public/operations/create.md +415 -0
- package/docs/public/operations/get.md +389 -0
- package/docs/public/package.json +1 -2
- package/docs/timing-range.svg +41 -39
- package/package.json +3 -4
- package/vitest.config.ts +0 -6
|
@@ -0,0 +1,389 @@
|
|
|
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
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"build": "tsc --noEmit && vite build",
|
|
25
25
|
"dev": "concurrently \"tsc --watch --noEmit\" \"vite build --watch\"",
|
|
26
26
|
"lint": "eslint . --ext .ts --fix",
|
|
27
|
-
"clean": "
|
|
27
|
+
"clean": "rm -rf dist",
|
|
28
28
|
"test": "npm run lint && vitest run --coverage",
|
|
29
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
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",
|
|
@@ -48,7 +48,6 @@
|
|
|
48
48
|
"concurrently": "^9.2.0",
|
|
49
49
|
"eslint": "^9.31.0",
|
|
50
50
|
"nodemon": "^3.1.10",
|
|
51
|
-
"rimraf": "^6.0.1",
|
|
52
51
|
"ts-node": "^10.9.2",
|
|
53
52
|
"tsc-alias": "^1.8.16",
|
|
54
53
|
"typescript": "^5.8.3",
|
package/docs/timing-range.svg
CHANGED
|
@@ -31,16 +31,18 @@
|
|
|
31
31
|
<g transform="translate(110,60)">
|
|
32
32
|
|
|
33
33
|
<!-- Grid lines (logarithmic scale) -->
|
|
34
|
-
<line x1="0" y1="
|
|
35
|
-
<text x="-10" y="
|
|
36
|
-
<line x1="0" y1="
|
|
37
|
-
<text x="-10" y="
|
|
38
|
-
<line x1="0" y1="
|
|
39
|
-
<text x="-10" y="
|
|
40
|
-
<line x1="0" y1="
|
|
41
|
-
<text x="-10" y="
|
|
42
|
-
<line x1="0" y1="
|
|
43
|
-
<text x="-10" y="
|
|
34
|
+
<line x1="0" y1="457.6666713805134" x2="1015" y2="457.6666713805134" class="grid"/>
|
|
35
|
+
<text x="-10" y="461.6666713805134" text-anchor="end" class="label">0.10µs</text>
|
|
36
|
+
<line x1="0" y1="387.70544969582414" x2="1015" y2="387.70544969582414" class="grid"/>
|
|
37
|
+
<text x="-10" y="391.70544969582414" text-anchor="end" class="label">0.20µs</text>
|
|
38
|
+
<line x1="0" y1="295.22174519819055" x2="1015" y2="295.22174519819055" class="grid"/>
|
|
39
|
+
<text x="-10" y="299.22174519819055" text-anchor="end" class="label">0.50µs</text>
|
|
40
|
+
<line x1="0" y1="225.26052351350134" x2="1015" y2="225.26052351350134" class="grid"/>
|
|
41
|
+
<text x="-10" y="229.26052351350134" text-anchor="end" class="label">1.0µs</text>
|
|
42
|
+
<line x1="0" y1="155.29930182881213" x2="1015" y2="155.29930182881213" class="grid"/>
|
|
43
|
+
<text x="-10" y="159.29930182881213" text-anchor="end" class="label">2.0µs</text>
|
|
44
|
+
<line x1="0" y1="62.815597331178594" x2="1015" y2="62.815597331178594" class="grid"/>
|
|
45
|
+
<text x="-10" y="66.8155973311786" text-anchor="end" class="label">5.0µs</text>
|
|
44
46
|
<line x1="0" y1="0" x2="0" y2="460" class="grid"/>
|
|
45
47
|
<text x="0" y="480" text-anchor="middle" class="label">10</text>
|
|
46
48
|
<line x1="76.38636139973525" y1="0" x2="76.38636139973525" y2="460" class="grid"/>
|
|
@@ -76,34 +78,34 @@
|
|
|
76
78
|
<!-- Axis labels -->
|
|
77
79
|
<text x="507.5" y="510" text-anchor="middle" class="axis-title">Tree Size (items) - Log Scale</text>
|
|
78
80
|
<text transform="rotate(-90,-70,230)" x="-70" y="230" text-anchor="middle" class="axis-title">Execution Time (µs)</text>
|
|
79
|
-
<path d="M 0
|
|
80
|
-
<path d="M 0
|
|
81
|
-
<circle cx="0" cy="
|
|
82
|
-
<circle cx="76.38636139973525" cy="
|
|
83
|
-
<circle cx="177.36363860026475" cy="
|
|
84
|
-
<circle cx="253.75" cy="
|
|
85
|
-
<circle cx="330.1363613997352" cy="
|
|
86
|
-
<circle cx="431.1136386002648" cy="
|
|
87
|
-
<circle cx="507.5" cy="
|
|
88
|
-
<circle cx="583.8863613997353" cy="
|
|
89
|
-
<circle cx="684.8636386002647" cy="
|
|
90
|
-
<circle cx="761.25" cy="
|
|
91
|
-
<circle cx="837.6363613997353" cy="
|
|
92
|
-
<circle cx="938.6136386002647" cy="
|
|
93
|
-
<circle cx="1015" cy="
|
|
94
|
-
<circle cx="0" cy="
|
|
95
|
-
<circle cx="76.38636139973525" cy="379.
|
|
96
|
-
<circle cx="177.36363860026475" cy="
|
|
97
|
-
<circle cx="253.75" cy="
|
|
98
|
-
<circle cx="330.1363613997352" cy="
|
|
99
|
-
<circle cx="431.1136386002648" cy="
|
|
100
|
-
<circle cx="507.5" cy="
|
|
101
|
-
<circle cx="583.8863613997353" cy="
|
|
102
|
-
<circle cx="684.8636386002647" cy="
|
|
103
|
-
<circle cx="761.25" cy="
|
|
104
|
-
<circle cx="837.6363613997353" cy="
|
|
105
|
-
<circle cx="938.6136386002647" cy="
|
|
106
|
-
<circle cx="1015" cy="
|
|
81
|
+
<path d="M 0 162.036023730032 L 76.38636139973525 199.92194454216684 L 177.36363860026475 180.79321863035807 L 253.75 187.60715615722802 L 330.1363613997352 173.91391428005716 L 431.1136386002648 184.06005752352138 L 507.5 141.383386116549 L 583.8863613997353 204.69578214186592 L 684.8636386002647 206.1311970357144 L 761.25 87.08624788584507 L 837.6363613997353 69.96122168468918 L 938.6136386002647 203.07288463701997 L 1015 215.57273165091996" class="register-mean"/>
|
|
82
|
+
<path d="M 0 364.8039704829771 L 76.38636139973525 379.11430981740193 L 177.36363860026475 284.9534522846775 L 253.75 390.0387783153108 L 330.1363613997352 389.7986492271557 L 431.1136386002648 364.7621485082677 L 507.5 313.9174075959719 L 583.8863613997353 365.8960461378602 L 684.8636386002647 218.5623785529402 L 761.25 182.11371170586403 L 837.6363613997353 272.868648401109 L 938.6136386002647 299.90544804219076 L 1015 308.2620429415109" class="lookup-mean"/>
|
|
83
|
+
<circle cx="0" cy="162.036023730032" r="4" class="register-dot"/>
|
|
84
|
+
<circle cx="76.38636139973525" cy="199.92194454216684" r="4" class="register-dot"/>
|
|
85
|
+
<circle cx="177.36363860026475" cy="180.79321863035807" r="4" class="register-dot"/>
|
|
86
|
+
<circle cx="253.75" cy="187.60715615722802" r="4" class="register-dot"/>
|
|
87
|
+
<circle cx="330.1363613997352" cy="173.91391428005716" r="4" class="register-dot"/>
|
|
88
|
+
<circle cx="431.1136386002648" cy="184.06005752352138" r="4" class="register-dot"/>
|
|
89
|
+
<circle cx="507.5" cy="141.383386116549" r="4" class="register-dot"/>
|
|
90
|
+
<circle cx="583.8863613997353" cy="204.69578214186592" r="4" class="register-dot"/>
|
|
91
|
+
<circle cx="684.8636386002647" cy="206.1311970357144" r="4" class="register-dot"/>
|
|
92
|
+
<circle cx="761.25" cy="87.08624788584507" r="4" class="register-dot"/>
|
|
93
|
+
<circle cx="837.6363613997353" cy="69.96122168468918" r="4" class="register-dot"/>
|
|
94
|
+
<circle cx="938.6136386002647" cy="203.07288463701997" r="4" class="register-dot"/>
|
|
95
|
+
<circle cx="1015" cy="215.57273165091996" r="4" class="register-dot"/>
|
|
96
|
+
<circle cx="0" cy="364.8039704829771" r="4" class="lookup-dot"/>
|
|
97
|
+
<circle cx="76.38636139973525" cy="379.11430981740193" r="4" class="lookup-dot"/>
|
|
98
|
+
<circle cx="177.36363860026475" cy="284.9534522846775" r="4" class="lookup-dot"/>
|
|
99
|
+
<circle cx="253.75" cy="390.0387783153108" r="4" class="lookup-dot"/>
|
|
100
|
+
<circle cx="330.1363613997352" cy="389.7986492271557" r="4" class="lookup-dot"/>
|
|
101
|
+
<circle cx="431.1136386002648" cy="364.7621485082677" r="4" class="lookup-dot"/>
|
|
102
|
+
<circle cx="507.5" cy="313.9174075959719" r="4" class="lookup-dot"/>
|
|
103
|
+
<circle cx="583.8863613997353" cy="365.8960461378602" r="4" class="lookup-dot"/>
|
|
104
|
+
<circle cx="684.8636386002647" cy="218.5623785529402" r="4" class="lookup-dot"/>
|
|
105
|
+
<circle cx="761.25" cy="182.11371170586403" r="4" class="lookup-dot"/>
|
|
106
|
+
<circle cx="837.6363613997353" cy="272.868648401109" r="4" class="lookup-dot"/>
|
|
107
|
+
<circle cx="938.6136386002647" cy="299.90544804219076" r="4" class="lookup-dot"/>
|
|
108
|
+
<circle cx="1015" cy="308.2620429415109" r="4" class="lookup-dot"/>
|
|
107
109
|
<!-- Legend -->
|
|
108
110
|
<g transform="translate(20, 20)">
|
|
109
111
|
<rect x="0" y="0" width="190" height="80" fill="white" stroke="#ccc" stroke-width="1"/>
|
|
@@ -130,7 +132,7 @@
|
|
|
130
132
|
<text x="0" y="0" class="metadata-section">System Information</text>
|
|
131
133
|
|
|
132
134
|
<text x="0" y="25" class="metadata-label">Test Date:</text>
|
|
133
|
-
<text x="150" y="25" class="metadata-value">2025-07-
|
|
135
|
+
<text x="150" y="25" class="metadata-value">2025-07-28</text>
|
|
134
136
|
|
|
135
137
|
<text x="0" y="45" class="metadata-label">Package Version:</text>
|
|
136
138
|
<text x="150" y="45" class="metadata-value">@fjell/registry v4.4.5</text>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjell/registry",
|
|
3
3
|
"description": "Dependency injection and service location system for the Fjell ecosystem",
|
|
4
|
-
"version": "4.4.
|
|
4
|
+
"version": "4.4.24",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"registry",
|
|
7
7
|
"dependency-injection",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"dev": "concurrently \"tsc --noEmit --watch\" \"node build.js --watch\"",
|
|
24
24
|
"build": "npm run lint && tsc --noEmit && node build.js",
|
|
25
25
|
"typecheck": "tsc --noEmit",
|
|
26
|
-
"clean": "
|
|
26
|
+
"clean": "rm -rf dist",
|
|
27
27
|
"test": "npm run lint && vitest run --coverage",
|
|
28
28
|
"prepublishOnly": "npm run clean && npm run build",
|
|
29
29
|
"docs:dev": "cd docs && npm run dev",
|
|
@@ -48,7 +48,6 @@
|
|
|
48
48
|
"esbuild": "^0.25.8",
|
|
49
49
|
"eslint": "^9.32.0",
|
|
50
50
|
"jsdom": "^26.1.0",
|
|
51
|
-
"rimraf": "^6.0.1",
|
|
52
51
|
"typescript": "^5.8.3",
|
|
53
52
|
"vitest": "3.2.4"
|
|
54
53
|
},
|
|
@@ -56,4 +55,4 @@
|
|
|
56
55
|
"type": "git",
|
|
57
56
|
"url": "git+https://github.com/getfjell/registry.git"
|
|
58
57
|
}
|
|
59
|
-
}
|
|
58
|
+
}
|
package/vitest.config.ts
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
/// <reference types="vitest" />
|
|
2
2
|
import { defineConfig } from 'vitest/config'
|
|
3
|
-
import { resolve } from 'path'
|
|
4
3
|
|
|
5
4
|
export default defineConfig({
|
|
6
|
-
resolve: {
|
|
7
|
-
alias: {
|
|
8
|
-
'@': resolve(__dirname, './src'),
|
|
9
|
-
},
|
|
10
|
-
},
|
|
11
5
|
test: {
|
|
12
6
|
environment: 'jsdom',
|
|
13
7
|
setupFiles: ['./tests/setup.ts'],
|