@lensjs/core 1.0.12 → 2.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.
Files changed (93) hide show
  1. package/README.md +69 -0
  2. package/dist/abstracts/store.cjs +23 -0
  3. package/dist/abstracts/store.d.cts +7 -2
  4. package/dist/abstracts/store.d.ts +7 -2
  5. package/dist/abstracts/store.js +23 -0
  6. package/dist/core/api_controller.cjs +47 -4
  7. package/dist/core/api_controller.d.cts +7 -3
  8. package/dist/core/api_controller.d.ts +7 -3
  9. package/dist/core/api_controller.js +47 -4
  10. package/dist/core/lens.cjs +109 -10
  11. package/dist/core/lens.js +110 -11
  12. package/dist/exception-3AZsPtAg.d.ts +52 -0
  13. package/dist/exception-C69UCHPk.d.cts +52 -0
  14. package/dist/index.cjs +301 -19
  15. package/dist/index.d.cts +7 -2
  16. package/dist/index.d.ts +7 -2
  17. package/dist/index.js +296 -20
  18. package/dist/stores/better_sqlite.cjs +40 -6
  19. package/dist/stores/better_sqlite.d.cts +17 -1
  20. package/dist/stores/better_sqlite.d.ts +17 -1
  21. package/dist/stores/better_sqlite.js +41 -7
  22. package/dist/stores/index.cjs +40 -6
  23. package/dist/stores/index.js +41 -7
  24. package/dist/types/index.cjs +2 -0
  25. package/dist/types/index.d.cts +49 -2
  26. package/dist/types/index.d.ts +49 -2
  27. package/dist/types/index.js +2 -0
  28. package/dist/ui/assets/CacheActionBadge-3t8U516j.js +1 -0
  29. package/dist/ui/assets/CacheEntriesTable-BqLquILg.js +1 -0
  30. package/dist/ui/assets/CacheEntryContainer-B86waEsR.js +2 -0
  31. package/dist/ui/assets/CacheEntryDetails-Dm-oXALj.js +1 -0
  32. package/dist/ui/assets/CacheEntryDetailsContainer-BCyXGgkx.js +2 -0
  33. package/dist/ui/assets/ExceptionContainer-DSQBz5cb.js +2 -0
  34. package/dist/ui/assets/ExceptionDetails-gmpSQ_eu.js +16 -0
  35. package/dist/ui/assets/ExceptionDetailsContainer-BHIz-TUv.js +2 -0
  36. package/dist/ui/assets/ExceptionTable-BhrX9MSS.js +1 -0
  37. package/dist/ui/assets/LoadMore-26PcNWcP.js +1 -0
  38. package/dist/ui/assets/QueriesContainer-BSF-O4s3.js +2 -0
  39. package/dist/ui/assets/{QueryDetailsContainer-E7P-IO7f.js → QueryDetailsContainer-BjQM9QIb.js} +15 -15
  40. package/dist/ui/assets/QueryTable-szgIT5Uc.js +1 -0
  41. package/dist/ui/assets/RequestDetails-CvQhX-2F.js +1 -0
  42. package/dist/ui/assets/{RequestDetailsContainer-DuDo-IqS.js → RequestDetailsContainer-XYPFJFX0.js} +2 -2
  43. package/dist/ui/assets/RequestsContainer-D0QPK2Ii.js +2 -0
  44. package/dist/ui/assets/RequetsTable-6Fqchsrt.js +1 -0
  45. package/dist/ui/assets/{StatusCode-FQEjz7gK.js → StatusCode-CfVCLID2.js} +1 -1
  46. package/dist/ui/assets/TabbedDataViewer-Cl5ednx4.js +1 -0
  47. package/dist/ui/assets/{Table-DYaXk80S.js → Table-CGe8JwTO.js} +2 -2
  48. package/dist/ui/assets/columns-BFxCubt5.js +1 -0
  49. package/dist/ui/assets/columns-Cw7tw3Em.js +1 -0
  50. package/dist/ui/assets/columns-RiCoo9Ea.js +1 -0
  51. package/dist/ui/assets/{index-CpP2Ap5X.js → index-BRRKsoNv.js} +1 -1
  52. package/dist/ui/assets/index-BzFeZyjf.css +1 -0
  53. package/dist/ui/assets/{index-BS8XxorB.js → index-XoJlyTFO.js} +32 -22
  54. package/dist/ui/assets/useCacheEntries-SCADuxKq.js +1 -0
  55. package/dist/ui/assets/useExceptions-BMGL3nir.js +1 -0
  56. package/dist/ui/assets/useLensApi-BYyiIIZR.js +1 -0
  57. package/dist/ui/assets/{useLoadMore-CJltToLI.js → useLoadMore-CksOcXOF.js} +1 -1
  58. package/dist/ui/assets/useQueries-6nYr0oG5.js +1 -0
  59. package/dist/ui/index.html +2 -2
  60. package/dist/utils/async_context.cjs +144 -0
  61. package/dist/utils/async_context.d.cts +13 -0
  62. package/dist/utils/async_context.d.ts +13 -0
  63. package/dist/utils/async_context.js +108 -0
  64. package/dist/utils/event_emitter.cjs +5 -2
  65. package/dist/utils/event_emitter.d.cts +8 -1
  66. package/dist/utils/event_emitter.d.ts +8 -1
  67. package/dist/utils/event_emitter.js +3 -1
  68. package/dist/utils/exception.cjs +130 -0
  69. package/dist/utils/exception.d.cts +3 -0
  70. package/dist/utils/exception.d.ts +3 -0
  71. package/dist/utils/exception.js +91 -0
  72. package/dist/watchers/cache_watcher.cjs +107 -0
  73. package/dist/watchers/cache_watcher.d.cts +11 -0
  74. package/dist/watchers/cache_watcher.d.ts +11 -0
  75. package/dist/watchers/cache_watcher.js +84 -0
  76. package/dist/watchers/exception_watcher.cjs +108 -0
  77. package/dist/watchers/exception_watcher.d.cts +10 -0
  78. package/dist/watchers/exception_watcher.d.ts +10 -0
  79. package/dist/watchers/exception_watcher.js +75 -0
  80. package/dist/watchers/index.cjs +81 -0
  81. package/dist/watchers/index.d.cts +2 -0
  82. package/dist/watchers/index.d.ts +2 -0
  83. package/dist/watchers/index.js +69 -0
  84. package/package.json +8 -6
  85. package/dist/ui/assets/QueriesContainer-CAAsjjW5.js +0 -2
  86. package/dist/ui/assets/QueryTable-BcrtUssT.js +0 -1
  87. package/dist/ui/assets/RequestDetails-C2DZBu5H.js +0 -1
  88. package/dist/ui/assets/RequestsContainer-DK3hQVz9.js +0 -2
  89. package/dist/ui/assets/RequetsTable-DgP8p60b.js +0 -1
  90. package/dist/ui/assets/TabbedDataViewer-cBDdPwIz.js +0 -1
  91. package/dist/ui/assets/index-DzNHqeKh.css +0 -1
  92. package/dist/ui/assets/useLensApi-DG6atd6d.js +0 -1
  93. package/dist/ui/assets/useQueries-C8mDDDc6.js +0 -1
package/dist/index.js CHANGED
@@ -51,6 +51,8 @@ var getUiConfig = () => {
51
51
  var WatcherTypeEnum = /* @__PURE__ */ ((WatcherTypeEnum2) => {
52
52
  WatcherTypeEnum2["REQUEST"] = "request";
53
53
  WatcherTypeEnum2["QUERY"] = "query";
54
+ WatcherTypeEnum2["CACHE"] = "cache";
55
+ WatcherTypeEnum2["EXCEPTION"] = "exception";
54
56
  return WatcherTypeEnum2;
55
57
  })(WatcherTypeEnum || {});
56
58
 
@@ -61,14 +63,30 @@ var ApiController = class {
61
63
  await getStore().getAllRequests(this.extractPaginationParams(qs))
62
64
  );
63
65
  }
64
- static async getRequest({
65
- params
66
- }) {
66
+ static async getRequest({ params }) {
67
67
  const request = await getStore().find("request" /* REQUEST */, params.id);
68
68
  if (!request) {
69
69
  return this.notFoundResponse();
70
70
  }
71
- return this.resourceResponse(request);
71
+ const queries = await getStore().allByRequestId(
72
+ request.id,
73
+ "query" /* QUERY */
74
+ );
75
+ const cacheEntries = await getStore().allByRequestId(
76
+ request.id,
77
+ "cache" /* CACHE */
78
+ );
79
+ const exceptions = await getStore().allByRequestId(
80
+ request.id,
81
+ "exception" /* EXCEPTION */,
82
+ false
83
+ );
84
+ return this.resourceResponse({
85
+ request,
86
+ queries,
87
+ cacheEntries,
88
+ exceptions
89
+ });
72
90
  }
73
91
  static async getQueries({
74
92
  qs
@@ -87,6 +105,33 @@ var ApiController = class {
87
105
  }
88
106
  return this.resourceResponse(query);
89
107
  }
108
+ static async getCacheEntries({ qs }) {
109
+ return this.paginatedResponse(
110
+ await getStore().getAllCacheEntries(this.extractPaginationParams(qs))
111
+ );
112
+ }
113
+ static async getCacheEntry({ params }) {
114
+ const cacheEntry = await getStore().find("cache" /* CACHE */, params.id);
115
+ if (!cacheEntry) {
116
+ return this.notFoundResponse();
117
+ }
118
+ return this.resourceResponse(cacheEntry);
119
+ }
120
+ static async getExceptions({ qs }) {
121
+ return this.paginatedResponse(
122
+ await getStore().getAllExceptions(this.extractPaginationParams(qs))
123
+ );
124
+ }
125
+ static async getException({ params }) {
126
+ const exception = await getStore().find(
127
+ "exception" /* EXCEPTION */,
128
+ params.id
129
+ );
130
+ if (!exception) {
131
+ return this.notFoundResponse();
132
+ }
133
+ return this.resourceResponse(exception);
134
+ }
90
135
  static async truncate() {
91
136
  await getStore().truncate();
92
137
  return this.baseResponse({}, 200, "All entries cleared");
@@ -138,12 +183,35 @@ import * as path2 from "path";
138
183
 
139
184
  // src/abstracts/store.ts
140
185
  var Store = class {
186
+ getAllExceptions(_paginationParams) {
187
+ return this.defaultMinimalPaginate();
188
+ }
189
+ stringifyData(data) {
190
+ if (typeof data === "string") {
191
+ return data;
192
+ }
193
+ try {
194
+ return JSON.stringify(data);
195
+ } catch (e) {
196
+ console.error(`Failed to stringify lens data: ${e}`);
197
+ }
198
+ }
199
+ defaultMinimalPaginate() {
200
+ return Promise.resolve({
201
+ data: [],
202
+ meta: {
203
+ currentPage: 0,
204
+ lastPage: 0,
205
+ total: 0
206
+ }
207
+ });
208
+ }
141
209
  };
142
210
 
143
211
  // src/stores/better_sqlite.ts
144
212
  import { randomUUID } from "crypto";
145
213
  import Database from "libsql";
146
- import { sqlDateTime } from "@lensjs/date";
214
+ import { nowISO } from "@lensjs/date";
147
215
  var TABLE_NAME = "lens_entries";
148
216
  var BetterSqliteStore = class extends Store {
149
217
  connection;
@@ -160,11 +228,11 @@ var BetterSqliteStore = class extends Store {
160
228
  `INSERT INTO ${TABLE_NAME} (id, data, type, created_at, lens_entry_id, minimal_data) values($id, $data, $type, $created_at, $lens_entry_id, $minimalData)`
161
229
  ).run({
162
230
  id: entry.id ?? randomUUID(),
163
- data: JSON.stringify(entry.data),
231
+ data: this.stringifyData(entry.data),
164
232
  type: entry.type,
165
- created_at: entry.timestamp ?? sqlDateTime(),
233
+ created_at: entry.timestamp ?? nowISO(),
166
234
  lens_entry_id: entry.requestId || null,
167
- minimalData: JSON.stringify(entry.minimal_data ?? {})
235
+ minimalData: this.stringifyData(entry.minimal_data ?? {})
168
236
  });
169
237
  }
170
238
  async getAllQueries(pagination) {
@@ -173,11 +241,17 @@ var BetterSqliteStore = class extends Store {
173
241
  async getAllRequests(pagination) {
174
242
  return await this.paginate("request" /* REQUEST */, pagination, false);
175
243
  }
176
- async allByRequestId(requestId, type) {
244
+ async getAllCacheEntries(pagination) {
245
+ return await this.paginate("cache" /* CACHE */, pagination);
246
+ }
247
+ async getAllExceptions(pagination) {
248
+ return await this.paginate("exception" /* EXCEPTION */, pagination, false);
249
+ }
250
+ async allByRequestId(requestId, type, includeFullData = true) {
177
251
  const rows = this.connection.prepare(
178
- `${this.getSelectedColumns()} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
252
+ `${this.getSelectedColumns(includeFullData)} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
179
253
  ).all({ type, requestId });
180
- return this.mapRows(rows);
254
+ return this.mapRows(rows, includeFullData);
181
255
  }
182
256
  async paginate(type, { page, perPage }, includeFullData = true) {
183
257
  const offset = (page - 1) * perPage;
@@ -225,8 +299,13 @@ var BetterSqliteStore = class extends Store {
225
299
  CREATE INDEX IF NOT EXISTS lens_entries_id_type_index
226
300
  ON ${TABLE_NAME} (id, type);
227
301
  `;
302
+ const lensEntryIdIndex = `
303
+ CREATE INDEX IF NOT EXISTS lens_entry_id_index
304
+ ON ${TABLE_NAME} (lens_entry_id);
305
+ `;
228
306
  this.connection.exec(createTable);
229
307
  this.connection.exec(createIndex);
308
+ this.connection.exec(lensEntryIdIndex);
230
309
  }
231
310
  mapRow(row, includeFullData = true) {
232
311
  let data = includeFullData ? JSON.parse(row.data) : {};
@@ -338,8 +417,8 @@ function stripBeforeAssetsPath(url) {
338
417
  const match = url.match(/assets.*/);
339
418
  return match ? match[0] : url;
340
419
  }
341
- function prepareIgnoredPaths(path3, ignoredPaths) {
342
- const normalizedPath = path3.replace(/^\/+|\/+$/g, "");
420
+ function prepareIgnoredPaths(path4, ignoredPaths) {
421
+ const normalizedPath = path4.replace(/^\/+|\/+$/g, "");
343
422
  ignoredPaths = [
344
423
  ...ignoredPaths,
345
424
  new RegExp(`^/?${normalizedPath}(/|$)`),
@@ -348,11 +427,11 @@ function prepareIgnoredPaths(path3, ignoredPaths) {
348
427
  ];
349
428
  return { ignoredPaths, normalizedPath };
350
429
  }
351
- function shouldIgnoreCurrentPath(path3, ignoredPaths, onlyPaths) {
430
+ function shouldIgnoreCurrentPath(path4, ignoredPaths, onlyPaths) {
352
431
  if (onlyPaths.length > 0) {
353
- return !onlyPaths.some((pattern) => pattern.test(path3));
432
+ return !onlyPaths.some((pattern) => pattern.test(path4));
354
433
  }
355
- return ignoredPaths.some((pattern) => pattern.test(path3));
434
+ return ignoredPaths.some((pattern) => pattern.test(path4));
356
435
  }
357
436
  function prettyHrTime(hrtime, verbose = false) {
358
437
  const seconds = hrtime[0];
@@ -434,6 +513,8 @@ var Lens = class {
434
513
  api: {
435
514
  requests: `/${config.basePath}/api/requests`,
436
515
  queries: `/${config.basePath}/api/queries`,
516
+ cache: `/${config.basePath}/api/cache`,
517
+ exceptions: `/${config.basePath}/api/exceptions`,
437
518
  truncate: `/${config.basePath}/api/truncate`
438
519
  }
439
520
  };
@@ -466,6 +547,26 @@ var Lens = class {
466
547
  path: `${basePath}/api/queries/:id`,
467
548
  handler: async (data) => await ApiController.getQuery(data)
468
549
  },
550
+ {
551
+ method: "GET",
552
+ path: `${basePath}/api/cache`,
553
+ handler: async (data) => await ApiController.getCacheEntries(data)
554
+ },
555
+ {
556
+ method: "GET",
557
+ path: `${basePath}/api/cache/:id`,
558
+ handler: async (data) => await ApiController.getCacheEntry(data)
559
+ },
560
+ {
561
+ method: "GET",
562
+ path: `${basePath}/api/exceptions`,
563
+ handler: async (data) => await ApiController.getExceptions(data)
564
+ },
565
+ {
566
+ method: "GET",
567
+ path: `${basePath}/api/exceptions/:id`,
568
+ handler: async (data) => await ApiController.getException(data)
569
+ },
469
570
  {
470
571
  method: "DELETE",
471
572
  path: `${basePath}/api/truncate`,
@@ -479,8 +580,8 @@ var Lens = class {
479
580
  await store.initialize();
480
581
  return store;
481
582
  }
482
- static normalizeDirName(path3) {
483
- return path3.replace(/(\/packages\/)[^/]+(?=\/dist)/, "$1core");
583
+ static normalizeDirName(path4) {
584
+ return path4.replace(/(\/packages\/)[^/]+(?=\/dist)/, "$1core");
484
585
  }
485
586
  };
486
587
 
@@ -524,6 +625,63 @@ var RequestWatcher = class extends Watcher {
524
625
  }
525
626
  };
526
627
 
628
+ // src/watchers/cache_watcher.ts
629
+ var CacheWatcher = class extends Watcher {
630
+ name = "cache" /* CACHE */;
631
+ async log(data) {
632
+ const payload = {
633
+ action: data.action,
634
+ data: this.normalizePayload(data),
635
+ requestId: data.requestId ?? "",
636
+ createdAt: data.createdAt
637
+ };
638
+ await getStore().save({
639
+ requestId: data.requestId ?? "",
640
+ type: this.name,
641
+ data: payload,
642
+ minimal_data: {
643
+ action: data.action,
644
+ key: payload.data.key,
645
+ createdAt: payload.createdAt
646
+ }
647
+ });
648
+ }
649
+ normalizePayload(data) {
650
+ let key = "";
651
+ let value = "";
652
+ if ("data" in data && typeof data.data === "object" && data.data !== null) {
653
+ if ("key" in data.data) {
654
+ key = String(data.data.key);
655
+ }
656
+ if ("value" in data.data) {
657
+ value = data.data.value;
658
+ }
659
+ } else if (typeof data.data === "string") {
660
+ value = data.data;
661
+ }
662
+ return { key, value };
663
+ }
664
+ };
665
+
666
+ // src/watchers/exception_watcher.ts
667
+ var ExceptionWatcher = class extends Watcher {
668
+ name = "exception" /* EXCEPTION */;
669
+ async log(payload) {
670
+ await getStore().save({
671
+ id: generateRandomUuid(),
672
+ type: "exception" /* EXCEPTION */,
673
+ requestId: payload.requestId,
674
+ timestamp: payload.createdAt,
675
+ data: payload,
676
+ minimal_data: {
677
+ name: payload.name,
678
+ message: payload.message,
679
+ createdAt: payload.createdAt
680
+ }
681
+ });
682
+ }
683
+ };
684
+
527
685
  // src/abstracts/adapter.ts
528
686
  var Adapter = class {
529
687
  watchers = [];
@@ -544,18 +702,132 @@ var Adapter = class {
544
702
  getWatchers() {
545
703
  return this.watchers;
546
704
  }
547
- shouldIgnorePath(path3) {
548
- return shouldIgnoreCurrentPath(path3, this.ignoredPaths, this.onlyPaths);
705
+ shouldIgnorePath(path4) {
706
+ return shouldIgnoreCurrentPath(path4, this.ignoredPaths, this.onlyPaths);
549
707
  }
550
708
  };
551
709
 
710
+ // src/utils/exception.ts
711
+ var exception_exports = {};
712
+ __export(exception_exports, {
713
+ cleanStack: () => cleanStack,
714
+ constructErrorObject: () => constructErrorObject,
715
+ extractCodeFrame: () => extractCodeFrame,
716
+ getFileInfo: () => getFileInfo,
717
+ getStackTrace: () => getStackTrace
718
+ });
719
+ import StackUtils from "stack-utils";
720
+ import path3 from "path";
721
+ import { existsSync, readFileSync } from "fs";
722
+ import { nowISO as nowISO2 } from "@lensjs/date";
723
+ var stackUtils = new StackUtils({
724
+ cwd: process.cwd(),
725
+ internals: StackUtils.nodeInternals()
726
+ });
727
+ function cleanStack(stack) {
728
+ if (!stack) return "";
729
+ return stackUtils.clean(stack);
730
+ }
731
+ function getFileInfo(stack) {
732
+ if (!stack) {
733
+ return { file: "", line: 0, column: 0, function: "" };
734
+ }
735
+ const firstLine = stack.split("\n")[1] ?? "";
736
+ const fileInfo = stackUtils.parseLine(firstLine) ?? {
737
+ file: "",
738
+ line: 0,
739
+ column: 0,
740
+ function: ""
741
+ };
742
+ return {
743
+ file: fileInfo.file ? path3.resolve(process.cwd(), fileInfo.file) : "",
744
+ line: fileInfo.line ?? 0,
745
+ column: fileInfo.column ?? 0,
746
+ function: fileInfo.function ?? ""
747
+ };
748
+ }
749
+ function getStackTrace(stack) {
750
+ if (!stack) return [];
751
+ return cleanStack(stack).split("\n").filter((frame) => Boolean(frame));
752
+ }
753
+ function extractCodeFrame({
754
+ file,
755
+ line,
756
+ column,
757
+ contextLines = 6
758
+ }) {
759
+ if (!file) return null;
760
+ const fullPath = path3.isAbsolute(file) ? file : path3.resolve(process.cwd(), file);
761
+ if (!existsSync(fullPath)) return null;
762
+ const fileContent = readFileSync(fullPath, "utf-8");
763
+ const lines = fileContent.split(/\r?\n/);
764
+ if (line < 1 || line > lines.length) return null;
765
+ const start = Math.max(0, line - 1 - contextLines);
766
+ const end = Math.min(lines.length, line - 1 + contextLines + 1);
767
+ const snippet = lines.slice(start, end);
768
+ const relativeLine = line - 1 - start;
769
+ const errorLine = lines[line - 1] ?? "";
770
+ return {
771
+ file: fullPath,
772
+ line,
773
+ column,
774
+ context: {
775
+ pre: snippet.slice(0, relativeLine),
776
+ error: errorLine,
777
+ post: snippet.slice(relativeLine + 1)
778
+ }
779
+ };
780
+ }
781
+ function constructErrorObject(err) {
782
+ const fileInfo = getFileInfo(err.stack);
783
+ const codeFrame = extractCodeFrame({
784
+ file: fileInfo.file,
785
+ line: fileInfo.line,
786
+ column: fileInfo.column
787
+ });
788
+ return {
789
+ name: err.name,
790
+ message: err.message,
791
+ createdAt: nowISO2(),
792
+ fileInfo: {
793
+ file: fileInfo.file,
794
+ function: fileInfo.function
795
+ },
796
+ cause: err.cause ?? null,
797
+ trace: getStackTrace(err.stack),
798
+ codeFrame,
799
+ originalStack: codeFrame === null ? cleanStack(err.stack) : null
800
+ };
801
+ }
802
+
552
803
  // src/utils/event_emitter.ts
553
804
  import Emittery from "emittery";
554
805
  var createEmittery = () => {
555
806
  return new Emittery();
556
807
  };
808
+ var lensEmitter = createEmittery();
809
+
810
+ // src/utils/async_context.ts
811
+ import { AsyncLocalStorage } from "async_hooks";
812
+ var lensContext = new AsyncLocalStorage();
813
+ var handleUncaughExceptions = (logger) => {
814
+ process.on("uncaughtExceptionMonitor", async (err) => {
815
+ await logger.log({
816
+ ...constructErrorObject(err),
817
+ requestId: lensContext.getStore()?.requestId
818
+ });
819
+ });
820
+ process.on("uncaughtException", async (err) => {
821
+ await logger.log({
822
+ ...constructErrorObject(err),
823
+ requestId: lensContext.getStore()?.requestId
824
+ });
825
+ });
826
+ };
557
827
  export {
558
828
  BetterSqliteStore,
829
+ CacheWatcher,
830
+ ExceptionWatcher,
559
831
  Lens,
560
832
  Adapter as LensAdapter,
561
833
  Store as LensStore,
@@ -565,5 +837,9 @@ export {
565
837
  WatcherTypeEnum,
566
838
  createEmittery,
567
839
  getStore as getLensStore,
840
+ handleUncaughExceptions,
841
+ lensContext,
842
+ lensEmitter,
843
+ exception_exports as lensExceptionUtils,
568
844
  utils_exports as lensUtils
569
845
  };
@@ -36,6 +36,29 @@ module.exports = __toCommonJS(better_sqlite_exports);
36
36
 
37
37
  // src/abstracts/store.ts
38
38
  var Store = class {
39
+ getAllExceptions(_paginationParams) {
40
+ return this.defaultMinimalPaginate();
41
+ }
42
+ stringifyData(data) {
43
+ if (typeof data === "string") {
44
+ return data;
45
+ }
46
+ try {
47
+ return JSON.stringify(data);
48
+ } catch (e) {
49
+ console.error(`Failed to stringify lens data: ${e}`);
50
+ }
51
+ }
52
+ defaultMinimalPaginate() {
53
+ return Promise.resolve({
54
+ data: [],
55
+ meta: {
56
+ currentPage: 0,
57
+ lastPage: 0,
58
+ total: 0
59
+ }
60
+ });
61
+ }
39
62
  };
40
63
 
41
64
  // src/stores/better_sqlite.ts
@@ -58,11 +81,11 @@ var BetterSqliteStore = class extends Store {
58
81
  `INSERT INTO ${TABLE_NAME} (id, data, type, created_at, lens_entry_id, minimal_data) values($id, $data, $type, $created_at, $lens_entry_id, $minimalData)`
59
82
  ).run({
60
83
  id: entry.id ?? (0, import_crypto.randomUUID)(),
61
- data: JSON.stringify(entry.data),
84
+ data: this.stringifyData(entry.data),
62
85
  type: entry.type,
63
- created_at: entry.timestamp ?? (0, import_date.sqlDateTime)(),
86
+ created_at: entry.timestamp ?? (0, import_date.nowISO)(),
64
87
  lens_entry_id: entry.requestId || null,
65
- minimalData: JSON.stringify(entry.minimal_data ?? {})
88
+ minimalData: this.stringifyData(entry.minimal_data ?? {})
66
89
  });
67
90
  }
68
91
  async getAllQueries(pagination) {
@@ -71,11 +94,17 @@ var BetterSqliteStore = class extends Store {
71
94
  async getAllRequests(pagination) {
72
95
  return await this.paginate("request" /* REQUEST */, pagination, false);
73
96
  }
74
- async allByRequestId(requestId, type) {
97
+ async getAllCacheEntries(pagination) {
98
+ return await this.paginate("cache" /* CACHE */, pagination);
99
+ }
100
+ async getAllExceptions(pagination) {
101
+ return await this.paginate("exception" /* EXCEPTION */, pagination, false);
102
+ }
103
+ async allByRequestId(requestId, type, includeFullData = true) {
75
104
  const rows = this.connection.prepare(
76
- `${this.getSelectedColumns()} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
105
+ `${this.getSelectedColumns(includeFullData)} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
77
106
  ).all({ type, requestId });
78
- return this.mapRows(rows);
107
+ return this.mapRows(rows, includeFullData);
79
108
  }
80
109
  async paginate(type, { page, perPage }, includeFullData = true) {
81
110
  const offset = (page - 1) * perPage;
@@ -123,8 +152,13 @@ var BetterSqliteStore = class extends Store {
123
152
  CREATE INDEX IF NOT EXISTS lens_entries_id_type_index
124
153
  ON ${TABLE_NAME} (id, type);
125
154
  `;
155
+ const lensEntryIdIndex = `
156
+ CREATE INDEX IF NOT EXISTS lens_entry_id_index
157
+ ON ${TABLE_NAME} (lens_entry_id);
158
+ `;
126
159
  this.connection.exec(createTable);
127
160
  this.connection.exec(createIndex);
161
+ this.connection.exec(lensEntryIdIndex);
128
162
  }
129
163
  mapRow(row, includeFullData = true) {
130
164
  let data = includeFullData ? JSON.parse(row.data) : {};
@@ -31,7 +31,23 @@ declare class BetterSqliteStore extends Store {
31
31
  };
32
32
  data: T;
33
33
  }>;
34
- allByRequestId(requestId: string, type: WatcherTypeEnum): Promise<LensEntry[]>;
34
+ getAllCacheEntries<T extends Omit<LensEntry, "data">[]>(pagination: PaginationParams): Promise<{
35
+ meta: {
36
+ total: number;
37
+ lastPage: number;
38
+ currentPage: number;
39
+ };
40
+ data: T;
41
+ }>;
42
+ getAllExceptions<T extends Omit<LensEntry, "data">[]>(pagination: PaginationParams): Promise<{
43
+ meta: {
44
+ total: number;
45
+ lastPage: number;
46
+ currentPage: number;
47
+ };
48
+ data: T;
49
+ }>;
50
+ allByRequestId(requestId: string, type: WatcherTypeEnum, includeFullData?: boolean): Promise<LensEntry[]>;
35
51
  paginate<T>(type: WatcherTypeEnum, { page, perPage }: PaginationParams, includeFullData?: boolean): Promise<{
36
52
  meta: {
37
53
  total: number;
@@ -31,7 +31,23 @@ declare class BetterSqliteStore extends Store {
31
31
  };
32
32
  data: T;
33
33
  }>;
34
- allByRequestId(requestId: string, type: WatcherTypeEnum): Promise<LensEntry[]>;
34
+ getAllCacheEntries<T extends Omit<LensEntry, "data">[]>(pagination: PaginationParams): Promise<{
35
+ meta: {
36
+ total: number;
37
+ lastPage: number;
38
+ currentPage: number;
39
+ };
40
+ data: T;
41
+ }>;
42
+ getAllExceptions<T extends Omit<LensEntry, "data">[]>(pagination: PaginationParams): Promise<{
43
+ meta: {
44
+ total: number;
45
+ lastPage: number;
46
+ currentPage: number;
47
+ };
48
+ data: T;
49
+ }>;
50
+ allByRequestId(requestId: string, type: WatcherTypeEnum, includeFullData?: boolean): Promise<LensEntry[]>;
35
51
  paginate<T>(type: WatcherTypeEnum, { page, perPage }: PaginationParams, includeFullData?: boolean): Promise<{
36
52
  meta: {
37
53
  total: number;
@@ -1,11 +1,34 @@
1
1
  // src/abstracts/store.ts
2
2
  var Store = class {
3
+ getAllExceptions(_paginationParams) {
4
+ return this.defaultMinimalPaginate();
5
+ }
6
+ stringifyData(data) {
7
+ if (typeof data === "string") {
8
+ return data;
9
+ }
10
+ try {
11
+ return JSON.stringify(data);
12
+ } catch (e) {
13
+ console.error(`Failed to stringify lens data: ${e}`);
14
+ }
15
+ }
16
+ defaultMinimalPaginate() {
17
+ return Promise.resolve({
18
+ data: [],
19
+ meta: {
20
+ currentPage: 0,
21
+ lastPage: 0,
22
+ total: 0
23
+ }
24
+ });
25
+ }
3
26
  };
4
27
 
5
28
  // src/stores/better_sqlite.ts
6
29
  import { randomUUID } from "crypto";
7
30
  import Database from "libsql";
8
- import { sqlDateTime } from "@lensjs/date";
31
+ import { nowISO } from "@lensjs/date";
9
32
  var TABLE_NAME = "lens_entries";
10
33
  var BetterSqliteStore = class extends Store {
11
34
  connection;
@@ -22,11 +45,11 @@ var BetterSqliteStore = class extends Store {
22
45
  `INSERT INTO ${TABLE_NAME} (id, data, type, created_at, lens_entry_id, minimal_data) values($id, $data, $type, $created_at, $lens_entry_id, $minimalData)`
23
46
  ).run({
24
47
  id: entry.id ?? randomUUID(),
25
- data: JSON.stringify(entry.data),
48
+ data: this.stringifyData(entry.data),
26
49
  type: entry.type,
27
- created_at: entry.timestamp ?? sqlDateTime(),
50
+ created_at: entry.timestamp ?? nowISO(),
28
51
  lens_entry_id: entry.requestId || null,
29
- minimalData: JSON.stringify(entry.minimal_data ?? {})
52
+ minimalData: this.stringifyData(entry.minimal_data ?? {})
30
53
  });
31
54
  }
32
55
  async getAllQueries(pagination) {
@@ -35,11 +58,17 @@ var BetterSqliteStore = class extends Store {
35
58
  async getAllRequests(pagination) {
36
59
  return await this.paginate("request" /* REQUEST */, pagination, false);
37
60
  }
38
- async allByRequestId(requestId, type) {
61
+ async getAllCacheEntries(pagination) {
62
+ return await this.paginate("cache" /* CACHE */, pagination);
63
+ }
64
+ async getAllExceptions(pagination) {
65
+ return await this.paginate("exception" /* EXCEPTION */, pagination, false);
66
+ }
67
+ async allByRequestId(requestId, type, includeFullData = true) {
39
68
  const rows = this.connection.prepare(
40
- `${this.getSelectedColumns()} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
69
+ `${this.getSelectedColumns(includeFullData)} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
41
70
  ).all({ type, requestId });
42
- return this.mapRows(rows);
71
+ return this.mapRows(rows, includeFullData);
43
72
  }
44
73
  async paginate(type, { page, perPage }, includeFullData = true) {
45
74
  const offset = (page - 1) * perPage;
@@ -87,8 +116,13 @@ var BetterSqliteStore = class extends Store {
87
116
  CREATE INDEX IF NOT EXISTS lens_entries_id_type_index
88
117
  ON ${TABLE_NAME} (id, type);
89
118
  `;
119
+ const lensEntryIdIndex = `
120
+ CREATE INDEX IF NOT EXISTS lens_entry_id_index
121
+ ON ${TABLE_NAME} (lens_entry_id);
122
+ `;
90
123
  this.connection.exec(createTable);
91
124
  this.connection.exec(createIndex);
125
+ this.connection.exec(lensEntryIdIndex);
92
126
  }
93
127
  mapRow(row, includeFullData = true) {
94
128
  let data = includeFullData ? JSON.parse(row.data) : {};