@b2bc-devkit/sheetorm 1.2.3 → 1.2.4

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 (149) hide show
  1. package/dist/npm/SheetOrm.d.ts +41 -0
  2. package/dist/npm/SheetOrm.d.ts.map +1 -0
  3. package/dist/npm/SheetOrm.js +41 -0
  4. package/dist/npm/SheetOrm.js.map +1 -0
  5. package/dist/npm/core/Decorators.d.ts +145 -0
  6. package/dist/npm/core/Decorators.d.ts.map +1 -0
  7. package/dist/npm/core/Decorators.js +226 -0
  8. package/dist/npm/core/Decorators.js.map +1 -0
  9. package/dist/npm/core/Record.d.ts +184 -0
  10. package/dist/npm/core/Record.d.ts.map +1 -0
  11. package/dist/npm/core/Record.js +321 -0
  12. package/dist/npm/core/Record.js.map +1 -0
  13. package/dist/npm/core/RecordConstructor.d.ts +20 -0
  14. package/dist/npm/core/RecordConstructor.d.ts.map +1 -0
  15. package/dist/npm/core/RecordConstructor.js +2 -0
  16. package/dist/npm/core/RecordConstructor.js.map +1 -0
  17. package/dist/npm/core/RecordStatic.d.ts +25 -0
  18. package/dist/npm/core/RecordStatic.d.ts.map +1 -0
  19. package/dist/npm/core/RecordStatic.js +2 -0
  20. package/dist/npm/core/RecordStatic.js.map +1 -0
  21. package/dist/npm/core/Registry.d.ts +101 -0
  22. package/dist/npm/core/Registry.d.ts.map +1 -0
  23. package/dist/npm/core/Registry.js +231 -0
  24. package/dist/npm/core/Registry.js.map +1 -0
  25. package/dist/npm/core/SheetRepository.d.ts +331 -0
  26. package/dist/npm/core/SheetRepository.d.ts.map +1 -0
  27. package/dist/npm/core/SheetRepository.js +1041 -0
  28. package/dist/npm/core/SheetRepository.js.map +1 -0
  29. package/dist/npm/core/cache/MemoryCache.d.ts +67 -0
  30. package/dist/npm/core/cache/MemoryCache.d.ts.map +1 -0
  31. package/dist/npm/core/cache/MemoryCache.js +112 -0
  32. package/dist/npm/core/cache/MemoryCache.js.map +1 -0
  33. package/dist/npm/core/types/Entity.d.ts +21 -0
  34. package/dist/npm/core/types/Entity.d.ts.map +1 -0
  35. package/dist/npm/core/types/Entity.js +2 -0
  36. package/dist/npm/core/types/Entity.js.map +1 -0
  37. package/dist/npm/core/types/FieldDefinition.d.ts +21 -0
  38. package/dist/npm/core/types/FieldDefinition.d.ts.map +1 -0
  39. package/dist/npm/core/types/FieldDefinition.js +2 -0
  40. package/dist/npm/core/types/FieldDefinition.js.map +1 -0
  41. package/dist/npm/core/types/FieldType.d.ts +12 -0
  42. package/dist/npm/core/types/FieldType.d.ts.map +1 -0
  43. package/dist/npm/core/types/FieldType.js +2 -0
  44. package/dist/npm/core/types/FieldType.js.map +1 -0
  45. package/dist/npm/core/types/Filter.d.ts +16 -0
  46. package/dist/npm/core/types/Filter.d.ts.map +1 -0
  47. package/dist/npm/core/types/Filter.js +2 -0
  48. package/dist/npm/core/types/Filter.js.map +1 -0
  49. package/dist/npm/core/types/FilterOperator.d.ts +16 -0
  50. package/dist/npm/core/types/FilterOperator.d.ts.map +1 -0
  51. package/dist/npm/core/types/FilterOperator.js +2 -0
  52. package/dist/npm/core/types/FilterOperator.js.map +1 -0
  53. package/dist/npm/core/types/GroupResult.d.ts +14 -0
  54. package/dist/npm/core/types/GroupResult.d.ts.map +1 -0
  55. package/dist/npm/core/types/GroupResult.js +2 -0
  56. package/dist/npm/core/types/GroupResult.js.map +1 -0
  57. package/dist/npm/core/types/ICacheProvider.d.ts +20 -0
  58. package/dist/npm/core/types/ICacheProvider.d.ts.map +1 -0
  59. package/dist/npm/core/types/ICacheProvider.js +2 -0
  60. package/dist/npm/core/types/ICacheProvider.js.map +1 -0
  61. package/dist/npm/core/types/ISheetAdapter.d.ts +53 -0
  62. package/dist/npm/core/types/ISheetAdapter.d.ts.map +1 -0
  63. package/dist/npm/core/types/ISheetAdapter.js +2 -0
  64. package/dist/npm/core/types/ISheetAdapter.js.map +1 -0
  65. package/dist/npm/core/types/ISpreadsheetAdapter.d.ts +49 -0
  66. package/dist/npm/core/types/ISpreadsheetAdapter.d.ts.map +1 -0
  67. package/dist/npm/core/types/ISpreadsheetAdapter.js +2 -0
  68. package/dist/npm/core/types/ISpreadsheetAdapter.js.map +1 -0
  69. package/dist/npm/core/types/IndexDefinition.d.ts +16 -0
  70. package/dist/npm/core/types/IndexDefinition.d.ts.map +1 -0
  71. package/dist/npm/core/types/IndexDefinition.js +2 -0
  72. package/dist/npm/core/types/IndexDefinition.js.map +1 -0
  73. package/dist/npm/core/types/LifecycleHooks.d.ts +32 -0
  74. package/dist/npm/core/types/LifecycleHooks.d.ts.map +1 -0
  75. package/dist/npm/core/types/LifecycleHooks.js +2 -0
  76. package/dist/npm/core/types/LifecycleHooks.js.map +1 -0
  77. package/dist/npm/core/types/PaginatedResult.d.ts +18 -0
  78. package/dist/npm/core/types/PaginatedResult.d.ts.map +1 -0
  79. package/dist/npm/core/types/PaginatedResult.js +2 -0
  80. package/dist/npm/core/types/PaginatedResult.js.map +1 -0
  81. package/dist/npm/core/types/QueryOptions.d.ts +21 -0
  82. package/dist/npm/core/types/QueryOptions.d.ts.map +1 -0
  83. package/dist/npm/core/types/QueryOptions.js +2 -0
  84. package/dist/npm/core/types/QueryOptions.js.map +1 -0
  85. package/dist/npm/core/types/SortClause.d.ts +10 -0
  86. package/dist/npm/core/types/SortClause.d.ts.map +1 -0
  87. package/dist/npm/core/types/SortClause.js +2 -0
  88. package/dist/npm/core/types/SortClause.js.map +1 -0
  89. package/dist/npm/core/types/SystemColumns.d.ts +16 -0
  90. package/dist/npm/core/types/SystemColumns.d.ts.map +1 -0
  91. package/dist/npm/core/types/SystemColumns.js +16 -0
  92. package/dist/npm/core/types/SystemColumns.js.map +1 -0
  93. package/dist/npm/core/types/TableSchema.d.ts +24 -0
  94. package/dist/npm/core/types/TableSchema.d.ts.map +1 -0
  95. package/dist/npm/core/types/TableSchema.js +2 -0
  96. package/dist/npm/core/types/TableSchema.js.map +1 -0
  97. package/dist/npm/index/IndexMeta.d.ts +16 -0
  98. package/dist/npm/index/IndexMeta.d.ts.map +1 -0
  99. package/dist/npm/index/IndexMeta.js +2 -0
  100. package/dist/npm/index/IndexMeta.js.map +1 -0
  101. package/dist/npm/index/IndexStore.d.ts +397 -0
  102. package/dist/npm/index/IndexStore.d.ts.map +1 -0
  103. package/dist/npm/index/IndexStore.js +1102 -0
  104. package/dist/npm/index/IndexStore.js.map +1 -0
  105. package/dist/npm/index.d.ts +117 -0
  106. package/dist/npm/index.d.ts.map +1 -0
  107. package/dist/npm/index.js +371 -0
  108. package/dist/npm/index.js.map +1 -0
  109. package/dist/npm/query/Query.d.ts +176 -0
  110. package/dist/npm/query/Query.d.ts.map +1 -0
  111. package/dist/npm/query/Query.js +270 -0
  112. package/dist/npm/query/Query.js.map +1 -0
  113. package/dist/npm/query/QueryEngine.d.ts +140 -0
  114. package/dist/npm/query/QueryEngine.d.ts.map +1 -0
  115. package/dist/npm/query/QueryEngine.js +453 -0
  116. package/dist/npm/query/QueryEngine.js.map +1 -0
  117. package/dist/npm/storage/GoogleSheetAdapter.d.ts +119 -0
  118. package/dist/npm/storage/GoogleSheetAdapter.d.ts.map +1 -0
  119. package/dist/npm/storage/GoogleSheetAdapter.js +238 -0
  120. package/dist/npm/storage/GoogleSheetAdapter.js.map +1 -0
  121. package/dist/npm/storage/GoogleSpreadsheetAdapter.d.ts +71 -0
  122. package/dist/npm/storage/GoogleSpreadsheetAdapter.d.ts.map +1 -0
  123. package/dist/npm/storage/GoogleSpreadsheetAdapter.js +131 -0
  124. package/dist/npm/storage/GoogleSpreadsheetAdapter.js.map +1 -0
  125. package/dist/npm/testing/ParityCatalog.d.ts +38 -0
  126. package/dist/npm/testing/ParityCatalog.d.ts.map +1 -0
  127. package/dist/npm/testing/ParityCatalog.js +407 -0
  128. package/dist/npm/testing/ParityCatalog.js.map +1 -0
  129. package/dist/npm/testing/RuntimeBenchmark.d.ts +37 -0
  130. package/dist/npm/testing/RuntimeBenchmark.d.ts.map +1 -0
  131. package/dist/npm/testing/RuntimeBenchmark.js +449 -0
  132. package/dist/npm/testing/RuntimeBenchmark.js.map +1 -0
  133. package/dist/npm/testing/RuntimeParity.d.ts +66 -0
  134. package/dist/npm/testing/RuntimeParity.d.ts.map +1 -0
  135. package/dist/npm/testing/RuntimeParity.js +4193 -0
  136. package/dist/npm/testing/RuntimeParity.js.map +1 -0
  137. package/dist/npm/utils/Serialization.d.ts +111 -0
  138. package/dist/npm/utils/Serialization.d.ts.map +1 -0
  139. package/dist/npm/utils/Serialization.js +281 -0
  140. package/dist/npm/utils/Serialization.js.map +1 -0
  141. package/dist/npm/utils/SheetOrmLogger.d.ts +31 -0
  142. package/dist/npm/utils/SheetOrmLogger.d.ts.map +1 -0
  143. package/dist/npm/utils/SheetOrmLogger.js +42 -0
  144. package/dist/npm/utils/SheetOrmLogger.js.map +1 -0
  145. package/dist/npm/utils/Uuid.d.ts +29 -0
  146. package/dist/npm/utils/Uuid.d.ts.map +1 -0
  147. package/dist/npm/utils/Uuid.js +86 -0
  148. package/dist/npm/utils/Uuid.js.map +1 -0
  149. package/package.json +3 -2
@@ -0,0 +1,449 @@
1
+ /**
2
+ * @module RuntimeBenchmark
3
+ *
4
+ * Runtime performance benchmark for SheetORM in Google Apps Script.
5
+ *
6
+ * Mirrors `tests/benchmark.test.ts` but runs against real Google Sheets API.
7
+ * Measures CRUD operations, query performance, and compares @Indexed
8
+ * n-gram search with full-scan "contains" queries.
9
+ *
10
+ * **GAS entry point**: `runBenchmark()` — full benchmark for Cars + Workers
11
+ * (default 1000 records each).
12
+ *
13
+ * **Comparison phases**:
14
+ * 1. CRUD + query benchmark for `Car` class (all fields @Indexed).
15
+ * 2. CRUD + query benchmark for `Worker` class (no @Indexed fields).
16
+ * 3. Search comparison: @Indexed "search" (n-gram) vs full-scan "contains".
17
+ *
18
+ * Results are logged to the GAS execution log and returned as a JSON report.
19
+ */
20
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
21
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
23
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
24
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
25
+ };
26
+ import { GoogleSpreadsheetAdapter } from "../storage/GoogleSpreadsheetAdapter.js";
27
+ import { Registry } from "../core/Registry.js";
28
+ import { Record as BaseRecord } from "../core/Record.js";
29
+ import { Decorators } from "../core/Decorators.js";
30
+ import { Query } from "../query/Query.js";
31
+ import { SheetOrmLogger } from "../utils/SheetOrmLogger.js";
32
+ const { Indexed, Required, resetDecoratorCaches } = Decorators;
33
+ // ─── Constants ───────────────────────────────────────────────────────────────
34
+ /** Number of records to create per benchmark table. */
35
+ const RECORD_COUNT = 1000;
36
+ /** Number of iterations for the search comparison phase. */
37
+ const SEARCH_ITERS = 100;
38
+ // ─── GAS logger helper ───────────────────────────────────────────────────────
39
+ /** Log a message to the GAS execution log (no-op outside GAS). */
40
+ function gasLog(msg) {
41
+ if (typeof Logger !== "undefined" && typeof Logger.log === "function") {
42
+ Logger.log(msg);
43
+ }
44
+ }
45
+ // ─── Model definitions (created fresh each run to avoid class cache issues) ──
46
+ /**
47
+ * Create a fresh Car model class with unique table names.
48
+ * All fields are @Indexed to measure index-write overhead.
49
+ */
50
+ function createCarClass(suffix) {
51
+ Registry.reset();
52
+ resetDecoratorCaches();
53
+ class Car extends BaseRecord {
54
+ static get tableName() {
55
+ return `tbl_Cars_${suffix}`;
56
+ }
57
+ static get indexTableName() {
58
+ return `idx_Cars_${suffix}`;
59
+ }
60
+ }
61
+ __decorate([
62
+ Indexed()
63
+ ], Car.prototype, "make", void 0);
64
+ __decorate([
65
+ Indexed(),
66
+ Required()
67
+ ], Car.prototype, "model", void 0);
68
+ __decorate([
69
+ Indexed()
70
+ ], Car.prototype, "year", void 0);
71
+ __decorate([
72
+ Indexed()
73
+ ], Car.prototype, "color", void 0);
74
+ return Car;
75
+ }
76
+ /**
77
+ * Create a fresh Worker model class with unique table names.
78
+ * No @Indexed fields — used as the baseline for comparison.
79
+ */
80
+ function createWorkerClass(suffix) {
81
+ Registry.reset();
82
+ resetDecoratorCaches();
83
+ class Worker extends BaseRecord {
84
+ static get tableName() {
85
+ return `tbl_Workers_${suffix}`;
86
+ }
87
+ static get indexTableName() {
88
+ return `idx_Workers_${suffix}`;
89
+ }
90
+ }
91
+ __decorate([
92
+ Required()
93
+ ], Worker.prototype, "department", void 0);
94
+ return Worker;
95
+ }
96
+ // ─── Assertion helpers ───────────────────────────────────────────────────────
97
+ /** Assert strict equality; throw with label on mismatch. */
98
+ function gasAssertEq(actual, expected, label) {
99
+ if (actual !== expected) {
100
+ throw new Error(`${label}: expected ${String(expected)}, got ${String(actual)}`);
101
+ }
102
+ }
103
+ /** Assert a boolean condition; throw with label if false. */
104
+ function gasAssertTrue(condition, label) {
105
+ if (!condition) {
106
+ throw new Error(`Assertion failed: ${label}`);
107
+ }
108
+ }
109
+ /**
110
+ * Run a full CRUD + query benchmark for a single Record subclass.
111
+ *
112
+ * Exercises: saveAll, count, findById, find, findOne, where, query().orderBy().limit(),
113
+ * select, groupBy, update via save, delete single, deleteAll with filter, Query.from, toJSON.
114
+ *
115
+ * @param Ctor - Record subclass constructor.
116
+ * @param makeData - Factory function producing entity data for index `i`.
117
+ * @param log - Logging function (GAS Logger.log or console.log).
118
+ * @returns BenchResult with timing, pass/fail counts, and errors.
119
+ */
120
+ function runBenchmarkFor(Ctor, makeData, log) {
121
+ const tableName = Ctor.tableName;
122
+ const indexTableName = Ctor.indexTableName;
123
+ const errors = [];
124
+ let passed = 0;
125
+ let failed = 0;
126
+ function step(label, fn) {
127
+ log(`[SheetORM] ─── ${label} ───`);
128
+ try {
129
+ fn();
130
+ passed++;
131
+ log(`[SheetORM] ✓ ${label} passed`);
132
+ }
133
+ catch (e) {
134
+ failed++;
135
+ const msg = e instanceof Error ? e.message : String(e);
136
+ errors.push(`${label}: ${msg}`);
137
+ log(`[SheetORM] ✗ ${label} FAILED: ${msg}`);
138
+ }
139
+ }
140
+ const startMs = Date.now();
141
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
142
+ log(`[SheetORM] Benchmark: ${tableName} (${RECORD_COUNT} records)`);
143
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
144
+ const saved = [];
145
+ step(`saveAll() × ${RECORD_COUNT}`, () => {
146
+ const allData = Array.from({ length: RECORD_COUNT }, (_, i) => makeData(i));
147
+ const t0 = Date.now();
148
+ // saveAll() batches all index writes into a single setValues() call
149
+ const allSaved = Ctor.saveAll(allData);
150
+ const saveAllMs = Date.now() - t0;
151
+ for (const s of allSaved)
152
+ saved.push(s);
153
+ gasAssertEq(saved.length, RECORD_COUNT, "saved.length");
154
+ log(`[SheetORM] Created ${saved.length} records in ${tableName} in ${saveAllMs} ms`);
155
+ });
156
+ step("count()", () => {
157
+ const c = Ctor.count();
158
+ gasAssertEq(c, RECORD_COUNT, "count()");
159
+ log(`[SheetORM] count() = ${c}`);
160
+ });
161
+ step("findById()", () => {
162
+ if (saved.length === 0)
163
+ return;
164
+ const mid = saved[Math.floor(RECORD_COUNT / 2)];
165
+ const found = Ctor.findById(mid.__id);
166
+ gasAssertTrue(found !== null, "findById not null");
167
+ gasAssertEq(found.__id, mid.__id, "findById id");
168
+ log(`[SheetORM] findById() returned id=${found.__id.slice(0, 8)}...`);
169
+ });
170
+ step("find() all", () => {
171
+ const all = Ctor.find();
172
+ gasAssertEq(all.length, RECORD_COUNT, "find() all length");
173
+ log(`[SheetORM] find() returned ${all.length} records`);
174
+ });
175
+ const firstField = Object.keys(makeData(0))[0];
176
+ const firstVal = makeData(0)[firstField];
177
+ step("find() with filter", () => {
178
+ const filtered = Ctor.find({ where: [{ field: firstField, operator: "=", value: firstVal }] });
179
+ gasAssertTrue(filtered.length > 0, "find(where) not empty");
180
+ log(`[SheetORM] find(where ${firstField}=${String(firstVal)}) returned ${filtered.length} records`);
181
+ });
182
+ step("findOne()", () => {
183
+ const one = Ctor.findOne({ where: [{ field: firstField, operator: "=", value: firstVal }] });
184
+ gasAssertTrue(one !== null, "findOne not null");
185
+ });
186
+ step("where() query chain", () => {
187
+ const results = Ctor.where(firstField, "=", firstVal).execute();
188
+ gasAssertTrue(results.length > 0, "where() not empty");
189
+ log(`[SheetORM] where() returned ${results.length} records`);
190
+ });
191
+ step("query().orderBy().limit()", () => {
192
+ const results = Ctor.query().orderBy(firstField, "asc").limit(10).execute();
193
+ gasAssertEq(results.length, Math.min(10, RECORD_COUNT), "query().limit(10)");
194
+ log(`[SheetORM] query().orderBy().limit(10) returned ${results.length} records`);
195
+ });
196
+ step("select() pagination", () => {
197
+ const page = Ctor.select(0, 10);
198
+ gasAssertEq(page.items.length, 10, "select items length");
199
+ gasAssertEq(page.total, RECORD_COUNT, "select total");
200
+ gasAssertTrue(page.hasNext, "select hasNext");
201
+ log(`[SheetORM] select(0,10) total=${page.total}, hasNext=${page.hasNext}`);
202
+ });
203
+ step("groupBy()", () => {
204
+ const groups = Ctor.groupBy(firstField);
205
+ gasAssertTrue(groups.length > 0, "groupBy not empty");
206
+ log(`[SheetORM] groupBy(${firstField}) returned ${groups.length} groups`);
207
+ });
208
+ step("update via save()", () => {
209
+ if (saved.length === 0)
210
+ return;
211
+ const toUpdate = Ctor.findById(saved[0].__id);
212
+ const fields = Object.keys(makeData(0));
213
+ const lastField = fields[fields.length - 1];
214
+ toUpdate[lastField] = "runtime-updated";
215
+ toUpdate.save();
216
+ const reloaded = Ctor.findById(saved[0].__id);
217
+ gasAssertEq(reloaded[lastField], "runtime-updated", "update persisted");
218
+ log(`[SheetORM] update persisted for id=${saved[0].__id.slice(0, 8)}...`);
219
+ });
220
+ step("delete() single record", () => {
221
+ if (saved.length < 2)
222
+ return;
223
+ const toDelete = Ctor.findById(saved[saved.length - 1].__id);
224
+ const ok = toDelete.delete();
225
+ gasAssertEq(ok, true, "delete() returned true");
226
+ gasAssertTrue(Ctor.findById(toDelete.__id) === null, "deleted record not found");
227
+ log(`[SheetORM] delete() removed record, count now ${Ctor.count()}`);
228
+ });
229
+ step("deleteAll() with filter", () => {
230
+ const before = Ctor.count();
231
+ const delCount = Ctor.deleteAll({
232
+ where: [{ field: firstField, operator: "=", value: firstVal }],
233
+ });
234
+ const after = Ctor.count();
235
+ gasAssertEq(after, before - delCount, "deleteAll count consistency");
236
+ log(`[SheetORM] deleteAll() removed ${delCount} records (${before} → ${after})`);
237
+ });
238
+ step("Query.from() class ref", () => {
239
+ const results = Query.from(Ctor)
240
+ .limit(5)
241
+ .execute();
242
+ gasAssertTrue(results.length <= 5, "Query.from() limit");
243
+ log(`[SheetORM] Query.from() returned ${results.length} records`);
244
+ });
245
+ step("toJSON()", () => {
246
+ const items = Ctor.find({ limit: 1 });
247
+ if (items.length > 0) {
248
+ const json = items[0].toJSON();
249
+ gasAssertEq(typeof json.__id, "string", "toJSON().__id is string");
250
+ }
251
+ });
252
+ const durationMs = Date.now() - startMs;
253
+ // Check index sheet
254
+ const indexSheetCreated = Registry.getInstance().getIndexStore().existsCombined(indexTableName);
255
+ log(`[SheetORM] ────────────────────────────────────────────────────`);
256
+ log(`[SheetORM] ${tableName} finished in ${durationMs} ms`);
257
+ log(`[SheetORM] Index sheet "${indexTableName}" exists: ${indexSheetCreated}`);
258
+ log(`[SheetORM] Passed: ${passed}, Failed: ${failed}`);
259
+ log(`[SheetORM] ────────────────────────────────────────────────────`);
260
+ return {
261
+ tableName,
262
+ indexTableName,
263
+ durationMs,
264
+ recordCount: RECORD_COUNT,
265
+ indexSheetCreated,
266
+ passed,
267
+ failed,
268
+ errors,
269
+ };
270
+ }
271
+ // ─── Public GAS function ─────────────────────────────────────────────────────
272
+ /**
273
+ * Main benchmark entry point — invoked from GAS menu.
274
+ *
275
+ * Runs two model benchmarks (Cars with @Indexed, Workers without),
276
+ * then a search comparison (n-gram vs full-scan), and returns a
277
+ * JSON report string with all timing data.
278
+ */
279
+ function runBenchmark() {
280
+ const log = gasLog;
281
+ const runId = String(Date.now());
282
+ if (typeof SpreadsheetApp === "undefined") {
283
+ throw new Error("runBenchmark() must be run in Google Apps Script runtime.");
284
+ }
285
+ SheetOrmLogger.verbose = true;
286
+ const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
287
+ const adapter = new GoogleSpreadsheetAdapter(spreadsheet);
288
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
289
+ log(`[SheetORM] SheetORM Benchmark (run ID: ${runId})`);
290
+ log(`[SheetORM] Records per table: ${RECORD_COUNT}`);
291
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
292
+ // ── Cars benchmark (with @Indexed on all fields) ──────────────────────────
293
+ const CarClass = createCarClass(runId);
294
+ Registry.getInstance().configure({ adapter });
295
+ const carData = (i) => ({
296
+ make: ["Toyota", "Honda", "BMW", "Ford", "VW"][i % 5],
297
+ model: `Model-${i}`,
298
+ year: 2015 + (i % 10),
299
+ color: ["red", "blue", "white", "black", "silver"][i % 5],
300
+ });
301
+ const carsResult = runBenchmarkFor(CarClass, carData, log);
302
+ // ── Workers benchmark (no @Indexed) ──────────────────────────────────────
303
+ const WorkerClass = createWorkerClass(runId);
304
+ Registry.getInstance().configure({ adapter });
305
+ const workerData = (i) => ({
306
+ name: `Worker-${i}`,
307
+ department: ["Engineering", "Marketing", "HR", "Finance", "Sales"][i % 5],
308
+ salary: 3000 + (i % 10) * 500,
309
+ active: i % 3 !== 0,
310
+ });
311
+ const workersResult = runBenchmarkFor(WorkerClass, workerData, log);
312
+ // ── Search benchmark: @Indexed "search" vs full-scan "contains" ──────────
313
+ // Re-uses data from the tables above (already in GAS Sheets).
314
+ // Warm-up call populates entity cache + n-gram search index in memory;
315
+ // subsequent SEARCH_ITERS iterations run purely in-memory.
316
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
317
+ log(`[SheetORM] SEARCH BENCHMARK`);
318
+ log(`[SheetORM] @Indexed "search" (n-gram, pre-filters candidates) vs`);
319
+ log(`[SheetORM] Full-scan "contains" (scans all entities per query)`);
320
+ log(`[SheetORM] Iterations: ${SEARCH_ITERS} (all in-memory after warm-up)`);
321
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
322
+ // ── Step 1: @Indexed "search" on Cars ────────────────────────────────────
323
+ Registry.reset();
324
+ Registry.getInstance().configure({ adapter });
325
+ // Warm-up: loads entity sheet (1 API call) + index sheet (1 API call),
326
+ // then caches both for all subsequent iterations.
327
+ CarClass.find({ where: [{ field: "make", operator: "search", value: "toy" }], limit: 1 });
328
+ const approxCars = CarClass.count();
329
+ const searchT0 = Date.now();
330
+ for (let _i = 0; _i < SEARCH_ITERS; _i++) {
331
+ CarClass.find({
332
+ where: [{ field: "make", operator: "search", value: "toy" }],
333
+ orderBy: [
334
+ { field: "year", direction: "asc" },
335
+ { field: "model", direction: "desc" },
336
+ ],
337
+ limit: 10,
338
+ });
339
+ }
340
+ const indexedSearchMs = Date.now() - searchT0;
341
+ log(`[SheetORM] ─── @Indexed "search" on Cars (${approxCars} records) ───`);
342
+ log(`[SheetORM] find(make search "toy") × ${SEARCH_ITERS}: ${indexedSearchMs} ms`);
343
+ log(`[SheetORM] → n-gram pre-filter → ~${Math.round(approxCars / 5)} candidates → 2-field sort → limit 10`);
344
+ // ── Step 2: Full-scan "contains" on Workers ───────────────────────────────
345
+ Registry.reset();
346
+ Registry.getInstance().configure({ adapter });
347
+ // Warm-up: loads entity sheet (1 API call), no index sheet.
348
+ WorkerClass.find({ where: [{ field: "department", operator: "contains", value: "Eng" }], limit: 1 });
349
+ const approxWorkers = WorkerClass.count();
350
+ const fullScanT0 = Date.now();
351
+ for (let _i = 0; _i < SEARCH_ITERS; _i++) {
352
+ WorkerClass.find({
353
+ where: [{ field: "department", operator: "contains", value: "Eng" }],
354
+ orderBy: [
355
+ { field: "salary", direction: "asc" },
356
+ { field: "name", direction: "desc" },
357
+ ],
358
+ limit: 10,
359
+ });
360
+ }
361
+ const fullScanMs = Date.now() - fullScanT0;
362
+ log(`[SheetORM] ─── Full-scan "contains" on Workers (${approxWorkers} records) ───`);
363
+ log(`[SheetORM] find(department contains "Eng") × ${SEARCH_ITERS}: ${fullScanMs} ms`);
364
+ log(`[SheetORM] → scan all ${approxWorkers} entities → 2-field sort → limit 10`);
365
+ log(`[SheetORM] ────────────────────────────────────────────────────`);
366
+ const searchRatio = indexedSearchMs > 0 ? `${(fullScanMs / indexedSearchMs).toFixed(2)}x` : `>${fullScanMs}x`;
367
+ const searchFaster = indexedSearchMs < fullScanMs ? "indexed" : "full-scan";
368
+ log(`[SheetORM] @Indexed search: ${indexedSearchMs} ms vs Full-scan: ${fullScanMs} ms`);
369
+ log(`[SheetORM] Ratio: ${searchRatio} (${searchFaster} is faster over ${SEARCH_ITERS} iterations)`);
370
+ log(`[SheetORM] Note: @Indexed "search" uses n-gram posting index to pre-filter`);
371
+ log(`[SheetORM] candidates before sort. With 20% selectivity ("toy"~Toyota)`);
372
+ log(`[SheetORM] the sort operates on ~${Math.round(approxCars / 5)} items instead of ${approxCars}.`);
373
+ log(`[SheetORM] In GAS, the index is also smaller to read on cold start`);
374
+ log(`[SheetORM] (3 columns vs all entity columns), saving API read time.`);
375
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
376
+ Registry.reset();
377
+ resetDecoratorCaches();
378
+ // ── Summary ───────────────────────────────────────────────────────────────
379
+ const diff = workersResult.durationMs - carsResult.durationMs;
380
+ const fasterSuite = diff > 0 ? carsResult.tableName : workersResult.tableName;
381
+ const slowerSuite = diff > 0 ? workersResult.tableName : carsResult.tableName;
382
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
383
+ log(`[SheetORM] BENCHMARK SUMMARY`);
384
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
385
+ log(`[SheetORM] ${carsResult.tableName} (with @Indexed): ${carsResult.durationMs} ms`);
386
+ log(`[SheetORM] ${workersResult.tableName} (no @Indexed): ${workersResult.durationMs} ms`);
387
+ log(`[SheetORM] Difference: ${Math.abs(diff)} ms`);
388
+ log(`[SheetORM] Faster: ${fasterSuite} (by ${Math.abs(diff)} ms)`);
389
+ log(`[SheetORM] Slower: ${slowerSuite}`);
390
+ log(`[SheetORM] Note: @Indexed adds write overhead in both mock and real GAS (index sheet writes).`);
391
+ log(`[SheetORM] In real Google Sheets, @Indexed enables faster point-lookups (fewer API reads per query).`);
392
+ log(`[SheetORM] The time saved by @Indexed in real GAS grows with dataset size.`);
393
+ log(`[SheetORM] ════════════════════════════════════════════════════`);
394
+ const totalPassed = carsResult.passed + workersResult.passed;
395
+ const totalFailed = carsResult.failed + workersResult.failed;
396
+ const allErrors = [...carsResult.errors, ...workersResult.errors];
397
+ log(`[SheetORM] Total: ${totalPassed} operations passed, ${totalFailed} failed`);
398
+ if (allErrors.length > 0) {
399
+ log(`[SheetORM] Errors:`);
400
+ for (const err of allErrors) {
401
+ log(`[SheetORM] ✗ ${err}`);
402
+ }
403
+ }
404
+ const report = {
405
+ runId,
406
+ recordCount: RECORD_COUNT,
407
+ cars: {
408
+ tableName: carsResult.tableName,
409
+ indexTableName: carsResult.indexTableName,
410
+ durationMs: carsResult.durationMs,
411
+ indexSheetCreated: carsResult.indexSheetCreated,
412
+ passed: carsResult.passed,
413
+ failed: carsResult.failed,
414
+ },
415
+ workers: {
416
+ tableName: workersResult.tableName,
417
+ indexTableName: workersResult.indexTableName,
418
+ durationMs: workersResult.durationMs,
419
+ indexSheetCreated: workersResult.indexSheetCreated,
420
+ passed: workersResult.passed,
421
+ failed: workersResult.failed,
422
+ },
423
+ search: {
424
+ iterations: SEARCH_ITERS,
425
+ indexedSearchMs,
426
+ fullScanMs,
427
+ ratio: indexedSearchMs > 0 ? +(fullScanMs / indexedSearchMs).toFixed(2) : null,
428
+ faster: searchFaster,
429
+ },
430
+ summary: {
431
+ fasterSuite,
432
+ slowerSuite,
433
+ differenceMs: Math.abs(diff),
434
+ },
435
+ errors: allErrors,
436
+ spreadsheetUrl: spreadsheet.getUrl(),
437
+ };
438
+ log(`[SheetORM] ${JSON.stringify(report)}`);
439
+ return JSON.stringify(report);
440
+ }
441
+ /**
442
+ * Exported wrapper class for the benchmark runner.
443
+ * `RuntimeBenchmark.run()` delegates to the module-level `runBenchmark()`.
444
+ */
445
+ export class RuntimeBenchmark {
446
+ }
447
+ /** Execute the full benchmark suite. */
448
+ RuntimeBenchmark.run = runBenchmark;
449
+ //# sourceMappingURL=RuntimeBenchmark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeBenchmark.js","sourceRoot":"","sources":["../../../src/testing/RuntimeBenchmark.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @module RuntimeParity
3
+ *
4
+ * Runtime parity test suite for Google Apps Script (GAS).
5
+ *
6
+ * This file mirrors the Jest test suites (tests/*.test.ts) but runs against
7
+ * real Google Sheets via the GAS execution environment. Its purpose is to
8
+ * verify that SheetORM behaves identically in both the Jest mock environment
9
+ * and the real GAS runtime ("parity").
10
+ *
11
+ * **Architecture**:
12
+ * - {@link RuntimeParityState} — per-run state: unique table names, spreadsheet access.
13
+ * - {@link runtimeSuiteHandlers} — a map of `file → testName → handler` that mirrors
14
+ * every Jest `test()` block. Each handler exercises the same logic but using
15
+ * real Google Sheets API calls instead of mocks.
16
+ * - {@link RuntimeParity} — public API (static methods) invoked from GAS menu:
17
+ * - `runStageOne()` / `runStageTwo()` / `runStageThree()` / `runStageFour()` — execute test subsets.
18
+ * - `validate()` — cross-check collected results against {@link ParityCatalog}.
19
+ *
20
+ * Tests are split into four stages to stay within the 6-minute GAS execution
21
+ * time limit. Each stage persists results to a `__parity_results_*` sheet so
22
+ * that `validate()` can aggregate them later.
23
+ *
24
+ * Helper functions (`fail`, `assertTrue`, `assertEqual`, `assertDeepEqual`,
25
+ * `assertThrows`, `sleepMs`) provide assertion primitives similar to Jest's
26
+ * `expect()` API.
27
+ */
28
+ /**
29
+ * Validate that every Jest test case in {@link ParityCatalog} has a
30
+ * corresponding runtime handler, and vice versa.
31
+ *
32
+ * Throws a descriptive error if any test is missing in either direction,
33
+ * preventing silent parity drift between Jest and GAS test suites.
34
+ */
35
+ declare function validateTests(): void;
36
+ /** Stage 1: cache, index-store, query, query-engine (~162 tests). */
37
+ declare function runTestsStageOne(): string;
38
+ /** Stage 2: serialization, uuid (~52 tests, ~60s). */
39
+ declare function runTestsStageTwo(): string;
40
+ /** Stage 3: record (~81 tests, ~250s). */
41
+ declare function runTestsStageThree(): string;
42
+ /** Stage 4: sheet-repository (~35 tests, ~120s). */
43
+ declare function runTestsStageFour(): string;
44
+ /**
45
+ * Public API for runtime parity testing.
46
+ *
47
+ * Provides static methods that GAS entry points delegate to.
48
+ * Results are persisted to dedicated sheets and can be aggregated
49
+ * via `validate()`.
50
+ */
51
+ export declare class RuntimeParity {
52
+ /** Execute stage-one parity tests (cache, index-store, query, query-engine). */
53
+ static runStageOne: typeof runTestsStageOne;
54
+ /** Execute stage-two parity tests (serialization, uuid). */
55
+ static runStageTwo: typeof runTestsStageTwo;
56
+ /** Execute stage-three parity tests (record). */
57
+ static runStageThree: typeof runTestsStageThree;
58
+ /** Execute stage-four parity tests (sheet-repository). */
59
+ static runStageFour: typeof runTestsStageFour;
60
+ /** Cross-check that all ParityCatalog case IDs have runtime handlers. */
61
+ static validate: typeof validateTests;
62
+ /** Complete list of runtime parity case IDs (for external cross-reference). */
63
+ static readonly CASE_IDS: string[];
64
+ }
65
+ export {};
66
+ //# sourceMappingURL=RuntimeParity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeParity.d.ts","sourceRoot":"","sources":["../../../src/testing/RuntimeParity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAi2JH;;;;;;GAMG;AACH,iBAAS,aAAa,IAAI,IAAI,CAiB7B;AA6GD,qEAAqE;AACrE,iBAAS,gBAAgB,IAAI,MAAM,CAIlC;AAED,sDAAsD;AACtD,iBAAS,gBAAgB,IAAI,MAAM,CAIlC;AAED,0CAA0C;AAC1C,iBAAS,kBAAkB,IAAI,MAAM,CAIpC;AAED,oDAAoD;AACpD,iBAAS,iBAAiB,IAAI,MAAM,CAInC;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,gFAAgF;IAChF,MAAM,CAAC,WAAW,0BAAoB;IACtC,4DAA4D;IAC5D,MAAM,CAAC,WAAW,0BAAoB;IACtC,iDAAiD;IACjD,MAAM,CAAC,aAAa,4BAAsB;IAC1C,0DAA0D;IAC1D,MAAM,CAAC,YAAY,2BAAqB;IACxC,yEAAyE;IACzE,MAAM,CAAC,QAAQ,uBAAiB;IAChC,+EAA+E;IAC/E,MAAM,CAAC,QAAQ,CAAC,QAAQ,WAA2B;CACpD"}