@firela/billclaw-core 0.1.3

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 (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/dist/billclaw.d.ts +76 -0
  4. package/dist/billclaw.d.ts.map +1 -0
  5. package/dist/billclaw.js +205 -0
  6. package/dist/billclaw.js.map +1 -0
  7. package/dist/credentials/index.d.ts +8 -0
  8. package/dist/credentials/index.d.ts.map +1 -0
  9. package/dist/credentials/index.js +8 -0
  10. package/dist/credentials/index.js.map +1 -0
  11. package/dist/credentials/keychain.d.ts +92 -0
  12. package/dist/credentials/keychain.d.ts.map +1 -0
  13. package/dist/credentials/keychain.js +172 -0
  14. package/dist/credentials/keychain.js.map +1 -0
  15. package/dist/credentials/store.d.ts +76 -0
  16. package/dist/credentials/store.d.ts.map +1 -0
  17. package/dist/credentials/store.js +144 -0
  18. package/dist/credentials/store.js.map +1 -0
  19. package/dist/errors/errors.d.ts +92 -0
  20. package/dist/errors/errors.d.ts.map +1 -0
  21. package/dist/errors/errors.js +315 -0
  22. package/dist/errors/errors.js.map +1 -0
  23. package/dist/errors/index.d.ts +7 -0
  24. package/dist/errors/index.d.ts.map +1 -0
  25. package/dist/errors/index.js +7 -0
  26. package/dist/errors/index.js.map +1 -0
  27. package/dist/exporters/beancount.d.ts +42 -0
  28. package/dist/exporters/beancount.d.ts.map +1 -0
  29. package/dist/exporters/beancount.js +141 -0
  30. package/dist/exporters/beancount.js.map +1 -0
  31. package/dist/exporters/index.d.ts +8 -0
  32. package/dist/exporters/index.d.ts.map +1 -0
  33. package/dist/exporters/index.js +8 -0
  34. package/dist/exporters/index.js.map +1 -0
  35. package/dist/exporters/ledger.d.ts +42 -0
  36. package/dist/exporters/ledger.d.ts.map +1 -0
  37. package/dist/exporters/ledger.js +139 -0
  38. package/dist/exporters/ledger.js.map +1 -0
  39. package/dist/index.d.ts +23 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +34 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/models/config.d.ts +552 -0
  44. package/dist/models/config.d.ts.map +1 -0
  45. package/dist/models/config.js +168 -0
  46. package/dist/models/config.js.map +1 -0
  47. package/dist/models/index.d.ts +7 -0
  48. package/dist/models/index.d.ts.map +1 -0
  49. package/dist/models/index.js +8 -0
  50. package/dist/models/index.js.map +1 -0
  51. package/dist/runtime/index.d.ts +7 -0
  52. package/dist/runtime/index.d.ts.map +1 -0
  53. package/dist/runtime/index.js +7 -0
  54. package/dist/runtime/index.js.map +1 -0
  55. package/dist/runtime/types.d.ts +110 -0
  56. package/dist/runtime/types.d.ts.map +1 -0
  57. package/dist/runtime/types.js +85 -0
  58. package/dist/runtime/types.js.map +1 -0
  59. package/dist/security/audit.d.ts +148 -0
  60. package/dist/security/audit.d.ts.map +1 -0
  61. package/dist/security/audit.js +286 -0
  62. package/dist/security/audit.js.map +1 -0
  63. package/dist/security/index.d.ts +7 -0
  64. package/dist/security/index.d.ts.map +1 -0
  65. package/dist/security/index.js +7 -0
  66. package/dist/security/index.js.map +1 -0
  67. package/dist/services/event-emitter.d.ts +171 -0
  68. package/dist/services/event-emitter.d.ts.map +1 -0
  69. package/dist/services/event-emitter.js +287 -0
  70. package/dist/services/event-emitter.js.map +1 -0
  71. package/dist/services/index.d.ts +8 -0
  72. package/dist/services/index.d.ts.map +1 -0
  73. package/dist/services/index.js +8 -0
  74. package/dist/services/index.js.map +1 -0
  75. package/dist/sources/gmail/bill-recognizer.d.ts +71 -0
  76. package/dist/sources/gmail/bill-recognizer.d.ts.map +1 -0
  77. package/dist/sources/gmail/bill-recognizer.js +341 -0
  78. package/dist/sources/gmail/bill-recognizer.js.map +1 -0
  79. package/dist/sources/gmail/email-parser.d.ts +68 -0
  80. package/dist/sources/gmail/email-parser.d.ts.map +1 -0
  81. package/dist/sources/gmail/email-parser.js +238 -0
  82. package/dist/sources/gmail/email-parser.js.map +1 -0
  83. package/dist/sources/gmail/gmail-fetch.d.ts +54 -0
  84. package/dist/sources/gmail/gmail-fetch.d.ts.map +1 -0
  85. package/dist/sources/gmail/gmail-fetch.js +300 -0
  86. package/dist/sources/gmail/gmail-fetch.js.map +1 -0
  87. package/dist/sources/gmail/index.d.ts +7 -0
  88. package/dist/sources/gmail/index.d.ts.map +1 -0
  89. package/dist/sources/gmail/index.js +7 -0
  90. package/dist/sources/gmail/index.js.map +1 -0
  91. package/dist/sources/index.d.ts +8 -0
  92. package/dist/sources/index.d.ts.map +1 -0
  93. package/dist/sources/index.js +8 -0
  94. package/dist/sources/index.js.map +1 -0
  95. package/dist/sources/plaid/index.d.ts +7 -0
  96. package/dist/sources/plaid/index.d.ts.map +1 -0
  97. package/dist/sources/plaid/index.js +7 -0
  98. package/dist/sources/plaid/index.js.map +1 -0
  99. package/dist/sources/plaid/plaid-sync.d.ts +42 -0
  100. package/dist/sources/plaid/plaid-sync.d.ts.map +1 -0
  101. package/dist/sources/plaid/plaid-sync.js +182 -0
  102. package/dist/sources/plaid/plaid-sync.js.map +1 -0
  103. package/dist/storage/cache.d.ts +134 -0
  104. package/dist/storage/cache.d.ts.map +1 -0
  105. package/dist/storage/cache.js +239 -0
  106. package/dist/storage/cache.js.map +1 -0
  107. package/dist/storage/index.d.ts +11 -0
  108. package/dist/storage/index.d.ts.map +1 -0
  109. package/dist/storage/index.js +11 -0
  110. package/dist/storage/index.js.map +1 -0
  111. package/dist/storage/indexes.d.ts +136 -0
  112. package/dist/storage/indexes.d.ts.map +1 -0
  113. package/dist/storage/indexes.js +294 -0
  114. package/dist/storage/indexes.js.map +1 -0
  115. package/dist/storage/locking.d.ts +103 -0
  116. package/dist/storage/locking.d.ts.map +1 -0
  117. package/dist/storage/locking.js +158 -0
  118. package/dist/storage/locking.js.map +1 -0
  119. package/dist/storage/streaming.d.ts +102 -0
  120. package/dist/storage/streaming.d.ts.map +1 -0
  121. package/dist/storage/streaming.js +245 -0
  122. package/dist/storage/streaming.js.map +1 -0
  123. package/dist/storage/transaction-storage.d.ts +101 -0
  124. package/dist/storage/transaction-storage.d.ts.map +1 -0
  125. package/dist/storage/transaction-storage.js +193 -0
  126. package/dist/storage/transaction-storage.js.map +1 -0
  127. package/dist/sync/index.d.ts +7 -0
  128. package/dist/sync/index.d.ts.map +1 -0
  129. package/dist/sync/index.js +7 -0
  130. package/dist/sync/index.js.map +1 -0
  131. package/dist/sync/sync-service.d.ts +42 -0
  132. package/dist/sync/sync-service.d.ts.map +1 -0
  133. package/dist/sync/sync-service.js +112 -0
  134. package/dist/sync/sync-service.js.map +1 -0
  135. package/dist/test-fixtures.d.ts +38 -0
  136. package/dist/test-fixtures.d.ts.map +1 -0
  137. package/dist/test-fixtures.js +137 -0
  138. package/dist/test-fixtures.js.map +1 -0
  139. package/package.json +68 -0
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Query indexes for BillClaw
3
+ *
4
+ * Provides in-memory indexes for common query patterns:
5
+ * - Date-based queries (transactions by date range)
6
+ * - Category-based queries
7
+ * - Merchant-based queries
8
+ * - Amount-based queries
9
+ *
10
+ * Indexes improve query performance from O(n) to O(log n) or O(1).
11
+ */
12
+ import type { Transaction } from "./transaction-storage.js";
13
+ import type { Logger } from "../errors/errors.js";
14
+ /**
15
+ * Index configuration
16
+ */
17
+ export interface IndexConfig {
18
+ rebuildThreshold?: number;
19
+ logger?: Logger;
20
+ }
21
+ /**
22
+ * Transaction indexes
23
+ */
24
+ export declare class TransactionIndexes {
25
+ private indexes;
26
+ private config;
27
+ constructor(config?: IndexConfig);
28
+ /**
29
+ * Build indexes for a set of transactions
30
+ *
31
+ * @param transactions - Transactions to index
32
+ * @param indexType - Type of index to build
33
+ */
34
+ buildIndex(transactions: Transaction[], indexType: IndexType): void;
35
+ /**
36
+ * Get the index key for a transaction
37
+ */
38
+ private getIndexKey;
39
+ /**
40
+ * Query transactions by index key
41
+ *
42
+ * @param indexType - Type of index to query
43
+ * @param _key - Key to look up (not used in simplified implementation)
44
+ * @returns Set of transaction IDs matching the key
45
+ */
46
+ query(indexType: IndexType, _key: string): Set<string>;
47
+ /**
48
+ * Clear all indexes
49
+ */
50
+ clear(): void;
51
+ /**
52
+ * Get index statistics
53
+ */
54
+ getStats(): Record<string, number>;
55
+ }
56
+ /**
57
+ * Index types
58
+ */
59
+ export declare enum IndexType {
60
+ /** Index by transaction date */
61
+ DATE = "date",
62
+ /** Index by primary category */
63
+ CATEGORY = "category",
64
+ /** Index by merchant name */
65
+ MERCHANT = "merchant",
66
+ /** Index by amount range (buckets) */
67
+ AMOUNT_RANGE = "amount_range",
68
+ /** Index by pending status */
69
+ PENDING = "pending"
70
+ }
71
+ /**
72
+ * Query builder for filtering transactions
73
+ */
74
+ export declare class TransactionQueryBuilder {
75
+ private filters;
76
+ /**
77
+ * Filter by date range
78
+ */
79
+ dateRange(start: Date, end: Date): this;
80
+ /**
81
+ * Filter by category
82
+ */
83
+ category(category: string): this;
84
+ /**
85
+ * Filter by merchant name (partial match)
86
+ */
87
+ merchant(merchant: string): this;
88
+ /**
89
+ * Filter by amount range (in cents)
90
+ */
91
+ amountRange(min: number, max: number): this;
92
+ /**
93
+ * Filter by pending status
94
+ */
95
+ pending(isPending: boolean): this;
96
+ /**
97
+ * Apply all filters to a set of transactions
98
+ */
99
+ apply(transactions: Transaction[]): Transaction[];
100
+ /**
101
+ * Clear all filters
102
+ */
103
+ clear(): this;
104
+ }
105
+ /**
106
+ * Inverted index for full-text search
107
+ */
108
+ export declare class FullTextIndex {
109
+ private index;
110
+ private transactionData;
111
+ /**
112
+ * Add a transaction to the index
113
+ */
114
+ add(transaction: Transaction): void;
115
+ /**
116
+ * Index a document
117
+ */
118
+ private indexDocument;
119
+ /**
120
+ * Search for transactions matching a query
121
+ */
122
+ search(query: string): Transaction[];
123
+ /**
124
+ * Clear the index
125
+ */
126
+ clear(): void;
127
+ }
128
+ /**
129
+ * Create a query builder
130
+ */
131
+ export declare function createQueryBuilder(): TransactionQueryBuilder;
132
+ /**
133
+ * Create a full-text index
134
+ */
135
+ export declare function createFullTextIndex(): FullTextIndex;
136
+ //# sourceMappingURL=indexes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexes.d.ts","sourceRoot":"","sources":["../../src/storage/indexes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAWjD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAeD;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,GAAE,WAAgB;IAQpC;;;;;OAKG;IACH,UAAU,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAoBnE;;OAEG;IACH,OAAO,CAAC,WAAW;IA+BnB;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAatD;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CASnC;AAED;;GAEG;AACH,oBAAY,SAAS;IACnB,gCAAgC;IAChC,IAAI,SAAS;IAEb,gCAAgC;IAChC,QAAQ,aAAa;IAErB,6BAA6B;IAC7B,QAAQ,aAAa;IAErB,sCAAsC;IACtC,YAAY,iBAAiB;IAE7B,8BAA8B;IAC9B,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,OAAO,CAA2C;IAE1D;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI;IAQvC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOhC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOhC;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAK3C;;OAEG;IACH,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAKjC;;OAEG;IACH,KAAK,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE;IAMjD;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,eAAe,CAAiC;IAExD;;OAEG;IACH,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAcnC;;OAEG;IACH,OAAO,CAAC,aAAa;IAcrB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE;IAoDpC;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,uBAAuB,CAE5D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CAEnD"}
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Query indexes for BillClaw
3
+ *
4
+ * Provides in-memory indexes for common query patterns:
5
+ * - Date-based queries (transactions by date range)
6
+ * - Category-based queries
7
+ * - Merchant-based queries
8
+ * - Amount-based queries
9
+ *
10
+ * Indexes improve query performance from O(n) to O(log n) or O(1).
11
+ */
12
+ /**
13
+ * Default index configuration
14
+ */
15
+ const DEFAULT_INDEX_CONFIG = {
16
+ rebuildThreshold: 0.1, // 10% change threshold
17
+ logger: {
18
+ info: () => { },
19
+ error: () => { },
20
+ warn: () => { },
21
+ debug: () => { },
22
+ },
23
+ };
24
+ /**
25
+ * Transaction indexes
26
+ */
27
+ export class TransactionIndexes {
28
+ indexes = new Map();
29
+ config;
30
+ constructor(config = {}) {
31
+ this.config = {
32
+ rebuildThreshold: config.rebuildThreshold ?? DEFAULT_INDEX_CONFIG.rebuildThreshold,
33
+ logger: config.logger ?? DEFAULT_INDEX_CONFIG.logger,
34
+ };
35
+ }
36
+ /**
37
+ * Build indexes for a set of transactions
38
+ *
39
+ * @param transactions - Transactions to index
40
+ * @param indexType - Type of index to build
41
+ */
42
+ buildIndex(transactions, indexType) {
43
+ const index = {
44
+ key: indexType,
45
+ transactionIds: new Set(),
46
+ updatedAt: Date.now(),
47
+ };
48
+ for (const txn of transactions) {
49
+ const key = this.getIndexKey(txn, indexType);
50
+ if (key) {
51
+ index.transactionIds.add(txn.transactionId);
52
+ }
53
+ }
54
+ this.indexes.set(indexType, index);
55
+ this.config.logger?.debug?.(`Built index: ${indexType} (${index.transactionIds.size} entries)`);
56
+ }
57
+ /**
58
+ * Get the index key for a transaction
59
+ */
60
+ getIndexKey(transaction, indexType) {
61
+ switch (indexType) {
62
+ case IndexType.DATE:
63
+ return transaction.date;
64
+ case IndexType.CATEGORY:
65
+ return transaction.category?.[0] || "uncategorized";
66
+ case IndexType.MERCHANT:
67
+ return transaction.merchantName || "unknown";
68
+ case IndexType.AMOUNT_RANGE:
69
+ // Bucket amounts into ranges
70
+ const amount = Math.abs(transaction.amount);
71
+ if (amount < 1000)
72
+ return "0-10"; // <$10
73
+ if (amount < 5000)
74
+ return "10-50"; // $10-$50
75
+ if (amount < 10000)
76
+ return "50-100"; // $50-$100
77
+ if (amount < 50000)
78
+ return "100-500"; // $100-$500
79
+ return "500+"; // >$500
80
+ case IndexType.PENDING:
81
+ return transaction.pending ? "pending" : "posted";
82
+ default:
83
+ return null;
84
+ }
85
+ }
86
+ /**
87
+ * Query transactions by index key
88
+ *
89
+ * @param indexType - Type of index to query
90
+ * @param _key - Key to look up (not used in simplified implementation)
91
+ * @returns Set of transaction IDs matching the key
92
+ */
93
+ query(indexType, _key) {
94
+ const index = this.indexes.get(indexType);
95
+ if (!index) {
96
+ this.config.logger?.warn?.(`Index not found: ${indexType}`);
97
+ return new Set();
98
+ }
99
+ // For now, return all IDs in the index
100
+ // A full implementation would need to store key -> IDs mapping
101
+ return index.transactionIds;
102
+ }
103
+ /**
104
+ * Clear all indexes
105
+ */
106
+ clear() {
107
+ this.indexes.clear();
108
+ this.config.logger?.debug?.("Indexes cleared");
109
+ }
110
+ /**
111
+ * Get index statistics
112
+ */
113
+ getStats() {
114
+ const stats = {};
115
+ for (const [key, entry] of this.indexes.entries()) {
116
+ stats[key] = entry.transactionIds.size;
117
+ }
118
+ return stats;
119
+ }
120
+ }
121
+ /**
122
+ * Index types
123
+ */
124
+ export var IndexType;
125
+ (function (IndexType) {
126
+ /** Index by transaction date */
127
+ IndexType["DATE"] = "date";
128
+ /** Index by primary category */
129
+ IndexType["CATEGORY"] = "category";
130
+ /** Index by merchant name */
131
+ IndexType["MERCHANT"] = "merchant";
132
+ /** Index by amount range (buckets) */
133
+ IndexType["AMOUNT_RANGE"] = "amount_range";
134
+ /** Index by pending status */
135
+ IndexType["PENDING"] = "pending";
136
+ })(IndexType || (IndexType = {}));
137
+ /**
138
+ * Query builder for filtering transactions
139
+ */
140
+ export class TransactionQueryBuilder {
141
+ filters = [];
142
+ /**
143
+ * Filter by date range
144
+ */
145
+ dateRange(start, end) {
146
+ this.filters.push((txn) => {
147
+ const txnDate = new Date(txn.date);
148
+ return txnDate >= start && txnDate <= end;
149
+ });
150
+ return this;
151
+ }
152
+ /**
153
+ * Filter by category
154
+ */
155
+ category(category) {
156
+ this.filters.push((txn) => txn.category?.some((c) => c.toLowerCase() === category.toLowerCase()));
157
+ return this;
158
+ }
159
+ /**
160
+ * Filter by merchant name (partial match)
161
+ */
162
+ merchant(merchant) {
163
+ this.filters.push((txn) => txn.merchantName?.toLowerCase().includes(merchant.toLowerCase()));
164
+ return this;
165
+ }
166
+ /**
167
+ * Filter by amount range (in cents)
168
+ */
169
+ amountRange(min, max) {
170
+ this.filters.push((txn) => txn.amount >= min && txn.amount <= max);
171
+ return this;
172
+ }
173
+ /**
174
+ * Filter by pending status
175
+ */
176
+ pending(isPending) {
177
+ this.filters.push((txn) => txn.pending === isPending);
178
+ return this;
179
+ }
180
+ /**
181
+ * Apply all filters to a set of transactions
182
+ */
183
+ apply(transactions) {
184
+ return transactions.filter((txn) => this.filters.every((filter) => filter(txn)));
185
+ }
186
+ /**
187
+ * Clear all filters
188
+ */
189
+ clear() {
190
+ this.filters = [];
191
+ return this;
192
+ }
193
+ }
194
+ /**
195
+ * Inverted index for full-text search
196
+ */
197
+ export class FullTextIndex {
198
+ index = new Map();
199
+ transactionData = new Map();
200
+ /**
201
+ * Add a transaction to the index
202
+ */
203
+ add(transaction) {
204
+ this.transactionData.set(transaction.transactionId, transaction);
205
+ // Index merchant name
206
+ if (transaction.merchantName) {
207
+ this.indexDocument(transaction.transactionId, transaction.merchantName);
208
+ }
209
+ // Index categories
210
+ for (const category of transaction.category || []) {
211
+ this.indexDocument(transaction.transactionId, category);
212
+ }
213
+ }
214
+ /**
215
+ * Index a document
216
+ */
217
+ indexDocument(transactionId, text) {
218
+ const words = text.toLowerCase().split(/\s+/);
219
+ for (const word of words) {
220
+ if (word.length < 2)
221
+ continue; // Skip very short words
222
+ if (!this.index.has(word)) {
223
+ this.index.set(word, new Set());
224
+ }
225
+ this.index.get(word).add(transactionId);
226
+ }
227
+ }
228
+ /**
229
+ * Search for transactions matching a query
230
+ */
231
+ search(query) {
232
+ const words = query
233
+ .toLowerCase()
234
+ .split(/\s+/)
235
+ .filter((w) => w.length >= 2);
236
+ if (words.length === 0) {
237
+ return [];
238
+ }
239
+ // Find transactions matching all words (AND query)
240
+ let matchingIds = null;
241
+ for (const word of words) {
242
+ const ids = this.index.get(word);
243
+ if (!ids) {
244
+ // Word not found, no results
245
+ return [];
246
+ }
247
+ if (!matchingIds) {
248
+ matchingIds = new Set(ids);
249
+ }
250
+ else {
251
+ // Intersect with current results
252
+ const existingIds = matchingIds;
253
+ matchingIds = new Set();
254
+ for (const id of existingIds) {
255
+ if (ids.has(id)) {
256
+ matchingIds.add(id);
257
+ }
258
+ }
259
+ }
260
+ if (matchingIds.size === 0) {
261
+ return [];
262
+ }
263
+ }
264
+ // Convert IDs to transactions
265
+ const results = [];
266
+ for (const id of matchingIds || []) {
267
+ const txn = this.transactionData.get(id);
268
+ if (txn) {
269
+ results.push(txn);
270
+ }
271
+ }
272
+ return results;
273
+ }
274
+ /**
275
+ * Clear the index
276
+ */
277
+ clear() {
278
+ this.index.clear();
279
+ this.transactionData.clear();
280
+ }
281
+ }
282
+ /**
283
+ * Create a query builder
284
+ */
285
+ export function createQueryBuilder() {
286
+ return new TransactionQueryBuilder();
287
+ }
288
+ /**
289
+ * Create a full-text index
290
+ */
291
+ export function createFullTextIndex() {
292
+ return new FullTextIndex();
293
+ }
294
+ //# sourceMappingURL=indexes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexes.js","sourceRoot":"","sources":["../../src/storage/indexes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * File locking for BillClaw
3
+ *
4
+ * Provides inter-process file locking to prevent concurrent write conflicts.
5
+ * Uses proper-lockfile for cross-platform file locking.
6
+ *
7
+ * Use cases:
8
+ * - Preventing concurrent sync operations
9
+ * - Protecting credential writes
10
+ * - Coordinating between multiple processes
11
+ */
12
+ import type { Logger } from "../errors/errors.js";
13
+ /**
14
+ * Lock options
15
+ */
16
+ export interface LockOptions {
17
+ /**
18
+ * Lock stale time in milliseconds
19
+ * If a lock is older than this, it will be considered stale and released
20
+ */
21
+ stale?: number;
22
+ /**
23
+ * Retry options
24
+ */
25
+ retries?: {
26
+ /**
27
+ * Number of retries to acquire the lock
28
+ */
29
+ count?: number;
30
+ /**
31
+ * Delay between retries in milliseconds
32
+ */
33
+ min?: number;
34
+ max?: number;
35
+ };
36
+ /**
37
+ * Logger for debug output
38
+ */
39
+ logger?: Logger;
40
+ }
41
+ /**
42
+ * Lock handle
43
+ */
44
+ export interface Lock {
45
+ /**
46
+ * Release the lock
47
+ */
48
+ release(): Promise<void>;
49
+ /**
50
+ * Check if the lock is still held
51
+ */
52
+ isLocked(): Promise<boolean>;
53
+ }
54
+ /**
55
+ * Acquire a file lock
56
+ *
57
+ * @param filePath - Path to the file to lock
58
+ * @param options - Lock options
59
+ * @returns Lock handle that must be released when done
60
+ */
61
+ export declare function acquireLock(filePath: string, options?: LockOptions): Promise<Lock>;
62
+ /**
63
+ * Execute a function while holding a lock
64
+ *
65
+ * @param filePath - Path to the file to lock
66
+ * @param fn - Function to execute while holding the lock
67
+ * @param options - Lock options
68
+ * @returns Result of the function
69
+ */
70
+ export declare function withLock<T>(filePath: string, fn: () => Promise<T>, options?: LockOptions): Promise<T>;
71
+ /**
72
+ * Check if a file is locked
73
+ *
74
+ * @param filePath - Path to the file to check
75
+ * @returns true if the file is locked
76
+ */
77
+ export declare function isLocked(filePath: string): Promise<boolean>;
78
+ /**
79
+ * Lock names for common operations
80
+ */
81
+ export declare const LockNames: {
82
+ /**
83
+ * Global sync lock (prevents concurrent sync operations)
84
+ */
85
+ SYNC: string;
86
+ /**
87
+ * Account-specific sync lock
88
+ */
89
+ accountSync(accountId: string): string;
90
+ /**
91
+ * Credential lock (protects credential writes)
92
+ */
93
+ CREDENTIALS: string;
94
+ /**
95
+ * Account-specific credential lock
96
+ */
97
+ accountCredentials(accountId: string): string;
98
+ /**
99
+ * Export lock (protects data export operations)
100
+ */
101
+ EXPORT: string;
102
+ };
103
+ //# sourceMappingURL=locking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locking.d.ts","sourceRoot":"","sources":["../../src/storage/locking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAqBjD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,OAAO,CAAC,EAAE;QACR;;WAEG;QACH,KAAK,CAAC,EAAE,MAAM,CAAA;QAEd;;WAEG;QACH,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,GAAG,CAAC,EAAE,MAAM,CAAA;KACb,CAAA;IAED;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAcD;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAExB;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAC7B;AAwCD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,CAAC,CAAC,CAQZ;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGjE;AAED;;GAEG;AACH,eAAO,MAAM,SAAS;IACpB;;OAEG;;IAGH;;OAEG;2BACoB,MAAM,GAAG,MAAM;IAItC;;OAEG;;IAGH;;OAEG;kCAC2B,MAAM,GAAG,MAAM;IAI7C;;OAEG;;CAEJ,CAAA"}