@trufnetwork/sdk-js 0.3.8 → 0.4.2

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 (78) hide show
  1. package/dist/cjs/client/client.cjs +44 -0
  2. package/dist/cjs/client/client.cjs.map +2 -2
  3. package/dist/cjs/contracts-api/action.cjs +301 -77
  4. package/dist/cjs/contracts-api/action.cjs.map +3 -3
  5. package/dist/cjs/contracts-api/cache.integration.test.cjs +265 -0
  6. package/dist/cjs/contracts-api/cache.integration.test.cjs.map +7 -0
  7. package/dist/cjs/contracts-api/composedAction.cjs +86 -0
  8. package/dist/cjs/contracts-api/composedAction.cjs.map +2 -2
  9. package/dist/cjs/contracts-api/composedAction.test.cjs +301 -0
  10. package/dist/cjs/contracts-api/composedAction.test.cjs.map +7 -0
  11. package/dist/cjs/index.common.cjs.map +1 -1
  12. package/dist/cjs/types/cache.cjs +34 -0
  13. package/dist/cjs/types/cache.cjs.map +7 -0
  14. package/dist/cjs/types/cache.test.cjs +205 -0
  15. package/dist/cjs/types/cache.test.cjs.map +7 -0
  16. package/dist/cjs/util/cacheMetadataParser.cjs +174 -0
  17. package/dist/cjs/util/cacheMetadataParser.cjs.map +7 -0
  18. package/dist/cjs/util/cacheMetadataParser.test.cjs +329 -0
  19. package/dist/cjs/util/cacheMetadataParser.test.cjs.map +7 -0
  20. package/dist/cjs/util/cacheValidation.cjs +88 -0
  21. package/dist/cjs/util/cacheValidation.cjs.map +7 -0
  22. package/dist/cjs/util/cacheValidation.test.cjs +108 -0
  23. package/dist/cjs/util/cacheValidation.test.cjs.map +7 -0
  24. package/dist/esm/client/client.mjs +44 -0
  25. package/dist/esm/client/client.mjs.map +2 -2
  26. package/dist/esm/contracts-api/action.mjs +302 -77
  27. package/dist/esm/contracts-api/action.mjs.map +3 -3
  28. package/dist/esm/contracts-api/cache.integration.test.mjs +263 -0
  29. package/dist/esm/contracts-api/cache.integration.test.mjs.map +7 -0
  30. package/dist/esm/contracts-api/composedAction.mjs +86 -0
  31. package/dist/esm/contracts-api/composedAction.mjs.map +2 -2
  32. package/dist/esm/contracts-api/composedAction.test.mjs +299 -0
  33. package/dist/esm/contracts-api/composedAction.test.mjs.map +7 -0
  34. package/dist/esm/index.common.mjs.map +1 -1
  35. package/dist/esm/types/cache.mjs +13 -0
  36. package/dist/esm/types/cache.mjs.map +7 -0
  37. package/dist/esm/types/cache.test.mjs +203 -0
  38. package/dist/esm/types/cache.test.mjs.map +7 -0
  39. package/dist/esm/util/cacheMetadataParser.mjs +153 -0
  40. package/dist/esm/util/cacheMetadataParser.mjs.map +7 -0
  41. package/dist/esm/util/cacheMetadataParser.test.mjs +327 -0
  42. package/dist/esm/util/cacheMetadataParser.test.mjs.map +7 -0
  43. package/dist/esm/util/cacheValidation.mjs +67 -0
  44. package/dist/esm/util/cacheValidation.mjs.map +7 -0
  45. package/dist/esm/util/cacheValidation.test.mjs +106 -0
  46. package/dist/esm/util/cacheValidation.test.mjs.map +7 -0
  47. package/dist/tsconfig.build.tsbuildinfo +1 -1
  48. package/dist/types/client/client.d.ts +39 -1
  49. package/dist/types/client/client.d.ts.map +1 -1
  50. package/dist/types/contracts-api/action.d.ts +11 -1
  51. package/dist/types/contracts-api/action.d.ts.map +1 -1
  52. package/dist/types/contracts-api/cache.integration.test.d.ts +2 -0
  53. package/dist/types/contracts-api/cache.integration.test.d.ts.map +1 -0
  54. package/dist/types/contracts-api/composedAction.d.ts +75 -0
  55. package/dist/types/contracts-api/composedAction.d.ts.map +1 -1
  56. package/dist/types/contracts-api/composedAction.test.d.ts +2 -0
  57. package/dist/types/contracts-api/composedAction.test.d.ts.map +1 -0
  58. package/dist/types/index.common.d.ts +1 -1
  59. package/dist/types/index.common.d.ts.map +1 -1
  60. package/dist/types/types/cache.d.ts +129 -0
  61. package/dist/types/types/cache.d.ts.map +1 -0
  62. package/dist/types/types/cache.test.d.ts +2 -0
  63. package/dist/types/types/cache.test.d.ts.map +1 -0
  64. package/dist/types/util/cacheMetadataParser.d.ts +38 -0
  65. package/dist/types/util/cacheMetadataParser.d.ts.map +1 -0
  66. package/dist/types/util/cacheMetadataParser.test.d.ts +2 -0
  67. package/dist/types/util/cacheMetadataParser.test.d.ts.map +1 -0
  68. package/dist/types/util/cacheValidation.d.ts +27 -0
  69. package/dist/types/util/cacheValidation.d.ts.map +1 -0
  70. package/dist/types/util/cacheValidation.test.d.ts +2 -0
  71. package/dist/types/util/cacheValidation.test.d.ts.map +1 -0
  72. package/package.json +5 -3
  73. package/dist/cjs/client/client.test.cjs +0 -32
  74. package/dist/cjs/client/client.test.cjs.map +0 -7
  75. package/dist/esm/client/client.test.mjs +0 -30
  76. package/dist/esm/client/client.test.mjs.map +0 -7
  77. package/dist/types/client/client.test.d.ts +0 -2
  78. package/dist/types/client/client.test.d.ts.map +0 -1
@@ -0,0 +1,153 @@
1
+ // src/util/cacheMetadataParser.ts
2
+ var CacheMetadataParser = class {
3
+ /**
4
+ * Parses logs and removes prepended numeric prefixes (e.g., "1. ", "2. ")
5
+ * @param logsInput - The logs string or array to parse
6
+ * @returns Array of clean log lines
7
+ */
8
+ static parseLogsForMetadata(logsInput) {
9
+ const logs = [];
10
+ const logArray = Array.isArray(logsInput) ? logsInput : [logsInput];
11
+ for (const log of logArray) {
12
+ if (!log || typeof log !== "string") {
13
+ continue;
14
+ }
15
+ const lines = log.split("\n");
16
+ for (const line of lines) {
17
+ const trimmedLine = line.trim();
18
+ if (!trimmedLine) {
19
+ continue;
20
+ }
21
+ const dotSpaceIndex = trimmedLine.indexOf(". ");
22
+ if (dotSpaceIndex > 0) {
23
+ const prefix = trimmedLine.substring(0, dotSpaceIndex);
24
+ if (/^\d+$/.test(prefix)) {
25
+ const cleanLine = trimmedLine.substring(dotSpaceIndex + 2).trim();
26
+ if (cleanLine) {
27
+ logs.push(cleanLine);
28
+ }
29
+ continue;
30
+ }
31
+ }
32
+ logs.push(trimmedLine);
33
+ }
34
+ }
35
+ return logs;
36
+ }
37
+ /**
38
+ * Extracts cache metadata from action logs
39
+ * @param logs - The action logs returned from the backend (may be a single string or array)
40
+ * @returns Cache metadata if found, null otherwise
41
+ */
42
+ static extractFromLogs(logs) {
43
+ const logLines = this.parseLogsForMetadata(logs);
44
+ for (const line of logLines) {
45
+ if (line.includes("cache_hit")) {
46
+ try {
47
+ const logData = JSON.parse(line);
48
+ if (logData.cache_hit === true) {
49
+ return {
50
+ hit: true,
51
+ cacheDisabled: logData.cache_disabled,
52
+ height: logData.cache_height ? Number(logData.cache_height) : void 0
53
+ };
54
+ }
55
+ if (logData.cache_hit === false) {
56
+ return {
57
+ hit: false,
58
+ cacheDisabled: logData.cache_disabled,
59
+ height: void 0
60
+ };
61
+ }
62
+ } catch (error) {
63
+ continue;
64
+ }
65
+ }
66
+ }
67
+ return null;
68
+ }
69
+ /**
70
+ * Validates cache metadata structure
71
+ * @param metadata - The cache metadata to validate
72
+ * @returns True if metadata is valid, false otherwise
73
+ */
74
+ static isValidCacheMetadata(metadata) {
75
+ if (!metadata || typeof metadata !== "object") {
76
+ return false;
77
+ }
78
+ if (typeof metadata.hit !== "boolean") {
79
+ return false;
80
+ }
81
+ if (metadata.cacheDisabled !== void 0 && typeof metadata.cacheDisabled !== "boolean") {
82
+ return false;
83
+ }
84
+ if (metadata.streamId !== void 0 && typeof metadata.streamId !== "string") {
85
+ return false;
86
+ }
87
+ if (metadata.dataProvider !== void 0 && typeof metadata.dataProvider !== "string") {
88
+ return false;
89
+ }
90
+ if (metadata.from !== void 0 && typeof metadata.from !== "number") {
91
+ return false;
92
+ }
93
+ if (metadata.to !== void 0 && typeof metadata.to !== "number") {
94
+ return false;
95
+ }
96
+ if (metadata.frozenAt !== void 0 && typeof metadata.frozenAt !== "number") {
97
+ return false;
98
+ }
99
+ if (metadata.rowsServed !== void 0 && typeof metadata.rowsServed !== "number") {
100
+ return false;
101
+ }
102
+ if (metadata.height !== void 0 && typeof metadata.height !== "number") {
103
+ return false;
104
+ }
105
+ return true;
106
+ }
107
+ /**
108
+ * Extracts cache metadata from Kwil response structure
109
+ * @param response - The full response from Kwil client
110
+ * @returns Cache metadata if found, null otherwise
111
+ */
112
+ static extractFromResponse(response) {
113
+ if (response && response.data && response.data.logs) {
114
+ return this.extractFromLogs(response.data.logs);
115
+ }
116
+ if (response && response.logs) {
117
+ return this.extractFromLogs(response.logs);
118
+ }
119
+ return null;
120
+ }
121
+ /**
122
+ * Aggregates multiple cache metadata entries into a collection
123
+ * @param metadataList - Array of cache metadata entries
124
+ * @returns Aggregated cache metadata collection
125
+ */
126
+ static aggregate(metadataList) {
127
+ const totalQueries = metadataList.length;
128
+ let cacheHits = 0;
129
+ let totalRowsServed = 0;
130
+ for (const metadata of metadataList) {
131
+ if (metadata.hit) {
132
+ cacheHits++;
133
+ }
134
+ if (metadata.rowsServed) {
135
+ totalRowsServed += metadata.rowsServed;
136
+ }
137
+ }
138
+ const cacheMisses = totalQueries - cacheHits;
139
+ const cacheHitRate = totalQueries > 0 ? cacheHits / totalQueries : 0;
140
+ return {
141
+ totalQueries,
142
+ cacheHits,
143
+ cacheMisses,
144
+ cacheHitRate,
145
+ totalRowsServed,
146
+ entries: metadataList
147
+ };
148
+ }
149
+ };
150
+ export {
151
+ CacheMetadataParser
152
+ };
153
+ //# sourceMappingURL=cacheMetadataParser.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/util/cacheMetadataParser.ts"],
4
+ "sourcesContent": ["import { CacheMetadata, CacheMetadataCollection } from '../types/cache';\n\n/**\n * Parser for extracting cache metadata from action logs\n * Handles the parsing of cache-related information from SQL action responses\n */\nexport class CacheMetadataParser {\n /**\n * Parses logs and removes prepended numeric prefixes (e.g., \"1. \", \"2. \")\n * @param logsInput - The logs string or array to parse\n * @returns Array of clean log lines\n */\n static parseLogsForMetadata(logsInput: string | string[]): string[] {\n const logs: string[] = [];\n const logArray = Array.isArray(logsInput) ? logsInput : [logsInput];\n \n for (const log of logArray) {\n if (!log || typeof log !== 'string') {\n continue;\n }\n \n const lines = log.split('\\n');\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (!trimmedLine) {\n continue;\n }\n \n // Check for prepended numeric format (e.g., \"1. \", \"2. \")\n const dotSpaceIndex = trimmedLine.indexOf('. ');\n if (dotSpaceIndex > 0) {\n const prefix = trimmedLine.substring(0, dotSpaceIndex);\n // Check if prefix is a number\n if (/^\\d+$/.test(prefix)) {\n const cleanLine = trimmedLine.substring(dotSpaceIndex + 2).trim();\n if (cleanLine) {\n logs.push(cleanLine);\n }\n continue;\n }\n }\n \n // If no prepended format found, add the line as-is\n logs.push(trimmedLine);\n }\n }\n \n return logs;\n }\n\n /**\n * Extracts cache metadata from action logs\n * @param logs - The action logs returned from the backend (may be a single string or array)\n * @returns Cache metadata if found, null otherwise\n */\n static extractFromLogs(logs: string | string[]): CacheMetadata | null {\n // Parse logs and remove prepended numeric prefixes\n const logLines = this.parseLogsForMetadata(logs);\n \n for (const line of logLines) {\n // Look for cache-related log entries\n if (line.includes('cache_hit')) {\n try {\n // Try to parse as JSON\n const logData = JSON.parse(line);\n \n // Check if this is a cache hit entry\n if (logData.cache_hit === true) {\n return {\n hit: true,\n cacheDisabled: logData.cache_disabled,\n height: logData.cache_height ? Number(logData.cache_height) : undefined\n };\n }\n \n // Cache miss case\n if (logData.cache_hit === false) {\n return {\n hit: false,\n cacheDisabled: logData.cache_disabled,\n height: undefined\n };\n }\n \n } catch (error) {\n // If JSON parsing fails, continue checking other logs\n // This is expected for non-JSON log entries\n continue;\n }\n }\n }\n \n // No cache metadata found\n return null;\n }\n \n /**\n * Validates cache metadata structure\n * @param metadata - The cache metadata to validate\n * @returns True if metadata is valid, false otherwise\n */\n static isValidCacheMetadata(metadata: any): metadata is CacheMetadata {\n if (!metadata || typeof metadata !== 'object') {\n return false;\n }\n \n // Check required fields\n if (typeof metadata.hit !== 'boolean') {\n return false;\n }\n \n // Check optional fields\n if (metadata.cacheDisabled !== undefined && typeof metadata.cacheDisabled !== 'boolean') {\n return false;\n }\n \n if (metadata.streamId !== undefined && typeof metadata.streamId !== 'string') {\n return false;\n }\n \n if (metadata.dataProvider !== undefined && typeof metadata.dataProvider !== 'string') {\n return false;\n }\n \n if (metadata.from !== undefined && typeof metadata.from !== 'number') {\n return false;\n }\n \n if (metadata.to !== undefined && typeof metadata.to !== 'number') {\n return false;\n }\n \n if (metadata.frozenAt !== undefined && typeof metadata.frozenAt !== 'number') {\n return false;\n }\n \n if (metadata.rowsServed !== undefined && typeof metadata.rowsServed !== 'number') {\n return false;\n }\n\n if (metadata.height !== undefined && typeof metadata.height !== 'number') {\n return false;\n }\n \n return true;\n }\n \n /**\n * Extracts cache metadata from Kwil response structure\n * @param response - The full response from Kwil client\n * @returns Cache metadata if found, null otherwise\n */\n static extractFromResponse(response: any): CacheMetadata | null {\n // Check if response has logs (new structure from kwil-js)\n if (response && response.data && response.data.logs) {\n return this.extractFromLogs(response.data.logs);\n }\n \n // Fallback: check if response has logs directly (for backward compatibility)\n if (response && response.logs) {\n return this.extractFromLogs(response.logs);\n }\n \n return null;\n }\n \n /**\n * Aggregates multiple cache metadata entries into a collection\n * @param metadataList - Array of cache metadata entries\n * @returns Aggregated cache metadata collection\n */\n static aggregate(metadataList: CacheMetadata[]): CacheMetadataCollection {\n const totalQueries = metadataList.length;\n let cacheHits = 0;\n let totalRowsServed = 0;\n \n for (const metadata of metadataList) {\n if (metadata.hit) {\n cacheHits++;\n }\n \n if (metadata.rowsServed) {\n totalRowsServed += metadata.rowsServed;\n }\n }\n \n const cacheMisses = totalQueries - cacheHits;\n const cacheHitRate = totalQueries > 0 ? cacheHits / totalQueries : 0;\n \n return {\n totalQueries,\n cacheHits,\n cacheMisses,\n cacheHitRate,\n totalRowsServed,\n entries: metadataList\n };\n }\n}"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,327 @@
1
+ // src/util/cacheMetadataParser.test.ts
2
+ import { describe, it, expect } from "vitest";
3
+ import { CacheMetadataParser } from "./cacheMetadataParser.mjs";
4
+ describe("CacheMetadataParser", () => {
5
+ describe("extractFromLogs", () => {
6
+ it("should extract cache hit metadata from valid log", () => {
7
+ const logs = ['{"cache_hit": true, "cache_height": 123456}'];
8
+ const result = CacheMetadataParser.extractFromLogs(logs);
9
+ expect(result).toEqual({
10
+ hit: true,
11
+ cacheDisabled: void 0,
12
+ height: 123456
13
+ });
14
+ });
15
+ it("should extract enhanced cache metadata with cacheDisabled field", () => {
16
+ const logs = ['{"cache_hit": false, "cache_disabled": true}'];
17
+ const result = CacheMetadataParser.extractFromLogs(logs);
18
+ expect(result).toEqual({
19
+ hit: false,
20
+ cacheDisabled: true,
21
+ height: void 0
22
+ });
23
+ });
24
+ it("should extract cache miss metadata from valid log", () => {
25
+ const logs = ['{"cache_hit": false}'];
26
+ const result = CacheMetadataParser.extractFromLogs(logs);
27
+ expect(result).toEqual({
28
+ hit: false,
29
+ cacheDisabled: void 0,
30
+ height: void 0
31
+ });
32
+ });
33
+ it("should handle cache hit without height field", () => {
34
+ const logs = ['{"cache_hit": true}'];
35
+ const result = CacheMetadataParser.extractFromLogs(logs);
36
+ expect(result).toEqual({
37
+ hit: true,
38
+ cacheDisabled: void 0,
39
+ height: void 0
40
+ });
41
+ });
42
+ it("should handle single string log with newlines", () => {
43
+ const log = 'other log entry\n{"cache_hit": true, "cache_height": 123456}\nmore logs';
44
+ const result = CacheMetadataParser.extractFromLogs(log);
45
+ expect(result).toEqual({
46
+ hit: true,
47
+ cacheDisabled: void 0,
48
+ height: 123456
49
+ });
50
+ });
51
+ it("should handle array of logs", () => {
52
+ const logs = [
53
+ "normal log entry",
54
+ '{"cache_hit": true, "cache_height": 123456}',
55
+ "another log"
56
+ ];
57
+ const result = CacheMetadataParser.extractFromLogs(logs);
58
+ expect(result).toEqual({
59
+ hit: true,
60
+ cacheDisabled: void 0,
61
+ height: 123456
62
+ });
63
+ });
64
+ it("should return null for logs without cache metadata", () => {
65
+ const logs = ["normal log entry", "another log"];
66
+ const result = CacheMetadataParser.extractFromLogs(logs);
67
+ expect(result).toBeNull();
68
+ });
69
+ it("should return null for malformed JSON", () => {
70
+ const logs = ['{"cache_hit": true invalid json}'];
71
+ const result = CacheMetadataParser.extractFromLogs(logs);
72
+ expect(result).toBeNull();
73
+ });
74
+ it("should return null for empty logs", () => {
75
+ const result = CacheMetadataParser.extractFromLogs([]);
76
+ expect(result).toBeNull();
77
+ });
78
+ it("should handle empty string logs", () => {
79
+ const result = CacheMetadataParser.extractFromLogs(["", " ", "\n"]);
80
+ expect(result).toBeNull();
81
+ });
82
+ it("should extract cache hit metadata with all fields", () => {
83
+ const logs = ['{"cache_hit": true, "cache_height": 123456}'];
84
+ const metadata = CacheMetadataParser.extractFromLogs(logs);
85
+ expect(metadata).toEqual({
86
+ hit: true,
87
+ cacheDisabled: void 0,
88
+ height: 123456
89
+ });
90
+ });
91
+ it("should extract cache hit without optional fields", () => {
92
+ const logs = ['{"cache_hit": true}'];
93
+ const metadata = CacheMetadataParser.extractFromLogs(logs);
94
+ expect(metadata).toEqual({
95
+ hit: true,
96
+ cacheDisabled: void 0,
97
+ height: void 0
98
+ });
99
+ });
100
+ it("should extract cache miss", () => {
101
+ const logs = ['{"cache_hit": false}'];
102
+ const metadata = CacheMetadataParser.extractFromLogs(logs);
103
+ expect(metadata).toEqual({
104
+ hit: false,
105
+ cacheDisabled: void 0,
106
+ height: void 0
107
+ });
108
+ });
109
+ it("should handle logs with prepended numeric prefixes", () => {
110
+ const logs = ['1. {"cache_hit": true, "cache_height": 123456}\n2. some other log\n3. {"cache_hit": false}'];
111
+ const metadata = CacheMetadataParser.extractFromLogs(logs);
112
+ expect(metadata).toEqual({
113
+ hit: true,
114
+ cacheDisabled: void 0,
115
+ height: 123456
116
+ });
117
+ });
118
+ it("should handle array of logs with prepended numeric prefixes", () => {
119
+ const logs = [
120
+ "1. normal log line",
121
+ '2. {"cache_hit": false, "cache_disabled": true}',
122
+ "3. another log line"
123
+ ];
124
+ const metadata = CacheMetadataParser.extractFromLogs(logs);
125
+ expect(metadata).toEqual({
126
+ hit: false,
127
+ cacheDisabled: true,
128
+ height: void 0
129
+ });
130
+ });
131
+ it("should handle mixed format logs (some with prefixes, some without)", () => {
132
+ const logs = [
133
+ "normal log without prefix",
134
+ '1. {"cache_hit": true}',
135
+ "another log without prefix"
136
+ ];
137
+ const metadata = CacheMetadataParser.extractFromLogs(logs);
138
+ expect(metadata).toEqual({
139
+ hit: true,
140
+ cacheDisabled: void 0,
141
+ height: void 0
142
+ });
143
+ });
144
+ });
145
+ describe("isValidCacheMetadata", () => {
146
+ it("should validate correct cache metadata", () => {
147
+ const metadata = { hit: true, height: 123456 };
148
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);
149
+ });
150
+ it("should validate metadata without height", () => {
151
+ const metadata = { hit: false };
152
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);
153
+ });
154
+ it("should validate enhanced cache metadata with all fields", () => {
155
+ const metadata = {
156
+ hit: true,
157
+ cacheDisabled: false,
158
+ height: 123456,
159
+ streamId: "test-stream",
160
+ dataProvider: "0x123456789abcdef",
161
+ from: 1609459100,
162
+ to: 1609459300,
163
+ frozenAt: 1609459250,
164
+ rowsServed: 10
165
+ };
166
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);
167
+ });
168
+ it("should validate metadata with optional fields", () => {
169
+ const metadata = { hit: true, cacheDisabled: true };
170
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);
171
+ });
172
+ it("should reject metadata without hit field", () => {
173
+ const metadata = { height: 123456 };
174
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);
175
+ });
176
+ it("should reject metadata with invalid hit type", () => {
177
+ const metadata = { hit: "true", height: 123456 };
178
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);
179
+ });
180
+ it("should reject metadata with invalid cacheDisabled type", () => {
181
+ const metadata = { hit: true, cacheDisabled: "false" };
182
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);
183
+ });
184
+ it("should reject metadata with invalid streamId type", () => {
185
+ const metadata = { hit: true, streamId: 123 };
186
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);
187
+ });
188
+ it("should reject metadata with invalid dataProvider type", () => {
189
+ const metadata = { hit: true, dataProvider: 456 };
190
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);
191
+ });
192
+ it("should reject metadata with invalid numeric fields", () => {
193
+ const invalidFromMetadata = { hit: true, from: "123" };
194
+ const invalidToMetadata = { hit: true, to: "456" };
195
+ const invalidFrozenAtMetadata = { hit: true, frozenAt: "789" };
196
+ const invalidRowsServedMetadata = { hit: true, rowsServed: "10" };
197
+ expect(CacheMetadataParser.isValidCacheMetadata(invalidFromMetadata)).toBe(false);
198
+ expect(CacheMetadataParser.isValidCacheMetadata(invalidToMetadata)).toBe(false);
199
+ expect(CacheMetadataParser.isValidCacheMetadata(invalidFrozenAtMetadata)).toBe(false);
200
+ expect(CacheMetadataParser.isValidCacheMetadata(invalidRowsServedMetadata)).toBe(false);
201
+ });
202
+ it("should validate complete metadata", () => {
203
+ const metadata = { hit: true, height: 123456 };
204
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);
205
+ });
206
+ it("should reject metadata with invalid height type", () => {
207
+ const metadata = { hit: true, height: "123456" };
208
+ expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);
209
+ });
210
+ it("should reject null or undefined", () => {
211
+ expect(CacheMetadataParser.isValidCacheMetadata(null)).toBe(false);
212
+ expect(CacheMetadataParser.isValidCacheMetadata(void 0)).toBe(false);
213
+ });
214
+ });
215
+ describe("extractFromResponse", () => {
216
+ it("should extract from response with logs", () => {
217
+ const response = {
218
+ data: { result: [] },
219
+ logs: ['{"cache_hit": true, "cache_height": 123456}']
220
+ };
221
+ const result = CacheMetadataParser.extractFromResponse(response);
222
+ expect(result).toEqual({
223
+ hit: true,
224
+ cacheDisabled: void 0,
225
+ height: 123456
226
+ });
227
+ });
228
+ it("should return null for response without logs", () => {
229
+ const response = { data: { result: [] } };
230
+ const result = CacheMetadataParser.extractFromResponse(response);
231
+ expect(result).toBeNull();
232
+ });
233
+ it("should return null for null response", () => {
234
+ const result = CacheMetadataParser.extractFromResponse(null);
235
+ expect(result).toBeNull();
236
+ });
237
+ });
238
+ describe("aggregate", () => {
239
+ it("should aggregate empty metadata list", () => {
240
+ const result = CacheMetadataParser.aggregate([]);
241
+ expect(result).toEqual({
242
+ totalQueries: 0,
243
+ cacheHits: 0,
244
+ cacheMisses: 0,
245
+ cacheHitRate: 0,
246
+ totalRowsServed: 0,
247
+ entries: []
248
+ });
249
+ });
250
+ it("should aggregate single metadata entry", () => {
251
+ const metadata = {
252
+ hit: true,
253
+ height: 123456,
254
+ streamId: "test-stream",
255
+ rowsServed: 5
256
+ };
257
+ const result = CacheMetadataParser.aggregate([metadata]);
258
+ expect(result).toEqual({
259
+ totalQueries: 1,
260
+ cacheHits: 1,
261
+ cacheMisses: 0,
262
+ cacheHitRate: 1,
263
+ totalRowsServed: 5,
264
+ entries: [metadata]
265
+ });
266
+ });
267
+ it("should aggregate multiple metadata entries", () => {
268
+ const metadata1 = {
269
+ hit: true,
270
+ height: 123456,
271
+ streamId: "stream-1",
272
+ rowsServed: 10
273
+ };
274
+ const metadata2 = {
275
+ hit: false,
276
+ streamId: "stream-2",
277
+ rowsServed: 5
278
+ };
279
+ const metadata3 = {
280
+ hit: true,
281
+ height: 123457,
282
+ streamId: "stream-3",
283
+ rowsServed: 15
284
+ };
285
+ const result = CacheMetadataParser.aggregate([metadata1, metadata2, metadata3]);
286
+ expect(result).toEqual({
287
+ totalQueries: 3,
288
+ cacheHits: 2,
289
+ cacheMisses: 1,
290
+ cacheHitRate: 2 / 3,
291
+ totalRowsServed: 30,
292
+ entries: [metadata1, metadata2, metadata3]
293
+ });
294
+ });
295
+ it("should handle metadata without rowsServed", () => {
296
+ const metadata1 = { hit: true, height: 123456 };
297
+ const metadata2 = { hit: false };
298
+ const metadata3 = { hit: true, rowsServed: 8 };
299
+ const result = CacheMetadataParser.aggregate([metadata1, metadata2, metadata3]);
300
+ expect(result).toEqual({
301
+ totalQueries: 3,
302
+ cacheHits: 2,
303
+ cacheMisses: 1,
304
+ cacheHitRate: 2 / 3,
305
+ totalRowsServed: 8,
306
+ // Only metadata3 has rowsServed
307
+ entries: [metadata1, metadata2, metadata3]
308
+ });
309
+ });
310
+ it("should calculate correct cache hit rate for mixed results", () => {
311
+ const metadataList = [
312
+ { hit: true, rowsServed: 1 },
313
+ { hit: false, rowsServed: 2 },
314
+ { hit: false, rowsServed: 3 },
315
+ { hit: true, rowsServed: 4 },
316
+ { hit: true, rowsServed: 5 }
317
+ ];
318
+ const result = CacheMetadataParser.aggregate(metadataList);
319
+ expect(result.totalQueries).toBe(5);
320
+ expect(result.cacheHits).toBe(3);
321
+ expect(result.cacheMisses).toBe(2);
322
+ expect(result.cacheHitRate).toBe(0.6);
323
+ expect(result.totalRowsServed).toBe(15);
324
+ });
325
+ });
326
+ });
327
+ //# sourceMappingURL=cacheMetadataParser.test.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/util/cacheMetadataParser.test.ts"],
4
+ "sourcesContent": ["import { describe, it, expect } from 'vitest';\nimport { CacheMetadataParser } from './cacheMetadataParser';\nimport type { CacheMetadata } from '../types/cache';\n\ndescribe('CacheMetadataParser', () => {\n describe('extractFromLogs', () => {\n it('should extract cache hit metadata from valid log', () => {\n const logs = ['{\"cache_hit\": true, \"cache_height\": 123456}'];\n const result = CacheMetadataParser.extractFromLogs(logs);\n \n expect(result).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: 123456\n });\n });\n\n it('should extract enhanced cache metadata with cacheDisabled field', () => {\n const logs = ['{\"cache_hit\": false, \"cache_disabled\": true}'];\n const result = CacheMetadataParser.extractFromLogs(logs);\n \n expect(result).toEqual({\n hit: false,\n cacheDisabled: true,\n height: undefined\n });\n });\n\n it('should extract cache miss metadata from valid log', () => {\n const logs = ['{\"cache_hit\": false}'];\n const result = CacheMetadataParser.extractFromLogs(logs);\n \n expect(result).toEqual({\n hit: false,\n cacheDisabled: undefined,\n height: undefined\n });\n });\n\n it('should handle cache hit without height field', () => {\n const logs = ['{\"cache_hit\": true}'];\n const result = CacheMetadataParser.extractFromLogs(logs);\n \n expect(result).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: undefined\n });\n });\n\n it('should handle single string log with newlines', () => {\n const log = 'other log entry\\n{\"cache_hit\": true, \"cache_height\": 123456}\\nmore logs';\n const result = CacheMetadataParser.extractFromLogs(log);\n \n expect(result).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: 123456\n });\n });\n\n it('should handle array of logs', () => {\n const logs = [\n 'normal log entry',\n '{\"cache_hit\": true, \"cache_height\": 123456}',\n 'another log'\n ];\n const result = CacheMetadataParser.extractFromLogs(logs);\n \n expect(result).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: 123456\n });\n });\n\n it('should return null for logs without cache metadata', () => {\n const logs = ['normal log entry', 'another log'];\n const result = CacheMetadataParser.extractFromLogs(logs);\n \n expect(result).toBeNull();\n });\n\n it('should return null for malformed JSON', () => {\n const logs = ['{\"cache_hit\": true invalid json}'];\n const result = CacheMetadataParser.extractFromLogs(logs);\n \n expect(result).toBeNull();\n });\n\n it('should return null for empty logs', () => {\n const result = CacheMetadataParser.extractFromLogs([]);\n expect(result).toBeNull();\n });\n\n it('should handle empty string logs', () => {\n const result = CacheMetadataParser.extractFromLogs(['', ' ', '\\n']);\n expect(result).toBeNull();\n });\n\n it('should extract cache hit metadata with all fields', () => {\n const logs = ['{\"cache_hit\": true, \"cache_height\": 123456}'];\n const metadata = CacheMetadataParser.extractFromLogs(logs);\n expect(metadata).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: 123456\n });\n });\n\n it('should extract cache hit without optional fields', () => {\n const logs = ['{\"cache_hit\": true}'];\n const metadata = CacheMetadataParser.extractFromLogs(logs);\n expect(metadata).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: undefined\n });\n });\n\n it('should extract cache miss', () => {\n const logs = ['{\"cache_hit\": false}'];\n const metadata = CacheMetadataParser.extractFromLogs(logs);\n expect(metadata).toEqual({\n hit: false,\n cacheDisabled: undefined,\n height: undefined\n });\n });\n\n it('should handle logs with prepended numeric prefixes', () => {\n const logs = ['1. {\"cache_hit\": true, \"cache_height\": 123456}\\n2. some other log\\n3. {\"cache_hit\": false}'];\n const metadata = CacheMetadataParser.extractFromLogs(logs);\n // Should extract the first cache metadata found (cache hit)\n expect(metadata).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: 123456\n });\n });\n\n it('should handle array of logs with prepended numeric prefixes', () => {\n const logs = [\n '1. normal log line',\n '2. {\"cache_hit\": false, \"cache_disabled\": true}',\n '3. another log line'\n ];\n const metadata = CacheMetadataParser.extractFromLogs(logs);\n expect(metadata).toEqual({\n hit: false,\n cacheDisabled: true,\n height: undefined\n });\n });\n\n it('should handle mixed format logs (some with prefixes, some without)', () => {\n const logs = [\n 'normal log without prefix',\n '1. {\"cache_hit\": true}',\n 'another log without prefix'\n ];\n const metadata = CacheMetadataParser.extractFromLogs(logs);\n expect(metadata).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: undefined\n });\n });\n });\n\n describe('isValidCacheMetadata', () => {\n it('should validate correct cache metadata', () => {\n const metadata = { hit: true, height: 123456 };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);\n });\n\n it('should validate metadata without height', () => {\n const metadata = { hit: false };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);\n });\n\n it('should validate enhanced cache metadata with all fields', () => {\n const metadata: CacheMetadata = {\n hit: true,\n cacheDisabled: false,\n height: 123456,\n streamId: 'test-stream',\n dataProvider: '0x123456789abcdef',\n from: 1609459100,\n to: 1609459300,\n frozenAt: 1609459250,\n rowsServed: 10\n };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);\n });\n\n it('should validate metadata with optional fields', () => {\n const metadata = { hit: true, cacheDisabled: true };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);\n });\n\n it('should reject metadata without hit field', () => {\n const metadata = { height: 123456 };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);\n });\n\n it('should reject metadata with invalid hit type', () => {\n const metadata = { hit: 'true', height: 123456 };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);\n });\n\n it('should reject metadata with invalid cacheDisabled type', () => {\n const metadata = { hit: true, cacheDisabled: 'false' };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);\n });\n\n it('should reject metadata with invalid streamId type', () => {\n const metadata = { hit: true, streamId: 123 };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);\n });\n\n it('should reject metadata with invalid dataProvider type', () => {\n const metadata = { hit: true, dataProvider: 456 };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);\n });\n\n it('should reject metadata with invalid numeric fields', () => {\n const invalidFromMetadata = { hit: true, from: '123' };\n const invalidToMetadata = { hit: true, to: '456' };\n const invalidFrozenAtMetadata = { hit: true, frozenAt: '789' };\n const invalidRowsServedMetadata = { hit: true, rowsServed: '10' };\n\n expect(CacheMetadataParser.isValidCacheMetadata(invalidFromMetadata)).toBe(false);\n expect(CacheMetadataParser.isValidCacheMetadata(invalidToMetadata)).toBe(false);\n expect(CacheMetadataParser.isValidCacheMetadata(invalidFrozenAtMetadata)).toBe(false);\n expect(CacheMetadataParser.isValidCacheMetadata(invalidRowsServedMetadata)).toBe(false);\n });\n\n it('should validate complete metadata', () => {\n const metadata = { hit: true, height: 123456 };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(true);\n });\n\n it('should reject metadata with invalid height type', () => {\n const metadata = { hit: true, height: '123456' };\n expect(CacheMetadataParser.isValidCacheMetadata(metadata)).toBe(false);\n });\n\n it('should reject null or undefined', () => {\n expect(CacheMetadataParser.isValidCacheMetadata(null)).toBe(false);\n expect(CacheMetadataParser.isValidCacheMetadata(undefined)).toBe(false);\n });\n });\n\n describe('extractFromResponse', () => {\n it('should extract from response with logs', () => {\n const response = {\n data: { result: [] },\n logs: ['{\"cache_hit\": true, \"cache_height\": 123456}']\n };\n const result = CacheMetadataParser.extractFromResponse(response);\n \n expect(result).toEqual({\n hit: true,\n cacheDisabled: undefined,\n height: 123456\n });\n });\n\n it('should return null for response without logs', () => {\n const response = { data: { result: [] } };\n const result = CacheMetadataParser.extractFromResponse(response);\n \n expect(result).toBeNull();\n });\n\n it('should return null for null response', () => {\n const result = CacheMetadataParser.extractFromResponse(null);\n expect(result).toBeNull();\n });\n });\n\n describe('aggregate', () => {\n it('should aggregate empty metadata list', () => {\n const result = CacheMetadataParser.aggregate([]);\n \n expect(result).toEqual({\n totalQueries: 0,\n cacheHits: 0,\n cacheMisses: 0,\n cacheHitRate: 0,\n totalRowsServed: 0,\n entries: []\n });\n });\n\n it('should aggregate single metadata entry', () => {\n const metadata: CacheMetadata = {\n hit: true,\n height: 123456,\n streamId: 'test-stream',\n rowsServed: 5\n };\n \n const result = CacheMetadataParser.aggregate([metadata]);\n \n expect(result).toEqual({\n totalQueries: 1,\n cacheHits: 1,\n cacheMisses: 0,\n cacheHitRate: 1.0,\n totalRowsServed: 5,\n entries: [metadata]\n });\n });\n\n it('should aggregate multiple metadata entries', () => {\n const metadata1: CacheMetadata = {\n hit: true,\n height: 123456,\n streamId: 'stream-1',\n rowsServed: 10\n };\n \n const metadata2: CacheMetadata = {\n hit: false,\n streamId: 'stream-2',\n rowsServed: 5\n };\n \n const metadata3: CacheMetadata = {\n hit: true,\n height: 123457,\n streamId: 'stream-3',\n rowsServed: 15\n };\n \n const result = CacheMetadataParser.aggregate([metadata1, metadata2, metadata3]);\n \n expect(result).toEqual({\n totalQueries: 3,\n cacheHits: 2,\n cacheMisses: 1,\n cacheHitRate: 2/3,\n totalRowsServed: 30,\n entries: [metadata1, metadata2, metadata3]\n });\n });\n\n it('should handle metadata without rowsServed', () => {\n const metadata1: CacheMetadata = { hit: true, height: 123456 };\n const metadata2: CacheMetadata = { hit: false };\n const metadata3: CacheMetadata = { hit: true, rowsServed: 8 };\n \n const result = CacheMetadataParser.aggregate([metadata1, metadata2, metadata3]);\n \n expect(result).toEqual({\n totalQueries: 3,\n cacheHits: 2,\n cacheMisses: 1,\n cacheHitRate: 2/3,\n totalRowsServed: 8, // Only metadata3 has rowsServed\n entries: [metadata1, metadata2, metadata3]\n });\n });\n\n it('should calculate correct cache hit rate for mixed results', () => {\n const metadataList: CacheMetadata[] = [\n { hit: true, rowsServed: 1 },\n { hit: false, rowsServed: 2 },\n { hit: false, rowsServed: 3 },\n { hit: true, rowsServed: 4 },\n { hit: true, rowsServed: 5 }\n ];\n \n const result = CacheMetadataParser.aggregate(metadataList);\n \n expect(result.totalQueries).toBe(5);\n expect(result.cacheHits).toBe(3);\n expect(result.cacheMisses).toBe(2);\n expect(result.cacheHitRate).toBe(0.6); // 3/5 = 0.6\n expect(result.totalRowsServed).toBe(15); // 1+2+3+4+5 = 15\n });\n });\n});"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,67 @@
1
+ // src/util/cacheValidation.ts
2
+ var CacheValidation = class {
3
+ /**
4
+ * Validates GetRecordOptions parameters
5
+ */
6
+ static validateGetRecordOptions(options) {
7
+ if (options.from !== void 0 && (typeof options.from !== "number" || options.from < 0)) {
8
+ throw new Error("Invalid from parameter: must be a non-negative number");
9
+ }
10
+ if (options.to !== void 0 && (typeof options.to !== "number" || options.to < 0)) {
11
+ throw new Error("Invalid to parameter: must be a non-negative number");
12
+ }
13
+ if (options.frozenAt !== void 0 && (typeof options.frozenAt !== "number" || options.frozenAt < 0)) {
14
+ throw new Error("Invalid frozenAt parameter: must be a non-negative number");
15
+ }
16
+ if (options.useCache !== void 0 && typeof options.useCache !== "boolean") {
17
+ throw new Error("Invalid useCache parameter: must be a boolean");
18
+ }
19
+ if (options.prefix !== void 0 && typeof options.prefix !== "string") {
20
+ throw new Error("Invalid prefix parameter: must be a string");
21
+ }
22
+ if (options.baseTime !== void 0 && typeof options.baseTime !== "number" && typeof options.baseTime !== "string") {
23
+ throw new Error("Invalid baseTime parameter: must be a number or string");
24
+ }
25
+ }
26
+ /**
27
+ * Validates GetIndexOptions parameters
28
+ */
29
+ static validateGetIndexOptions(options) {
30
+ this.validateGetRecordOptions(options);
31
+ }
32
+ /**
33
+ * Validates GetIndexChangeOptions parameters
34
+ */
35
+ static validateGetIndexChangeOptions(options) {
36
+ this.validateGetRecordOptions(options);
37
+ if (typeof options.timeInterval !== "number" || options.timeInterval <= 0) {
38
+ throw new Error("Invalid timeInterval parameter: must be a positive number");
39
+ }
40
+ }
41
+ /**
42
+ * Validates GetFirstRecordOptions parameters
43
+ */
44
+ static validateGetFirstRecordOptions(options) {
45
+ if (options.after !== void 0 && (typeof options.after !== "number" || options.after < 0)) {
46
+ throw new Error("Invalid after parameter: must be a non-negative number");
47
+ }
48
+ if (options.frozenAt !== void 0 && (typeof options.frozenAt !== "number" || options.frozenAt < 0)) {
49
+ throw new Error("Invalid frozenAt parameter: must be a non-negative number");
50
+ }
51
+ if (options.useCache !== void 0 && typeof options.useCache !== "boolean") {
52
+ throw new Error("Invalid useCache parameter: must be a boolean");
53
+ }
54
+ }
55
+ /**
56
+ * Validates time range parameters
57
+ */
58
+ static validateTimeRange(from, to) {
59
+ if (from !== void 0 && to !== void 0 && from > to) {
60
+ throw new Error("Invalid time range: from time cannot be greater than to time");
61
+ }
62
+ }
63
+ };
64
+ export {
65
+ CacheValidation
66
+ };
67
+ //# sourceMappingURL=cacheValidation.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/util/cacheValidation.ts"],
4
+ "sourcesContent": ["import { GetRecordOptions, GetIndexOptions, GetIndexChangeOptions, GetFirstRecordOptions } from '../types/cache';\n\n/**\n * Validation utilities for cache-related parameters\n */\nexport class CacheValidation {\n /**\n * Validates GetRecordOptions parameters\n */\n static validateGetRecordOptions(options: GetRecordOptions): void {\n if (options.from !== undefined && (typeof options.from !== 'number' || options.from < 0)) {\n throw new Error('Invalid from parameter: must be a non-negative number');\n }\n \n if (options.to !== undefined && (typeof options.to !== 'number' || options.to < 0)) {\n throw new Error('Invalid to parameter: must be a non-negative number');\n }\n \n if (options.frozenAt !== undefined && (typeof options.frozenAt !== 'number' || options.frozenAt < 0)) {\n throw new Error('Invalid frozenAt parameter: must be a non-negative number');\n }\n \n if (options.useCache !== undefined && typeof options.useCache !== 'boolean') {\n throw new Error('Invalid useCache parameter: must be a boolean');\n }\n \n if (options.prefix !== undefined && typeof options.prefix !== 'string') {\n throw new Error('Invalid prefix parameter: must be a string');\n }\n \n if (options.baseTime !== undefined && typeof options.baseTime !== 'number' && typeof options.baseTime !== 'string') {\n throw new Error('Invalid baseTime parameter: must be a number or string');\n }\n }\n \n /**\n * Validates GetIndexOptions parameters\n */\n static validateGetIndexOptions(options: GetIndexOptions): void {\n // GetIndexOptions has the same validation as GetRecordOptions\n this.validateGetRecordOptions(options);\n }\n \n /**\n * Validates GetIndexChangeOptions parameters\n */\n static validateGetIndexChangeOptions(options: GetIndexChangeOptions): void {\n // Validate base options\n this.validateGetRecordOptions(options);\n \n // Validate timeInterval - required for index change\n if (typeof options.timeInterval !== 'number' || options.timeInterval <= 0) {\n throw new Error('Invalid timeInterval parameter: must be a positive number');\n }\n }\n \n /**\n * Validates GetFirstRecordOptions parameters\n */\n static validateGetFirstRecordOptions(options: GetFirstRecordOptions): void {\n if (options.after !== undefined && (typeof options.after !== 'number' || options.after < 0)) {\n throw new Error('Invalid after parameter: must be a non-negative number');\n }\n \n if (options.frozenAt !== undefined && (typeof options.frozenAt !== 'number' || options.frozenAt < 0)) {\n throw new Error('Invalid frozenAt parameter: must be a non-negative number');\n }\n \n if (options.useCache !== undefined && typeof options.useCache !== 'boolean') {\n throw new Error('Invalid useCache parameter: must be a boolean');\n }\n }\n \n /**\n * Validates time range parameters\n */\n static validateTimeRange(from?: number, to?: number): void {\n if (from !== undefined && to !== undefined && from > to) {\n throw new Error('Invalid time range: from time cannot be greater than to time');\n }\n }\n}"],
5
+ "mappings": ";AAKO,IAAM,kBAAN,MAAsB;AAAA;AAAA;AAAA;AAAA,EAI3B,OAAO,yBAAyB,SAAiC;AAC/D,QAAI,QAAQ,SAAS,WAAc,OAAO,QAAQ,SAAS,YAAY,QAAQ,OAAO,IAAI;AACxF,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAEA,QAAI,QAAQ,OAAO,WAAc,OAAO,QAAQ,OAAO,YAAY,QAAQ,KAAK,IAAI;AAClF,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,QAAI,QAAQ,aAAa,WAAc,OAAO,QAAQ,aAAa,YAAY,QAAQ,WAAW,IAAI;AACpG,YAAM,IAAI,MAAM,2DAA2D;AAAA,IAC7E;AAEA,QAAI,QAAQ,aAAa,UAAa,OAAO,QAAQ,aAAa,WAAW;AAC3E,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAEA,QAAI,QAAQ,WAAW,UAAa,OAAO,QAAQ,WAAW,UAAU;AACtE,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAEA,QAAI,QAAQ,aAAa,UAAa,OAAO,QAAQ,aAAa,YAAY,OAAO,QAAQ,aAAa,UAAU;AAClH,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,wBAAwB,SAAgC;AAE7D,SAAK,yBAAyB,OAAO;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,8BAA8B,SAAsC;AAEzE,SAAK,yBAAyB,OAAO;AAGrC,QAAI,OAAO,QAAQ,iBAAiB,YAAY,QAAQ,gBAAgB,GAAG;AACzE,YAAM,IAAI,MAAM,2DAA2D;AAAA,IAC7E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,8BAA8B,SAAsC;AACzE,QAAI,QAAQ,UAAU,WAAc,OAAO,QAAQ,UAAU,YAAY,QAAQ,QAAQ,IAAI;AAC3F,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AAEA,QAAI,QAAQ,aAAa,WAAc,OAAO,QAAQ,aAAa,YAAY,QAAQ,WAAW,IAAI;AACpG,YAAM,IAAI,MAAM,2DAA2D;AAAA,IAC7E;AAEA,QAAI,QAAQ,aAAa,UAAa,OAAO,QAAQ,aAAa,WAAW;AAC3E,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,kBAAkB,MAAe,IAAmB;AACzD,QAAI,SAAS,UAAa,OAAO,UAAa,OAAO,IAAI;AACvD,YAAM,IAAI,MAAM,8DAA8D;AAAA,IAChF;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }