metal-orm 1.0.118 → 1.1.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.
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Indexa chaves por tags para invalidação em massa
3
+ * Implementação em memória (pode ser persistida no Redis)
4
+ */
5
+ export class TagIndex {
6
+ private tagToKeys: Map<string, Set<string>> = new Map();
7
+ private keyToTags: Map<string, Set<string>> = new Map();
8
+
9
+ /**
10
+ * Registra que uma chave pertence a determinadas tags
11
+ */
12
+ register(key: string, tags: string[]): void {
13
+ // Mapeia tag -> chaves
14
+ for (const tag of tags) {
15
+ if (!this.tagToKeys.has(tag)) {
16
+ this.tagToKeys.set(tag, new Set());
17
+ }
18
+ this.tagToKeys.get(tag)!.add(key);
19
+ }
20
+
21
+ // Mapeia chave -> tags (para limpeza futura)
22
+ const existingTags = this.keyToTags.get(key) ?? new Set();
23
+ tags.forEach(tag => existingTags.add(tag));
24
+ this.keyToTags.set(key, existingTags);
25
+ }
26
+
27
+ /**
28
+ * Remove uma chave do índice
29
+ */
30
+ unregister(key: string): void {
31
+ const tags = this.keyToTags.get(key);
32
+ if (tags) {
33
+ for (const tag of tags) {
34
+ this.tagToKeys.get(tag)?.delete(key);
35
+ // Limpa tags vazias
36
+ if (this.tagToKeys.get(tag)?.size === 0) {
37
+ this.tagToKeys.delete(tag);
38
+ }
39
+ }
40
+ this.keyToTags.delete(key);
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Obtém todas as chaves de uma tag
46
+ */
47
+ getKeysByTag(tag: string): string[] {
48
+ return Array.from(this.tagToKeys.get(tag) ?? []);
49
+ }
50
+
51
+ /**
52
+ * Obtém todas as tags de uma chave
53
+ */
54
+ getTagsByKey(key: string): string[] {
55
+ return Array.from(this.keyToTags.get(key) ?? []);
56
+ }
57
+
58
+ /**
59
+ * Invalida todas as chaves de um conjunto de tags
60
+ * Retorna as chaves afetadas
61
+ */
62
+ invalidateTags(tags: string[]): string[] {
63
+ const keysToInvalidate = new Set<string>();
64
+
65
+ for (const tag of tags) {
66
+ const keys = this.tagToKeys.get(tag);
67
+ if (keys) {
68
+ for (const key of keys) {
69
+ keysToInvalidate.add(key);
70
+ this.unregister(key); // Remove do índice
71
+ }
72
+ // Remove a tag completamente
73
+ this.tagToKeys.delete(tag);
74
+ }
75
+ }
76
+
77
+ return Array.from(keysToInvalidate);
78
+ }
79
+
80
+ /**
81
+ * Invalida por prefixo (útil para multi-tenancy)
82
+ * Retorna as chaves afetadas
83
+ */
84
+ invalidatePrefix(prefix: string): string[] {
85
+ const keysToInvalidate: string[] = [];
86
+
87
+ for (const key of this.keyToTags.keys()) {
88
+ if (key.startsWith(prefix)) {
89
+ keysToInvalidate.push(key);
90
+ this.unregister(key);
91
+ }
92
+ }
93
+
94
+ return keysToInvalidate;
95
+ }
96
+
97
+ /**
98
+ * Retorna todas as tags registradas
99
+ */
100
+ getAllTags(): string[] {
101
+ return Array.from(this.tagToKeys.keys());
102
+ }
103
+
104
+ /**
105
+ * Retorna todas as chaves registradas
106
+ */
107
+ getAllKeys(): string[] {
108
+ return Array.from(this.keyToTags.keys());
109
+ }
110
+
111
+ /**
112
+ * Limpa todo o índice
113
+ */
114
+ clear(): void {
115
+ this.tagToKeys.clear();
116
+ this.keyToTags.clear();
117
+ }
118
+
119
+ /**
120
+ * Retorna estatísticas do índice
121
+ */
122
+ getStats(): { tags: number; keys: number } {
123
+ return {
124
+ tags: this.tagToKeys.size,
125
+ keys: this.keyToTags.size,
126
+ };
127
+ }
128
+ }