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.
Files changed (295) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +179 -0
  3. package/dist/builder.d.ts +158 -0
  4. package/dist/builder.d.ts.map +1 -0
  5. package/dist/builder.js +255 -0
  6. package/dist/builder.js.map +1 -0
  7. package/dist/factory.d.ts +154 -0
  8. package/dist/factory.d.ts.map +1 -0
  9. package/dist/factory.js +243 -0
  10. package/dist/factory.js.map +1 -0
  11. package/dist/fetcher/client/config.d.ts +140 -0
  12. package/dist/fetcher/client/config.d.ts.map +1 -0
  13. package/dist/fetcher/client/config.js +2 -0
  14. package/dist/fetcher/client/config.js.map +1 -0
  15. package/dist/fetcher/client/fetch-with-progress.d.ts +156 -0
  16. package/dist/fetcher/client/fetch-with-progress.d.ts.map +1 -0
  17. package/dist/fetcher/client/fetch-with-progress.js +313 -0
  18. package/dist/fetcher/client/fetch-with-progress.js.map +1 -0
  19. package/dist/fetcher/client/fetch-with-timeout.d.ts +6 -0
  20. package/dist/fetcher/client/fetch-with-timeout.d.ts.map +1 -0
  21. package/dist/fetcher/client/fetch-with-timeout.js +48 -0
  22. package/dist/fetcher/client/fetch-with-timeout.js.map +1 -0
  23. package/dist/fetcher/client/protopedia-api-custom-client.d.ts +141 -0
  24. package/dist/fetcher/client/protopedia-api-custom-client.d.ts.map +1 -0
  25. package/dist/fetcher/client/protopedia-api-custom-client.js +268 -0
  26. package/dist/fetcher/client/protopedia-api-custom-client.js.map +1 -0
  27. package/dist/fetcher/client/select-custom-fetch.d.ts +58 -0
  28. package/dist/fetcher/client/select-custom-fetch.d.ts.map +1 -0
  29. package/dist/fetcher/client/select-custom-fetch.js +58 -0
  30. package/dist/fetcher/client/select-custom-fetch.js.map +1 -0
  31. package/dist/fetcher/errors/fetcher-error.d.ts +10 -0
  32. package/dist/fetcher/errors/fetcher-error.d.ts.map +1 -0
  33. package/dist/fetcher/errors/fetcher-error.js +15 -0
  34. package/dist/fetcher/errors/fetcher-error.js.map +1 -0
  35. package/dist/fetcher/index.d.ts +73 -0
  36. package/dist/fetcher/index.d.ts.map +1 -0
  37. package/dist/fetcher/index.js +70 -0
  38. package/dist/fetcher/index.js.map +1 -0
  39. package/dist/fetcher/types/index.d.ts +9 -0
  40. package/dist/fetcher/types/index.d.ts.map +1 -0
  41. package/dist/fetcher/types/index.js +7 -0
  42. package/dist/fetcher/types/index.js.map +1 -0
  43. package/dist/fetcher/types/progress-event.types.d.ts +221 -0
  44. package/dist/fetcher/types/progress-event.types.d.ts.map +1 -0
  45. package/dist/fetcher/types/progress-event.types.js +10 -0
  46. package/dist/fetcher/types/progress-event.types.js.map +1 -0
  47. package/dist/fetcher/types/prototype-api.types.d.ts +106 -0
  48. package/dist/fetcher/types/prototype-api.types.d.ts.map +1 -0
  49. package/dist/fetcher/types/prototype-api.types.js +2 -0
  50. package/dist/fetcher/types/prototype-api.types.js.map +1 -0
  51. package/dist/fetcher/types/result.types.d.ts +75 -0
  52. package/dist/fetcher/types/result.types.d.ts.map +1 -0
  53. package/dist/fetcher/types/result.types.js +2 -0
  54. package/dist/fetcher/types/result.types.js.map +1 -0
  55. package/dist/fetcher/utils/create-client-fetch.d.ts +63 -0
  56. package/dist/fetcher/utils/create-client-fetch.d.ts.map +1 -0
  57. package/dist/fetcher/utils/create-client-fetch.js +89 -0
  58. package/dist/fetcher/utils/create-client-fetch.js.map +1 -0
  59. package/dist/fetcher/utils/create-fetch-with-stripped-headers.d.ts +6 -0
  60. package/dist/fetcher/utils/create-fetch-with-stripped-headers.d.ts.map +1 -0
  61. package/dist/fetcher/utils/create-fetch-with-stripped-headers.js +40 -0
  62. package/dist/fetcher/utils/create-fetch-with-stripped-headers.js.map +1 -0
  63. package/dist/fetcher/utils/errors/handler.d.ts +58 -0
  64. package/dist/fetcher/utils/errors/handler.d.ts.map +1 -0
  65. package/dist/fetcher/utils/errors/handler.js +243 -0
  66. package/dist/fetcher/utils/errors/handler.js.map +1 -0
  67. package/dist/fetcher/utils/errors/messages.d.ts +75 -0
  68. package/dist/fetcher/utils/errors/messages.d.ts.map +1 -0
  69. package/dist/fetcher/utils/errors/messages.js +88 -0
  70. package/dist/fetcher/utils/errors/messages.js.map +1 -0
  71. package/dist/fetcher/utils/index.d.ts +13 -0
  72. package/dist/fetcher/utils/index.d.ts.map +1 -0
  73. package/dist/fetcher/utils/index.js +12 -0
  74. package/dist/fetcher/utils/index.js.map +1 -0
  75. package/dist/fetcher/utils/log-timestamp-normalization-warnings.d.ts +10 -0
  76. package/dist/fetcher/utils/log-timestamp-normalization-warnings.d.ts.map +1 -0
  77. package/dist/fetcher/utils/log-timestamp-normalization-warnings.js +32 -0
  78. package/dist/fetcher/utils/log-timestamp-normalization-warnings.js.map +1 -0
  79. package/dist/fetcher/utils/normalize-protopedia-timestamp.d.ts +59 -0
  80. package/dist/fetcher/utils/normalize-protopedia-timestamp.d.ts.map +1 -0
  81. package/dist/fetcher/utils/normalize-protopedia-timestamp.js +81 -0
  82. package/dist/fetcher/utils/normalize-protopedia-timestamp.js.map +1 -0
  83. package/dist/fetcher/utils/normalize-prototype.d.ts +56 -0
  84. package/dist/fetcher/utils/normalize-prototype.d.ts.map +1 -0
  85. package/dist/fetcher/utils/normalize-prototype.js +113 -0
  86. package/dist/fetcher/utils/normalize-prototype.js.map +1 -0
  87. package/dist/fetcher/utils/sanitize-options.d.ts +14 -0
  88. package/dist/fetcher/utils/sanitize-options.d.ts.map +1 -0
  89. package/dist/fetcher/utils/sanitize-options.js +16 -0
  90. package/dist/fetcher/utils/sanitize-options.js.map +1 -0
  91. package/dist/fetcher/utils/string-parsers.d.ts +45 -0
  92. package/dist/fetcher/utils/string-parsers.d.ts.map +1 -0
  93. package/dist/fetcher/utils/string-parsers.js +53 -0
  94. package/dist/fetcher/utils/string-parsers.js.map +1 -0
  95. package/dist/index.d.ts +66 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +70 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/logger/console-logger.d.ts +74 -0
  100. package/dist/logger/console-logger.d.ts.map +1 -0
  101. package/dist/logger/console-logger.js +113 -0
  102. package/dist/logger/console-logger.js.map +1 -0
  103. package/dist/logger/factory.d.ts +88 -0
  104. package/dist/logger/factory.d.ts.map +1 -0
  105. package/dist/logger/factory.js +94 -0
  106. package/dist/logger/factory.js.map +1 -0
  107. package/dist/logger/index.d.ts +42 -0
  108. package/dist/logger/index.d.ts.map +1 -0
  109. package/dist/logger/index.js +41 -0
  110. package/dist/logger/index.js.map +1 -0
  111. package/dist/logger/logger.types.d.ts +49 -0
  112. package/dist/logger/logger.types.d.ts.map +1 -0
  113. package/dist/logger/logger.types.js +2 -0
  114. package/dist/logger/logger.types.js.map +1 -0
  115. package/dist/repository/errors/validation-error.d.ts +24 -0
  116. package/dist/repository/errors/validation-error.d.ts.map +1 -0
  117. package/dist/repository/errors/validation-error.js +26 -0
  118. package/dist/repository/errors/validation-error.js.map +1 -0
  119. package/dist/repository/index.d.ts +122 -0
  120. package/dist/repository/index.d.ts.map +1 -0
  121. package/dist/repository/index.js +44 -0
  122. package/dist/repository/index.js.map +1 -0
  123. package/dist/repository/protopedia-in-memory-repository.d.ts +560 -0
  124. package/dist/repository/protopedia-in-memory-repository.d.ts.map +1 -0
  125. package/dist/repository/protopedia-in-memory-repository.js +929 -0
  126. package/dist/repository/protopedia-in-memory-repository.js.map +1 -0
  127. package/dist/repository/schemas/index.d.ts +9 -0
  128. package/dist/repository/schemas/index.d.ts.map +1 -0
  129. package/dist/repository/schemas/index.js +11 -0
  130. package/dist/repository/schemas/index.js.map +1 -0
  131. package/dist/repository/schemas/params.d.ts +44 -0
  132. package/dist/repository/schemas/params.d.ts.map +1 -0
  133. package/dist/repository/schemas/params.js +44 -0
  134. package/dist/repository/schemas/params.js.map +1 -0
  135. package/dist/repository/schemas/serializable-snapshot.d.ts +33 -0
  136. package/dist/repository/schemas/serializable-snapshot.d.ts.map +1 -0
  137. package/dist/repository/schemas/serializable-snapshot.js +45 -0
  138. package/dist/repository/schemas/serializable-snapshot.js.map +1 -0
  139. package/dist/repository/types/analysis.types.d.ts +89 -0
  140. package/dist/repository/types/analysis.types.d.ts.map +1 -0
  141. package/dist/repository/types/analysis.types.js +2 -0
  142. package/dist/repository/types/analysis.types.js.map +1 -0
  143. package/dist/repository/types/index.d.ts +12 -0
  144. package/dist/repository/types/index.d.ts.map +1 -0
  145. package/dist/repository/types/index.js +7 -0
  146. package/dist/repository/types/index.js.map +1 -0
  147. package/dist/repository/types/repository-events.types.d.ts +110 -0
  148. package/dist/repository/types/repository-events.types.d.ts.map +1 -0
  149. package/dist/repository/types/repository-events.types.js +2 -0
  150. package/dist/repository/types/repository-events.types.js.map +1 -0
  151. package/dist/repository/types/repository.types.d.ts +330 -0
  152. package/dist/repository/types/repository.types.d.ts.map +1 -0
  153. package/dist/repository/types/repository.types.js +2 -0
  154. package/dist/repository/types/repository.types.js.map +1 -0
  155. package/dist/repository/types/result.types.d.ts +55 -0
  156. package/dist/repository/types/result.types.d.ts.map +1 -0
  157. package/dist/repository/types/result.types.js +2 -0
  158. package/dist/repository/types/result.types.js.map +1 -0
  159. package/dist/repository/types/serialization.types.d.ts +61 -0
  160. package/dist/repository/types/serialization.types.d.ts.map +1 -0
  161. package/dist/repository/types/serialization.types.js +2 -0
  162. package/dist/repository/types/serialization.types.js.map +1 -0
  163. package/dist/repository/types/snapshot-operation.types.d.ts +140 -0
  164. package/dist/repository/types/snapshot-operation.types.d.ts.map +1 -0
  165. package/dist/repository/types/snapshot-operation.types.js +2 -0
  166. package/dist/repository/types/snapshot-operation.types.js.map +1 -0
  167. package/dist/repository/utils/convert-fetch-result.d.ts +46 -0
  168. package/dist/repository/utils/convert-fetch-result.d.ts.map +1 -0
  169. package/dist/repository/utils/convert-fetch-result.js +59 -0
  170. package/dist/repository/utils/convert-fetch-result.js.map +1 -0
  171. package/dist/repository/utils/convert-store-result.d.ts +36 -0
  172. package/dist/repository/utils/convert-store-result.d.ts.map +1 -0
  173. package/dist/repository/utils/convert-store-result.js +36 -0
  174. package/dist/repository/utils/convert-store-result.js.map +1 -0
  175. package/dist/repository/utils/emit-repository-event-safely.d.ts +5 -0
  176. package/dist/repository/utils/emit-repository-event-safely.d.ts.map +1 -0
  177. package/dist/repository/utils/emit-repository-event-safely.js +17 -0
  178. package/dist/repository/utils/emit-repository-event-safely.js.map +1 -0
  179. package/dist/repository/utils/index.d.ts +3 -0
  180. package/dist/repository/utils/index.d.ts.map +1 -0
  181. package/dist/repository/utils/index.js +3 -0
  182. package/dist/repository/utils/index.js.map +1 -0
  183. package/dist/repository/validation/index.d.ts +9 -0
  184. package/dist/repository/validation/index.d.ts.map +1 -0
  185. package/dist/repository/validation/index.js +10 -0
  186. package/dist/repository/validation/index.js.map +1 -0
  187. package/dist/repository/validation/params-validators.d.ts +46 -0
  188. package/dist/repository/validation/params-validators.d.ts.map +1 -0
  189. package/dist/repository/validation/params-validators.js +68 -0
  190. package/dist/repository/validation/params-validators.js.map +1 -0
  191. package/dist/repository/validation/serializable-snapshot.d.ts +47 -0
  192. package/dist/repository/validation/serializable-snapshot.d.ts.map +1 -0
  193. package/dist/repository/validation/serializable-snapshot.js +104 -0
  194. package/dist/repository/validation/serializable-snapshot.js.map +1 -0
  195. package/dist/schemas/index.d.ts +8 -0
  196. package/dist/schemas/index.d.ts.map +1 -0
  197. package/dist/schemas/index.js +8 -0
  198. package/dist/schemas/index.js.map +1 -0
  199. package/dist/schemas/normalized-prototype.d.ts +56 -0
  200. package/dist/schemas/normalized-prototype.d.ts.map +1 -0
  201. package/dist/schemas/normalized-prototype.js +123 -0
  202. package/dist/schemas/normalized-prototype.js.map +1 -0
  203. package/dist/store/errors/store-error.d.ts +148 -0
  204. package/dist/store/errors/store-error.d.ts.map +1 -0
  205. package/dist/store/errors/store-error.js +156 -0
  206. package/dist/store/errors/store-error.js.map +1 -0
  207. package/dist/store/index.d.ts +84 -0
  208. package/dist/store/index.d.ts.map +1 -0
  209. package/dist/store/index.js +83 -0
  210. package/dist/store/index.js.map +1 -0
  211. package/dist/store/store.d.ts +295 -0
  212. package/dist/store/store.d.ts.map +1 -0
  213. package/dist/store/store.js +411 -0
  214. package/dist/store/store.js.map +1 -0
  215. package/dist/store/types/index.d.ts +2 -0
  216. package/dist/store/types/index.d.ts.map +1 -0
  217. package/dist/store/types/index.js +2 -0
  218. package/dist/store/types/index.js.map +1 -0
  219. package/dist/store/types/result.types.d.ts +67 -0
  220. package/dist/store/types/result.types.d.ts.map +1 -0
  221. package/dist/store/types/result.types.js +2 -0
  222. package/dist/store/types/result.types.js.map +1 -0
  223. package/dist/types/codes.d.ts +44 -0
  224. package/dist/types/codes.d.ts.map +1 -0
  225. package/dist/types/codes.js +9 -0
  226. package/dist/types/codes.js.map +1 -0
  227. package/dist/types/index.d.ts +61 -0
  228. package/dist/types/index.d.ts.map +1 -0
  229. package/dist/types/index.js +60 -0
  230. package/dist/types/index.js.map +1 -0
  231. package/dist/types/normalized-prototype.d.ts +95 -0
  232. package/dist/types/normalized-prototype.d.ts.map +1 -0
  233. package/dist/types/normalized-prototype.js +2 -0
  234. package/dist/types/normalized-prototype.js.map +1 -0
  235. package/dist/utils/converters/index.d.ts +15 -0
  236. package/dist/utils/converters/index.d.ts.map +1 -0
  237. package/dist/utils/converters/index.js +15 -0
  238. package/dist/utils/converters/index.js.map +1 -0
  239. package/dist/utils/converters/license-type.d.ts +23 -0
  240. package/dist/utils/converters/license-type.d.ts.map +1 -0
  241. package/dist/utils/converters/license-type.js +38 -0
  242. package/dist/utils/converters/license-type.js.map +1 -0
  243. package/dist/utils/converters/release-flag.d.ts +24 -0
  244. package/dist/utils/converters/release-flag.d.ts.map +1 -0
  245. package/dist/utils/converters/release-flag.js +40 -0
  246. package/dist/utils/converters/release-flag.js.map +1 -0
  247. package/dist/utils/converters/status.d.ts +23 -0
  248. package/dist/utils/converters/status.d.ts.map +1 -0
  249. package/dist/utils/converters/status.js +40 -0
  250. package/dist/utils/converters/status.js.map +1 -0
  251. package/dist/utils/converters/thanks-flag.d.ts +25 -0
  252. package/dist/utils/converters/thanks-flag.d.ts.map +1 -0
  253. package/dist/utils/converters/thanks-flag.js +41 -0
  254. package/dist/utils/converters/thanks-flag.js.map +1 -0
  255. package/dist/utils/deep-merge.d.ts +38 -0
  256. package/dist/utils/deep-merge.d.ts.map +1 -0
  257. package/dist/utils/deep-merge.js +85 -0
  258. package/dist/utils/deep-merge.js.map +1 -0
  259. package/dist/utils/index.d.ts +80 -0
  260. package/dist/utils/index.d.ts.map +1 -0
  261. package/dist/utils/index.js +85 -0
  262. package/dist/utils/index.js.map +1 -0
  263. package/dist/utils/logger-utils.d.ts +100 -0
  264. package/dist/utils/logger-utils.d.ts.map +1 -0
  265. package/dist/utils/logger-utils.js +265 -0
  266. package/dist/utils/logger-utils.js.map +1 -0
  267. package/dist/utils/time/constants.d.ts +14 -0
  268. package/dist/utils/time/constants.d.ts.map +1 -0
  269. package/dist/utils/time/constants.js +14 -0
  270. package/dist/utils/time/constants.js.map +1 -0
  271. package/dist/utils/time/index.d.ts +28 -0
  272. package/dist/utils/time/index.d.ts.map +1 -0
  273. package/dist/utils/time/index.js +28 -0
  274. package/dist/utils/time/index.js.map +1 -0
  275. package/dist/utils/time/parser.d.ts +91 -0
  276. package/dist/utils/time/parser.d.ts.map +1 -0
  277. package/dist/utils/time/parser.js +143 -0
  278. package/dist/utils/time/parser.js.map +1 -0
  279. package/dist/utils/validation/index.d.ts +8 -0
  280. package/dist/utils/validation/index.d.ts.map +1 -0
  281. package/dist/utils/validation/index.js +7 -0
  282. package/dist/utils/validation/index.js.map +1 -0
  283. package/dist/utils/validation/normalized-prototype.d.ts +64 -0
  284. package/dist/utils/validation/normalized-prototype.d.ts.map +1 -0
  285. package/dist/utils/validation/normalized-prototype.js +97 -0
  286. package/dist/utils/validation/normalized-prototype.js.map +1 -0
  287. package/dist/utils/validation/types.d.ts +62 -0
  288. package/dist/utils/validation/types.d.ts.map +1 -0
  289. package/dist/utils/validation/types.js +8 -0
  290. package/dist/utils/validation/types.js.map +1 -0
  291. package/dist/version.d.ts +6 -0
  292. package/dist/version.d.ts.map +1 -0
  293. package/dist/version.js +6 -0
  294. package/dist/version.js.map +1 -0
  295. package/package.json +138 -0
@@ -0,0 +1,411 @@
1
+ import { ConsoleLogger, createConsoleLogger, } from '../logger/index.js';
2
+ import { sanitizeDataForLogging } from '../utils/index.js';
3
+ import { ConfigurationError, DataSizeExceededError, SizeEstimationError, } from './errors/store-error.js';
4
+ const DEFAULT_TTL_MS = 30 * 60 * 1_000; // 30 minutes
5
+ const DEFAULT_DATA_SIZE_BYTES = 10 * 1024 * 1024; // 10 MiB
6
+ /**
7
+ * Hard limit for data size in bytes for storing snapshots.
8
+ * Attempting to configure a store with a size larger than this will throw an error.
9
+ */
10
+ export const LIMIT_DATA_SIZE_BYTES = 30 * 1024 * 1024; // 30 MiB
11
+ /**
12
+ * In-memory store that keeps the full set of normalized prototypes with an ID-based index.
13
+ *
14
+ * The store accepts full snapshots (`setAll`) and exposes O(1) lookups by prototype id
15
+ * via an internal index. When TTL expires, data remains readable while callers kick off
16
+ * background refresh tasks using {@link runExclusive} to avoid redundant upstream calls.
17
+ */
18
+ export class PrototypeInMemoryStore {
19
+ logger;
20
+ logLevel;
21
+ ttlMs;
22
+ maxDataSizeBytes;
23
+ prototypeIdIndex = new Map();
24
+ prototypes = [];
25
+ cachedAt = null;
26
+ dataSizeBytes = 0;
27
+ refreshPromise = null;
28
+ /**
29
+ * Create a new PrototypeInMemoryStore instance.
30
+ *
31
+ * Initializes an in-memory cache for normalized prototypes with configurable
32
+ * TTL and size limits. The store manages snapshot expiration, refresh state,
33
+ * and provides type-safe read-only access to cached data.
34
+ *
35
+ * @param config - Configuration options for the store
36
+ * @param config.ttlMs - Time-to-live in milliseconds for cached snapshots.
37
+ * Defaults to 30 minutes (1,800,000ms). After this duration, the snapshot
38
+ * is considered expired and should be refreshed.
39
+ * @param config.maxDataSizeBytes - Maximum allowed size for cached data in bytes.
40
+ * Defaults to 10 MiB (10,485,760 bytes). Must not exceed 30 MiB.
41
+ * If a snapshot exceeds this limit, setAll() will reject it.
42
+ * @param config.logger - Optional custom logger instance. If not provided,
43
+ * a default ConsoleLogger is created.
44
+ * @param config.logLevel - Log level for the logger. When `logger` is not provided,
45
+ * creates a ConsoleLogger with this level. When `logger` is provided and mutable,
46
+ * updates the logger's level property.
47
+ *
48
+ * @throws {ConfigurationError} When maxDataSizeBytes exceeds LIMIT_DATA_SIZE_BYTES (30 MiB)
49
+ */
50
+ constructor({ ttlMs = DEFAULT_TTL_MS, maxDataSizeBytes = DEFAULT_DATA_SIZE_BYTES, logger, logLevel, } = {}) {
51
+ this.ttlMs = ttlMs;
52
+ this.maxDataSizeBytes = maxDataSizeBytes;
53
+ // Fastify-style logger configuration
54
+ if (logger) {
55
+ // Custom logger provided
56
+ this.logger = logger;
57
+ this.logLevel = logLevel ?? 'info';
58
+ // If logLevel is specified, update logger's level property (if mutable)
59
+ if (logLevel !== undefined && 'level' in logger) {
60
+ logger.level = logLevel;
61
+ }
62
+ }
63
+ else {
64
+ // No custom logger → create ConsoleLogger with logLevel
65
+ const resolvedLogLevel = logLevel ?? 'info';
66
+ this.logger = new ConsoleLogger(resolvedLogLevel);
67
+ this.logLevel = resolvedLogLevel;
68
+ }
69
+ this.logger.info('PrototypeInMemoryStore constructor called', {
70
+ ttlMs,
71
+ maxDataSizeBytes,
72
+ logger: logger ? 'custom' : undefined,
73
+ logLevel,
74
+ });
75
+ // Throw if maxDataSizeBytes exceeds the hard limit
76
+ if (maxDataSizeBytes > LIMIT_DATA_SIZE_BYTES) {
77
+ const maxMiB = (LIMIT_DATA_SIZE_BYTES / (1024 * 1024)).toFixed(0);
78
+ throw new ConfigurationError(`PrototypeInMemoryStore maxDataSizeBytes must be <= ${LIMIT_DATA_SIZE_BYTES} bytes (${maxMiB} MiB) to prevent oversized data`);
79
+ }
80
+ }
81
+ /**
82
+ * Retrieve the configuration used to initialize this store.
83
+ *
84
+ * Returns the resolved configuration values (TTL and max payload size) that were
85
+ * set during instantiation. These values are immutable after construction.
86
+ */
87
+ getConfig() {
88
+ return {
89
+ ttlMs: this.ttlMs,
90
+ maxDataSizeBytes: this.maxDataSizeBytes,
91
+ logLevel: this.logLevel,
92
+ };
93
+ }
94
+ /** Count of prototypes currently kept in the in-memory store. */
95
+ get size() {
96
+ return this.prototypeIdIndex.size;
97
+ }
98
+ /** Timestamp representing when the snapshot was last refreshed. */
99
+ getCachedAt() {
100
+ return this.cachedAt;
101
+ }
102
+ /**
103
+ * Calculate elapsed time in milliseconds since the snapshot was cached.
104
+ * Returns 0 if no data is cached.
105
+ */
106
+ getElapsedTime() {
107
+ if (!this.cachedAt) {
108
+ return 0;
109
+ }
110
+ return Date.now() - this.cachedAt.getTime();
111
+ }
112
+ /**
113
+ * Calculate remaining time in milliseconds until expiration.
114
+ * Returns 0 if already expired or no data is cached.
115
+ */
116
+ getRemainingTtl() {
117
+ if (!this.cachedAt) {
118
+ return 0;
119
+ }
120
+ const elapsed = this.getElapsedTime();
121
+ const remaining = this.ttlMs - elapsed;
122
+ return Math.max(0, remaining);
123
+ }
124
+ /** Determine whether the snapshot is stale based on the configured TTL. */
125
+ isExpired() {
126
+ if (!this.cachedAt) {
127
+ return true;
128
+ }
129
+ return this.getElapsedTime() > this.ttlMs;
130
+ }
131
+ /** Report whether a background refresh is currently in flight. */
132
+ isRefreshInFlight() {
133
+ return this.refreshPromise !== null;
134
+ }
135
+ /**
136
+ * Provide statistics describing cache health and runtime state.
137
+ *
138
+ * Returns metadata about the current snapshot including size, expiration status,
139
+ * and refresh state. For configuration values like TTL, use {@link getConfig}.
140
+ */
141
+ getStats() {
142
+ return {
143
+ size: this.prototypeIdIndex.size,
144
+ cachedAt: this.cachedAt,
145
+ isExpired: this.isExpired(),
146
+ remainingTtlMs: this.getRemainingTtl(),
147
+ dataSizeBytes: this.dataSizeBytes,
148
+ refreshInFlight: this.isRefreshInFlight(),
149
+ };
150
+ }
151
+ /**
152
+ * Estimates the JSON payload size of an array of NormalizedPrototypes in bytes.
153
+ *
154
+ * This method calculates the size by iteratively serializing each item and summing their byte lengths,
155
+ * along with the overhead for array brackets and commas. This approach minimizes memory usage
156
+ * by avoiding the creation of a single large JSON string for the entire array, thus reducing
157
+ * the risk of out-of-memory errors, especially with large datasets.
158
+ *
159
+ * @param data - The array of NormalizedPrototypes to estimate the size for.
160
+ * @returns The estimated size in bytes of the JSON-serialized data.
161
+ * @throws {SizeEstimationError} When JSON serialization fails (e.g., circular references).
162
+ */
163
+ estimateSize(data) {
164
+ try {
165
+ if (data.length === 0) {
166
+ return 2; // "[]"
167
+ }
168
+ // Start with 2 bytes for "[]" and 1 byte for each comma (N-1 commas)
169
+ let totalBytes = 2 + (data.length - 1);
170
+ if (typeof Buffer !== 'undefined') {
171
+ for (const item of data) {
172
+ totalBytes += Buffer.byteLength(JSON.stringify(item), 'utf8');
173
+ }
174
+ }
175
+ else if (typeof TextEncoder !== 'undefined') {
176
+ const encoder = new TextEncoder();
177
+ for (const item of data) {
178
+ totalBytes += encoder.encode(JSON.stringify(item)).length;
179
+ }
180
+ }
181
+ else {
182
+ // Fallback for environments without Buffer/TextEncoder (should not happen in Node.js)
183
+ this.logger.warn('Neither Buffer nor TextEncoder found for size estimation. Returning 0.', {});
184
+ return 0;
185
+ }
186
+ return totalBytes;
187
+ }
188
+ catch (error) {
189
+ this.logger.error('Failed to estimate payload size', {
190
+ error: sanitizeDataForLogging(error),
191
+ });
192
+ throw new SizeEstimationError('UNKNOWN', error instanceof Error ? error : undefined);
193
+ }
194
+ }
195
+ /**
196
+ * Execute a refresh task while preventing concurrent execution.
197
+ *
198
+ * @returns Promise resolved when the task completes; callers may ignore it for background refreshes.
199
+ */
200
+ runExclusive(task) {
201
+ if (this.refreshPromise) {
202
+ return this.refreshPromise;
203
+ }
204
+ this.refreshPromise = (async () => {
205
+ try {
206
+ await task();
207
+ }
208
+ catch (error) {
209
+ this.logger.error('PrototypeInMemoryStore refresh task failed', {
210
+ error: sanitizeDataForLogging(error),
211
+ });
212
+ throw error;
213
+ }
214
+ finally {
215
+ this.refreshPromise = null;
216
+ }
217
+ })();
218
+ return this.refreshPromise;
219
+ }
220
+ /** Reset the store to an empty state and clear all metadata. */
221
+ clear() {
222
+ const previousSize = this.prototypeIdIndex.size;
223
+ this.prototypeIdIndex.clear();
224
+ this.prototypes = [];
225
+ this.cachedAt = null;
226
+ this.dataSizeBytes = 0;
227
+ this.logger.info('PrototypeInMemoryStore cleared', { previousSize });
228
+ }
229
+ /**
230
+ * Store the provided snapshot if it fits within the configured payload limit.
231
+ * Creates a shallow copy of the input array to prevent external mutations.
232
+ *
233
+ * @param prototypes - Array of normalized prototypes to store (array will be copied)
234
+ * @returns Metadata about the stored snapshot including the exact data size in bytes
235
+ * @throws {SizeEstimationError} When data size estimation fails
236
+ * @throws {DataSizeExceededError} When the payload exceeds the configured maximum size limit
237
+ *
238
+ * @remarks
239
+ * **Error Handling**: When an error is thrown, the store is NOT modified.
240
+ * Any previously stored snapshot remains intact and accessible. This ensures
241
+ * that applications can continue serving data from the last successful snapshot
242
+ * even when new data cannot be stored.
243
+ *
244
+ * The method creates a shallow copy of the input array to ensure the store's
245
+ * internal state cannot be corrupted by external mutations of the array.
246
+ * However, the prototype objects themselves are not cloned. Callers must not
247
+ * mutate the prototype objects after passing them to this method.
248
+ *
249
+ * Size calculation is performed AFTER deduplication to ensure accurate size checking.
250
+ * If duplicate IDs are present in the input array, only the last occurrence is kept.
251
+ */
252
+ setAll(prototypes) {
253
+ // Build O(1) lookup index by prototype ID first to deduplicate
254
+ // Note: If duplicate IDs are present in the input array, the last one wins.
255
+ const uniqueMap = new Map(prototypes.map((prototype) => [prototype.id, prototype]));
256
+ // Warn if duplicate IDs were detected in the input array
257
+ if (uniqueMap.size !== prototypes.length) {
258
+ this.logger.warn('Duplicate prototype IDs detected in snapshot', {
259
+ inputCount: prototypes.length,
260
+ storedCount: uniqueMap.size,
261
+ });
262
+ }
263
+ // Reconstruct prototypes array from the map to ensure consistency and uniqueness by ID.
264
+ // This will also ensure that `getAll().length` matches `this.size`.
265
+ const uniquePrototypes = Array.from(uniqueMap.values());
266
+ // Validate payload size AFTER deduplication
267
+ const dataSizeBytes = (() => {
268
+ try {
269
+ return this.estimateSize(uniquePrototypes);
270
+ }
271
+ catch (error) {
272
+ // At this point, store data is unchanged (estimation failed before any store updates)
273
+ if (error instanceof SizeEstimationError) {
274
+ throw new SizeEstimationError('UNCHANGED', error.cause);
275
+ }
276
+ // Re-throw unexpected errors
277
+ throw error;
278
+ }
279
+ })();
280
+ if (dataSizeBytes > this.maxDataSizeBytes) {
281
+ this.logger.warn('Snapshot rejected: data exceeds maximum size', {
282
+ dataSizeBytes,
283
+ maxDataSizeBytes: this.maxDataSizeBytes,
284
+ inputCount: prototypes.length,
285
+ uniqueCount: uniqueMap.size,
286
+ });
287
+ throw new DataSizeExceededError('UNCHANGED', dataSizeBytes, this.maxDataSizeBytes);
288
+ }
289
+ // Store the deduplicated data
290
+ this.prototypeIdIndex = uniqueMap;
291
+ this.prototypes = uniquePrototypes;
292
+ // Update cache metadata
293
+ this.cachedAt = new Date();
294
+ this.dataSizeBytes = dataSizeBytes;
295
+ this.logger.info('PrototypeInMemoryStore snapshot updated', {
296
+ count: this.prototypeIdIndex.size,
297
+ dataSizeBytes,
298
+ });
299
+ return { dataSizeBytes };
300
+ }
301
+ /**
302
+ * Retrieve the latest fetched prototypes in their original order.
303
+ *
304
+ * Returns type-level readonly reference to the internal prototypes array.
305
+ * The readonly type provides compile-time safety but not runtime protection.
306
+ *
307
+ * @returns Type-level readonly array of prototypes
308
+ *
309
+ * @remarks
310
+ * **Type Safety**: This method returns a readonly-typed reference without
311
+ * runtime immutability enforcement (no Object.freeze or defensive copying).
312
+ * Callers must honor the readonly contract and not cast it away.
313
+ *
314
+ * **Performance**: Direct reference with zero overhead - suitable for
315
+ * high-frequency reads of large datasets.
316
+ */
317
+ getAll() {
318
+ return this.prototypes;
319
+ }
320
+ /**
321
+ * Return a lightweight structure containing the cached data and metadata.
322
+ *
323
+ * Useful for callers that want to inspect expiry state without mutating the store.
324
+ */
325
+ getSnapshot() {
326
+ return {
327
+ data: this.getAll(),
328
+ cachedAt: this.cachedAt,
329
+ isExpired: this.isExpired(),
330
+ };
331
+ }
332
+ /**
333
+ * Retrieve a single prototype by its numeric identifier.
334
+ *
335
+ * Uses the internal prototypeIdIndex for O(1) constant-time lookup, providing
336
+ * exceptional performance even with thousands of cached prototypes. This is
337
+ * significantly faster than linear search alternatives (approximately 12,500x
338
+ * faster for 5,000 items).
339
+ *
340
+ * The index-based implementation adds minimal memory overhead (~230KB for 5,000
341
+ * items, or ~0.8% of total cache size) while delivering constant-time access
342
+ * regardless of cache size.
343
+ *
344
+ * @param prototypeId - The numeric ID of the prototype to retrieve
345
+ * @returns The prototype with type-level immutability, or null if not found
346
+ *
347
+ * @example
348
+ * ```typescript
349
+ * const proto = store.getByPrototypeId(123);
350
+ * if (proto) {
351
+ * console.log(proto.prototypeNm);
352
+ * }
353
+ * ```
354
+ *
355
+ * @performance
356
+ * - Time complexity: O(1) - constant time regardless of cache size
357
+ * - Measured: ~0.0002ms per lookup (10,000 items)
358
+ * - Memory overhead: ~40 bytes per entry (including index metadata and hash table)
359
+ */
360
+ getByPrototypeId(prototypeId) {
361
+ const prototype = this.prototypeIdIndex.get(prototypeId) ?? null;
362
+ return prototype;
363
+ }
364
+ /**
365
+ * Return an array of all cached prototype IDs.
366
+ *
367
+ * This method provides efficient access to prototype IDs without copying the
368
+ * entire prototype objects. Useful for operations that only need IDs, such as
369
+ * ID-based filtering, statistics, or exporting ID lists.
370
+ *
371
+ * @returns Read-only array of prototype IDs in insertion order
372
+ *
373
+ * @performance
374
+ * - Time complexity: O(n) - must iterate through all Map keys
375
+ * - Memory: Creates a new array of numbers (~40 bytes per ID)
376
+ * - Lighter than getAll() which copies full objects (~300+ bytes each)
377
+ *
378
+ * @example
379
+ * ```typescript
380
+ * // ✅ Good: Call once and reuse
381
+ * const ids = store.getPrototypeIds();
382
+ * const count = ids.length;
383
+ * const maxId = Math.max(...ids);
384
+ *
385
+ * // ✅ Good: Single-use cases
386
+ * return { availableIds: store.getPrototypeIds() };
387
+ *
388
+ * // ❌ Bad: Repeated calls in loops
389
+ * for (let i = 0; i < 1000; i++) {
390
+ * const ids = store.getPrototypeIds(); // O(n) × 1000 = very slow!
391
+ * const id = ids[Math.floor(Math.random() * ids.length)];
392
+ * }
393
+ *
394
+ * // ✅ Better: Use getAll() once for repeated access
395
+ * const all = store.getAll();
396
+ * for (let i = 0; i < 1000; i++) {
397
+ * const item = all[Math.floor(Math.random() * all.length)];
398
+ * }
399
+ * ```
400
+ *
401
+ * @remarks
402
+ * **Performance Warning**: This method creates a new array on every call.
403
+ * For high-frequency operations (loops, repeated random access), prefer
404
+ * calling {@link getAll} once and reusing the result. The O(n) cost per
405
+ * call makes this unsuitable for tight loops.
406
+ */
407
+ getPrototypeIds() {
408
+ return Array.from(this.prototypeIdIndex.keys());
409
+ }
410
+ }
411
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../lib/store/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export type { SetFailure, SetResult, SetSuccess, StoreErrorCode, StoreFailureKind, } from './result.types.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/store/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,cAAc,EACd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/store/types/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import type { StoreDataState } from '../errors/store-error.js';
2
+ import type { PrototypeInMemoryStats } from '../store.js';
3
+ /**
4
+ * Failure kinds specific to store operations.
5
+ *
6
+ * - `storage_limit`: Store capacity exceeded
7
+ * - `serialization`: JSON serialization failed during size estimation
8
+ * - `unknown`: Unexpected store error
9
+ */
10
+ export type StoreFailureKind = 'storage_limit' | 'serialization' | 'unknown';
11
+ /**
12
+ * Error codes for store-originated failures.
13
+ *
14
+ * - `STORE_CAPACITY_EXCEEDED`: Data size exceeds configured limit
15
+ * - `STORE_SERIALIZATION_FAILED`: Failed to serialize data for size estimation
16
+ * - `STORE_UNKNOWN`: Unexpected error from store
17
+ */
18
+ export type StoreErrorCode = 'STORE_CAPACITY_EXCEEDED' | 'STORE_SERIALIZATION_FAILED' | 'STORE_UNKNOWN';
19
+ /**
20
+ * Successful result from setAll operation.
21
+ */
22
+ export type SetSuccess = {
23
+ /** Indicates successful operation. */
24
+ ok: true;
25
+ /** Statistics about the current snapshot after storing. */
26
+ stats: PrototypeInMemoryStats;
27
+ };
28
+ /**
29
+ * Failed result from setAll operation.
30
+ *
31
+ * Contains store-specific error information.
32
+ */
33
+ export type SetFailure = {
34
+ /** Indicates failed operation. */
35
+ ok: false;
36
+ /** Always store-originated. */
37
+ origin: 'store';
38
+ /** Coarse-grained classification of the failure cause. */
39
+ kind: StoreFailureKind;
40
+ /** Canonical error code from the store. */
41
+ code: StoreErrorCode;
42
+ /** Human-readable error message. */
43
+ message: string;
44
+ /** State of the store's data when the error occurred. */
45
+ dataState: StoreDataState;
46
+ /** Underlying cause of the error (for serialization failures). */
47
+ cause?: unknown;
48
+ };
49
+ /**
50
+ * Result from setAll operation.
51
+ *
52
+ * Returns either success with stats or failure with store-specific error details.
53
+ * This type maintains symmetry with FetchPrototypesResult at the operation boundary,
54
+ * allowing fetchAndStore to handle both fetch and store operations uniformly.
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const result = storeSnapshot(data);
59
+ * if (result.ok) {
60
+ * console.log('Stored:', result.stats.size);
61
+ * } else {
62
+ * console.error('Store failed:', result.kind, result.code);
63
+ * }
64
+ * ```
65
+ */
66
+ export type SetResult = SetSuccess | SetFailure;
67
+ //# sourceMappingURL=result.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.types.d.ts","sourceRoot":"","sources":["../../../lib/store/types/result.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,eAAe,GAAG,SAAS,CAAC;AAE7E;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GACtB,yBAAyB,GACzB,4BAA4B,GAC5B,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,sCAAsC;IACtC,EAAE,EAAE,IAAI,CAAC;IACT,2DAA2D;IAC3D,KAAK,EAAE,sBAAsB,CAAC;CAC/B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,kCAAkC;IAClC,EAAE,EAAE,KAAK,CAAC;IACV,+BAA+B;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,IAAI,EAAE,gBAAgB,CAAC;IACvB,2CAA2C;IAC3C,IAAI,EAAE,cAAc,CAAC;IACrB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,SAAS,EAAE,cAAc,CAAC;IAC1B,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=result.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.types.js","sourceRoot":"","sources":["../../../lib/store/types/result.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Type definitions for ProtoPedia field value codes.
3
+ *
4
+ * These types define the valid numeric values for various ProtoPedia fields.
5
+ *
6
+ * @module types
7
+ */
8
+ /**
9
+ * Valid status code values.
10
+ *
11
+ * - 1: 'アイデア' (Idea)
12
+ * - 2: '開発中' (In Development)
13
+ * - 3: '完成' (Completed)
14
+ * - 4: '供養' (Retired/Memorial)
15
+ *
16
+ * All four status values appear in public API responses.
17
+ */
18
+ export type StatusCode = 1 | 2 | 3 | 4;
19
+ /**
20
+ * Valid release flag code values.
21
+ *
22
+ * - 1: '下書き保存' (Draft) - Not accessible via public API
23
+ * - 2: '一般公開' (Public) - Only this value appears in API responses
24
+ * - 3: '限定共有' (Limited Sharing) - Not accessible via public API
25
+ */
26
+ export type ReleaseFlagCode = 1 | 2 | 3;
27
+ /**
28
+ * Valid license type code values.
29
+ *
30
+ * - 0: 'なし' (None) - Not observed in API responses
31
+ * - 1: '表示(CC:BY)' (Display with CC BY license) - All API responses have this value
32
+ */
33
+ export type LicenseTypeCode = 0 | 1;
34
+ /**
35
+ * Valid thanks flag code values.
36
+ *
37
+ * - 0: (Implicit) Message not yet shown - Rarely or never seen in API responses
38
+ * - 1: '初回表示済' ("Thank you for posting" message shown) - Most common value
39
+ * - undefined: Field not present in older prototypes (pre-thanksFlg era, ~3.26% of data)
40
+ *
41
+ * Note: Historical data may not include this field. Always handle undefined case.
42
+ */
43
+ export type ThanksFlagCode = 0 | 1 | undefined;
44
+ //# sourceMappingURL=codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../../lib/types/codes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAExC;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,CAAC;AAEpC;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Type definitions for ProtoPedia field value codes.
3
+ *
4
+ * These types define the valid numeric values for various ProtoPedia fields.
5
+ *
6
+ * @module types
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codes.js","sourceRoot":"","sources":["../../lib/types/codes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared type definitions for the library.
3
+ *
4
+ * This module provides the core data structures used throughout the library.
5
+ * It serves as the single source of truth for type definitions, ensuring
6
+ * consistency across all layers (Fetcher, Store, Repository).
7
+ *
8
+ * ## Main Exports
9
+ *
10
+ * - {@link NormalizedPrototype} — The standardized shape of a prototype
11
+ * after normalization from ProtoPedia API responses.
12
+ * - {@link StatusCode} — Type for prototype status codes (1-4)
13
+ * - {@link ReleaseFlagCode} — Type for release flag codes (1-3)
14
+ * - {@link LicenseTypeCode} — Type for license type codes (0-1)
15
+ * - {@link ThanksFlagCode} — Type for thanks flag codes (0, 1, or undefined)
16
+ *
17
+ * ## Type Characteristics
18
+ *
19
+ * - **Type Safety**: Strongly typed with clear required/optional field distinction
20
+ * - **Normalization**: Pipe-separated strings converted to arrays, timestamps to UTC ISO 8601
21
+ * - **Strict Typing**: Compatible with TypeScript's `exactOptionalPropertyTypes: true`
22
+ * - **Cross-Layer Consistency**: Used uniformly across Fetcher, Store, and Repository
23
+ *
24
+ * ## Usage
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * import type { NormalizedPrototype, StatusCode } from 'promidas/types';
29
+ *
30
+ * function processPrototype(prototype: NormalizedPrototype) {
31
+ * // Required fields are always accessible
32
+ * console.log(prototype.id, prototype.prototypeNm);
33
+ *
34
+ * // Array fields are type-safe
35
+ * prototype.tags.forEach(tag => console.log(tag)); // tag is string
36
+ *
37
+ * // Optional fields require undefined checks
38
+ * if (prototype.releaseDate !== undefined) {
39
+ * console.log(new Date(prototype.releaseDate));
40
+ * }
41
+ *
42
+ * // Code types are available
43
+ * const status: StatusCode = prototype.status as StatusCode;
44
+ * }
45
+ * ```
46
+ *
47
+ * ## Data Transformation
48
+ *
49
+ * This type represents data after normalization:
50
+ *
51
+ * - **Raw API data** (`UpstreamPrototype`) → `normalizePrototype()` → **Normalized data** (`NormalizedPrototype`)
52
+ * - Pipe-separated strings (`"tag1|tag2"`) → Arrays (`["tag1", "tag2"]`)
53
+ * - JST timestamps (`"2025-12-12 09:00:00.0"`) → UTC ISO 8601 (`"2025-12-12T00:00:00.000Z"`)
54
+ *
55
+ * @module
56
+ * @see {@link NormalizedPrototype} for detailed field documentation
57
+ * @see {@link ../fetcher/index.js} for normalization utilities
58
+ */
59
+ export type { NormalizedPrototype } from './normalized-prototype.js';
60
+ export type { StatusCode, ReleaseFlagCode, LicenseTypeCode, ThanksFlagCode, } from './codes.js';
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,YAAY,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC"}