@hedystia/db 2.0.6 → 2.0.8

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 (67) hide show
  1. package/dist/cache/index.mjs +12 -0
  2. package/dist/cache/index.mjs.map +1 -0
  3. package/dist/cache/manager.mjs +156 -153
  4. package/dist/cache/manager.mjs.map +1 -1
  5. package/dist/cache/memory-store.mjs +113 -111
  6. package/dist/cache/memory-store.mjs.map +1 -1
  7. package/dist/cli/commands/migrate.cjs +78 -0
  8. package/dist/cli/commands/migrate.cjs.map +1 -0
  9. package/dist/cli/commands/migrate.mjs +83 -0
  10. package/dist/cli/commands/migrate.mjs.map +1 -0
  11. package/dist/cli/commands/migration.cjs +3 -2
  12. package/dist/cli/commands/migration.cjs.map +1 -1
  13. package/dist/cli/commands/migration.mjs +4 -3
  14. package/dist/cli/commands/migration.mjs.map +1 -1
  15. package/dist/cli.cjs +44 -5
  16. package/dist/cli.cjs.map +1 -1
  17. package/dist/cli.mjs +45 -5
  18. package/dist/cli.mjs.map +1 -1
  19. package/dist/core/database.cjs +75 -29
  20. package/dist/core/database.cjs.map +1 -1
  21. package/dist/core/database.d.cts +11 -0
  22. package/dist/core/database.d.mts +11 -0
  23. package/dist/core/database.mjs +91 -34
  24. package/dist/core/database.mjs.map +1 -1
  25. package/dist/core/repository.mjs +414 -410
  26. package/dist/core/repository.mjs.map +1 -1
  27. package/dist/drivers/driver.mjs +9 -7
  28. package/dist/drivers/driver.mjs.map +1 -1
  29. package/dist/drivers/file.mjs +315 -312
  30. package/dist/drivers/file.mjs.map +1 -1
  31. package/dist/drivers/index.mjs +15 -6
  32. package/dist/drivers/index.mjs.map +1 -1
  33. package/dist/drivers/mysql.mjs +261 -256
  34. package/dist/drivers/mysql.mjs.map +1 -1
  35. package/dist/drivers/sql-compiler.mjs +4 -1
  36. package/dist/drivers/sql-compiler.mjs.map +1 -1
  37. package/dist/drivers/sqlite.cjs +12 -1
  38. package/dist/drivers/sqlite.cjs.map +1 -1
  39. package/dist/drivers/sqlite.mjs +258 -242
  40. package/dist/drivers/sqlite.mjs.map +1 -1
  41. package/dist/errors.mjs +48 -64
  42. package/dist/errors.mjs.map +1 -1
  43. package/dist/index.mjs +21 -9
  44. package/dist/index.mjs.map +1 -1
  45. package/dist/migrations/templates.cjs +4 -3
  46. package/dist/migrations/templates.cjs.map +1 -1
  47. package/dist/migrations/templates.d.cts +3 -2
  48. package/dist/migrations/templates.d.mts +3 -2
  49. package/dist/migrations/templates.mjs +4 -3
  50. package/dist/migrations/templates.mjs.map +1 -1
  51. package/dist/schema/column.mjs +155 -157
  52. package/dist/schema/column.mjs.map +1 -1
  53. package/dist/schema/columns/index.mjs +103 -171
  54. package/dist/schema/columns/index.mjs.map +1 -1
  55. package/dist/schema/index.mjs +15 -0
  56. package/dist/schema/index.mjs.map +1 -0
  57. package/dist/schema/registry.mjs +122 -119
  58. package/dist/schema/registry.mjs.map +1 -1
  59. package/dist/schema/table.mjs +4 -1
  60. package/dist/schema/table.mjs.map +1 -1
  61. package/dist/sync/synchronizer.mjs +2 -1
  62. package/dist/sync/synchronizer.mjs.map +1 -1
  63. package/dist/utils/naming.cjs +9 -0
  64. package/dist/utils/naming.cjs.map +1 -1
  65. package/dist/utils/naming.mjs +9 -1
  66. package/dist/utils/naming.mjs.map +1 -1
  67. package/package.json +1 -1
@@ -0,0 +1,12 @@
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.mjs";
2
+ import "./memory-store.mjs";
3
+ import { init_manager } from "./manager.mjs";
4
+ //#region src/cache/index.ts
5
+ var init_cache = __esmMin((() => {
6
+ init_manager();
7
+ }));
8
+ //#endregion
9
+ init_cache();
10
+ export { init_cache };
11
+
12
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/cache/index.ts"],"sourcesContent":["export { CacheManager } from \"./manager\";\nexport { MemoryStore } from \"./memory-store\";\n"],"mappings":";;;;;eAAyC"}
@@ -1,163 +1,166 @@
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.mjs";
1
2
  import { DEFAULT_CACHE_MAX_ENTRIES, DEFAULT_CACHE_MAX_TTL, DEFAULT_CACHE_TTL, init_constants } from "../constants.mjs";
2
3
  import { stableStringify } from "../utils/stable-stringify.mjs";
3
4
  import { init_utils } from "../utils/index.mjs";
4
- import { MemoryStore } from "./memory-store.mjs";
5
+ import { MemoryStore, init_memory_store } from "./memory-store.mjs";
5
6
  //#region src/cache/manager.ts
6
- init_constants();
7
- init_utils();
8
- /**
9
- * Cache manager that wraps query execution with caching behavior
10
- */
11
- var CacheManager = class {
12
- store;
13
- baseTtl;
14
- maxTtl;
15
- enabled;
16
- constructor(config) {
17
- if (typeof config === "boolean") {
18
- this.enabled = config;
19
- this.baseTtl = DEFAULT_CACHE_TTL;
20
- this.maxTtl = DEFAULT_CACHE_MAX_TTL;
21
- this.store = new MemoryStore(DEFAULT_CACHE_MAX_ENTRIES);
22
- } else if (config) {
23
- this.enabled = config.enabled;
24
- this.baseTtl = config.ttl ?? 6e4;
25
- this.maxTtl = config.maxTtl ?? 3e5;
26
- this.store = new MemoryStore(config.maxEntries ?? 1e4);
27
- } else {
28
- this.enabled = false;
29
- this.baseTtl = DEFAULT_CACHE_TTL;
30
- this.maxTtl = DEFAULT_CACHE_MAX_TTL;
31
- this.store = new MemoryStore();
7
+ var CacheManager;
8
+ var init_manager = __esmMin((() => {
9
+ init_constants();
10
+ init_utils();
11
+ init_memory_store();
12
+ CacheManager = class {
13
+ store;
14
+ baseTtl;
15
+ maxTtl;
16
+ enabled;
17
+ constructor(config) {
18
+ if (typeof config === "boolean") {
19
+ this.enabled = config;
20
+ this.baseTtl = DEFAULT_CACHE_TTL;
21
+ this.maxTtl = DEFAULT_CACHE_MAX_TTL;
22
+ this.store = new MemoryStore(DEFAULT_CACHE_MAX_ENTRIES);
23
+ } else if (config) {
24
+ this.enabled = config.enabled;
25
+ this.baseTtl = config.ttl ?? 6e4;
26
+ this.maxTtl = config.maxTtl ?? 3e5;
27
+ this.store = new MemoryStore(config.maxEntries ?? 1e4);
28
+ } else {
29
+ this.enabled = false;
30
+ this.baseTtl = DEFAULT_CACHE_TTL;
31
+ this.maxTtl = DEFAULT_CACHE_MAX_TTL;
32
+ this.store = new MemoryStore();
33
+ }
32
34
  }
33
- }
34
- /**
35
- * Get a cached query result or execute the query and cache the result
36
- * @param {string} table - Table name
37
- * @param {string} method - Method name (find, findFirst, etc.)
38
- * @param {unknown} options - Query options
39
- * @param {() => Promise<T>} executor - Function that executes the query
40
- * @returns {Promise<T>} The query result
41
- */
42
- async getOrSet(table, method, options, executor) {
43
- if (!this.enabled) return executor();
44
- const key = this.buildKey(table, method, options);
45
- const cached = this.store.get(key);
46
- if (cached !== void 0) {
47
- this.store.extendTtl(key, this.baseTtl, this.maxTtl);
48
- return cached;
35
+ /**
36
+ * Get a cached query result or execute the query and cache the result
37
+ * @param {string} table - Table name
38
+ * @param {string} method - Method name (find, findFirst, etc.)
39
+ * @param {unknown} options - Query options
40
+ * @param {() => Promise<T>} executor - Function that executes the query
41
+ * @returns {Promise<T>} The query result
42
+ */
43
+ async getOrSet(table, method, options, executor) {
44
+ if (!this.enabled) return executor();
45
+ const key = this.buildKey(table, method, options);
46
+ const cached = this.store.get(key);
47
+ if (cached !== void 0) {
48
+ this.store.extendTtl(key, this.baseTtl, this.maxTtl);
49
+ return cached;
50
+ }
51
+ const result = await executor();
52
+ this.store.set(key, result, this.baseTtl);
53
+ return result;
49
54
  }
50
- const result = await executor();
51
- this.store.set(key, result, this.baseTtl);
52
- return result;
53
- }
54
- /**
55
- * Set an entity in the cache by primary key
56
- * @param {string} table - Table name
57
- * @param {string | number} id - Primary key value
58
- * @param {unknown} data - Entity data
59
- */
60
- setEntity(table, id, data) {
61
- if (!this.enabled) return;
62
- const key = `entity:${table}:${id}`;
63
- this.store.set(key, data, this.baseTtl);
64
- }
65
- /**
66
- * Get a cached entity by primary key
67
- * @param {string} table - Table name
68
- * @param {string | number} id - Primary key value
69
- * @returns {unknown | undefined} Cached entity or undefined
70
- */
71
- getEntity(table, id) {
72
- if (!this.enabled) return;
73
- const key = `entity:${table}:${id}`;
74
- const result = this.store.get(key);
75
- if (result !== void 0) this.store.extendTtl(key, this.baseTtl, this.maxTtl);
76
- return result;
77
- }
78
- /**
79
- * Invalidate all cache entries for a table
80
- * @param {string} table - Table name
81
- */
82
- invalidateTable(table) {
83
- if (!this.enabled) return;
84
- this.store.invalidateByPrefix(`query:${table}:`);
85
- this.store.invalidateByPrefix(`entity:${table}:`);
86
- }
87
- /**
88
- * Invalidate a specific entity cache entry
89
- * @param {string} table - Table name
90
- * @param {string | number} id - Primary key value
91
- */
92
- invalidateEntity(table, id) {
93
- if (!this.enabled) return;
94
- this.store.delete(`entity:${table}:${id}`);
95
- this.store.invalidateByPrefix(`query:${table}:`);
96
- }
97
- /**
98
- * Update an entity in cache if it exists
99
- * @param {string} table - Table name
100
- * @param {string | number} id - Primary key value
101
- * @param {Record<string, unknown>} data - Updated data
102
- */
103
- updateEntity(table, id, data) {
104
- if (!this.enabled) return;
105
- const key = `entity:${table}:${id}`;
106
- const existing = this.store.get(key);
107
- if (existing && typeof existing === "object") this.store.set(key, {
108
- ...existing,
109
- ...data
110
- }, this.baseTtl);
111
- this.store.invalidateByPrefix(`query:${table}:`);
112
- }
113
- /**
114
- * Clear the entire cache
115
- */
116
- clear() {
117
- this.store.clear();
118
- }
119
- /**
120
- * Get the number of cached entries
121
- * @returns {number} Cache size
122
- */
123
- get size() {
124
- return this.store.size;
125
- }
126
- /**
127
- * Check if caching is enabled
128
- * @returns {boolean} Whether caching is enabled
129
- */
130
- get isEnabled() {
131
- return this.enabled;
132
- }
133
- /**
134
- * Get a cached query result or execute the query with per-table cache config override
135
- * @param {string} table - Table name
136
- * @param {string} method - Method name (find, findFirst, etc.)
137
- * @param {unknown} options - Query options
138
- * @param {() => Promise<T>} executor - Function that executes the query
139
- * @param {{ enabled: boolean; ttl?: number; maxTtl?: number }} [tableConfig] - Per-table cache config
140
- * @returns {Promise<T>} The query result
141
- */
142
- async getOrSetWithTableConfig(table, method, options, executor, tableConfig) {
143
- if (!(tableConfig ? tableConfig.enabled : this.enabled)) return executor();
144
- const effectiveTtl = tableConfig?.ttl ?? this.baseTtl;
145
- const effectiveMaxTtl = tableConfig?.maxTtl ?? this.maxTtl;
146
- const key = this.buildKey(table, method, options);
147
- const cached = this.store.get(key);
148
- if (cached !== void 0) {
149
- this.store.extendTtl(key, effectiveTtl, effectiveMaxTtl);
150
- return cached;
55
+ /**
56
+ * Set an entity in the cache by primary key
57
+ * @param {string} table - Table name
58
+ * @param {string | number} id - Primary key value
59
+ * @param {unknown} data - Entity data
60
+ */
61
+ setEntity(table, id, data) {
62
+ if (!this.enabled) return;
63
+ const key = `entity:${table}:${id}`;
64
+ this.store.set(key, data, this.baseTtl);
151
65
  }
152
- const result = await executor();
153
- this.store.set(key, result, effectiveTtl);
154
- return result;
155
- }
156
- buildKey(table, method, options) {
157
- return `query:${table}:${method}:${stableStringify(options)}`;
158
- }
159
- };
66
+ /**
67
+ * Get a cached entity by primary key
68
+ * @param {string} table - Table name
69
+ * @param {string | number} id - Primary key value
70
+ * @returns {unknown | undefined} Cached entity or undefined
71
+ */
72
+ getEntity(table, id) {
73
+ if (!this.enabled) return;
74
+ const key = `entity:${table}:${id}`;
75
+ const result = this.store.get(key);
76
+ if (result !== void 0) this.store.extendTtl(key, this.baseTtl, this.maxTtl);
77
+ return result;
78
+ }
79
+ /**
80
+ * Invalidate all cache entries for a table
81
+ * @param {string} table - Table name
82
+ */
83
+ invalidateTable(table) {
84
+ if (!this.enabled) return;
85
+ this.store.invalidateByPrefix(`query:${table}:`);
86
+ this.store.invalidateByPrefix(`entity:${table}:`);
87
+ }
88
+ /**
89
+ * Invalidate a specific entity cache entry
90
+ * @param {string} table - Table name
91
+ * @param {string | number} id - Primary key value
92
+ */
93
+ invalidateEntity(table, id) {
94
+ if (!this.enabled) return;
95
+ this.store.delete(`entity:${table}:${id}`);
96
+ this.store.invalidateByPrefix(`query:${table}:`);
97
+ }
98
+ /**
99
+ * Update an entity in cache if it exists
100
+ * @param {string} table - Table name
101
+ * @param {string | number} id - Primary key value
102
+ * @param {Record<string, unknown>} data - Updated data
103
+ */
104
+ updateEntity(table, id, data) {
105
+ if (!this.enabled) return;
106
+ const key = `entity:${table}:${id}`;
107
+ const existing = this.store.get(key);
108
+ if (existing && typeof existing === "object") this.store.set(key, {
109
+ ...existing,
110
+ ...data
111
+ }, this.baseTtl);
112
+ this.store.invalidateByPrefix(`query:${table}:`);
113
+ }
114
+ /**
115
+ * Clear the entire cache
116
+ */
117
+ clear() {
118
+ this.store.clear();
119
+ }
120
+ /**
121
+ * Get the number of cached entries
122
+ * @returns {number} Cache size
123
+ */
124
+ get size() {
125
+ return this.store.size;
126
+ }
127
+ /**
128
+ * Check if caching is enabled
129
+ * @returns {boolean} Whether caching is enabled
130
+ */
131
+ get isEnabled() {
132
+ return this.enabled;
133
+ }
134
+ /**
135
+ * Get a cached query result or execute the query with per-table cache config override
136
+ * @param {string} table - Table name
137
+ * @param {string} method - Method name (find, findFirst, etc.)
138
+ * @param {unknown} options - Query options
139
+ * @param {() => Promise<T>} executor - Function that executes the query
140
+ * @param {{ enabled: boolean; ttl?: number; maxTtl?: number }} [tableConfig] - Per-table cache config
141
+ * @returns {Promise<T>} The query result
142
+ */
143
+ async getOrSetWithTableConfig(table, method, options, executor, tableConfig) {
144
+ if (!(tableConfig ? tableConfig.enabled : this.enabled)) return executor();
145
+ const effectiveTtl = tableConfig?.ttl ?? this.baseTtl;
146
+ const effectiveMaxTtl = tableConfig?.maxTtl ?? this.maxTtl;
147
+ const key = this.buildKey(table, method, options);
148
+ const cached = this.store.get(key);
149
+ if (cached !== void 0) {
150
+ this.store.extendTtl(key, effectiveTtl, effectiveMaxTtl);
151
+ return cached;
152
+ }
153
+ const result = await executor();
154
+ this.store.set(key, result, effectiveTtl);
155
+ return result;
156
+ }
157
+ buildKey(table, method, options) {
158
+ return `query:${table}:${method}:${stableStringify(options)}`;
159
+ }
160
+ };
161
+ }));
160
162
  //#endregion
161
- export { CacheManager };
163
+ init_manager();
164
+ export { CacheManager, init_manager };
162
165
 
163
166
  //# sourceMappingURL=manager.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.mjs","names":[],"sources":["../../src/cache/manager.ts"],"sourcesContent":["import { DEFAULT_CACHE_MAX_ENTRIES, DEFAULT_CACHE_MAX_TTL, DEFAULT_CACHE_TTL } from \"../constants\";\nimport type { CacheConfig } from \"../types\";\nimport { stableStringify } from \"../utils\";\nimport { MemoryStore } from \"./memory-store\";\n\n/**\n * Cache manager that wraps query execution with caching behavior\n */\nexport class CacheManager {\n private store: MemoryStore;\n private baseTtl: number;\n private maxTtl: number;\n private enabled: boolean;\n\n constructor(config?: boolean | CacheConfig) {\n if (typeof config === \"boolean\") {\n this.enabled = config;\n this.baseTtl = DEFAULT_CACHE_TTL;\n this.maxTtl = DEFAULT_CACHE_MAX_TTL;\n this.store = new MemoryStore(DEFAULT_CACHE_MAX_ENTRIES);\n } else if (config) {\n this.enabled = config.enabled;\n this.baseTtl = config.ttl ?? DEFAULT_CACHE_TTL;\n this.maxTtl = config.maxTtl ?? DEFAULT_CACHE_MAX_TTL;\n this.store = new MemoryStore(config.maxEntries ?? DEFAULT_CACHE_MAX_ENTRIES);\n } else {\n this.enabled = false;\n this.baseTtl = DEFAULT_CACHE_TTL;\n this.maxTtl = DEFAULT_CACHE_MAX_TTL;\n this.store = new MemoryStore();\n }\n }\n\n /**\n * Get a cached query result or execute the query and cache the result\n * @param {string} table - Table name\n * @param {string} method - Method name (find, findFirst, etc.)\n * @param {unknown} options - Query options\n * @param {() => Promise<T>} executor - Function that executes the query\n * @returns {Promise<T>} The query result\n */\n async getOrSet<T>(\n table: string,\n method: string,\n options: unknown,\n executor: () => Promise<T>,\n ): Promise<T> {\n if (!this.enabled) {\n return executor();\n }\n\n const key = this.buildKey(table, method, options);\n const cached = this.store.get(key);\n if (cached !== undefined) {\n this.store.extendTtl(key, this.baseTtl, this.maxTtl);\n return cached as T;\n }\n\n const result = await executor();\n this.store.set(key, result, this.baseTtl);\n return result;\n }\n\n /**\n * Set an entity in the cache by primary key\n * @param {string} table - Table name\n * @param {string | number} id - Primary key value\n * @param {unknown} data - Entity data\n */\n setEntity(table: string, id: string | number, data: unknown): void {\n if (!this.enabled) {\n return;\n }\n const key = `entity:${table}:${id}`;\n this.store.set(key, data, this.baseTtl);\n }\n\n /**\n * Get a cached entity by primary key\n * @param {string} table - Table name\n * @param {string | number} id - Primary key value\n * @returns {unknown | undefined} Cached entity or undefined\n */\n getEntity(table: string, id: string | number): unknown | undefined {\n if (!this.enabled) {\n return undefined;\n }\n const key = `entity:${table}:${id}`;\n const result = this.store.get(key);\n if (result !== undefined) {\n this.store.extendTtl(key, this.baseTtl, this.maxTtl);\n }\n return result;\n }\n\n /**\n * Invalidate all cache entries for a table\n * @param {string} table - Table name\n */\n invalidateTable(table: string): void {\n if (!this.enabled) {\n return;\n }\n this.store.invalidateByPrefix(`query:${table}:`);\n this.store.invalidateByPrefix(`entity:${table}:`);\n }\n\n /**\n * Invalidate a specific entity cache entry\n * @param {string} table - Table name\n * @param {string | number} id - Primary key value\n */\n invalidateEntity(table: string, id: string | number): void {\n if (!this.enabled) {\n return;\n }\n this.store.delete(`entity:${table}:${id}`);\n this.store.invalidateByPrefix(`query:${table}:`);\n }\n\n /**\n * Update an entity in cache if it exists\n * @param {string} table - Table name\n * @param {string | number} id - Primary key value\n * @param {Record<string, unknown>} data - Updated data\n */\n updateEntity(table: string, id: string | number, data: Record<string, unknown>): void {\n if (!this.enabled) {\n return;\n }\n const key = `entity:${table}:${id}`;\n const existing = this.store.get(key);\n if (existing && typeof existing === \"object\") {\n this.store.set(key, { ...existing, ...data }, this.baseTtl);\n }\n this.store.invalidateByPrefix(`query:${table}:`);\n }\n\n /**\n * Clear the entire cache\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get the number of cached entries\n * @returns {number} Cache size\n */\n get size(): number {\n return this.store.size;\n }\n\n /**\n * Check if caching is enabled\n * @returns {boolean} Whether caching is enabled\n */\n get isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Get a cached query result or execute the query with per-table cache config override\n * @param {string} table - Table name\n * @param {string} method - Method name (find, findFirst, etc.)\n * @param {unknown} options - Query options\n * @param {() => Promise<T>} executor - Function that executes the query\n * @param {{ enabled: boolean; ttl?: number; maxTtl?: number }} [tableConfig] - Per-table cache config\n * @returns {Promise<T>} The query result\n */\n async getOrSetWithTableConfig<T>(\n table: string,\n method: string,\n options: unknown,\n executor: () => Promise<T>,\n tableConfig?: { enabled: boolean; ttl?: number; maxTtl?: number },\n ): Promise<T> {\n const effectiveEnabled = tableConfig ? tableConfig.enabled : this.enabled;\n if (!effectiveEnabled) {\n return executor();\n }\n\n const effectiveTtl = tableConfig?.ttl ?? this.baseTtl;\n const effectiveMaxTtl = tableConfig?.maxTtl ?? this.maxTtl;\n const key = this.buildKey(table, method, options);\n const cached = this.store.get(key);\n if (cached !== undefined) {\n this.store.extendTtl(key, effectiveTtl, effectiveMaxTtl);\n return cached as T;\n }\n\n const result = await executor();\n this.store.set(key, result, effectiveTtl);\n return result;\n }\n\n private buildKey(table: string, method: string, options: unknown): string {\n return `query:${table}:${method}:${stableStringify(options)}`;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manager.mjs","names":[],"sources":["../../src/cache/manager.ts"],"sourcesContent":["import { DEFAULT_CACHE_MAX_ENTRIES, DEFAULT_CACHE_MAX_TTL, DEFAULT_CACHE_TTL } from \"../constants\";\nimport type { CacheConfig } from \"../types\";\nimport { stableStringify } from \"../utils\";\nimport { MemoryStore } from \"./memory-store\";\n\n/**\n * Cache manager that wraps query execution with caching behavior\n */\nexport class CacheManager {\n private store: MemoryStore;\n private baseTtl: number;\n private maxTtl: number;\n private enabled: boolean;\n\n constructor(config?: boolean | CacheConfig) {\n if (typeof config === \"boolean\") {\n this.enabled = config;\n this.baseTtl = DEFAULT_CACHE_TTL;\n this.maxTtl = DEFAULT_CACHE_MAX_TTL;\n this.store = new MemoryStore(DEFAULT_CACHE_MAX_ENTRIES);\n } else if (config) {\n this.enabled = config.enabled;\n this.baseTtl = config.ttl ?? DEFAULT_CACHE_TTL;\n this.maxTtl = config.maxTtl ?? DEFAULT_CACHE_MAX_TTL;\n this.store = new MemoryStore(config.maxEntries ?? DEFAULT_CACHE_MAX_ENTRIES);\n } else {\n this.enabled = false;\n this.baseTtl = DEFAULT_CACHE_TTL;\n this.maxTtl = DEFAULT_CACHE_MAX_TTL;\n this.store = new MemoryStore();\n }\n }\n\n /**\n * Get a cached query result or execute the query and cache the result\n * @param {string} table - Table name\n * @param {string} method - Method name (find, findFirst, etc.)\n * @param {unknown} options - Query options\n * @param {() => Promise<T>} executor - Function that executes the query\n * @returns {Promise<T>} The query result\n */\n async getOrSet<T>(\n table: string,\n method: string,\n options: unknown,\n executor: () => Promise<T>,\n ): Promise<T> {\n if (!this.enabled) {\n return executor();\n }\n\n const key = this.buildKey(table, method, options);\n const cached = this.store.get(key);\n if (cached !== undefined) {\n this.store.extendTtl(key, this.baseTtl, this.maxTtl);\n return cached as T;\n }\n\n const result = await executor();\n this.store.set(key, result, this.baseTtl);\n return result;\n }\n\n /**\n * Set an entity in the cache by primary key\n * @param {string} table - Table name\n * @param {string | number} id - Primary key value\n * @param {unknown} data - Entity data\n */\n setEntity(table: string, id: string | number, data: unknown): void {\n if (!this.enabled) {\n return;\n }\n const key = `entity:${table}:${id}`;\n this.store.set(key, data, this.baseTtl);\n }\n\n /**\n * Get a cached entity by primary key\n * @param {string} table - Table name\n * @param {string | number} id - Primary key value\n * @returns {unknown | undefined} Cached entity or undefined\n */\n getEntity(table: string, id: string | number): unknown | undefined {\n if (!this.enabled) {\n return undefined;\n }\n const key = `entity:${table}:${id}`;\n const result = this.store.get(key);\n if (result !== undefined) {\n this.store.extendTtl(key, this.baseTtl, this.maxTtl);\n }\n return result;\n }\n\n /**\n * Invalidate all cache entries for a table\n * @param {string} table - Table name\n */\n invalidateTable(table: string): void {\n if (!this.enabled) {\n return;\n }\n this.store.invalidateByPrefix(`query:${table}:`);\n this.store.invalidateByPrefix(`entity:${table}:`);\n }\n\n /**\n * Invalidate a specific entity cache entry\n * @param {string} table - Table name\n * @param {string | number} id - Primary key value\n */\n invalidateEntity(table: string, id: string | number): void {\n if (!this.enabled) {\n return;\n }\n this.store.delete(`entity:${table}:${id}`);\n this.store.invalidateByPrefix(`query:${table}:`);\n }\n\n /**\n * Update an entity in cache if it exists\n * @param {string} table - Table name\n * @param {string | number} id - Primary key value\n * @param {Record<string, unknown>} data - Updated data\n */\n updateEntity(table: string, id: string | number, data: Record<string, unknown>): void {\n if (!this.enabled) {\n return;\n }\n const key = `entity:${table}:${id}`;\n const existing = this.store.get(key);\n if (existing && typeof existing === \"object\") {\n this.store.set(key, { ...existing, ...data }, this.baseTtl);\n }\n this.store.invalidateByPrefix(`query:${table}:`);\n }\n\n /**\n * Clear the entire cache\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get the number of cached entries\n * @returns {number} Cache size\n */\n get size(): number {\n return this.store.size;\n }\n\n /**\n * Check if caching is enabled\n * @returns {boolean} Whether caching is enabled\n */\n get isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Get a cached query result or execute the query with per-table cache config override\n * @param {string} table - Table name\n * @param {string} method - Method name (find, findFirst, etc.)\n * @param {unknown} options - Query options\n * @param {() => Promise<T>} executor - Function that executes the query\n * @param {{ enabled: boolean; ttl?: number; maxTtl?: number }} [tableConfig] - Per-table cache config\n * @returns {Promise<T>} The query result\n */\n async getOrSetWithTableConfig<T>(\n table: string,\n method: string,\n options: unknown,\n executor: () => Promise<T>,\n tableConfig?: { enabled: boolean; ttl?: number; maxTtl?: number },\n ): Promise<T> {\n const effectiveEnabled = tableConfig ? tableConfig.enabled : this.enabled;\n if (!effectiveEnabled) {\n return executor();\n }\n\n const effectiveTtl = tableConfig?.ttl ?? this.baseTtl;\n const effectiveMaxTtl = tableConfig?.maxTtl ?? this.maxTtl;\n const key = this.buildKey(table, method, options);\n const cached = this.store.get(key);\n if (cached !== undefined) {\n this.store.extendTtl(key, effectiveTtl, effectiveMaxTtl);\n return cached as T;\n }\n\n const result = await executor();\n this.store.set(key, result, effectiveTtl);\n return result;\n }\n\n private buildKey(table: string, method: string, options: unknown): string {\n return `query:${table}:${method}:${stableStringify(options)}`;\n }\n}\n"],"mappings":"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"}
@@ -1,122 +1,124 @@
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.mjs";
1
2
  //#region src/cache/memory-store.ts
2
- /**
3
- * In-memory cache store with TTL and hit-count tracking
4
- */
5
- var MemoryStore = class {
6
- store = /* @__PURE__ */ new Map();
7
- maxEntries;
8
- constructor(maxEntries = 1e4) {
9
- this.maxEntries = maxEntries;
10
- }
11
- /**
12
- * Get a value from cache
13
- * @param {string} key - Cache key
14
- * @returns {unknown | undefined} Cached value or undefined
15
- */
16
- get(key) {
17
- const entry = this.store.get(key);
18
- if (!entry) return;
19
- if (Date.now() > entry.expiresAt) {
20
- this.store.delete(key);
21
- return;
22
- }
23
- entry.hitCount++;
24
- entry.lastAccess = Date.now();
25
- return entry.value;
26
- }
27
- /**
28
- * Set a value in cache with TTL
29
- * @param {string} key - Cache key
30
- * @param {unknown} value - Value to cache
31
- * @param {number} ttl - Time to live in milliseconds
32
- */
33
- set(key, value, ttl) {
34
- if (this.store.size >= this.maxEntries) this.evict();
35
- this.store.set(key, {
36
- value,
37
- expiresAt: Date.now() + ttl,
38
- hitCount: 1,
39
- lastAccess: Date.now()
40
- });
41
- }
42
- /**
43
- * Check if a key exists in cache and is not expired
44
- * @param {string} key - Cache key
45
- * @returns {boolean} Whether the key exists
46
- */
47
- has(key) {
48
- const entry = this.store.get(key);
49
- if (!entry) return false;
50
- if (Date.now() > entry.expiresAt) {
51
- this.store.delete(key);
52
- return false;
3
+ var MemoryStore;
4
+ var init_memory_store = __esmMin((() => {
5
+ MemoryStore = class {
6
+ store = /* @__PURE__ */ new Map();
7
+ maxEntries;
8
+ constructor(maxEntries = 1e4) {
9
+ this.maxEntries = maxEntries;
53
10
  }
54
- return true;
55
- }
56
- /**
57
- * Delete a key from cache
58
- * @param {string} key - Cache key
59
- */
60
- delete(key) {
61
- this.store.delete(key);
62
- }
63
- /**
64
- * Invalidate all cache entries matching a prefix
65
- * @param {string} prefix - Key prefix
66
- */
67
- invalidateByPrefix(prefix) {
68
- for (const key of this.store.keys()) if (key.startsWith(prefix)) this.store.delete(key);
69
- }
70
- /**
71
- * Clear all cached entries
72
- */
73
- clear() {
74
- this.store.clear();
75
- }
76
- /**
77
- * Get the number of cached entries
78
- * @returns {number} Number of entries
79
- */
80
- get size() {
81
- return this.store.size;
82
- }
83
- /**
84
- * Get hit count for a cache key
85
- * @param {string} key - Cache key
86
- * @returns {number} Number of hits
87
- */
88
- getHitCount(key) {
89
- return this.store.get(key)?.hitCount ?? 0;
90
- }
91
- /**
92
- * Extend the TTL of a cache entry based on hit count
93
- * @param {string} key - Cache key
94
- * @param {number} baseTtl - Base TTL in milliseconds
95
- * @param {number} maxTtl - Maximum TTL in milliseconds
96
- */
97
- extendTtl(key, baseTtl, maxTtl) {
98
- const entry = this.store.get(key);
99
- if (!entry) return;
100
- const adaptiveTtl = Math.min(maxTtl, baseTtl * (1 + Math.log2(entry.hitCount + 1)));
101
- entry.expiresAt = Date.now() + adaptiveTtl;
102
- }
103
- evict() {
104
- let oldestKey = null;
105
- let oldestAccess = Number.POSITIVE_INFINITY;
106
- for (const [key, entry] of this.store) {
11
+ /**
12
+ * Get a value from cache
13
+ * @param {string} key - Cache key
14
+ * @returns {unknown | undefined} Cached value or undefined
15
+ */
16
+ get(key) {
17
+ const entry = this.store.get(key);
18
+ if (!entry) return;
107
19
  if (Date.now() > entry.expiresAt) {
108
20
  this.store.delete(key);
109
21
  return;
110
22
  }
111
- if (entry.lastAccess < oldestAccess) {
112
- oldestAccess = entry.lastAccess;
113
- oldestKey = key;
23
+ entry.hitCount++;
24
+ entry.lastAccess = Date.now();
25
+ return entry.value;
26
+ }
27
+ /**
28
+ * Set a value in cache with TTL
29
+ * @param {string} key - Cache key
30
+ * @param {unknown} value - Value to cache
31
+ * @param {number} ttl - Time to live in milliseconds
32
+ */
33
+ set(key, value, ttl) {
34
+ if (this.store.size >= this.maxEntries) this.evict();
35
+ this.store.set(key, {
36
+ value,
37
+ expiresAt: Date.now() + ttl,
38
+ hitCount: 1,
39
+ lastAccess: Date.now()
40
+ });
41
+ }
42
+ /**
43
+ * Check if a key exists in cache and is not expired
44
+ * @param {string} key - Cache key
45
+ * @returns {boolean} Whether the key exists
46
+ */
47
+ has(key) {
48
+ const entry = this.store.get(key);
49
+ if (!entry) return false;
50
+ if (Date.now() > entry.expiresAt) {
51
+ this.store.delete(key);
52
+ return false;
53
+ }
54
+ return true;
55
+ }
56
+ /**
57
+ * Delete a key from cache
58
+ * @param {string} key - Cache key
59
+ */
60
+ delete(key) {
61
+ this.store.delete(key);
62
+ }
63
+ /**
64
+ * Invalidate all cache entries matching a prefix
65
+ * @param {string} prefix - Key prefix
66
+ */
67
+ invalidateByPrefix(prefix) {
68
+ for (const key of this.store.keys()) if (key.startsWith(prefix)) this.store.delete(key);
69
+ }
70
+ /**
71
+ * Clear all cached entries
72
+ */
73
+ clear() {
74
+ this.store.clear();
75
+ }
76
+ /**
77
+ * Get the number of cached entries
78
+ * @returns {number} Number of entries
79
+ */
80
+ get size() {
81
+ return this.store.size;
82
+ }
83
+ /**
84
+ * Get hit count for a cache key
85
+ * @param {string} key - Cache key
86
+ * @returns {number} Number of hits
87
+ */
88
+ getHitCount(key) {
89
+ return this.store.get(key)?.hitCount ?? 0;
90
+ }
91
+ /**
92
+ * Extend the TTL of a cache entry based on hit count
93
+ * @param {string} key - Cache key
94
+ * @param {number} baseTtl - Base TTL in milliseconds
95
+ * @param {number} maxTtl - Maximum TTL in milliseconds
96
+ */
97
+ extendTtl(key, baseTtl, maxTtl) {
98
+ const entry = this.store.get(key);
99
+ if (!entry) return;
100
+ const adaptiveTtl = Math.min(maxTtl, baseTtl * (1 + Math.log2(entry.hitCount + 1)));
101
+ entry.expiresAt = Date.now() + adaptiveTtl;
102
+ }
103
+ evict() {
104
+ let oldestKey = null;
105
+ let oldestAccess = Number.POSITIVE_INFINITY;
106
+ for (const [key, entry] of this.store) {
107
+ if (Date.now() > entry.expiresAt) {
108
+ this.store.delete(key);
109
+ return;
110
+ }
111
+ if (entry.lastAccess < oldestAccess) {
112
+ oldestAccess = entry.lastAccess;
113
+ oldestKey = key;
114
+ }
114
115
  }
116
+ if (oldestKey) this.store.delete(oldestKey);
115
117
  }
116
- if (oldestKey) this.store.delete(oldestKey);
117
- }
118
- };
118
+ };
119
+ }));
119
120
  //#endregion
120
- export { MemoryStore };
121
+ init_memory_store();
122
+ export { MemoryStore, init_memory_store };
121
123
 
122
124
  //# sourceMappingURL=memory-store.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-store.mjs","names":[],"sources":["../../src/cache/memory-store.ts"],"sourcesContent":["interface CacheEntry {\n value: unknown;\n expiresAt: number;\n hitCount: number;\n lastAccess: number;\n}\n\n/**\n * In-memory cache store with TTL and hit-count tracking\n */\nexport class MemoryStore {\n private store = new Map<string, CacheEntry>();\n private maxEntries: number;\n\n constructor(maxEntries = 10_000) {\n this.maxEntries = maxEntries;\n }\n\n /**\n * Get a value from cache\n * @param {string} key - Cache key\n * @returns {unknown | undefined} Cached value or undefined\n */\n get(key: string): unknown | undefined {\n const entry = this.store.get(key);\n if (!entry) {\n return undefined;\n }\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return undefined;\n }\n entry.hitCount++;\n entry.lastAccess = Date.now();\n return entry.value;\n }\n\n /**\n * Set a value in cache with TTL\n * @param {string} key - Cache key\n * @param {unknown} value - Value to cache\n * @param {number} ttl - Time to live in milliseconds\n */\n set(key: string, value: unknown, ttl: number): void {\n if (this.store.size >= this.maxEntries) {\n this.evict();\n }\n this.store.set(key, {\n value,\n expiresAt: Date.now() + ttl,\n hitCount: 1,\n lastAccess: Date.now(),\n });\n }\n\n /**\n * Check if a key exists in cache and is not expired\n * @param {string} key - Cache key\n * @returns {boolean} Whether the key exists\n */\n has(key: string): boolean {\n const entry = this.store.get(key);\n if (!entry) {\n return false;\n }\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return false;\n }\n return true;\n }\n\n /**\n * Delete a key from cache\n * @param {string} key - Cache key\n */\n delete(key: string): void {\n this.store.delete(key);\n }\n\n /**\n * Invalidate all cache entries matching a prefix\n * @param {string} prefix - Key prefix\n */\n invalidateByPrefix(prefix: string): void {\n for (const key of this.store.keys()) {\n if (key.startsWith(prefix)) {\n this.store.delete(key);\n }\n }\n }\n\n /**\n * Clear all cached entries\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get the number of cached entries\n * @returns {number} Number of entries\n */\n get size(): number {\n return this.store.size;\n }\n\n /**\n * Get hit count for a cache key\n * @param {string} key - Cache key\n * @returns {number} Number of hits\n */\n getHitCount(key: string): number {\n return this.store.get(key)?.hitCount ?? 0;\n }\n\n /**\n * Extend the TTL of a cache entry based on hit count\n * @param {string} key - Cache key\n * @param {number} baseTtl - Base TTL in milliseconds\n * @param {number} maxTtl - Maximum TTL in milliseconds\n */\n extendTtl(key: string, baseTtl: number, maxTtl: number): void {\n const entry = this.store.get(key);\n if (!entry) {\n return;\n }\n const adaptiveTtl = Math.min(maxTtl, baseTtl * (1 + Math.log2(entry.hitCount + 1)));\n entry.expiresAt = Date.now() + adaptiveTtl;\n }\n\n private evict(): void {\n let oldestKey: string | null = null;\n let oldestAccess = Number.POSITIVE_INFINITY;\n for (const [key, entry] of this.store) {\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return;\n }\n if (entry.lastAccess < oldestAccess) {\n oldestAccess = entry.lastAccess;\n oldestKey = key;\n }\n }\n if (oldestKey) {\n this.store.delete(oldestKey);\n }\n }\n}\n"],"mappings":";;;;AAUA,IAAa,cAAb,MAAyB;CACvB,wBAAgB,IAAI,KAAyB;CAC7C;CAEA,YAAY,aAAa,KAAQ;AAC/B,OAAK,aAAa;;;;;;;CAQpB,IAAI,KAAkC;EACpC,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAI;AACjC,MAAI,CAAC,MACH;AAEF,MAAI,KAAK,KAAK,GAAG,MAAM,WAAW;AAChC,QAAK,MAAM,OAAO,IAAI;AACtB;;AAEF,QAAM;AACN,QAAM,aAAa,KAAK,KAAK;AAC7B,SAAO,MAAM;;;;;;;;CASf,IAAI,KAAa,OAAgB,KAAmB;AAClD,MAAI,KAAK,MAAM,QAAQ,KAAK,WAC1B,MAAK,OAAO;AAEd,OAAK,MAAM,IAAI,KAAK;GAClB;GACA,WAAW,KAAK,KAAK,GAAG;GACxB,UAAU;GACV,YAAY,KAAK,KAAK;GACvB,CAAC;;;;;;;CAQJ,IAAI,KAAsB;EACxB,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAI;AACjC,MAAI,CAAC,MACH,QAAO;AAET,MAAI,KAAK,KAAK,GAAG,MAAM,WAAW;AAChC,QAAK,MAAM,OAAO,IAAI;AACtB,UAAO;;AAET,SAAO;;;;;;CAOT,OAAO,KAAmB;AACxB,OAAK,MAAM,OAAO,IAAI;;;;;;CAOxB,mBAAmB,QAAsB;AACvC,OAAK,MAAM,OAAO,KAAK,MAAM,MAAM,CACjC,KAAI,IAAI,WAAW,OAAO,CACxB,MAAK,MAAM,OAAO,IAAI;;;;;CAQ5B,QAAc;AACZ,OAAK,MAAM,OAAO;;;;;;CAOpB,IAAI,OAAe;AACjB,SAAO,KAAK,MAAM;;;;;;;CAQpB,YAAY,KAAqB;AAC/B,SAAO,KAAK,MAAM,IAAI,IAAI,EAAE,YAAY;;;;;;;;CAS1C,UAAU,KAAa,SAAiB,QAAsB;EAC5D,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAI;AACjC,MAAI,CAAC,MACH;EAEF,MAAM,cAAc,KAAK,IAAI,QAAQ,WAAW,IAAI,KAAK,KAAK,MAAM,WAAW,EAAE,EAAE;AACnF,QAAM,YAAY,KAAK,KAAK,GAAG;;CAGjC,QAAsB;EACpB,IAAI,YAA2B;EAC/B,IAAI,eAAe,OAAO;AAC1B,OAAK,MAAM,CAAC,KAAK,UAAU,KAAK,OAAO;AACrC,OAAI,KAAK,KAAK,GAAG,MAAM,WAAW;AAChC,SAAK,MAAM,OAAO,IAAI;AACtB;;AAEF,OAAI,MAAM,aAAa,cAAc;AACnC,mBAAe,MAAM;AACrB,gBAAY;;;AAGhB,MAAI,UACF,MAAK,MAAM,OAAO,UAAU"}
1
+ {"version":3,"file":"memory-store.mjs","names":[],"sources":["../../src/cache/memory-store.ts"],"sourcesContent":["interface CacheEntry {\n value: unknown;\n expiresAt: number;\n hitCount: number;\n lastAccess: number;\n}\n\n/**\n * In-memory cache store with TTL and hit-count tracking\n */\nexport class MemoryStore {\n private store = new Map<string, CacheEntry>();\n private maxEntries: number;\n\n constructor(maxEntries = 10_000) {\n this.maxEntries = maxEntries;\n }\n\n /**\n * Get a value from cache\n * @param {string} key - Cache key\n * @returns {unknown | undefined} Cached value or undefined\n */\n get(key: string): unknown | undefined {\n const entry = this.store.get(key);\n if (!entry) {\n return undefined;\n }\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return undefined;\n }\n entry.hitCount++;\n entry.lastAccess = Date.now();\n return entry.value;\n }\n\n /**\n * Set a value in cache with TTL\n * @param {string} key - Cache key\n * @param {unknown} value - Value to cache\n * @param {number} ttl - Time to live in milliseconds\n */\n set(key: string, value: unknown, ttl: number): void {\n if (this.store.size >= this.maxEntries) {\n this.evict();\n }\n this.store.set(key, {\n value,\n expiresAt: Date.now() + ttl,\n hitCount: 1,\n lastAccess: Date.now(),\n });\n }\n\n /**\n * Check if a key exists in cache and is not expired\n * @param {string} key - Cache key\n * @returns {boolean} Whether the key exists\n */\n has(key: string): boolean {\n const entry = this.store.get(key);\n if (!entry) {\n return false;\n }\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return false;\n }\n return true;\n }\n\n /**\n * Delete a key from cache\n * @param {string} key - Cache key\n */\n delete(key: string): void {\n this.store.delete(key);\n }\n\n /**\n * Invalidate all cache entries matching a prefix\n * @param {string} prefix - Key prefix\n */\n invalidateByPrefix(prefix: string): void {\n for (const key of this.store.keys()) {\n if (key.startsWith(prefix)) {\n this.store.delete(key);\n }\n }\n }\n\n /**\n * Clear all cached entries\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get the number of cached entries\n * @returns {number} Number of entries\n */\n get size(): number {\n return this.store.size;\n }\n\n /**\n * Get hit count for a cache key\n * @param {string} key - Cache key\n * @returns {number} Number of hits\n */\n getHitCount(key: string): number {\n return this.store.get(key)?.hitCount ?? 0;\n }\n\n /**\n * Extend the TTL of a cache entry based on hit count\n * @param {string} key - Cache key\n * @param {number} baseTtl - Base TTL in milliseconds\n * @param {number} maxTtl - Maximum TTL in milliseconds\n */\n extendTtl(key: string, baseTtl: number, maxTtl: number): void {\n const entry = this.store.get(key);\n if (!entry) {\n return;\n }\n const adaptiveTtl = Math.min(maxTtl, baseTtl * (1 + Math.log2(entry.hitCount + 1)));\n entry.expiresAt = Date.now() + adaptiveTtl;\n }\n\n private evict(): void {\n let oldestKey: string | null = null;\n let oldestAccess = Number.POSITIVE_INFINITY;\n for (const [key, entry] of this.store) {\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return;\n }\n if (entry.lastAccess < oldestAccess) {\n oldestAccess = entry.lastAccess;\n oldestKey = key;\n }\n }\n if (oldestKey) {\n this.store.delete(oldestKey);\n }\n }\n}\n"],"mappings":";;;;AAUa,eAAb,MAAyB;EACvB,wBAAgB,IAAI,KAAyB;EAC7C;EAEA,YAAY,aAAa,KAAQ;AAC/B,QAAK,aAAa;;;;;;;EAQpB,IAAI,KAAkC;GACpC,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAI;AACjC,OAAI,CAAC,MACH;AAEF,OAAI,KAAK,KAAK,GAAG,MAAM,WAAW;AAChC,SAAK,MAAM,OAAO,IAAI;AACtB;;AAEF,SAAM;AACN,SAAM,aAAa,KAAK,KAAK;AAC7B,UAAO,MAAM;;;;;;;;EASf,IAAI,KAAa,OAAgB,KAAmB;AAClD,OAAI,KAAK,MAAM,QAAQ,KAAK,WAC1B,MAAK,OAAO;AAEd,QAAK,MAAM,IAAI,KAAK;IAClB;IACA,WAAW,KAAK,KAAK,GAAG;IACxB,UAAU;IACV,YAAY,KAAK,KAAK;IACvB,CAAC;;;;;;;EAQJ,IAAI,KAAsB;GACxB,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAI;AACjC,OAAI,CAAC,MACH,QAAO;AAET,OAAI,KAAK,KAAK,GAAG,MAAM,WAAW;AAChC,SAAK,MAAM,OAAO,IAAI;AACtB,WAAO;;AAET,UAAO;;;;;;EAOT,OAAO,KAAmB;AACxB,QAAK,MAAM,OAAO,IAAI;;;;;;EAOxB,mBAAmB,QAAsB;AACvC,QAAK,MAAM,OAAO,KAAK,MAAM,MAAM,CACjC,KAAI,IAAI,WAAW,OAAO,CACxB,MAAK,MAAM,OAAO,IAAI;;;;;EAQ5B,QAAc;AACZ,QAAK,MAAM,OAAO;;;;;;EAOpB,IAAI,OAAe;AACjB,UAAO,KAAK,MAAM;;;;;;;EAQpB,YAAY,KAAqB;AAC/B,UAAO,KAAK,MAAM,IAAI,IAAI,EAAE,YAAY;;;;;;;;EAS1C,UAAU,KAAa,SAAiB,QAAsB;GAC5D,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAI;AACjC,OAAI,CAAC,MACH;GAEF,MAAM,cAAc,KAAK,IAAI,QAAQ,WAAW,IAAI,KAAK,KAAK,MAAM,WAAW,EAAE,EAAE;AACnF,SAAM,YAAY,KAAK,KAAK,GAAG;;EAGjC,QAAsB;GACpB,IAAI,YAA2B;GAC/B,IAAI,eAAe,OAAO;AAC1B,QAAK,MAAM,CAAC,KAAK,UAAU,KAAK,OAAO;AACrC,QAAI,KAAK,KAAK,GAAG,MAAM,WAAW;AAChC,UAAK,MAAM,OAAO,IAAI;AACtB;;AAEF,QAAI,MAAM,aAAa,cAAc;AACnC,oBAAe,MAAM;AACrB,iBAAY;;;AAGhB,OAAI,UACF,MAAK,MAAM,OAAO,UAAU"}