promidas 2.0.0
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/LICENSE +21 -0
- package/README.md +179 -0
- package/dist/builder.d.ts +158 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +255 -0
- package/dist/builder.js.map +1 -0
- package/dist/factory.d.ts +154 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +243 -0
- package/dist/factory.js.map +1 -0
- package/dist/fetcher/client/config.d.ts +140 -0
- package/dist/fetcher/client/config.d.ts.map +1 -0
- package/dist/fetcher/client/config.js +2 -0
- package/dist/fetcher/client/config.js.map +1 -0
- package/dist/fetcher/client/fetch-with-progress.d.ts +156 -0
- package/dist/fetcher/client/fetch-with-progress.d.ts.map +1 -0
- package/dist/fetcher/client/fetch-with-progress.js +313 -0
- package/dist/fetcher/client/fetch-with-progress.js.map +1 -0
- package/dist/fetcher/client/fetch-with-timeout.d.ts +6 -0
- package/dist/fetcher/client/fetch-with-timeout.d.ts.map +1 -0
- package/dist/fetcher/client/fetch-with-timeout.js +48 -0
- package/dist/fetcher/client/fetch-with-timeout.js.map +1 -0
- package/dist/fetcher/client/protopedia-api-custom-client.d.ts +141 -0
- package/dist/fetcher/client/protopedia-api-custom-client.d.ts.map +1 -0
- package/dist/fetcher/client/protopedia-api-custom-client.js +268 -0
- package/dist/fetcher/client/protopedia-api-custom-client.js.map +1 -0
- package/dist/fetcher/client/select-custom-fetch.d.ts +58 -0
- package/dist/fetcher/client/select-custom-fetch.d.ts.map +1 -0
- package/dist/fetcher/client/select-custom-fetch.js +58 -0
- package/dist/fetcher/client/select-custom-fetch.js.map +1 -0
- package/dist/fetcher/errors/fetcher-error.d.ts +10 -0
- package/dist/fetcher/errors/fetcher-error.d.ts.map +1 -0
- package/dist/fetcher/errors/fetcher-error.js +15 -0
- package/dist/fetcher/errors/fetcher-error.js.map +1 -0
- package/dist/fetcher/index.d.ts +73 -0
- package/dist/fetcher/index.d.ts.map +1 -0
- package/dist/fetcher/index.js +70 -0
- package/dist/fetcher/index.js.map +1 -0
- package/dist/fetcher/types/index.d.ts +9 -0
- package/dist/fetcher/types/index.d.ts.map +1 -0
- package/dist/fetcher/types/index.js +7 -0
- package/dist/fetcher/types/index.js.map +1 -0
- package/dist/fetcher/types/progress-event.types.d.ts +221 -0
- package/dist/fetcher/types/progress-event.types.d.ts.map +1 -0
- package/dist/fetcher/types/progress-event.types.js +10 -0
- package/dist/fetcher/types/progress-event.types.js.map +1 -0
- package/dist/fetcher/types/prototype-api.types.d.ts +106 -0
- package/dist/fetcher/types/prototype-api.types.d.ts.map +1 -0
- package/dist/fetcher/types/prototype-api.types.js +2 -0
- package/dist/fetcher/types/prototype-api.types.js.map +1 -0
- package/dist/fetcher/types/result.types.d.ts +75 -0
- package/dist/fetcher/types/result.types.d.ts.map +1 -0
- package/dist/fetcher/types/result.types.js +2 -0
- package/dist/fetcher/types/result.types.js.map +1 -0
- package/dist/fetcher/utils/create-client-fetch.d.ts +63 -0
- package/dist/fetcher/utils/create-client-fetch.d.ts.map +1 -0
- package/dist/fetcher/utils/create-client-fetch.js +89 -0
- package/dist/fetcher/utils/create-client-fetch.js.map +1 -0
- package/dist/fetcher/utils/create-fetch-with-stripped-headers.d.ts +6 -0
- package/dist/fetcher/utils/create-fetch-with-stripped-headers.d.ts.map +1 -0
- package/dist/fetcher/utils/create-fetch-with-stripped-headers.js +40 -0
- package/dist/fetcher/utils/create-fetch-with-stripped-headers.js.map +1 -0
- package/dist/fetcher/utils/errors/handler.d.ts +58 -0
- package/dist/fetcher/utils/errors/handler.d.ts.map +1 -0
- package/dist/fetcher/utils/errors/handler.js +243 -0
- package/dist/fetcher/utils/errors/handler.js.map +1 -0
- package/dist/fetcher/utils/errors/messages.d.ts +75 -0
- package/dist/fetcher/utils/errors/messages.d.ts.map +1 -0
- package/dist/fetcher/utils/errors/messages.js +88 -0
- package/dist/fetcher/utils/errors/messages.js.map +1 -0
- package/dist/fetcher/utils/index.d.ts +13 -0
- package/dist/fetcher/utils/index.d.ts.map +1 -0
- package/dist/fetcher/utils/index.js +12 -0
- package/dist/fetcher/utils/index.js.map +1 -0
- package/dist/fetcher/utils/log-timestamp-normalization-warnings.d.ts +10 -0
- package/dist/fetcher/utils/log-timestamp-normalization-warnings.d.ts.map +1 -0
- package/dist/fetcher/utils/log-timestamp-normalization-warnings.js +32 -0
- package/dist/fetcher/utils/log-timestamp-normalization-warnings.js.map +1 -0
- package/dist/fetcher/utils/normalize-protopedia-timestamp.d.ts +59 -0
- package/dist/fetcher/utils/normalize-protopedia-timestamp.d.ts.map +1 -0
- package/dist/fetcher/utils/normalize-protopedia-timestamp.js +81 -0
- package/dist/fetcher/utils/normalize-protopedia-timestamp.js.map +1 -0
- package/dist/fetcher/utils/normalize-prototype.d.ts +56 -0
- package/dist/fetcher/utils/normalize-prototype.d.ts.map +1 -0
- package/dist/fetcher/utils/normalize-prototype.js +113 -0
- package/dist/fetcher/utils/normalize-prototype.js.map +1 -0
- package/dist/fetcher/utils/sanitize-options.d.ts +14 -0
- package/dist/fetcher/utils/sanitize-options.d.ts.map +1 -0
- package/dist/fetcher/utils/sanitize-options.js +16 -0
- package/dist/fetcher/utils/sanitize-options.js.map +1 -0
- package/dist/fetcher/utils/string-parsers.d.ts +45 -0
- package/dist/fetcher/utils/string-parsers.d.ts.map +1 -0
- package/dist/fetcher/utils/string-parsers.js +53 -0
- package/dist/fetcher/utils/string-parsers.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/console-logger.d.ts +74 -0
- package/dist/logger/console-logger.d.ts.map +1 -0
- package/dist/logger/console-logger.js +113 -0
- package/dist/logger/console-logger.js.map +1 -0
- package/dist/logger/factory.d.ts +88 -0
- package/dist/logger/factory.d.ts.map +1 -0
- package/dist/logger/factory.js +94 -0
- package/dist/logger/factory.js.map +1 -0
- package/dist/logger/index.d.ts +42 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +41 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/logger.types.d.ts +49 -0
- package/dist/logger/logger.types.d.ts.map +1 -0
- package/dist/logger/logger.types.js +2 -0
- package/dist/logger/logger.types.js.map +1 -0
- package/dist/repository/errors/validation-error.d.ts +24 -0
- package/dist/repository/errors/validation-error.d.ts.map +1 -0
- package/dist/repository/errors/validation-error.js +26 -0
- package/dist/repository/errors/validation-error.js.map +1 -0
- package/dist/repository/index.d.ts +122 -0
- package/dist/repository/index.d.ts.map +1 -0
- package/dist/repository/index.js +44 -0
- package/dist/repository/index.js.map +1 -0
- package/dist/repository/protopedia-in-memory-repository.d.ts +560 -0
- package/dist/repository/protopedia-in-memory-repository.d.ts.map +1 -0
- package/dist/repository/protopedia-in-memory-repository.js +929 -0
- package/dist/repository/protopedia-in-memory-repository.js.map +1 -0
- package/dist/repository/schemas/index.d.ts +9 -0
- package/dist/repository/schemas/index.d.ts.map +1 -0
- package/dist/repository/schemas/index.js +11 -0
- package/dist/repository/schemas/index.js.map +1 -0
- package/dist/repository/schemas/params.d.ts +44 -0
- package/dist/repository/schemas/params.d.ts.map +1 -0
- package/dist/repository/schemas/params.js +44 -0
- package/dist/repository/schemas/params.js.map +1 -0
- package/dist/repository/schemas/serializable-snapshot.d.ts +33 -0
- package/dist/repository/schemas/serializable-snapshot.d.ts.map +1 -0
- package/dist/repository/schemas/serializable-snapshot.js +45 -0
- package/dist/repository/schemas/serializable-snapshot.js.map +1 -0
- package/dist/repository/types/analysis.types.d.ts +89 -0
- package/dist/repository/types/analysis.types.d.ts.map +1 -0
- package/dist/repository/types/analysis.types.js +2 -0
- package/dist/repository/types/analysis.types.js.map +1 -0
- package/dist/repository/types/index.d.ts +12 -0
- package/dist/repository/types/index.d.ts.map +1 -0
- package/dist/repository/types/index.js +7 -0
- package/dist/repository/types/index.js.map +1 -0
- package/dist/repository/types/repository-events.types.d.ts +110 -0
- package/dist/repository/types/repository-events.types.d.ts.map +1 -0
- package/dist/repository/types/repository-events.types.js +2 -0
- package/dist/repository/types/repository-events.types.js.map +1 -0
- package/dist/repository/types/repository.types.d.ts +330 -0
- package/dist/repository/types/repository.types.d.ts.map +1 -0
- package/dist/repository/types/repository.types.js +2 -0
- package/dist/repository/types/repository.types.js.map +1 -0
- package/dist/repository/types/result.types.d.ts +55 -0
- package/dist/repository/types/result.types.d.ts.map +1 -0
- package/dist/repository/types/result.types.js +2 -0
- package/dist/repository/types/result.types.js.map +1 -0
- package/dist/repository/types/serialization.types.d.ts +61 -0
- package/dist/repository/types/serialization.types.d.ts.map +1 -0
- package/dist/repository/types/serialization.types.js +2 -0
- package/dist/repository/types/serialization.types.js.map +1 -0
- package/dist/repository/types/snapshot-operation.types.d.ts +140 -0
- package/dist/repository/types/snapshot-operation.types.d.ts.map +1 -0
- package/dist/repository/types/snapshot-operation.types.js +2 -0
- package/dist/repository/types/snapshot-operation.types.js.map +1 -0
- package/dist/repository/utils/convert-fetch-result.d.ts +46 -0
- package/dist/repository/utils/convert-fetch-result.d.ts.map +1 -0
- package/dist/repository/utils/convert-fetch-result.js +59 -0
- package/dist/repository/utils/convert-fetch-result.js.map +1 -0
- package/dist/repository/utils/convert-store-result.d.ts +36 -0
- package/dist/repository/utils/convert-store-result.d.ts.map +1 -0
- package/dist/repository/utils/convert-store-result.js +36 -0
- package/dist/repository/utils/convert-store-result.js.map +1 -0
- package/dist/repository/utils/emit-repository-event-safely.d.ts +5 -0
- package/dist/repository/utils/emit-repository-event-safely.d.ts.map +1 -0
- package/dist/repository/utils/emit-repository-event-safely.js +17 -0
- package/dist/repository/utils/emit-repository-event-safely.js.map +1 -0
- package/dist/repository/utils/index.d.ts +3 -0
- package/dist/repository/utils/index.d.ts.map +1 -0
- package/dist/repository/utils/index.js +3 -0
- package/dist/repository/utils/index.js.map +1 -0
- package/dist/repository/validation/index.d.ts +9 -0
- package/dist/repository/validation/index.d.ts.map +1 -0
- package/dist/repository/validation/index.js +10 -0
- package/dist/repository/validation/index.js.map +1 -0
- package/dist/repository/validation/params-validators.d.ts +46 -0
- package/dist/repository/validation/params-validators.d.ts.map +1 -0
- package/dist/repository/validation/params-validators.js +68 -0
- package/dist/repository/validation/params-validators.js.map +1 -0
- package/dist/repository/validation/serializable-snapshot.d.ts +47 -0
- package/dist/repository/validation/serializable-snapshot.d.ts.map +1 -0
- package/dist/repository/validation/serializable-snapshot.js +104 -0
- package/dist/repository/validation/serializable-snapshot.js.map +1 -0
- package/dist/schemas/index.d.ts +8 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +8 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/normalized-prototype.d.ts +56 -0
- package/dist/schemas/normalized-prototype.d.ts.map +1 -0
- package/dist/schemas/normalized-prototype.js +123 -0
- package/dist/schemas/normalized-prototype.js.map +1 -0
- package/dist/store/errors/store-error.d.ts +148 -0
- package/dist/store/errors/store-error.d.ts.map +1 -0
- package/dist/store/errors/store-error.js +156 -0
- package/dist/store/errors/store-error.js.map +1 -0
- package/dist/store/index.d.ts +84 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +83 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/store.d.ts +295 -0
- package/dist/store/store.d.ts.map +1 -0
- package/dist/store/store.js +411 -0
- package/dist/store/store.js.map +1 -0
- package/dist/store/types/index.d.ts +2 -0
- package/dist/store/types/index.d.ts.map +1 -0
- package/dist/store/types/index.js +2 -0
- package/dist/store/types/index.js.map +1 -0
- package/dist/store/types/result.types.d.ts +67 -0
- package/dist/store/types/result.types.d.ts.map +1 -0
- package/dist/store/types/result.types.js +2 -0
- package/dist/store/types/result.types.js.map +1 -0
- package/dist/types/codes.d.ts +44 -0
- package/dist/types/codes.d.ts.map +1 -0
- package/dist/types/codes.js +9 -0
- package/dist/types/codes.js.map +1 -0
- package/dist/types/index.d.ts +61 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +60 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/normalized-prototype.d.ts +95 -0
- package/dist/types/normalized-prototype.d.ts.map +1 -0
- package/dist/types/normalized-prototype.js +2 -0
- package/dist/types/normalized-prototype.js.map +1 -0
- package/dist/utils/converters/index.d.ts +15 -0
- package/dist/utils/converters/index.d.ts.map +1 -0
- package/dist/utils/converters/index.js +15 -0
- package/dist/utils/converters/index.js.map +1 -0
- package/dist/utils/converters/license-type.d.ts +23 -0
- package/dist/utils/converters/license-type.d.ts.map +1 -0
- package/dist/utils/converters/license-type.js +38 -0
- package/dist/utils/converters/license-type.js.map +1 -0
- package/dist/utils/converters/release-flag.d.ts +24 -0
- package/dist/utils/converters/release-flag.d.ts.map +1 -0
- package/dist/utils/converters/release-flag.js +40 -0
- package/dist/utils/converters/release-flag.js.map +1 -0
- package/dist/utils/converters/status.d.ts +23 -0
- package/dist/utils/converters/status.d.ts.map +1 -0
- package/dist/utils/converters/status.js +40 -0
- package/dist/utils/converters/status.js.map +1 -0
- package/dist/utils/converters/thanks-flag.d.ts +25 -0
- package/dist/utils/converters/thanks-flag.d.ts.map +1 -0
- package/dist/utils/converters/thanks-flag.js +41 -0
- package/dist/utils/converters/thanks-flag.js.map +1 -0
- package/dist/utils/deep-merge.d.ts +38 -0
- package/dist/utils/deep-merge.d.ts.map +1 -0
- package/dist/utils/deep-merge.js +85 -0
- package/dist/utils/deep-merge.js.map +1 -0
- package/dist/utils/index.d.ts +80 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +85 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger-utils.d.ts +100 -0
- package/dist/utils/logger-utils.d.ts.map +1 -0
- package/dist/utils/logger-utils.js +265 -0
- package/dist/utils/logger-utils.js.map +1 -0
- package/dist/utils/time/constants.d.ts +14 -0
- package/dist/utils/time/constants.d.ts.map +1 -0
- package/dist/utils/time/constants.js +14 -0
- package/dist/utils/time/constants.js.map +1 -0
- package/dist/utils/time/index.d.ts +28 -0
- package/dist/utils/time/index.d.ts.map +1 -0
- package/dist/utils/time/index.js +28 -0
- package/dist/utils/time/index.js.map +1 -0
- package/dist/utils/time/parser.d.ts +91 -0
- package/dist/utils/time/parser.d.ts.map +1 -0
- package/dist/utils/time/parser.js +143 -0
- package/dist/utils/time/parser.js.map +1 -0
- package/dist/utils/validation/index.d.ts +8 -0
- package/dist/utils/validation/index.d.ts.map +1 -0
- package/dist/utils/validation/index.js +7 -0
- package/dist/utils/validation/index.js.map +1 -0
- package/dist/utils/validation/normalized-prototype.d.ts +64 -0
- package/dist/utils/validation/normalized-prototype.d.ts.map +1 -0
- package/dist/utils/validation/normalized-prototype.js +97 -0
- package/dist/utils/validation/normalized-prototype.js.map +1 -0
- package/dist/utils/validation/types.d.ts +62 -0
- package/dist/utils/validation/types.d.ts.map +1 -0
- package/dist/utils/validation/types.js +8 -0
- package/dist/utils/validation/types.js.map +1 -0
- package/dist/version.d.ts +6 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +138 -0
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory repository implementation for ProtoPedia prototypes.
|
|
3
|
+
*
|
|
4
|
+
* This module contains the concrete implementation of the repository pattern
|
|
5
|
+
* for managing ProtoPedia prototype data in memory with snapshot-based access.
|
|
6
|
+
*
|
|
7
|
+
* ## Architecture
|
|
8
|
+
*
|
|
9
|
+
* The {@link ProtopediaInMemoryRepositoryImpl} class orchestrates:
|
|
10
|
+
*
|
|
11
|
+
* - **API Client**: ProtoPedia API v2 client for fetching prototype data
|
|
12
|
+
* - **Memory Store**: {@link PrototypeInMemoryStore} for snapshot management
|
|
13
|
+
* - **Repository Interface**: {@link ProtopediaInMemoryRepository} for high-level operations
|
|
14
|
+
*
|
|
15
|
+
* ## Design Patterns
|
|
16
|
+
*
|
|
17
|
+
* ### Repository Pattern
|
|
18
|
+
* Abstracts data access behind a clean interface, isolating business logic
|
|
19
|
+
* from data fetching and storage mechanisms.
|
|
20
|
+
*
|
|
21
|
+
* ### Snapshot Isolation
|
|
22
|
+
* All read operations work against an immutable in-memory snapshot.
|
|
23
|
+
* Network I/O only occurs during explicit setup/refresh operations.
|
|
24
|
+
*
|
|
25
|
+
* ### Private Fields
|
|
26
|
+
* Uses ECMAScript private fields (#) for proper encapsulation:
|
|
27
|
+
* - `#store` - Internal memory store instance
|
|
28
|
+
* - `#apiClient` - HTTP client for ProtoPedia API
|
|
29
|
+
* - `#lastFetchParams` - Cache of last fetch parameters
|
|
30
|
+
*
|
|
31
|
+
* ## Performance Optimizations
|
|
32
|
+
*
|
|
33
|
+
* 1. **O(1) Lookups**: Direct Map access by prototype ID
|
|
34
|
+
* 2. **Hybrid Sampling**: Adaptive algorithm based on sample size ratio
|
|
35
|
+
* - Small samples (< 50%): Set-based random selection
|
|
36
|
+
* - Large samples (≥ 50%): Fisher-Yates shuffle
|
|
37
|
+
* 3. **Efficient Checks**: Use `store.size` instead of array operations
|
|
38
|
+
* 4. **Parameter Validation**: Zod schemas for runtime type safety
|
|
39
|
+
*
|
|
40
|
+
* ## Usage Recommendation
|
|
41
|
+
*
|
|
42
|
+
* For normal usage, import from `promidas` instead of direct instantiation:
|
|
43
|
+
* - `createPromidasForLocal()` for local development
|
|
44
|
+
* - `createPromidasForServer()` for server environments
|
|
45
|
+
* - `PromidasRepositoryBuilder` for advanced customization
|
|
46
|
+
*
|
|
47
|
+
* Direct instantiation is only recommended for:
|
|
48
|
+
* - Testing scenarios
|
|
49
|
+
* - Advanced customization needs
|
|
50
|
+
* - Framework integration
|
|
51
|
+
*
|
|
52
|
+
* @module
|
|
53
|
+
* @see {@link ProtopediaInMemoryRepository} for the public interface
|
|
54
|
+
*/
|
|
55
|
+
import { EventEmitter } from 'events';
|
|
56
|
+
import type { ListPrototypesParams } from 'protopedia-api-v2-client';
|
|
57
|
+
import type { DeepReadonly } from 'ts-essentials';
|
|
58
|
+
import { ProtopediaApiCustomClient } from '../fetcher/index.js';
|
|
59
|
+
import { PrototypeInMemoryStore, type PrototypeInMemoryStats, type PrototypeInMemoryStoreConfig } from '../store/index.js';
|
|
60
|
+
import type { NormalizedPrototype } from '../types/index.js';
|
|
61
|
+
import type { ProtopediaInMemoryRepositoryConfig, PrototypeAnalysisResult, SerializableSnapshot, SnapshotOperationResult } from './types/index.js';
|
|
62
|
+
import type { ProtopediaInMemoryRepository } from './index.js';
|
|
63
|
+
/**
|
|
64
|
+
* Implementation class for the ProtoPedia in-memory repository.
|
|
65
|
+
*
|
|
66
|
+
* This class provides the concrete implementation of {@link ProtopediaInMemoryRepository}
|
|
67
|
+
* with full encapsulation using ECMAScript private fields.
|
|
68
|
+
*
|
|
69
|
+
* ## Responsibilities
|
|
70
|
+
*
|
|
71
|
+
* 1. **Dependency Management**
|
|
72
|
+
* - Receives {@link PrototypeInMemoryStore} and {@link ProtopediaApiCustomClient} via DI
|
|
73
|
+
* - Maintains internal state for fetch parameters
|
|
74
|
+
*
|
|
75
|
+
* 2. **Snapshot Operations**
|
|
76
|
+
* - {@link setupSnapshot} - Initial data fetch and population
|
|
77
|
+
* - {@link refreshSnapshot} - Update snapshot with fresh API data
|
|
78
|
+
*
|
|
79
|
+
* 3. **Data Access**
|
|
80
|
+
* - {@link getAllFromSnapshot} - Retrieve all prototypes
|
|
81
|
+
* - {@link getPrototypeFromSnapshotByPrototypeId} - Fast ID lookup
|
|
82
|
+
* - {@link getRandomPrototypeFromSnapshot} - Single random sample
|
|
83
|
+
* - {@link getRandomSampleFromSnapshot} - Multiple random samples
|
|
84
|
+
* - {@link getPrototypeIdsFromSnapshot} - Get all IDs efficiently
|
|
85
|
+
*
|
|
86
|
+
* 4. **Analysis & Metadata**
|
|
87
|
+
* - {@link analyzePrototypes} - Statistical analysis (min/max)
|
|
88
|
+
* - {@link getStats} - Snapshot statistics and TTL info
|
|
89
|
+
* - {@link getConfig} - Store configuration details
|
|
90
|
+
*
|
|
91
|
+
* ## Implementation Details
|
|
92
|
+
*
|
|
93
|
+
* ### Validation
|
|
94
|
+
* All public methods validate their parameters using {@link RepositoryParamsValidator}:
|
|
95
|
+
* - {@link RepositoryParamsValidator.validatePrototypeId} - Ensures valid prototype IDs
|
|
96
|
+
* - {@link RepositoryParamsValidator.validateSampleSize} - Ensures valid sample sizes
|
|
97
|
+
*
|
|
98
|
+
* ### Error Handling
|
|
99
|
+
* Network operations return {@link SnapshotOperationResult}:
|
|
100
|
+
* - `{ ok: true, ... }` - Success with metadata
|
|
101
|
+
* - `{ ok: false, error: string }` - Failure with error message
|
|
102
|
+
*
|
|
103
|
+
* ### Performance
|
|
104
|
+
* - Uses `store.size` for O(1) empty checks
|
|
105
|
+
* - Implements hybrid sampling algorithm (see {@link SAMPLE_SIZE_THRESHOLD_RATIO})
|
|
106
|
+
* - Returns read-only data to prevent accidental mutations
|
|
107
|
+
*
|
|
108
|
+
* ## Usage
|
|
109
|
+
*
|
|
110
|
+
* **Recommended**: Import from `promidas` instead of direct instantiation
|
|
111
|
+
*
|
|
112
|
+
* **Direct instantiation** (advanced):
|
|
113
|
+
* ```typescript
|
|
114
|
+
* // Dependencies must be created manually
|
|
115
|
+
* const store = new PrototypeInMemoryStore({ ... });
|
|
116
|
+
* const client = new ProtopediaApiCustomClient({ ... });
|
|
117
|
+
*
|
|
118
|
+
* const repo = new ProtopediaInMemoryRepositoryImpl({
|
|
119
|
+
* store,
|
|
120
|
+
* apiClient: client
|
|
121
|
+
* });
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @see {@link ProtopediaInMemoryRepository} for the public interface contract
|
|
125
|
+
*/
|
|
126
|
+
export declare class ProtopediaInMemoryRepositoryImpl implements ProtopediaInMemoryRepository {
|
|
127
|
+
#private;
|
|
128
|
+
/**
|
|
129
|
+
* Event emitter for snapshot operation notifications.
|
|
130
|
+
*
|
|
131
|
+
* Only defined when enableEvents: true is set in repository configuration.
|
|
132
|
+
*/
|
|
133
|
+
readonly events?: EventEmitter;
|
|
134
|
+
/**
|
|
135
|
+
* Creates a new ProtoPedia in-memory repository instance.
|
|
136
|
+
*
|
|
137
|
+
* @param dependencies - Dependency injection object
|
|
138
|
+
* @param dependencies.store - Pre-configured in-memory store instance
|
|
139
|
+
* @param dependencies.apiClient - Pre-configured API client instance
|
|
140
|
+
* @param dependencies.repositoryConfig - Repository-level configuration (optional)
|
|
141
|
+
*/
|
|
142
|
+
constructor({ store, apiClient, repositoryConfig, }: {
|
|
143
|
+
store: PrototypeInMemoryStore;
|
|
144
|
+
apiClient: ProtopediaApiCustomClient;
|
|
145
|
+
repositoryConfig?: ProtopediaInMemoryRepositoryConfig;
|
|
146
|
+
});
|
|
147
|
+
/**
|
|
148
|
+
* Fetch and normalize prototypes from the ProtoPedia API.
|
|
149
|
+
*
|
|
150
|
+
* @param params - Fetch parameters to merge with {@link DEFAULT_FETCH_PARAMS}
|
|
151
|
+
* @returns {@link FetchPrototypesResult} from the API client
|
|
152
|
+
*
|
|
153
|
+
* @remarks
|
|
154
|
+
* This method delegates directly to the API client's `fetchPrototypes()` method,
|
|
155
|
+
* which handles all error cases and returns them as {@link FetchPrototypesFailure}
|
|
156
|
+
* instead of throwing exceptions.
|
|
157
|
+
*
|
|
158
|
+
* **Responsibility Separation**:
|
|
159
|
+
* - This method only fetches and normalizes data
|
|
160
|
+
* - The caller is responsible for storing the data via {@link storeSnapshot}
|
|
161
|
+
* - The caller must update lastFetchParams on successful storage
|
|
162
|
+
*
|
|
163
|
+
* **Error Handling**:
|
|
164
|
+
* - The API client never throws exceptions under normal operation
|
|
165
|
+
* - The try-catch block is defensive programming for unexpected cases
|
|
166
|
+
* - All expected errors are returned as part of {@link FetchPrototypesResult}
|
|
167
|
+
*
|
|
168
|
+
* **Logging**:
|
|
169
|
+
* - Success: `debug` level with fetch count and parameters
|
|
170
|
+
* - Failure: No logging (API client layer already logs failures)
|
|
171
|
+
* - Unexpected exceptions: `error` level (defensive fallback)
|
|
172
|
+
*
|
|
173
|
+
* @see {@link ProtopediaApiCustomClient.fetchPrototypes} for API client implementation
|
|
174
|
+
* @internal
|
|
175
|
+
*/
|
|
176
|
+
private fetchAndNormalize;
|
|
177
|
+
/**
|
|
178
|
+
* Store normalized prototypes in the in-memory snapshot.
|
|
179
|
+
*
|
|
180
|
+
* This private method handles:
|
|
181
|
+
* - Storing data via the memory store
|
|
182
|
+
* - Converting store errors to {@link SetFailure}
|
|
183
|
+
* - Logging detailed operation information with sanitized data
|
|
184
|
+
*
|
|
185
|
+
* @param data - Array of normalized prototypes to store
|
|
186
|
+
* @returns {@link SetResult} - Success with stats or failure details
|
|
187
|
+
*
|
|
188
|
+
* @remarks
|
|
189
|
+
* **Error Handling**:
|
|
190
|
+
* - {@link DataSizeExceededError} → {@link SetFailure} with kind='storage_limit'
|
|
191
|
+
* - {@link SizeEstimationError} → {@link SetFailure} with kind='serialization'
|
|
192
|
+
* - Unexpected errors → {@link SetFailure} with kind='unknown'
|
|
193
|
+
*
|
|
194
|
+
* All store errors include `dataState` to indicate whether existing data was preserved.
|
|
195
|
+
*
|
|
196
|
+
* **Logging**:
|
|
197
|
+
* - Success: `debug` level with store size and data size
|
|
198
|
+
* - DataSizeExceededError: `warn` level (configuration issue)
|
|
199
|
+
* - SizeEstimationError: `error` level (serialization failure)
|
|
200
|
+
* - Unexpected errors: `error` level (unknown failures)
|
|
201
|
+
*
|
|
202
|
+
* @internal
|
|
203
|
+
*/
|
|
204
|
+
private storeSnapshot;
|
|
205
|
+
/**
|
|
206
|
+
* Return the configuration used to initialize the underlying store.
|
|
207
|
+
*/
|
|
208
|
+
getConfig(): Omit<Required<PrototypeInMemoryStoreConfig>, 'logger'>;
|
|
209
|
+
/**
|
|
210
|
+
* Return stats for the current snapshot from the underlying store.
|
|
211
|
+
*/
|
|
212
|
+
getStats(): PrototypeInMemoryStats;
|
|
213
|
+
/**
|
|
214
|
+
* Fetch prototypes from the API and store them in memory.
|
|
215
|
+
*
|
|
216
|
+
* This is the core implementation shared by {@link setupSnapshot} and {@link refreshSnapshot}.
|
|
217
|
+
* It encapsulates the complete fetch-and-store workflow with proper error handling and
|
|
218
|
+
* optional parameter caching.
|
|
219
|
+
*
|
|
220
|
+
* @param params - Fetch parameters to merge with {@link DEFAULT_FETCH_PARAMS}
|
|
221
|
+
* @param updateLastFetchParams - Whether to update {@link #lastFetchParams} on successful storage.
|
|
222
|
+
* Set to `true` for {@link setupSnapshot} to cache parameters for future {@link refreshSnapshot} calls.
|
|
223
|
+
* Set to `false` for {@link refreshSnapshot} to avoid overwriting cached parameters.
|
|
224
|
+
* @returns {@link SnapshotOperationResult} indicating success or failure
|
|
225
|
+
*
|
|
226
|
+
* @remarks
|
|
227
|
+
* **Operation Flow**:
|
|
228
|
+
* 1. Fetch and normalize prototypes via {@link fetchAndNormalize}
|
|
229
|
+
* 2. Convert fetch result (both success and failure) via {@link convertFetchResult}
|
|
230
|
+
* 3. Return early if fetch failed
|
|
231
|
+
* 4. Store the fetched data in memory via {@link storeSnapshot}
|
|
232
|
+
* 5. Convert store result via {@link convertStoreResult}
|
|
233
|
+
* 6. Update {@link #lastFetchParams} only if `updateLastFetchParams` is `true` AND storage succeeds
|
|
234
|
+
*
|
|
235
|
+
* **Parameter Handling**:
|
|
236
|
+
* - Input `params` are merged with {@link DEFAULT_FETCH_PARAMS} by {@link fetchAndNormalize}
|
|
237
|
+
* - Merged parameters are cached in {@link #lastFetchParams} only when:
|
|
238
|
+
* - `updateLastFetchParams` is `true` (typically {@link setupSnapshot})
|
|
239
|
+
* - Storage operation succeeds
|
|
240
|
+
* - Failed operations never update {@link #lastFetchParams}
|
|
241
|
+
*
|
|
242
|
+
* **Concurrency Control**:
|
|
243
|
+
* - Uses {@link #executeWithCoalescing} to prevent concurrent API calls
|
|
244
|
+
* - Multiple concurrent calls are coalesced into a single API request
|
|
245
|
+
* - All callers receive the same result
|
|
246
|
+
* - The first caller's operation (fetch + store) is executed
|
|
247
|
+
* - Subsequent concurrent callers wait for the same result
|
|
248
|
+
* - This is necessary because async operations can run concurrently (await allows other calls to start)
|
|
249
|
+
*
|
|
250
|
+
* **Error Handling**:
|
|
251
|
+
* - Returns error result if API fetch fails (network, timeout, API errors)
|
|
252
|
+
* - Returns error result if storage fails (e.g., {@link DataSizeExceededError})
|
|
253
|
+
* - Previous snapshot remains intact on failure
|
|
254
|
+
* - Never throws exceptions - all errors are returned as {@link SnapshotOperationResult}
|
|
255
|
+
*
|
|
256
|
+
* @internal This method is private and used only by {@link setupSnapshot} and {@link refreshSnapshot}.
|
|
257
|
+
* It can be accessed in tests via `(repo as any).fetchAndStore(...)` for unit testing.
|
|
258
|
+
*
|
|
259
|
+
* @see {@link setupSnapshot} for initial snapshot setup with parameter caching
|
|
260
|
+
* @see {@link refreshSnapshot} for refreshing with cached parameters
|
|
261
|
+
*/
|
|
262
|
+
private fetchAndStore;
|
|
263
|
+
/**
|
|
264
|
+
* Initialize the in-memory snapshot using the provided fetch parameters.
|
|
265
|
+
*
|
|
266
|
+
* Typically called once at startup. Fetches data from the API, stores it in memory,
|
|
267
|
+
* and caches the parameters for future {@link refreshSnapshot} calls.
|
|
268
|
+
*
|
|
269
|
+
* @param params - Fetch parameters to merge with {@link DEFAULT_FETCH_PARAMS}
|
|
270
|
+
* @returns {@link SnapshotOperationResult} indicating success or failure
|
|
271
|
+
*
|
|
272
|
+
* @remarks
|
|
273
|
+
* Delegates to {@link fetchAndStore} with `updateLastFetchParams: true`.
|
|
274
|
+
* Emits `snapshotStarted('setup')` event before operation (if events enabled).
|
|
275
|
+
*
|
|
276
|
+
* See {@link fetchAndStore} for operation flow, concurrency control, and error handling details.
|
|
277
|
+
*
|
|
278
|
+
* @see {@link fetchAndStore}
|
|
279
|
+
* @see {@link refreshSnapshot}
|
|
280
|
+
*/
|
|
281
|
+
setupSnapshot(params: ListPrototypesParams): Promise<SnapshotOperationResult>;
|
|
282
|
+
/**
|
|
283
|
+
* Refresh the in-memory snapshot using cached fetch parameters.
|
|
284
|
+
*
|
|
285
|
+
* Typically called periodically to refresh expired data. Uses parameters
|
|
286
|
+
* cached by the last successful {@link setupSnapshot} call.
|
|
287
|
+
*
|
|
288
|
+
* **Prerequisite**: {@link setupSnapshot} must have been called successfully at least once.
|
|
289
|
+
* If called before {@link setupSnapshot}, returns an error with code `REPOSITORY_INVALID_STATE`.
|
|
290
|
+
*
|
|
291
|
+
* @returns Promise resolving to {@link SnapshotOperationResult}:
|
|
292
|
+
* - **Success** (`ok: true`): Contains {@link PrototypeInMemoryStats} with snapshot metadata
|
|
293
|
+
* - **Failure** (`ok: false`): One of:
|
|
294
|
+
* - {@link RepositorySnapshotFailure} - Invalid state (setupSnapshot not called)
|
|
295
|
+
* - {@link FetcherSnapshotFailure} - Network/HTTP errors from API
|
|
296
|
+
* - {@link StoreSnapshotFailure} - Storage errors (size limits, serialization)
|
|
297
|
+
* - {@link UnknownSnapshotFailure} - Unexpected errors
|
|
298
|
+
*
|
|
299
|
+
* @remarks
|
|
300
|
+
* **Operation Flow**:
|
|
301
|
+
* 1. Validate that {@link setupSnapshot} has been called (check `#lastFetchParams`)
|
|
302
|
+
* 2. Return error immediately if validation fails (before coalescing)
|
|
303
|
+
* 3. Emit `snapshotStarted('refresh')` event (if events enabled)
|
|
304
|
+
* 4. Delegate to {@link fetchAndStore} with `updateLastFetchParams: false`
|
|
305
|
+
* 5. Preserve existing snapshot on failure (atomic operation)
|
|
306
|
+
*
|
|
307
|
+
* **Concurrency Control**:
|
|
308
|
+
* - Multiple concurrent calls are coalesced into a single API request
|
|
309
|
+
* - All callers receive the same result
|
|
310
|
+
* - Validation check executes before coalescing, ensuring deterministic failure
|
|
311
|
+
*
|
|
312
|
+
* **Error Handling**:
|
|
313
|
+
* - Never throws exceptions
|
|
314
|
+
* - All errors returned as Result type with `ok: false`
|
|
315
|
+
* - Use `result.origin` to discriminate error types
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* // Typical usage: periodic refresh
|
|
320
|
+
* const result = await repo.refreshSnapshot();
|
|
321
|
+
* if (result.ok) {
|
|
322
|
+
* console.log(`Refreshed ${result.stats.size} prototypes`);
|
|
323
|
+
* } else {
|
|
324
|
+
* console.error(`Refresh failed: ${result.message}`);
|
|
325
|
+
* }
|
|
326
|
+
* ```
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```typescript
|
|
330
|
+
* // Error handling by origin
|
|
331
|
+
* const result = await repo.refreshSnapshot();
|
|
332
|
+
* if (!result.ok) {
|
|
333
|
+
* if (result.origin === 'repository') {
|
|
334
|
+
* console.error('Call setupSnapshot first');
|
|
335
|
+
* } else if (result.origin === 'fetcher') {
|
|
336
|
+
* console.error(`HTTP ${result.status}: ${result.message}`);
|
|
337
|
+
* }
|
|
338
|
+
* }
|
|
339
|
+
* ```
|
|
340
|
+
*
|
|
341
|
+
* @see {@link fetchAndStore} - Core implementation
|
|
342
|
+
* @see {@link setupSnapshot} - Initial snapshot setup
|
|
343
|
+
* @see {@link SnapshotOperationResult} - Return type details
|
|
344
|
+
*/
|
|
345
|
+
refreshSnapshot(): Promise<SnapshotOperationResult>;
|
|
346
|
+
/**
|
|
347
|
+
* Load and validate snapshot data, then store it in memory.
|
|
348
|
+
*
|
|
349
|
+
* This is the core implementation for {@link setupSnapshotFromSerializedData}.
|
|
350
|
+
* It encapsulates the complete validation-and-store workflow with proper error handling.
|
|
351
|
+
*
|
|
352
|
+
* @param data - Serializable snapshot object to validate and store
|
|
353
|
+
* @returns {@link SnapshotOperationResult} indicating success or failure
|
|
354
|
+
*
|
|
355
|
+
* @remarks
|
|
356
|
+
* **Operation Flow**:
|
|
357
|
+
* 1. Validate data structure via {@link validateSerializableSnapshot}
|
|
358
|
+
* 2. Return early if validation failed (origin: 'repository')
|
|
359
|
+
* 3. Store the validated prototypes via {@link storeSnapshot}
|
|
360
|
+
* 4. Return success or store failure result
|
|
361
|
+
*
|
|
362
|
+
* **Concurrency Control**:
|
|
363
|
+
* Unlike {@link fetchAndStore}, this method does NOT use concurrency control because:
|
|
364
|
+
* - This is a synchronous method (no await points)
|
|
365
|
+
* - JavaScript's single-threaded nature prevents concurrent execution
|
|
366
|
+
* - Multiple calls will execute sequentially, not simultaneously
|
|
367
|
+
* - Each call will update the store in order
|
|
368
|
+
*
|
|
369
|
+
* **Error Handling**:
|
|
370
|
+
* - Returns {@link RepositorySnapshotFailure} if validation fails
|
|
371
|
+
* - Returns {@link StoreSnapshotFailure} if storage fails (e.g., {@link DataSizeExceededError})
|
|
372
|
+
* - Previous snapshot remains intact on failure
|
|
373
|
+
* - Never throws exceptions - all errors are returned as {@link SnapshotOperationResult}
|
|
374
|
+
*
|
|
375
|
+
* **Logging**:
|
|
376
|
+
* - Validation: Handled by {@link validateSerializableSnapshot}
|
|
377
|
+
* - Storage success: Handled by {@link storeSnapshot} at `debug` level
|
|
378
|
+
* - Storage failure: Handled by {@link storeSnapshot}
|
|
379
|
+
*
|
|
380
|
+
* @internal
|
|
381
|
+
* This method is private and used only by {@link setupSnapshotFromSerializedData}.
|
|
382
|
+
*
|
|
383
|
+
* @see {@link setupSnapshotFromSerializedData} - Public API
|
|
384
|
+
* @see {@link validateSerializableSnapshot} - Validation logic
|
|
385
|
+
* @see {@link storeSnapshot} - Storage implementation
|
|
386
|
+
* @see {@link fetchAndStore} - Async equivalent with concurrency control
|
|
387
|
+
*/
|
|
388
|
+
private loadAndStore;
|
|
389
|
+
/**
|
|
390
|
+
* Setup snapshot from previously serialized data.
|
|
391
|
+
*
|
|
392
|
+
* Alternative to {@link setupSnapshot} for offline/cached initialization.
|
|
393
|
+
* Validates the data structure and populates the in-memory store.
|
|
394
|
+
*
|
|
395
|
+
* **Important**: This method resets `#lastFetchParams` to `undefined`, preventing
|
|
396
|
+
* {@link refreshSnapshot} from working until {@link setupSnapshot} is called.
|
|
397
|
+
* This ensures that API parameters don't become mismatched with serialized data.
|
|
398
|
+
*
|
|
399
|
+
* @param data - Serializable snapshot object (previously exported via {@link getSerializableSnapshot})
|
|
400
|
+
* @returns {@link SnapshotOperationResult} indicating success or failure
|
|
401
|
+
*
|
|
402
|
+
* @remarks
|
|
403
|
+
* **Caller Responsibilities**:
|
|
404
|
+
* - Load snapshot file (e.g., `fs.readFile()`)
|
|
405
|
+
* - Parse JSON to JavaScript object (e.g., `JSON.parse()`)
|
|
406
|
+
* - Pass the parsed object to this method
|
|
407
|
+
*
|
|
408
|
+
* **Operation Flow**:
|
|
409
|
+
* 1. Reset `#lastFetchParams` to `undefined`
|
|
410
|
+
* 2. Emit `snapshotStarted('setupFromSerializedData')` event (if enabled)
|
|
411
|
+
* 3. Validate data structure via {@link loadAndStore}
|
|
412
|
+
* 4. Store validated prototypes if validation succeeds
|
|
413
|
+
* 5. Return operation result
|
|
414
|
+
*
|
|
415
|
+
* **Side Effects**:
|
|
416
|
+
* - Resets cached API fetch parameters
|
|
417
|
+
* - Subsequent {@link refreshSnapshot} calls will fail with `REPOSITORY_INVALID_STATE`
|
|
418
|
+
* - Use {@link setupSnapshot} after this method to re-enable {@link refreshSnapshot}
|
|
419
|
+
*
|
|
420
|
+
* **This method does NOT**:
|
|
421
|
+
* - Perform file I/O operations
|
|
422
|
+
* - Parse JSON strings
|
|
423
|
+
* - Make network requests
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* // Import from file
|
|
428
|
+
* const json = await fs.readFile('snapshot.json', 'utf-8');
|
|
429
|
+
* const data = JSON.parse(json);
|
|
430
|
+
* const result = repo.setupSnapshotFromSerializedData(data);
|
|
431
|
+
*
|
|
432
|
+
* if (result.ok) {
|
|
433
|
+
* console.log(`Loaded ${result.stats.size} prototypes`);
|
|
434
|
+
* } else {
|
|
435
|
+
* console.error(`Import failed: ${result.message}`);
|
|
436
|
+
* }
|
|
437
|
+
* ```
|
|
438
|
+
*
|
|
439
|
+
* @see {@link loadAndStore} for the core implementation
|
|
440
|
+
* @see {@link getSerializableSnapshot} for exporting snapshots
|
|
441
|
+
* @see {@link setupSnapshot} for API-based initialization
|
|
442
|
+
*/
|
|
443
|
+
setupSnapshotFromSerializedData(data: SerializableSnapshot): SnapshotOperationResult;
|
|
444
|
+
/**
|
|
445
|
+
* Get current snapshot as a serializable object.
|
|
446
|
+
*
|
|
447
|
+
* Returns a plain JavaScript object containing all prototypes from the current
|
|
448
|
+
* snapshot along with metadata. The returned object can be passed to
|
|
449
|
+
* JSON.stringify() for persistence.
|
|
450
|
+
*
|
|
451
|
+
* This method does NOT perform file I/O or JSON.stringify().
|
|
452
|
+
* The caller is responsible for serialization and storage.
|
|
453
|
+
*
|
|
454
|
+
* @returns Serializable snapshot object with version, timestamp, and prototypes
|
|
455
|
+
*
|
|
456
|
+
* @example
|
|
457
|
+
* ```typescript
|
|
458
|
+
* // Export to file
|
|
459
|
+
* const snapshot = repo.getSerializableSnapshot();
|
|
460
|
+
* const json = JSON.stringify(snapshot, null, 2);
|
|
461
|
+
* await fs.writeFile('snapshot.json', json, 'utf-8');
|
|
462
|
+
* ```
|
|
463
|
+
*/
|
|
464
|
+
getSerializableSnapshot(): SerializableSnapshot;
|
|
465
|
+
/**
|
|
466
|
+
* Look up a prototype by id in the current snapshot.
|
|
467
|
+
* Never performs HTTP requests.
|
|
468
|
+
*
|
|
469
|
+
* @param prototypeId - The prototype ID to look up. Must be a positive integer.
|
|
470
|
+
* @returns The prototype if found, null otherwise
|
|
471
|
+
* @throws {ValidationError} If prototypeId is not a positive integer
|
|
472
|
+
*/
|
|
473
|
+
getPrototypeFromSnapshotByPrototypeId(prototypeId: number): Promise<DeepReadonly<NormalizedPrototype> | null>;
|
|
474
|
+
/**
|
|
475
|
+
* Return a random prototype from the current snapshot, or null
|
|
476
|
+
* when the snapshot is empty. Never performs HTTP requests.
|
|
477
|
+
*
|
|
478
|
+
* @remarks
|
|
479
|
+
* **Implementation Note**: This method uses `store.size` for O(1) empty check,
|
|
480
|
+
* then `store.getAll()` to select a random element. While it might seem wasteful
|
|
481
|
+
* to copy all objects just to select one, the alternative would require:
|
|
482
|
+
*
|
|
483
|
+
* 1. Call `getPrototypeIds()` - O(n) to iterate Map keys
|
|
484
|
+
* 2. Select random ID - O(1)
|
|
485
|
+
* 3. Call `getByPrototypeId(id)` - O(1)
|
|
486
|
+
*
|
|
487
|
+
* This approach still costs O(n) for step 1, making it no better than
|
|
488
|
+
* `getAll()` in terms of time complexity, but with additional function
|
|
489
|
+
* call overhead. The current implementation is simpler and equally
|
|
490
|
+
* efficient.
|
|
491
|
+
*/
|
|
492
|
+
getRandomPrototypeFromSnapshot(): Promise<DeepReadonly<NormalizedPrototype> | null>;
|
|
493
|
+
/**
|
|
494
|
+
* Return random samples from the current snapshot.
|
|
495
|
+
*
|
|
496
|
+
* Returns up to `size` random prototypes without duplicates.
|
|
497
|
+
* If `size` exceeds the available data, returns all prototypes in random order.
|
|
498
|
+
* Never performs HTTP requests.
|
|
499
|
+
*
|
|
500
|
+
* @param size - Maximum number of samples to return. Must be an integer.
|
|
501
|
+
* @returns Array of random prototypes (empty array if size <= 0 or snapshot is empty)
|
|
502
|
+
* @throws {ValidationError} If size is not an integer
|
|
503
|
+
*
|
|
504
|
+
* @remarks
|
|
505
|
+
* **Implementation Note**: Uses a hybrid approach for optimal performance:
|
|
506
|
+
*
|
|
507
|
+
* - `store.size` provides O(1) empty check
|
|
508
|
+
* - `store.getAll()` is O(1) (returns reference to internal array)
|
|
509
|
+
* - For small samples (< 50% of total): Set-based random selection, O(size)
|
|
510
|
+
* - For large samples (≥ 50% of total): Fisher-Yates shuffle, O(n)
|
|
511
|
+
*
|
|
512
|
+
* This hybrid approach optimizes for the common case where sample size is
|
|
513
|
+
* much smaller than the total population, while avoiding performance
|
|
514
|
+
* degradation when the sample size approaches the total size.
|
|
515
|
+
*/
|
|
516
|
+
getRandomSampleFromSnapshot(size: number): Promise<readonly DeepReadonly<NormalizedPrototype>[]>;
|
|
517
|
+
/**
|
|
518
|
+
* Return all prototype IDs from the current snapshot.
|
|
519
|
+
* Never performs HTTP requests.
|
|
520
|
+
*/
|
|
521
|
+
getPrototypeIdsFromSnapshot(): Promise<readonly number[]>;
|
|
522
|
+
/**
|
|
523
|
+
* Return all prototypes from the current snapshot.
|
|
524
|
+
* Never performs HTTP requests.
|
|
525
|
+
*/
|
|
526
|
+
getAllFromSnapshot(): Promise<readonly DeepReadonly<NormalizedPrototype>[]>;
|
|
527
|
+
/**
|
|
528
|
+
* Analyze prototypes to extract ID range (minimum and maximum).
|
|
529
|
+
*
|
|
530
|
+
* Uses a for-loop implementation for better performance with large datasets (5,000+ items).
|
|
531
|
+
* Single-pass algorithm with minimal memory allocations.
|
|
532
|
+
*
|
|
533
|
+
* @param prototypes - Array of prototypes to analyze
|
|
534
|
+
* @returns Object containing min and max IDs, or null values if array is empty
|
|
535
|
+
*/
|
|
536
|
+
analyzePrototypesWithForLoop(prototypes: readonly DeepReadonly<NormalizedPrototype>[]): PrototypeAnalysisResult;
|
|
537
|
+
/**
|
|
538
|
+
* Analyze prototypes from the current snapshot to extract ID range.
|
|
539
|
+
*
|
|
540
|
+
* Currently uses the for-loop implementation for optimal performance with typical dataset sizes.
|
|
541
|
+
* Never performs HTTP requests.
|
|
542
|
+
*
|
|
543
|
+
* @returns Object containing min and max IDs, or null values if snapshot is empty
|
|
544
|
+
*/
|
|
545
|
+
analyzePrototypes(): Promise<PrototypeAnalysisResult>;
|
|
546
|
+
/**
|
|
547
|
+
* Clean up event listeners and release resources.
|
|
548
|
+
*
|
|
549
|
+
* Removes all event listeners from the internal EventEmitter to prevent memory leaks.
|
|
550
|
+
* Safe to call even when events are disabled.
|
|
551
|
+
*
|
|
552
|
+
* @remarks
|
|
553
|
+
* Always call this method in cleanup paths:
|
|
554
|
+
* - Test cleanup (afterEach)
|
|
555
|
+
* - Component unmounting (React useEffect cleanup)
|
|
556
|
+
* - Before creating a new repository instance
|
|
557
|
+
*/
|
|
558
|
+
dispose(): void;
|
|
559
|
+
}
|
|
560
|
+
//# sourceMappingURL=protopedia-in-memory-repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protopedia-in-memory-repository.d.ts","sourceRoot":"","sources":["../../lib/repository/protopedia-in-memory-repository.ts"],"names":[],"mappings":"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"}
|