@vibe-agent-toolkit/resources 0.1.0 → 0.1.1
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 +223 -1
- package/dist/checksum.d.ts +9 -0
- package/dist/checksum.d.ts.map +1 -0
- package/dist/checksum.js +16 -0
- package/dist/checksum.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/resource-collection-interface.d.ts +70 -0
- package/dist/resource-collection-interface.d.ts.map +1 -0
- package/dist/resource-collection-interface.js +16 -0
- package/dist/resource-collection-interface.js.map +1 -0
- package/dist/resource-collection.d.ts +87 -0
- package/dist/resource-collection.d.ts.map +1 -0
- package/dist/resource-collection.js +131 -0
- package/dist/resource-collection.js.map +1 -0
- package/dist/resource-query.d.ts +136 -0
- package/dist/resource-query.d.ts.map +1 -0
- package/dist/resource-query.js +153 -0
- package/dist/resource-query.js.map +1 -0
- package/dist/resource-registry.d.ts +171 -1
- package/dist/resource-registry.d.ts.map +1 -1
- package/dist/resource-registry.js +249 -30
- package/dist/resource-registry.js.map +1 -1
- package/dist/schemas/checksum.d.ts +8 -0
- package/dist/schemas/checksum.d.ts.map +1 -0
- package/dist/schemas/checksum.js +11 -0
- package/dist/schemas/checksum.js.map +1 -0
- package/dist/schemas/resource-metadata.d.ts +9 -6
- package/dist/schemas/resource-metadata.d.ts.map +1 -1
- package/dist/schemas/resource-metadata.js +2 -0
- package/dist/schemas/resource-metadata.js.map +1 -1
- package/dist/schemas/validation-result.d.ts +6 -6
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +19 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +38 -0
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/checksum.ts +18 -0
- package/src/index.ts +9 -0
- package/src/resource-collection-interface.ts +75 -0
- package/src/resource-collection.ts +142 -0
- package/src/resource-query.ts +175 -0
- package/src/resource-registry.ts +281 -35
- package/src/schemas/checksum.ts +13 -0
- package/src/schemas/resource-metadata.ts +3 -0
- package/src/types.ts +4 -0
- package/src/utils.ts +43 -0
package/README.md
CHANGED
|
@@ -8,7 +8,9 @@ Markdown resource parsing, validation, and link integrity checking for AI agent
|
|
|
8
8
|
- **Validate link integrity** - Check local file links, anchor links, and detect broken references
|
|
9
9
|
- **Track resource collections** - Manage multiple markdown files with automatic ID generation
|
|
10
10
|
- **Resolve cross-references** - Link resources together and track dependencies
|
|
11
|
-
- **Query capabilities** - Find resources by path, ID, or glob patterns
|
|
11
|
+
- **Query capabilities** - Find resources by path, ID, or glob patterns with lazy evaluation
|
|
12
|
+
- **Duplicate detection** - Identify duplicate content using SHA-256 checksums
|
|
13
|
+
- **Collection operations** - Filter, transform, and materialize resource collections efficiently
|
|
12
14
|
- **GitHub Flavored Markdown** - Full support for GFM including tables, task lists, and autolinks
|
|
13
15
|
|
|
14
16
|
## Installation
|
|
@@ -239,6 +241,226 @@ registry.clear();
|
|
|
239
241
|
console.log(registry.getAllResources().length); // 0
|
|
240
242
|
```
|
|
241
243
|
|
|
244
|
+
##### size(): number
|
|
245
|
+
|
|
246
|
+
Get the number of resources in the registry.
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
console.log(`Registry has ${registry.size()} resources`);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
##### isEmpty(): boolean
|
|
253
|
+
|
|
254
|
+
Check if the registry is empty.
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
if (registry.isEmpty()) {
|
|
258
|
+
console.log('No resources yet');
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
##### getDuplicates(): ResourceMetadata[][]
|
|
263
|
+
|
|
264
|
+
Get groups of duplicate resources based on content checksum.
|
|
265
|
+
|
|
266
|
+
Returns an array where each element is an array of resources that have identical content. Only groups with 2+ resources are included.
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
const duplicates = registry.getDuplicates();
|
|
270
|
+
for (const group of duplicates) {
|
|
271
|
+
console.log(`Found ${group.length} duplicates:`);
|
|
272
|
+
for (const resource of group) {
|
|
273
|
+
console.log(` - ${resource.filePath}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
##### getUniqueByChecksum(): ResourceMetadata[]
|
|
279
|
+
|
|
280
|
+
Get one representative resource for each unique checksum.
|
|
281
|
+
|
|
282
|
+
When multiple resources have identical content, only the first one encountered is included.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const unique = registry.getUniqueByChecksum();
|
|
286
|
+
console.log(`${unique.length} unique resources by content`);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
##### getResourcesByName(name: string): ResourceMetadata[]
|
|
290
|
+
|
|
291
|
+
Get resources by filename (basename).
|
|
292
|
+
|
|
293
|
+
Returns all resources with the given filename, regardless of directory. Useful for finding duplicate filenames across the project.
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
const readmeFiles = registry.getResourcesByName('README.md');
|
|
297
|
+
console.log(`Found ${readmeFiles.length} README.md files`);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
##### getResourcesByChecksum(checksum: SHA256): ResourceMetadata[]
|
|
301
|
+
|
|
302
|
+
Get resources by SHA-256 checksum.
|
|
303
|
+
|
|
304
|
+
Returns all resources with the given content checksum (i.e., identical content).
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
const resource = registry.getResourceById('readme');
|
|
308
|
+
if (resource) {
|
|
309
|
+
const sameContent = registry.getResourcesByChecksum(resource.checksum);
|
|
310
|
+
console.log(`Found ${sameContent.length} files with identical content`);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### ResourceQuery
|
|
315
|
+
|
|
316
|
+
Lazy query builder for filtering and transforming resource collections.
|
|
317
|
+
|
|
318
|
+
Operations are stored and only executed when `execute()` or `toCollection()` is called, allowing for efficient chaining and optimization.
|
|
319
|
+
|
|
320
|
+
#### Creating Queries
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
import { ResourceQuery } from '@vibe-agent-toolkit/resources';
|
|
324
|
+
|
|
325
|
+
const query = ResourceQuery.from(registry.getAllResources());
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
#### Methods
|
|
329
|
+
|
|
330
|
+
##### filter(predicate: (resource: ResourceMetadata) => boolean): this
|
|
331
|
+
|
|
332
|
+
Filter resources by a predicate function.
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
const query = ResourceQuery.from(resources)
|
|
336
|
+
.filter(r => r.links.length > 0)
|
|
337
|
+
.filter(r => r.sizeBytes < 10000);
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
##### map(transformer: (resource: ResourceMetadata) => ResourceMetadata): this
|
|
341
|
+
|
|
342
|
+
Transform resources with a mapping function.
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
const query = ResourceQuery.from(resources)
|
|
346
|
+
.map(r => ({ ...r, id: r.id.toUpperCase() }));
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
##### matchesPattern(pattern: string): this
|
|
350
|
+
|
|
351
|
+
Filter resources by glob pattern matching their file paths.
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
const query = ResourceQuery.from(resources)
|
|
355
|
+
.matchesPattern('docs/**/*.md')
|
|
356
|
+
.matchesPattern('*.ts');
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
##### execute(): ResourceMetadata[]
|
|
360
|
+
|
|
361
|
+
Execute the query and return the results as an array.
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
const results = query.execute();
|
|
365
|
+
console.log(`Found ${results.length} resources`);
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
##### toCollection(): ResourceCollection
|
|
369
|
+
|
|
370
|
+
Execute the query and return a ResourceCollection.
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
const collection = query.toCollection();
|
|
374
|
+
const duplicates = collection.getDuplicates();
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
#### Example Workflows
|
|
378
|
+
|
|
379
|
+
**Find all docs with links:**
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
const docsWithLinks = ResourceQuery.from(registry.getAllResources())
|
|
383
|
+
.matchesPattern('docs/**/*.md')
|
|
384
|
+
.filter(r => r.links.length > 0)
|
|
385
|
+
.execute();
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Get unique API docs:**
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
const uniqueApiDocs = ResourceQuery.from(registry.getAllResources())
|
|
392
|
+
.matchesPattern('**/api/**')
|
|
393
|
+
.toCollection()
|
|
394
|
+
.getUniqueByChecksum();
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### ResourceCollection
|
|
398
|
+
|
|
399
|
+
Immutable collection of resources with lazy duplicate detection.
|
|
400
|
+
|
|
401
|
+
ResourceCollection wraps an array of resources and provides efficient duplicate detection. Duplicate detection is performed lazily - checksum indexes are only built when `getDuplicates()` or `getUniqueByChecksum()` is first called.
|
|
402
|
+
|
|
403
|
+
#### Creating Collections
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
import { ResourceCollection } from '@vibe-agent-toolkit/resources';
|
|
407
|
+
|
|
408
|
+
const collection = new ResourceCollection([resource1, resource2, resource3]);
|
|
409
|
+
|
|
410
|
+
// Or from a query
|
|
411
|
+
const collection = ResourceQuery.from(registry.getAllResources())
|
|
412
|
+
.filter(r => r.sizeBytes > 1000)
|
|
413
|
+
.toCollection();
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
#### Methods
|
|
417
|
+
|
|
418
|
+
##### size(): number
|
|
419
|
+
|
|
420
|
+
Get the number of resources in the collection.
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
console.log(`Collection has ${collection.size()} resources`);
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
##### isEmpty(): boolean
|
|
427
|
+
|
|
428
|
+
Check if the collection is empty.
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
if (collection.isEmpty()) {
|
|
432
|
+
console.log('Empty collection');
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
##### getAllResources(): ResourceMetadata[]
|
|
437
|
+
|
|
438
|
+
Get all resources in the collection.
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
const all = collection.getAllResources();
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
##### getDuplicates(): ResourceMetadata[][]
|
|
445
|
+
|
|
446
|
+
Get groups of duplicate resources based on checksum.
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
const duplicates = collection.getDuplicates();
|
|
450
|
+
for (const group of duplicates) {
|
|
451
|
+
console.log(`${group.length} files with identical content`);
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
##### getUniqueByChecksum(): ResourceMetadata[]
|
|
456
|
+
|
|
457
|
+
Get one representative resource for each unique checksum.
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
const unique = collection.getUniqueByChecksum();
|
|
461
|
+
console.log(`${unique.length} unique resources`);
|
|
462
|
+
```
|
|
463
|
+
|
|
242
464
|
## Type Definitions
|
|
243
465
|
|
|
244
466
|
### ResourceMetadata
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SHA256 } from './schemas/checksum.js';
|
|
2
|
+
/**
|
|
3
|
+
* Calculate SHA-256 checksum of a file
|
|
4
|
+
* @param filePath Absolute path to file
|
|
5
|
+
* @returns SHA-256 checksum as lowercase hex string
|
|
6
|
+
* @throws Error if file cannot be read
|
|
7
|
+
*/
|
|
8
|
+
export declare function calculateChecksum(filePath: string): Promise<SHA256>;
|
|
9
|
+
//# sourceMappingURL=checksum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum.d.ts","sourceRoot":"","sources":["../src/checksum.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKzE"}
|
package/dist/checksum.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import { SHA256Schema } from './schemas/checksum.js';
|
|
4
|
+
/**
|
|
5
|
+
* Calculate SHA-256 checksum of a file
|
|
6
|
+
* @param filePath Absolute path to file
|
|
7
|
+
* @returns SHA-256 checksum as lowercase hex string
|
|
8
|
+
* @throws Error if file cannot be read
|
|
9
|
+
*/
|
|
10
|
+
export async function calculateChecksum(filePath) {
|
|
11
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
12
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
13
|
+
const hash = createHash('sha256').update(content, 'utf-8').digest('hex');
|
|
14
|
+
return SHA256Schema.parse(hash);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=checksum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum.js","sourceRoot":"","sources":["../src/checksum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IACtD,mEAAmE;IACnE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzE,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,9 @@
|
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
export { ResourceRegistry, type CrawlOptions, type ResourceRegistryOptions, type RegistryStats, } from './resource-registry.js';
|
|
29
|
+
export { ResourceQuery } from './resource-query.js';
|
|
30
|
+
export { ResourceCollection } from './resource-collection.js';
|
|
31
|
+
export type { ResourceCollectionInterface } from './resource-collection-interface.js';
|
|
29
32
|
export type { LinkType, HeadingNode, ResourceLink, ResourceMetadata, ValidationSeverity, ValidationIssue, ValidationResult, } from './types.js';
|
|
30
33
|
export { LinkTypeSchema, HeadingNodeSchema, ResourceLinkSchema, ResourceMetadataSchema, } from './schemas/resource-metadata.js';
|
|
31
34
|
export { ValidationSeveritySchema, ValidationIssueSchema, ValidationResultSchema, } from './schemas/validation-result.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EACL,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EACL,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAG9D,YAAY,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAGtF,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
*/
|
|
28
28
|
// Export main ResourceRegistry class
|
|
29
29
|
export { ResourceRegistry, } from './resource-registry.js';
|
|
30
|
+
// Export ResourceQuery for lazy evaluation and filtering
|
|
31
|
+
export { ResourceQuery } from './resource-query.js';
|
|
32
|
+
// Export ResourceCollection for immutable collections with lazy duplicate detection
|
|
33
|
+
export { ResourceCollection } from './resource-collection.js';
|
|
30
34
|
// Export schemas for external use (e.g., JSON Schema generation, runtime validation)
|
|
31
35
|
export { LinkTypeSchema, HeadingNodeSchema, ResourceLinkSchema, ResourceMetadataSchema, } from './schemas/resource-metadata.js';
|
|
32
36
|
export { ValidationSeveritySchema, ValidationIssueSchema, ValidationResultSchema, } from './schemas/validation-result.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,qCAAqC;AACrC,OAAO,EACL,gBAAgB,GAIjB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,qCAAqC;AACrC,OAAO,EACL,gBAAgB,GAIjB,MAAM,wBAAwB,CAAC;AAEhC,yDAAyD;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,oFAAoF;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAgB9D,qFAAqF;AACrF,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;AAExC,iDAAiD;AACjD,OAAO,EAAE,aAAa,EAAoB,MAAM,kBAAkB,CAAC;AAEnE,kEAAkE;AAClE,0EAA0E"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for resource collections that support duplicate detection and filtering.
|
|
3
|
+
*
|
|
4
|
+
* This interface is implemented by ResourceRegistry and ResourceCollection
|
|
5
|
+
* to provide a consistent API for working with collections of resources.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const collection: ResourceCollectionInterface = new ResourceRegistry();
|
|
10
|
+
* console.log(collection.size());
|
|
11
|
+
* console.log(collection.isEmpty());
|
|
12
|
+
* const duplicates = collection.getDuplicates();
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
import type { ResourceMetadata } from './schemas/resource-metadata.js';
|
|
16
|
+
/**
|
|
17
|
+
* Interface for collections of resources with duplicate detection.
|
|
18
|
+
*/
|
|
19
|
+
export interface ResourceCollectionInterface {
|
|
20
|
+
/**
|
|
21
|
+
* Get the number of resources in the collection.
|
|
22
|
+
*
|
|
23
|
+
* @returns Number of resources
|
|
24
|
+
*/
|
|
25
|
+
size(): number;
|
|
26
|
+
/**
|
|
27
|
+
* Check if the collection is empty.
|
|
28
|
+
*
|
|
29
|
+
* @returns True if the collection has no resources
|
|
30
|
+
*/
|
|
31
|
+
isEmpty(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Get all resources in the collection.
|
|
34
|
+
*
|
|
35
|
+
* @returns Array of all resources
|
|
36
|
+
*/
|
|
37
|
+
getAllResources(): ResourceMetadata[];
|
|
38
|
+
/**
|
|
39
|
+
* Get groups of duplicate resources based on checksum.
|
|
40
|
+
*
|
|
41
|
+
* Returns an array where each element is an array of resources
|
|
42
|
+
* that have the same checksum (i.e., identical content).
|
|
43
|
+
* Only groups with 2+ resources are included.
|
|
44
|
+
*
|
|
45
|
+
* @returns Array of duplicate groups
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const duplicates = collection.getDuplicates();
|
|
50
|
+
* // [[resource1, resource2], [resource3, resource4, resource5]]
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
getDuplicates(): ResourceMetadata[][];
|
|
54
|
+
/**
|
|
55
|
+
* Get one representative resource for each unique checksum.
|
|
56
|
+
*
|
|
57
|
+
* When multiple resources have the same checksum, only the first
|
|
58
|
+
* one encountered is included in the result.
|
|
59
|
+
*
|
|
60
|
+
* @returns Array of unique resources (one per checksum)
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const unique = collection.getUniqueByChecksum();
|
|
65
|
+
* // All resources have different checksums
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
getUniqueByChecksum(): ResourceMetadata[];
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=resource-collection-interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-collection-interface.d.ts","sourceRoot":"","sources":["../src/resource-collection-interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,IAAI,IAAI,MAAM,CAAC;IAEf;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC;IAEnB;;;;OAIG;IACH,eAAe,IAAI,gBAAgB,EAAE,CAAC;IAEtC;;;;;;;;;;;;;;OAcG;IACH,aAAa,IAAI,gBAAgB,EAAE,EAAE,CAAC;IAEtC;;;;;;;;;;;;;OAaG;IACH,mBAAmB,IAAI,gBAAgB,EAAE,CAAC;CAC3C"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for resource collections that support duplicate detection and filtering.
|
|
3
|
+
*
|
|
4
|
+
* This interface is implemented by ResourceRegistry and ResourceCollection
|
|
5
|
+
* to provide a consistent API for working with collections of resources.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const collection: ResourceCollectionInterface = new ResourceRegistry();
|
|
10
|
+
* console.log(collection.size());
|
|
11
|
+
* console.log(collection.isEmpty());
|
|
12
|
+
* const duplicates = collection.getDuplicates();
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=resource-collection-interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-collection-interface.js","sourceRoot":"","sources":["../src/resource-collection-interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Immutable collection of resources with lazy duplicate detection.
|
|
3
|
+
*
|
|
4
|
+
* ResourceCollection wraps an array of resources and provides efficient
|
|
5
|
+
* duplicate detection and filtering operations. Duplicate detection is
|
|
6
|
+
* performed lazily - the collection builds checksum indexes only when
|
|
7
|
+
* getDuplicates() or getUniqueByChecksum() is first called.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const collection = new ResourceCollection([resource1, resource2, resource3]);
|
|
12
|
+
*
|
|
13
|
+
* console.log(collection.size());
|
|
14
|
+
* const duplicates = collection.getDuplicates();
|
|
15
|
+
* const unique = collection.getUniqueByChecksum();
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import type { ResourceCollectionInterface } from './resource-collection-interface.js';
|
|
19
|
+
import type { ResourceMetadata } from './schemas/resource-metadata.js';
|
|
20
|
+
/**
|
|
21
|
+
* Immutable collection of resources with lazy duplicate detection.
|
|
22
|
+
*
|
|
23
|
+
* This class implements the ResourceCollectionInterface and provides
|
|
24
|
+
* efficient operations for working with collections of resources.
|
|
25
|
+
* Duplicate detection is lazy - checksum indexes are only built when needed.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ResourceCollection implements ResourceCollectionInterface {
|
|
28
|
+
private readonly resources;
|
|
29
|
+
private checksumIndex;
|
|
30
|
+
/**
|
|
31
|
+
* Create a new ResourceCollection from an array of resources.
|
|
32
|
+
*
|
|
33
|
+
* @param resources - Array of resources to wrap
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const collection = new ResourceCollection([resource1, resource2]);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
constructor(resources: ResourceMetadata[]);
|
|
41
|
+
/**
|
|
42
|
+
* Get the number of resources in the collection.
|
|
43
|
+
*
|
|
44
|
+
* @returns Number of resources
|
|
45
|
+
*/
|
|
46
|
+
size(): number;
|
|
47
|
+
/**
|
|
48
|
+
* Check if the collection is empty.
|
|
49
|
+
*
|
|
50
|
+
* @returns True if the collection has no resources
|
|
51
|
+
*/
|
|
52
|
+
isEmpty(): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Get all resources in the collection.
|
|
55
|
+
*
|
|
56
|
+
* @returns Array of all resources
|
|
57
|
+
*/
|
|
58
|
+
getAllResources(): ResourceMetadata[];
|
|
59
|
+
/**
|
|
60
|
+
* Get groups of duplicate resources based on checksum.
|
|
61
|
+
*
|
|
62
|
+
* Lazily builds a checksum index on first call. Returns an array where
|
|
63
|
+
* each element is an array of resources that have the same checksum
|
|
64
|
+
* (i.e., identical content). Only groups with 2+ resources are included.
|
|
65
|
+
*
|
|
66
|
+
* @returns Array of duplicate groups
|
|
67
|
+
*/
|
|
68
|
+
getDuplicates(): ResourceMetadata[][];
|
|
69
|
+
/**
|
|
70
|
+
* Get one representative resource for each unique checksum.
|
|
71
|
+
*
|
|
72
|
+
* Lazily builds a checksum index on first call. When multiple resources
|
|
73
|
+
* have the same checksum, only the first one encountered is included
|
|
74
|
+
* in the result.
|
|
75
|
+
*
|
|
76
|
+
* @returns Array of unique resources (one per checksum)
|
|
77
|
+
*/
|
|
78
|
+
getUniqueByChecksum(): ResourceMetadata[];
|
|
79
|
+
/**
|
|
80
|
+
* Ensure the checksum index is built.
|
|
81
|
+
*
|
|
82
|
+
* Builds the index on first call, subsequent calls do nothing.
|
|
83
|
+
* This provides lazy evaluation for duplicate detection.
|
|
84
|
+
*/
|
|
85
|
+
private ensureChecksumIndex;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=resource-collection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-collection.d.ts","sourceRoot":"","sources":["../src/resource-collection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAEtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE;;;;;;GAMG;AACH,qBAAa,kBAAmB,YAAW,2BAA2B;IACpE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,aAAa,CAAgD;IAErE;;;;;;;;;OASG;gBACS,SAAS,EAAE,gBAAgB,EAAE;IAIzC;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAId;;;;OAIG;IACH,OAAO,IAAI,OAAO;IAIlB;;;;OAIG;IACH,eAAe,IAAI,gBAAgB,EAAE;IAIrC;;;;;;;;OAQG;IACH,aAAa,IAAI,gBAAgB,EAAE,EAAE;IAcrC;;;;;;;;OAQG;IACH,mBAAmB,IAAI,gBAAgB,EAAE;IAczC;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;CAe5B"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Immutable collection of resources with lazy duplicate detection.
|
|
3
|
+
*
|
|
4
|
+
* ResourceCollection wraps an array of resources and provides efficient
|
|
5
|
+
* duplicate detection and filtering operations. Duplicate detection is
|
|
6
|
+
* performed lazily - the collection builds checksum indexes only when
|
|
7
|
+
* getDuplicates() or getUniqueByChecksum() is first called.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const collection = new ResourceCollection([resource1, resource2, resource3]);
|
|
12
|
+
*
|
|
13
|
+
* console.log(collection.size());
|
|
14
|
+
* const duplicates = collection.getDuplicates();
|
|
15
|
+
* const unique = collection.getUniqueByChecksum();
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Immutable collection of resources with lazy duplicate detection.
|
|
20
|
+
*
|
|
21
|
+
* This class implements the ResourceCollectionInterface and provides
|
|
22
|
+
* efficient operations for working with collections of resources.
|
|
23
|
+
* Duplicate detection is lazy - checksum indexes are only built when needed.
|
|
24
|
+
*/
|
|
25
|
+
export class ResourceCollection {
|
|
26
|
+
resources;
|
|
27
|
+
checksumIndex = null;
|
|
28
|
+
/**
|
|
29
|
+
* Create a new ResourceCollection from an array of resources.
|
|
30
|
+
*
|
|
31
|
+
* @param resources - Array of resources to wrap
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const collection = new ResourceCollection([resource1, resource2]);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
constructor(resources) {
|
|
39
|
+
this.resources = resources;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the number of resources in the collection.
|
|
43
|
+
*
|
|
44
|
+
* @returns Number of resources
|
|
45
|
+
*/
|
|
46
|
+
size() {
|
|
47
|
+
return this.resources.length;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if the collection is empty.
|
|
51
|
+
*
|
|
52
|
+
* @returns True if the collection has no resources
|
|
53
|
+
*/
|
|
54
|
+
isEmpty() {
|
|
55
|
+
return this.resources.length === 0;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get all resources in the collection.
|
|
59
|
+
*
|
|
60
|
+
* @returns Array of all resources
|
|
61
|
+
*/
|
|
62
|
+
getAllResources() {
|
|
63
|
+
return this.resources;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get groups of duplicate resources based on checksum.
|
|
67
|
+
*
|
|
68
|
+
* Lazily builds a checksum index on first call. Returns an array where
|
|
69
|
+
* each element is an array of resources that have the same checksum
|
|
70
|
+
* (i.e., identical content). Only groups with 2+ resources are included.
|
|
71
|
+
*
|
|
72
|
+
* @returns Array of duplicate groups
|
|
73
|
+
*/
|
|
74
|
+
getDuplicates() {
|
|
75
|
+
this.ensureChecksumIndex();
|
|
76
|
+
if (!this.checksumIndex) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
const duplicateGroups = [];
|
|
80
|
+
for (const group of this.checksumIndex.values()) {
|
|
81
|
+
if (group.length >= 2) {
|
|
82
|
+
duplicateGroups.push(group);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return duplicateGroups;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get one representative resource for each unique checksum.
|
|
89
|
+
*
|
|
90
|
+
* Lazily builds a checksum index on first call. When multiple resources
|
|
91
|
+
* have the same checksum, only the first one encountered is included
|
|
92
|
+
* in the result.
|
|
93
|
+
*
|
|
94
|
+
* @returns Array of unique resources (one per checksum)
|
|
95
|
+
*/
|
|
96
|
+
getUniqueByChecksum() {
|
|
97
|
+
this.ensureChecksumIndex();
|
|
98
|
+
if (!this.checksumIndex) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
const unique = [];
|
|
102
|
+
for (const group of this.checksumIndex.values()) {
|
|
103
|
+
if (group[0]) {
|
|
104
|
+
unique.push(group[0]);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return unique;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Ensure the checksum index is built.
|
|
111
|
+
*
|
|
112
|
+
* Builds the index on first call, subsequent calls do nothing.
|
|
113
|
+
* This provides lazy evaluation for duplicate detection.
|
|
114
|
+
*/
|
|
115
|
+
ensureChecksumIndex() {
|
|
116
|
+
if (this.checksumIndex !== null) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.checksumIndex = new Map();
|
|
120
|
+
for (const resource of this.resources) {
|
|
121
|
+
const group = this.checksumIndex.get(resource.checksum);
|
|
122
|
+
if (group) {
|
|
123
|
+
group.push(resource);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.checksumIndex.set(resource.checksum, [resource]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=resource-collection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-collection.js","sourceRoot":"","sources":["../src/resource-collection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;;;;;GAMG;AACH,MAAM,OAAO,kBAAkB;IACZ,SAAS,CAAqB;IACvC,aAAa,GAA2C,IAAI,CAAC;IAErE;;;;;;;;;OASG;IACH,YAAY,SAA6B;QACvC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa;QACX,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,eAAe,GAAyB,EAAE,CAAC;QACjD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBACtB,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QACD,OAAO,eAAe,CAAC;IACzB,CAAC;IAED;;;;;;;;OAQG;IACH,mBAAmB;QACjB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,MAAM,GAAuB,EAAE,CAAC;QACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACK,mBAAmB;QACzB,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAC/B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxD,IAAI,KAAK,EAAE,CAAC;gBACV,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|