@b2bc-devkit/sheetorm 1.1.0 → 1.2.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 (150) hide show
  1. package/package.json +171 -86
  2. package/readme.md +57 -17
  3. package/dist/npm/SheetOrm.d.ts +0 -41
  4. package/dist/npm/SheetOrm.d.ts.map +0 -1
  5. package/dist/npm/SheetOrm.js +0 -41
  6. package/dist/npm/SheetOrm.js.map +0 -1
  7. package/dist/npm/core/Decorators.d.ts +0 -145
  8. package/dist/npm/core/Decorators.d.ts.map +0 -1
  9. package/dist/npm/core/Decorators.js +0 -226
  10. package/dist/npm/core/Decorators.js.map +0 -1
  11. package/dist/npm/core/Record.d.ts +0 -178
  12. package/dist/npm/core/Record.d.ts.map +0 -1
  13. package/dist/npm/core/Record.js +0 -313
  14. package/dist/npm/core/Record.js.map +0 -1
  15. package/dist/npm/core/RecordConstructor.d.ts +0 -20
  16. package/dist/npm/core/RecordConstructor.d.ts.map +0 -1
  17. package/dist/npm/core/RecordConstructor.js +0 -2
  18. package/dist/npm/core/RecordConstructor.js.map +0 -1
  19. package/dist/npm/core/RecordStatic.d.ts +0 -23
  20. package/dist/npm/core/RecordStatic.d.ts.map +0 -1
  21. package/dist/npm/core/RecordStatic.js +0 -2
  22. package/dist/npm/core/RecordStatic.js.map +0 -1
  23. package/dist/npm/core/Registry.d.ts +0 -101
  24. package/dist/npm/core/Registry.d.ts.map +0 -1
  25. package/dist/npm/core/Registry.js +0 -226
  26. package/dist/npm/core/Registry.js.map +0 -1
  27. package/dist/npm/core/SheetRepository.d.ts +0 -331
  28. package/dist/npm/core/SheetRepository.d.ts.map +0 -1
  29. package/dist/npm/core/SheetRepository.js +0 -1041
  30. package/dist/npm/core/SheetRepository.js.map +0 -1
  31. package/dist/npm/core/cache/MemoryCache.d.ts +0 -67
  32. package/dist/npm/core/cache/MemoryCache.d.ts.map +0 -1
  33. package/dist/npm/core/cache/MemoryCache.js +0 -112
  34. package/dist/npm/core/cache/MemoryCache.js.map +0 -1
  35. package/dist/npm/core/types/Entity.d.ts +0 -21
  36. package/dist/npm/core/types/Entity.d.ts.map +0 -1
  37. package/dist/npm/core/types/Entity.js +0 -2
  38. package/dist/npm/core/types/Entity.js.map +0 -1
  39. package/dist/npm/core/types/FieldDefinition.d.ts +0 -21
  40. package/dist/npm/core/types/FieldDefinition.d.ts.map +0 -1
  41. package/dist/npm/core/types/FieldDefinition.js +0 -2
  42. package/dist/npm/core/types/FieldDefinition.js.map +0 -1
  43. package/dist/npm/core/types/FieldType.d.ts +0 -12
  44. package/dist/npm/core/types/FieldType.d.ts.map +0 -1
  45. package/dist/npm/core/types/FieldType.js +0 -2
  46. package/dist/npm/core/types/FieldType.js.map +0 -1
  47. package/dist/npm/core/types/Filter.d.ts +0 -16
  48. package/dist/npm/core/types/Filter.d.ts.map +0 -1
  49. package/dist/npm/core/types/Filter.js +0 -2
  50. package/dist/npm/core/types/Filter.js.map +0 -1
  51. package/dist/npm/core/types/FilterOperator.d.ts +0 -16
  52. package/dist/npm/core/types/FilterOperator.d.ts.map +0 -1
  53. package/dist/npm/core/types/FilterOperator.js +0 -2
  54. package/dist/npm/core/types/FilterOperator.js.map +0 -1
  55. package/dist/npm/core/types/GroupResult.d.ts +0 -14
  56. package/dist/npm/core/types/GroupResult.d.ts.map +0 -1
  57. package/dist/npm/core/types/GroupResult.js +0 -2
  58. package/dist/npm/core/types/GroupResult.js.map +0 -1
  59. package/dist/npm/core/types/ICacheProvider.d.ts +0 -20
  60. package/dist/npm/core/types/ICacheProvider.d.ts.map +0 -1
  61. package/dist/npm/core/types/ICacheProvider.js +0 -2
  62. package/dist/npm/core/types/ICacheProvider.js.map +0 -1
  63. package/dist/npm/core/types/ISheetAdapter.d.ts +0 -53
  64. package/dist/npm/core/types/ISheetAdapter.d.ts.map +0 -1
  65. package/dist/npm/core/types/ISheetAdapter.js +0 -2
  66. package/dist/npm/core/types/ISheetAdapter.js.map +0 -1
  67. package/dist/npm/core/types/ISpreadsheetAdapter.d.ts +0 -41
  68. package/dist/npm/core/types/ISpreadsheetAdapter.d.ts.map +0 -1
  69. package/dist/npm/core/types/ISpreadsheetAdapter.js +0 -2
  70. package/dist/npm/core/types/ISpreadsheetAdapter.js.map +0 -1
  71. package/dist/npm/core/types/IndexDefinition.d.ts +0 -16
  72. package/dist/npm/core/types/IndexDefinition.d.ts.map +0 -1
  73. package/dist/npm/core/types/IndexDefinition.js +0 -2
  74. package/dist/npm/core/types/IndexDefinition.js.map +0 -1
  75. package/dist/npm/core/types/LifecycleHooks.d.ts +0 -32
  76. package/dist/npm/core/types/LifecycleHooks.d.ts.map +0 -1
  77. package/dist/npm/core/types/LifecycleHooks.js +0 -2
  78. package/dist/npm/core/types/LifecycleHooks.js.map +0 -1
  79. package/dist/npm/core/types/PaginatedResult.d.ts +0 -18
  80. package/dist/npm/core/types/PaginatedResult.d.ts.map +0 -1
  81. package/dist/npm/core/types/PaginatedResult.js +0 -2
  82. package/dist/npm/core/types/PaginatedResult.js.map +0 -1
  83. package/dist/npm/core/types/QueryOptions.d.ts +0 -21
  84. package/dist/npm/core/types/QueryOptions.d.ts.map +0 -1
  85. package/dist/npm/core/types/QueryOptions.js +0 -2
  86. package/dist/npm/core/types/QueryOptions.js.map +0 -1
  87. package/dist/npm/core/types/SortClause.d.ts +0 -10
  88. package/dist/npm/core/types/SortClause.d.ts.map +0 -1
  89. package/dist/npm/core/types/SortClause.js +0 -2
  90. package/dist/npm/core/types/SortClause.js.map +0 -1
  91. package/dist/npm/core/types/SystemColumns.d.ts +0 -16
  92. package/dist/npm/core/types/SystemColumns.d.ts.map +0 -1
  93. package/dist/npm/core/types/SystemColumns.js +0 -16
  94. package/dist/npm/core/types/SystemColumns.js.map +0 -1
  95. package/dist/npm/core/types/TableSchema.d.ts +0 -24
  96. package/dist/npm/core/types/TableSchema.d.ts.map +0 -1
  97. package/dist/npm/core/types/TableSchema.js +0 -2
  98. package/dist/npm/core/types/TableSchema.js.map +0 -1
  99. package/dist/npm/index/IndexMeta.d.ts +0 -16
  100. package/dist/npm/index/IndexMeta.d.ts.map +0 -1
  101. package/dist/npm/index/IndexMeta.js +0 -2
  102. package/dist/npm/index/IndexMeta.js.map +0 -1
  103. package/dist/npm/index/IndexStore.d.ts +0 -397
  104. package/dist/npm/index/IndexStore.d.ts.map +0 -1
  105. package/dist/npm/index/IndexStore.js +0 -1102
  106. package/dist/npm/index/IndexStore.js.map +0 -1
  107. package/dist/npm/index.d.ts +0 -115
  108. package/dist/npm/index.d.ts.map +0 -1
  109. package/dist/npm/index.js +0 -367
  110. package/dist/npm/index.js.map +0 -1
  111. package/dist/npm/query/Query.d.ts +0 -176
  112. package/dist/npm/query/Query.d.ts.map +0 -1
  113. package/dist/npm/query/Query.js +0 -270
  114. package/dist/npm/query/Query.js.map +0 -1
  115. package/dist/npm/query/QueryEngine.d.ts +0 -140
  116. package/dist/npm/query/QueryEngine.d.ts.map +0 -1
  117. package/dist/npm/query/QueryEngine.js +0 -453
  118. package/dist/npm/query/QueryEngine.js.map +0 -1
  119. package/dist/npm/storage/GoogleSheetAdapter.d.ts +0 -119
  120. package/dist/npm/storage/GoogleSheetAdapter.d.ts.map +0 -1
  121. package/dist/npm/storage/GoogleSheetAdapter.js +0 -238
  122. package/dist/npm/storage/GoogleSheetAdapter.js.map +0 -1
  123. package/dist/npm/storage/GoogleSpreadsheetAdapter.d.ts +0 -65
  124. package/dist/npm/storage/GoogleSpreadsheetAdapter.d.ts.map +0 -1
  125. package/dist/npm/storage/GoogleSpreadsheetAdapter.js +0 -119
  126. package/dist/npm/storage/GoogleSpreadsheetAdapter.js.map +0 -1
  127. package/dist/npm/testing/ParityCatalog.d.ts +0 -38
  128. package/dist/npm/testing/ParityCatalog.d.ts.map +0 -1
  129. package/dist/npm/testing/ParityCatalog.js +0 -404
  130. package/dist/npm/testing/ParityCatalog.js.map +0 -1
  131. package/dist/npm/testing/RuntimeBenchmark.d.ts +0 -37
  132. package/dist/npm/testing/RuntimeBenchmark.d.ts.map +0 -1
  133. package/dist/npm/testing/RuntimeBenchmark.js +0 -449
  134. package/dist/npm/testing/RuntimeBenchmark.js.map +0 -1
  135. package/dist/npm/testing/RuntimeParity.d.ts +0 -62
  136. package/dist/npm/testing/RuntimeParity.d.ts.map +0 -1
  137. package/dist/npm/testing/RuntimeParity.js +0 -4126
  138. package/dist/npm/testing/RuntimeParity.js.map +0 -1
  139. package/dist/npm/utils/Serialization.d.ts +0 -111
  140. package/dist/npm/utils/Serialization.d.ts.map +0 -1
  141. package/dist/npm/utils/Serialization.js +0 -281
  142. package/dist/npm/utils/Serialization.js.map +0 -1
  143. package/dist/npm/utils/SheetOrmLogger.d.ts +0 -31
  144. package/dist/npm/utils/SheetOrmLogger.d.ts.map +0 -1
  145. package/dist/npm/utils/SheetOrmLogger.js +0 -42
  146. package/dist/npm/utils/SheetOrmLogger.js.map +0 -1
  147. package/dist/npm/utils/Uuid.d.ts +0 -29
  148. package/dist/npm/utils/Uuid.d.ts.map +0 -1
  149. package/dist/npm/utils/Uuid.js +0 -86
  150. package/dist/npm/utils/Uuid.js.map +0 -1
@@ -1,453 +0,0 @@
1
- /**
2
- * QueryEngine — pure in-memory filter, sort, paginate, and group engine.
3
- *
4
- * Every function operates on plain entity arrays and returns new arrays
5
- * without mutating the input. The implementation is heavily optimised for
6
- * the GAS V8 runtime (limited JIT, no SIMD, high GC cost):
7
- *
8
- * - Filters are **compiled** into predicate closures once; the hot loop
9
- * invokes closures instead of evaluating operator strings.
10
- * - Sort keys are **pre-extracted** into column-major arrays to avoid
11
- * repeated field navigation during comparison callbacks.
12
- * - The `in` operator converts to a `Set` when the value list exceeds
13
- * 8 elements for O(1) membership checks.
14
- * - String comparison operators (`contains`, `startsWith`, `search`)
15
- * are case-insensitive and pre-lower the filter value once.
16
- *
17
- * @module QueryEngine
18
- */
19
- import { SheetOrmLogger } from "../utils/SheetOrmLogger.js";
20
- /**
21
- * Split a field path into segments for nested property access.
22
- *
23
- * Single-segment paths (no dots or slashes) return `null` to signal the
24
- * fast-path in {@link compileFieldAccessor} — a direct property read.
25
- *
26
- * @param field - Dot- or slash-separated field path (e.g. `"address.city"`).
27
- * @returns Array of segments, or `null` for a simple field name.
28
- */
29
- function splitFieldPath(field) {
30
- if (field.indexOf(".") === -1 && field.indexOf("/") === -1)
31
- return null;
32
- return field.replace(/\//g, ".").split(".");
33
- }
34
- /**
35
- * Pre-compile a field accessor closure for the given field path.
36
- *
37
- * Simple fields return a direct property reader; nested paths return a
38
- * closure that walks each segment, returning `undefined` for missing
39
- * intermediate objects.
40
- *
41
- * @param field - Dot-separated field path.
42
- * @returns Accessor function: `(entity) => fieldValue`.
43
- */
44
- function compileFieldAccessor(field) {
45
- const parts = splitFieldPath(field);
46
- if (parts === null) {
47
- // Simple field — direct property access (fast path)
48
- return (entity) => entity[field];
49
- }
50
- // Nested field — walk the path with null-safe navigation
51
- return (entity) => {
52
- let current = entity;
53
- for (let i = 0; i < parts.length; i++) {
54
- if (current == null)
55
- return undefined;
56
- current = current[parts[i]];
57
- }
58
- return current;
59
- };
60
- }
61
- /**
62
- * Compile a single {@link Filter} into a fast predicate function.
63
- *
64
- * Pre-computes the field accessor and, for the `in` operator, converts
65
- * large value arrays (>8 elements) to a `Set` for O(1) membership checks.
66
- *
67
- * Supported operators: `=`, `!=`, `<`, `>`, `<=`, `>=`, `contains`,
68
- * `startsWith`, `in`, `search`.
69
- *
70
- * @param f - The filter to compile.
71
- * @returns Predicate function: `(entity) => boolean`.
72
- */
73
- function compileFilter(f) {
74
- const accessor = compileFieldAccessor(f.field);
75
- const op = f.operator;
76
- const fv = f.value;
77
- switch (op) {
78
- case "=":
79
- return (e) => accessor(e) === fv;
80
- case "!=":
81
- return (e) => accessor(e) !== fv;
82
- case "<":
83
- return (e) => {
84
- const v = accessor(e);
85
- if (typeof v !== typeof fv)
86
- return false;
87
- return v < fv;
88
- };
89
- case ">":
90
- return (e) => {
91
- const v = accessor(e);
92
- if (typeof v !== typeof fv)
93
- return false;
94
- return v > fv;
95
- };
96
- case "<=":
97
- return (e) => {
98
- const v = accessor(e);
99
- if (typeof v !== typeof fv)
100
- return false;
101
- return v <= fv;
102
- };
103
- case ">=":
104
- return (e) => {
105
- const v = accessor(e);
106
- if (typeof v !== typeof fv)
107
- return false;
108
- return v >= fv;
109
- };
110
- case "contains": {
111
- // Case-insensitive substring match
112
- if (typeof fv !== "string")
113
- return () => false;
114
- const lowerC = fv.toLowerCase();
115
- return (e) => {
116
- const v = accessor(e);
117
- return typeof v === "string" && v.toLowerCase().includes(lowerC);
118
- };
119
- }
120
- case "startsWith": {
121
- // Case-insensitive prefix match
122
- if (typeof fv !== "string")
123
- return () => false;
124
- const lowerS = fv.toLowerCase();
125
- return (e) => {
126
- const v = accessor(e);
127
- return typeof v === "string" && v.toLowerCase().startsWith(lowerS);
128
- };
129
- }
130
- case "in": {
131
- // Membership check — uses Set for large lists (>8) for O(1) lookups
132
- if (!Array.isArray(fv))
133
- return () => false;
134
- if (fv.length > 8) {
135
- const set = new Set(fv);
136
- return (e) => set.has(accessor(e));
137
- }
138
- return (e) => fv.includes(accessor(e));
139
- }
140
- case "search": {
141
- // Case-insensitive substring search (same as "contains" but semantically distinct —
142
- // in SheetRepository.find() the "search" operator can leverage n-gram indexes)
143
- if (typeof fv !== "string")
144
- return () => false;
145
- const lowerSr = fv.toLowerCase();
146
- return (e) => {
147
- const v = accessor(e);
148
- return typeof v === "string" && v.toLowerCase().includes(lowerSr);
149
- };
150
- }
151
- default:
152
- return () => false;
153
- }
154
- }
155
- /**
156
- * Filter entities by an array of filters using AND logic.
157
- *
158
- * All predicates are compiled once; the hot loop uses a labeled `continue outer`
159
- * to short-circuit on the first failing predicate per entity (minimal GC pressure).
160
- *
161
- * @typeParam T - Entity type.
162
- * @param entities - Source array (not mutated).
163
- * @param filters - Filters to apply (all must match — AND).
164
- * @returns New array of matching entities.
165
- */
166
- function filterEntities(entities, filters) {
167
- if (!filters || filters.length === 0)
168
- return entities;
169
- // Compile all filter predicates once
170
- const predicates = new Array(filters.length);
171
- for (let i = 0; i < filters.length; i++) {
172
- predicates[i] = compileFilter(filters[i]);
173
- }
174
- const len = entities.length;
175
- const predLen = predicates.length;
176
- const result = [];
177
- // Labeled loop: `continue outer` skips to next entity on first failing predicate
178
- outer: for (let i = 0; i < len; i++) {
179
- const entity = entities[i];
180
- for (let j = 0; j < predLen; j++) {
181
- if (!predicates[j](entity))
182
- continue outer;
183
- }
184
- result.push(entity);
185
- }
186
- return result;
187
- }
188
- /**
189
- * Filter entities with OR-connected groups of AND-connected filters.
190
- *
191
- * An entity matches if it satisfies **any** group (OR), where within each
192
- * group all filters must match (AND). Empty groups never match.
193
- *
194
- * @typeParam T - Entity type.
195
- * @param entities - Source array (not mutated).
196
- * @param groups - Array of filter groups (outer=OR, inner=AND).
197
- * @returns New array of matching entities.
198
- */
199
- function filterEntitiesOr(entities, groups) {
200
- if (!groups || groups.length === 0)
201
- return entities;
202
- // Compile each group into an array of predicate closures
203
- const compiledGroups = new Array(groups.length);
204
- for (let g = 0; g < groups.length; g++) {
205
- const group = groups[g];
206
- const predicates = new Array(group.length);
207
- for (let i = 0; i < group.length; i++) {
208
- predicates[i] = compileFilter(group[i]);
209
- }
210
- compiledGroups[g] = predicates;
211
- }
212
- const len = entities.length;
213
- const numGroups = compiledGroups.length;
214
- const result = [];
215
- for (let i = 0; i < len; i++) {
216
- const entity = entities[i];
217
- let matched = false;
218
- // Try each group — entity matches if ANY group's predicates all pass
219
- for (let g = 0; g < numGroups; g++) {
220
- const predicates = compiledGroups[g];
221
- const predLen = predicates.length;
222
- // An empty group never matches — it has no conditions to satisfy
223
- let groupMatch = predLen > 0;
224
- for (let j = 0; j < predLen; j++) {
225
- if (!predicates[j](entity)) {
226
- groupMatch = false;
227
- break;
228
- }
229
- }
230
- if (groupMatch) {
231
- matched = true;
232
- break;
233
- }
234
- }
235
- if (matched)
236
- result.push(entity);
237
- }
238
- return result;
239
- }
240
- /**
241
- * Sort entities by multiple {@link SortClause} fields.
242
- *
243
- * **Performance strategy** (optimised for GAS V8):
244
- *
245
- * 1. Sort keys are **pre-extracted** into column-major arrays
246
- * (`keys[sortIndex][entityIndex]`) so the comparator never calls
247
- * field accessors — it reads from pre-populated primitive arrays.
248
- * 2. An **index array** is sorted instead of the entities themselves,
249
- * avoiding expensive object moves in the V8 sort implementation.
250
- * 3. The final result is assembled from the sorted indices in one pass.
251
- *
252
- * Null handling: `null`/`undefined` values sort **first** (before any
253
- * non-null value) regardless of direction.
254
- *
255
- * @typeParam T - Entity type.
256
- * @param entities - Source array (not mutated).
257
- * @param sorts - Sort clauses in priority order (first = primary sort).
258
- * @returns New sorted array.
259
- */
260
- function sortEntities(entities, sorts) {
261
- if (!sorts || sorts.length === 0)
262
- return entities;
263
- const len = entities.length;
264
- const numSorts = sorts.length;
265
- // Pre-compile field accessors and direction multipliers (+1 for asc, -1 for desc)
266
- const accessors = new Array(numSorts);
267
- const directions = new Array(numSorts);
268
- for (let s = 0; s < numSorts; s++) {
269
- accessors[s] = compileFieldAccessor(sorts[s].field);
270
- directions[s] = sorts[s].direction === "desc" ? -1 : 1;
271
- }
272
- // Pre-extract sort keys into column-major layout: keys[sortIndex][entityIndex]
273
- // This avoids repeated field accessor calls during the sort comparator
274
- const keys = new Array(numSorts);
275
- for (let s = 0; s < numSorts; s++) {
276
- const accessor = accessors[s];
277
- const col = new Array(len);
278
- for (let i = 0; i < len; i++) {
279
- col[i] = accessor(entities[i]);
280
- }
281
- keys[s] = col;
282
- }
283
- // Build index array — sort indices instead of objects to avoid expensive moves
284
- const indices = new Array(len);
285
- for (let i = 0; i < len; i++)
286
- indices[i] = i;
287
- // Multi-key comparator using pre-extracted key columns
288
- indices.sort((ai, bi) => {
289
- for (let s = 0; s < numSorts; s++) {
290
- const aVal = keys[s][ai];
291
- const bVal = keys[s][bi];
292
- let cmp;
293
- if (aVal === bVal) {
294
- cmp = 0;
295
- }
296
- else if (aVal == null) {
297
- cmp = -1; // Nulls sort first
298
- }
299
- else if (bVal == null) {
300
- cmp = 1; // Nulls sort first
301
- }
302
- else if (typeof aVal === "number" && typeof bVal === "number") {
303
- cmp = aVal - bVal; // Numeric comparison (avoids string coercion)
304
- }
305
- else {
306
- cmp = String(aVal).localeCompare(String(bVal)); // String fallback
307
- }
308
- if (cmp !== 0)
309
- return cmp * directions[s]; // Apply asc/desc multiplier
310
- }
311
- return 0; // All keys equal — stable order
312
- });
313
- // Build sorted result array from the sorted index permutation
314
- const result = new Array(len);
315
- for (let i = 0; i < len; i++) {
316
- result[i] = entities[indices[i]];
317
- }
318
- return result;
319
- }
320
- /**
321
- * Apply pagination (offset + limit) to an entity array.
322
- *
323
- * Both `offset` and `limit` are sanitised: non-finite, negative, or
324
- * fractional values are clamped to safe defaults (0 for offset, full
325
- * length for limit).
326
- *
327
- * @typeParam T - Entity type.
328
- * @param entities - Source array.
329
- * @param offset - Number of items to skip from the start.
330
- * @param limit - Maximum number of items to return.
331
- * @returns Paginated result with metadata (total, hasNext, etc.).
332
- */
333
- function paginateEntities(entities, offset, limit) {
334
- const safeOffset = Number.isFinite(offset) && offset >= 0 ? Math.floor(offset) : 0;
335
- const safeLimit = Number.isFinite(limit) && limit >= 0 ? Math.floor(limit) : entities.length;
336
- const total = entities.length;
337
- const sliced = entities.slice(safeOffset, safeOffset + safeLimit);
338
- return {
339
- items: sliced,
340
- total,
341
- offset: safeOffset,
342
- limit: safeLimit,
343
- hasNext: safeOffset + safeLimit < total,
344
- };
345
- }
346
- /**
347
- * Group entities by a single field, producing one {@link GroupResult} per distinct value.
348
- *
349
- * Uses a `Map` keyed by the field value to collect entities in insertion
350
- * order. The pre-compiled field accessor avoids repeated path resolution.
351
- *
352
- * @typeParam T - Entity type.
353
- * @param entities - Source array (not mutated).
354
- * @param field - Dot-separated field path to group by.
355
- * @returns Array of group results, each containing key, count, and items.
356
- */
357
- function groupEntities(entities, field) {
358
- const accessor = compileFieldAccessor(field);
359
- const groups = new Map();
360
- // Distribute entities into groups by their field value
361
- for (let i = 0, len = entities.length; i < len; i++) {
362
- const entity = entities[i];
363
- const key = accessor(entity);
364
- const existing = groups.get(key);
365
- if (existing) {
366
- existing.push(entity);
367
- }
368
- else {
369
- groups.set(key, [entity]);
370
- }
371
- }
372
- // Convert Map entries to GroupResult array
373
- const results = [];
374
- groups.forEach((items, key) => {
375
- results.push({ key, count: items.length, items });
376
- });
377
- return results;
378
- }
379
- /**
380
- * Execute a complete query pipeline on an in-memory entity array.
381
- *
382
- * Pipeline stages (executed in order):
383
- *
384
- * 1. **Filter**: `whereGroups` (OR of ANDs) takes precedence over `where`
385
- * (simple AND). If both are present, only `whereGroups` is applied.
386
- * 2. **Sort**: Multi-field sort via {@link sortEntities}.
387
- * 3. **Paginate**: `offset` and `limit` applied via `Array.slice`.
388
- *
389
- * This function does NOT call {@link paginateEntities} — it applies a
390
- * lighter slice-only pagination without producing a `PaginatedResult`
391
- * wrapper. The caller (typically {@link SheetRepository}) is responsible
392
- * for wrapping the result if needed.
393
- *
394
- * @typeParam T - Entity type.
395
- * @param entities - Full entity array to query against.
396
- * @param options - Query options controlling filter, sort, and pagination.
397
- * @returns Filtered, sorted, and paginated entity array.
398
- */
399
- function executeQuery(entities, options) {
400
- SheetOrmLogger.log(`[QueryEngine] executeQuery in=${entities.length}` +
401
- ` where=${options.where?.length ?? 0}` +
402
- ` whereGroups=${options.whereGroups?.length ?? 0}` +
403
- ` orderBy=${options.orderBy?.length ?? 0}` +
404
- ` offset=${options.offset ?? "-"} limit=${options.limit ?? "-"}`);
405
- let result = entities;
406
- // Stage 1: Filter — whereGroups (OR of ANDs) takes precedence over where (AND)
407
- if (options.whereGroups && options.whereGroups.length > 0) {
408
- result = filterEntitiesOr(result, options.whereGroups);
409
- }
410
- else if (options.where && options.where.length > 0) {
411
- result = filterEntities(result, options.where);
412
- }
413
- // Stage 2: Sort — multi-field ordering
414
- if (options.orderBy && options.orderBy.length > 0) {
415
- result = sortEntities(result, options.orderBy);
416
- }
417
- // Stage 3: Paginate — slice-only (no PaginatedResult wrapper)
418
- if (options.offset !== undefined || options.limit !== undefined) {
419
- const rawOffset = options.offset ?? 0;
420
- const offset = Number.isFinite(rawOffset) && rawOffset >= 0 ? Math.floor(rawOffset) : 0;
421
- const limit = options.limit !== undefined
422
- ? Number.isFinite(options.limit) && options.limit >= 0
423
- ? Math.floor(options.limit)
424
- : result.length
425
- : result.length;
426
- result = result.slice(offset, offset + limit);
427
- }
428
- SheetOrmLogger.log(`[QueryEngine] executeQuery out=${result.length}`);
429
- return result;
430
- }
431
- /**
432
- * Static facade exposing the query engine's pure functions as class methods.
433
- *
434
- * All methods are stateless — they operate on the provided entity array
435
- * and return new arrays without side effects. The class form exists so
436
- * that callers can reference `QueryEngine.filterEntities(...)` instead of
437
- * importing individual module-level functions.
438
- */
439
- export class QueryEngine {
440
- }
441
- /** Filter entities with AND-connected conditions. */
442
- QueryEngine.filterEntities = filterEntities;
443
- /** Filter entities with OR-connected groups of AND-connected conditions. */
444
- QueryEngine.filterEntitiesOr = filterEntitiesOr;
445
- /** Sort entities by multiple fields with asc/desc directions. */
446
- QueryEngine.sortEntities = sortEntities;
447
- /** Paginate entities and return metadata (total, hasNext, etc.). */
448
- QueryEngine.paginateEntities = paginateEntities;
449
- /** Group entities by a field into key/count/items buckets. */
450
- QueryEngine.groupEntities = groupEntities;
451
- /** Execute a full filter → sort → paginate pipeline. */
452
- QueryEngine.executeQuery = executeQuery;
453
- //# sourceMappingURL=QueryEngine.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"QueryEngine.js","sourceRoot":"","sources":["../../../src/query/QueryEngine.ts"],"names":[],"mappings":"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"}
@@ -1,119 +0,0 @@
1
- /**
2
- * Google Apps Script adapter implementing the ISheetAdapter interface.
3
- *
4
- * Wraps a single GAS `Sheet` object (one tab in a Spreadsheet) and
5
- * translates 0-based data indexes used by the ORM into 1-based sheet
6
- * rows required by the GAS Range API. Row 1 is always the header row;
7
- * data rows start at row 2.
8
- *
9
- * All multi-cell reads/writes are performed with `getRange().getValues()`
10
- * / `setValues()` to minimise GAS API calls (each call adds ~300 ms of
11
- * latency in the Apps Script runtime).
12
- *
13
- * @module GoogleSheetAdapter
14
- */
15
- import type { ISheetAdapter } from "../core/types/ISheetAdapter.js";
16
- /**
17
- * Production implementation of {@link ISheetAdapter} for Google Apps Script.
18
- * Delegates every operation to the underlying `GoogleAppsScript.Spreadsheet.Sheet`.
19
- */
20
- export declare class GoogleSheetAdapter implements ISheetAdapter {
21
- /** The wrapped GAS Sheet object representing one spreadsheet tab. */
22
- private sheet;
23
- /**
24
- * @param sheet - A GAS Sheet object obtained via Spreadsheet.getSheetByName()
25
- * or Spreadsheet.insertSheet().
26
- */
27
- constructor(sheet: GoogleAppsScript.Spreadsheet.Sheet);
28
- /** Return the name of the underlying sheet tab. */
29
- getName(): string;
30
- /**
31
- * Read the header row (row 1) and return the column names as strings.
32
- * Returns an empty array if the sheet has no columns.
33
- */
34
- getHeaders(): string[];
35
- /**
36
- * Overwrite the header row (row 1) with the given column names.
37
- * No-op if the headers array is empty.
38
- */
39
- setHeaders(headers: string[]): void;
40
- /**
41
- * Read all data rows (row 2+) as a 2D array.
42
- * Returns an empty array if the sheet has no data rows.
43
- */
44
- getAllData(): unknown[][];
45
- /**
46
- * Return the number of data rows (excludes the header row).
47
- * Computed as `lastRow - 1`, where lastRow includes the header.
48
- */
49
- getRowCount(): number;
50
- /** Append a single row after the last occupied row using GAS appendRow(). */
51
- appendRow(values: unknown[]): void;
52
- /**
53
- * Append multiple rows in a single setValues() API call.
54
- * Much faster than calling appendRow() in a loop (~300 ms per call saved).
55
- */
56
- appendRows(rows: unknown[][]): void;
57
- /**
58
- * Write rows starting at the given 0-based data index.
59
- * Overwrites existing cells — used for batch-update operations.
60
- *
61
- * @param startRowIndex - 0-based data index (sheet row = index + 2).
62
- * @param rows - 2D array of values.
63
- */
64
- writeRowsAt(startRowIndex: number, rows: unknown[][]): void;
65
- /**
66
- * Overwrite a single data row.
67
- *
68
- * @param rowIndex - 0-based data index (sheet row = index + 2).
69
- * @param values - Column values.
70
- */
71
- updateRow(rowIndex: number, values: unknown[]): void;
72
- /**
73
- * Overwrite multiple rows, batching contiguous groups into single
74
- * setValues() calls to minimise GAS API round-trips.
75
- *
76
- * Example: updating rows 3, 4, 5, 10, 11 produces two setValues() calls
77
- * instead of five.
78
- */
79
- updateRows(updates: Array<{
80
- rowIndex: number;
81
- values: unknown[];
82
- }>): void;
83
- /**
84
- * Delete a single data row. GAS deleteRow() shifts all rows below up by one.
85
- * @param rowIndex - 0-based data index.
86
- */
87
- deleteRow(rowIndex: number): void;
88
- /**
89
- * Delete multiple data rows by index.
90
- * Rows are deleted from bottom to top so that earlier indexes remain valid.
91
- */
92
- deleteRows(rowIndexes: number[]): void;
93
- /**
94
- * Read a single data row.
95
- * @param rowIndex - 0-based data index.
96
- * @returns Array of cell values.
97
- */
98
- getRow(rowIndex: number): unknown[];
99
- /**
100
- * Replace all data rows (row 2+) with the provided 2D array.
101
- *
102
- * If the new data has fewer rows than the old data, surplus old rows
103
- * are cleared. If the new data is narrower (fewer columns), surplus
104
- * columns in the written region are also cleared.
105
- */
106
- replaceAllData(rows: unknown[][]): void;
107
- /** Clear the entire sheet (headers + data). */
108
- clear(): void;
109
- /** Force-flush pending changes to the spreadsheet (calls SpreadsheetApp.flush()). */
110
- flush(): void;
111
- /**
112
- * Write the header row and all data rows in a single setValues() API call.
113
- * Row 1 = headers, row 2+ = data.
114
- *
115
- * Used for newly-created sheets to avoid a separate setHeaders() round-trip.
116
- */
117
- writeAllRowsWithHeaders(headers: string[], rows: unknown[][]): void;
118
- }
119
- //# sourceMappingURL=GoogleSheetAdapter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GoogleSheetAdapter.d.ts","sourceRoot":"","sources":["../../../src/storage/GoogleSheetAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAGpE;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IACtD,qEAAqE;IACrE,OAAO,CAAC,KAAK,CAAqC;IAElD;;;OAGG;gBACS,KAAK,EAAE,gBAAgB,CAAC,WAAW,CAAC,KAAK;IAIrD,mDAAmD;IACnD,OAAO,IAAI,MAAM;IAIjB;;;OAGG;IACH,UAAU,IAAI,MAAM,EAAE;IAStB;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAKnC;;;OAGG;IACH,UAAU,IAAI,OAAO,EAAE,EAAE;IAgBzB;;;OAGG;IACH,WAAW,IAAI,MAAM;IAOrB,6EAA6E;IAC7E,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI;IAIlC;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI;IAWnC;;;;;;OAMG;IACH,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI;IAW3D;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI;IAMpD;;;;;;OAMG;IACH,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC,GAAG,IAAI;IAiCzE;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKjC;;;OAGG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAQtC;;;;OAIG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE;IAOnC;;;;;;OAMG;IACH,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI;IAuBvC,+CAA+C;IAC/C,KAAK,IAAI,IAAI;IAIb,qFAAqF;IACrF,KAAK,IAAI,IAAI;IAIb;;;;;OAKG;IACH,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI;CASpE"}