@wtfalch/reporting 0.2.1 → 0.3.1

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.
package/dist/tables.d.ts CHANGED
@@ -1243,12 +1243,276 @@ export declare const reportingAnalyticsWeekly: import("drizzle-orm/pg-core").PgT
1243
1243
  };
1244
1244
  dialect: "pg";
1245
1245
  }>;
1246
+ /** One row per fingerprint; mirrored from migrations/0003_errors.sql. */
1247
+ export declare const reportingErrors: import("drizzle-orm/pg-core").PgTableWithColumns<{
1248
+ name: "reporting_errors";
1249
+ schema: undefined;
1250
+ columns: {
1251
+ fingerprint: import("drizzle-orm/pg-core").PgColumn<{
1252
+ name: "fingerprint";
1253
+ tableName: "reporting_errors";
1254
+ dataType: "string";
1255
+ columnType: "PgText";
1256
+ data: string;
1257
+ driverParam: string;
1258
+ notNull: true;
1259
+ hasDefault: false;
1260
+ isPrimaryKey: true;
1261
+ isAutoincrement: false;
1262
+ hasRuntimeDefault: false;
1263
+ enumValues: [string, ...string[]];
1264
+ baseColumn: never;
1265
+ identity: undefined;
1266
+ generated: undefined;
1267
+ }, {}, {}>;
1268
+ site: import("drizzle-orm/pg-core").PgColumn<{
1269
+ name: "site";
1270
+ tableName: "reporting_errors";
1271
+ dataType: "string";
1272
+ columnType: "PgText";
1273
+ data: string;
1274
+ driverParam: string;
1275
+ notNull: true;
1276
+ hasDefault: false;
1277
+ isPrimaryKey: false;
1278
+ isAutoincrement: false;
1279
+ hasRuntimeDefault: false;
1280
+ enumValues: [string, ...string[]];
1281
+ baseColumn: never;
1282
+ identity: undefined;
1283
+ generated: undefined;
1284
+ }, {}, {}>;
1285
+ kind: import("drizzle-orm/pg-core").PgColumn<{
1286
+ name: "kind";
1287
+ tableName: "reporting_errors";
1288
+ dataType: "string";
1289
+ columnType: "PgText";
1290
+ data: string;
1291
+ driverParam: string;
1292
+ notNull: true;
1293
+ hasDefault: false;
1294
+ isPrimaryKey: false;
1295
+ isAutoincrement: false;
1296
+ hasRuntimeDefault: false;
1297
+ enumValues: [string, ...string[]];
1298
+ baseColumn: never;
1299
+ identity: undefined;
1300
+ generated: undefined;
1301
+ }, {}, {}>;
1302
+ message: import("drizzle-orm/pg-core").PgColumn<{
1303
+ name: "message";
1304
+ tableName: "reporting_errors";
1305
+ dataType: "string";
1306
+ columnType: "PgText";
1307
+ data: string;
1308
+ driverParam: string;
1309
+ notNull: true;
1310
+ hasDefault: false;
1311
+ isPrimaryKey: false;
1312
+ isAutoincrement: false;
1313
+ hasRuntimeDefault: false;
1314
+ enumValues: [string, ...string[]];
1315
+ baseColumn: never;
1316
+ identity: undefined;
1317
+ generated: undefined;
1318
+ }, {}, {}>;
1319
+ stack: import("drizzle-orm/pg-core").PgColumn<{
1320
+ name: "stack";
1321
+ tableName: "reporting_errors";
1322
+ dataType: "string";
1323
+ columnType: "PgText";
1324
+ data: string;
1325
+ driverParam: string;
1326
+ notNull: false;
1327
+ hasDefault: false;
1328
+ isPrimaryKey: false;
1329
+ isAutoincrement: false;
1330
+ hasRuntimeDefault: false;
1331
+ enumValues: [string, ...string[]];
1332
+ baseColumn: never;
1333
+ identity: undefined;
1334
+ generated: undefined;
1335
+ }, {}, {}>;
1336
+ runtime: import("drizzle-orm/pg-core").PgColumn<{
1337
+ name: "runtime";
1338
+ tableName: "reporting_errors";
1339
+ dataType: "string";
1340
+ columnType: "PgText";
1341
+ data: string;
1342
+ driverParam: string;
1343
+ notNull: true;
1344
+ hasDefault: false;
1345
+ isPrimaryKey: false;
1346
+ isAutoincrement: false;
1347
+ hasRuntimeDefault: false;
1348
+ enumValues: [string, ...string[]];
1349
+ baseColumn: never;
1350
+ identity: undefined;
1351
+ generated: undefined;
1352
+ }, {}, {}>;
1353
+ release: import("drizzle-orm/pg-core").PgColumn<{
1354
+ name: "release";
1355
+ tableName: "reporting_errors";
1356
+ dataType: "string";
1357
+ columnType: "PgText";
1358
+ data: string;
1359
+ driverParam: string;
1360
+ notNull: false;
1361
+ hasDefault: false;
1362
+ isPrimaryKey: false;
1363
+ isAutoincrement: false;
1364
+ hasRuntimeDefault: false;
1365
+ enumValues: [string, ...string[]];
1366
+ baseColumn: never;
1367
+ identity: undefined;
1368
+ generated: undefined;
1369
+ }, {}, {}>;
1370
+ firstSeenAt: import("drizzle-orm/pg-core").PgColumn<{
1371
+ name: "first_seen_at";
1372
+ tableName: "reporting_errors";
1373
+ dataType: "date";
1374
+ columnType: "PgTimestamp";
1375
+ data: Date;
1376
+ driverParam: string;
1377
+ notNull: true;
1378
+ hasDefault: false;
1379
+ isPrimaryKey: false;
1380
+ isAutoincrement: false;
1381
+ hasRuntimeDefault: false;
1382
+ enumValues: undefined;
1383
+ baseColumn: never;
1384
+ identity: undefined;
1385
+ generated: undefined;
1386
+ }, {}, {}>;
1387
+ lastSeenAt: import("drizzle-orm/pg-core").PgColumn<{
1388
+ name: "last_seen_at";
1389
+ tableName: "reporting_errors";
1390
+ dataType: "date";
1391
+ columnType: "PgTimestamp";
1392
+ data: Date;
1393
+ driverParam: string;
1394
+ notNull: true;
1395
+ hasDefault: false;
1396
+ isPrimaryKey: false;
1397
+ isAutoincrement: false;
1398
+ hasRuntimeDefault: false;
1399
+ enumValues: undefined;
1400
+ baseColumn: never;
1401
+ identity: undefined;
1402
+ generated: undefined;
1403
+ }, {}, {}>;
1404
+ occurrences: import("drizzle-orm/pg-core").PgColumn<{
1405
+ name: "occurrences";
1406
+ tableName: "reporting_errors";
1407
+ dataType: "number";
1408
+ columnType: "PgBigInt53";
1409
+ data: number;
1410
+ driverParam: string | number;
1411
+ notNull: true;
1412
+ hasDefault: true;
1413
+ isPrimaryKey: false;
1414
+ isAutoincrement: false;
1415
+ hasRuntimeDefault: false;
1416
+ enumValues: undefined;
1417
+ baseColumn: never;
1418
+ identity: undefined;
1419
+ generated: undefined;
1420
+ }, {}, {}>;
1421
+ state: import("drizzle-orm/pg-core").PgColumn<{
1422
+ name: "state";
1423
+ tableName: "reporting_errors";
1424
+ dataType: "string";
1425
+ columnType: "PgText";
1426
+ data: string;
1427
+ driverParam: string;
1428
+ notNull: true;
1429
+ hasDefault: true;
1430
+ isPrimaryKey: false;
1431
+ isAutoincrement: false;
1432
+ hasRuntimeDefault: false;
1433
+ enumValues: [string, ...string[]];
1434
+ baseColumn: never;
1435
+ identity: undefined;
1436
+ generated: undefined;
1437
+ }, {}, {}>;
1438
+ resolvedAt: import("drizzle-orm/pg-core").PgColumn<{
1439
+ name: "resolved_at";
1440
+ tableName: "reporting_errors";
1441
+ dataType: "date";
1442
+ columnType: "PgTimestamp";
1443
+ data: Date;
1444
+ driverParam: string;
1445
+ notNull: false;
1446
+ hasDefault: false;
1447
+ isPrimaryKey: false;
1448
+ isAutoincrement: false;
1449
+ hasRuntimeDefault: false;
1450
+ enumValues: undefined;
1451
+ baseColumn: never;
1452
+ identity: undefined;
1453
+ generated: undefined;
1454
+ }, {}, {}>;
1455
+ resolvedBy: import("drizzle-orm/pg-core").PgColumn<{
1456
+ name: "resolved_by";
1457
+ tableName: "reporting_errors";
1458
+ dataType: "string";
1459
+ columnType: "PgText";
1460
+ data: string;
1461
+ driverParam: string;
1462
+ notNull: false;
1463
+ hasDefault: false;
1464
+ isPrimaryKey: false;
1465
+ isAutoincrement: false;
1466
+ hasRuntimeDefault: false;
1467
+ enumValues: [string, ...string[]];
1468
+ baseColumn: never;
1469
+ identity: undefined;
1470
+ generated: undefined;
1471
+ }, {}, {}>;
1472
+ tenantId: import("drizzle-orm/pg-core").PgColumn<{
1473
+ name: "tenant_id";
1474
+ tableName: "reporting_errors";
1475
+ dataType: "string";
1476
+ columnType: "PgUUID";
1477
+ data: string;
1478
+ driverParam: string;
1479
+ notNull: false;
1480
+ hasDefault: false;
1481
+ isPrimaryKey: false;
1482
+ isAutoincrement: false;
1483
+ hasRuntimeDefault: false;
1484
+ enumValues: undefined;
1485
+ baseColumn: never;
1486
+ identity: undefined;
1487
+ generated: undefined;
1488
+ }, {}, {}>;
1489
+ requestId: import("drizzle-orm/pg-core").PgColumn<{
1490
+ name: "request_id";
1491
+ tableName: "reporting_errors";
1492
+ dataType: "string";
1493
+ columnType: "PgText";
1494
+ data: string;
1495
+ driverParam: string;
1496
+ notNull: false;
1497
+ hasDefault: false;
1498
+ isPrimaryKey: false;
1499
+ isAutoincrement: false;
1500
+ hasRuntimeDefault: false;
1501
+ enumValues: [string, ...string[]];
1502
+ baseColumn: never;
1503
+ identity: undefined;
1504
+ generated: undefined;
1505
+ }, {}, {}>;
1506
+ };
1507
+ dialect: "pg";
1508
+ }>;
1246
1509
  export type ReportingEventRow = typeof reportingEvents.$inferSelect;
1247
1510
  export type ReportingAnalyticsRow = typeof reportingAnalytics.$inferSelect;
1248
1511
  export type ReportingAnalyticsDailyRow = typeof reportingAnalyticsDaily.$inferSelect;
1249
1512
  export type ReportingAnalyticsWeeklyRow = typeof reportingAnalyticsWeekly.$inferSelect;
1250
1513
  export type ReportingTaskRow = typeof reportingTasks.$inferSelect;
1251
1514
  export type ReportingSettingRow = typeof reportingSettings.$inferSelect;
1515
+ export type ReportingErrorRow = typeof reportingErrors.$inferSelect;
1252
1516
  export declare const tables: {
1253
1517
  events: import("drizzle-orm/pg-core").PgTableWithColumns<{
1254
1518
  name: "reporting_events";
@@ -2485,4 +2749,266 @@ export declare const tables: {
2485
2749
  };
2486
2750
  dialect: "pg";
2487
2751
  }>;
2752
+ errors: import("drizzle-orm/pg-core").PgTableWithColumns<{
2753
+ name: "reporting_errors";
2754
+ schema: undefined;
2755
+ columns: {
2756
+ fingerprint: import("drizzle-orm/pg-core").PgColumn<{
2757
+ name: "fingerprint";
2758
+ tableName: "reporting_errors";
2759
+ dataType: "string";
2760
+ columnType: "PgText";
2761
+ data: string;
2762
+ driverParam: string;
2763
+ notNull: true;
2764
+ hasDefault: false;
2765
+ isPrimaryKey: true;
2766
+ isAutoincrement: false;
2767
+ hasRuntimeDefault: false;
2768
+ enumValues: [string, ...string[]];
2769
+ baseColumn: never;
2770
+ identity: undefined;
2771
+ generated: undefined;
2772
+ }, {}, {}>;
2773
+ site: import("drizzle-orm/pg-core").PgColumn<{
2774
+ name: "site";
2775
+ tableName: "reporting_errors";
2776
+ dataType: "string";
2777
+ columnType: "PgText";
2778
+ data: string;
2779
+ driverParam: string;
2780
+ notNull: true;
2781
+ hasDefault: false;
2782
+ isPrimaryKey: false;
2783
+ isAutoincrement: false;
2784
+ hasRuntimeDefault: false;
2785
+ enumValues: [string, ...string[]];
2786
+ baseColumn: never;
2787
+ identity: undefined;
2788
+ generated: undefined;
2789
+ }, {}, {}>;
2790
+ kind: import("drizzle-orm/pg-core").PgColumn<{
2791
+ name: "kind";
2792
+ tableName: "reporting_errors";
2793
+ dataType: "string";
2794
+ columnType: "PgText";
2795
+ data: string;
2796
+ driverParam: string;
2797
+ notNull: true;
2798
+ hasDefault: false;
2799
+ isPrimaryKey: false;
2800
+ isAutoincrement: false;
2801
+ hasRuntimeDefault: false;
2802
+ enumValues: [string, ...string[]];
2803
+ baseColumn: never;
2804
+ identity: undefined;
2805
+ generated: undefined;
2806
+ }, {}, {}>;
2807
+ message: import("drizzle-orm/pg-core").PgColumn<{
2808
+ name: "message";
2809
+ tableName: "reporting_errors";
2810
+ dataType: "string";
2811
+ columnType: "PgText";
2812
+ data: string;
2813
+ driverParam: string;
2814
+ notNull: true;
2815
+ hasDefault: false;
2816
+ isPrimaryKey: false;
2817
+ isAutoincrement: false;
2818
+ hasRuntimeDefault: false;
2819
+ enumValues: [string, ...string[]];
2820
+ baseColumn: never;
2821
+ identity: undefined;
2822
+ generated: undefined;
2823
+ }, {}, {}>;
2824
+ stack: import("drizzle-orm/pg-core").PgColumn<{
2825
+ name: "stack";
2826
+ tableName: "reporting_errors";
2827
+ dataType: "string";
2828
+ columnType: "PgText";
2829
+ data: string;
2830
+ driverParam: string;
2831
+ notNull: false;
2832
+ hasDefault: false;
2833
+ isPrimaryKey: false;
2834
+ isAutoincrement: false;
2835
+ hasRuntimeDefault: false;
2836
+ enumValues: [string, ...string[]];
2837
+ baseColumn: never;
2838
+ identity: undefined;
2839
+ generated: undefined;
2840
+ }, {}, {}>;
2841
+ runtime: import("drizzle-orm/pg-core").PgColumn<{
2842
+ name: "runtime";
2843
+ tableName: "reporting_errors";
2844
+ dataType: "string";
2845
+ columnType: "PgText";
2846
+ data: string;
2847
+ driverParam: string;
2848
+ notNull: true;
2849
+ hasDefault: false;
2850
+ isPrimaryKey: false;
2851
+ isAutoincrement: false;
2852
+ hasRuntimeDefault: false;
2853
+ enumValues: [string, ...string[]];
2854
+ baseColumn: never;
2855
+ identity: undefined;
2856
+ generated: undefined;
2857
+ }, {}, {}>;
2858
+ release: import("drizzle-orm/pg-core").PgColumn<{
2859
+ name: "release";
2860
+ tableName: "reporting_errors";
2861
+ dataType: "string";
2862
+ columnType: "PgText";
2863
+ data: string;
2864
+ driverParam: string;
2865
+ notNull: false;
2866
+ hasDefault: false;
2867
+ isPrimaryKey: false;
2868
+ isAutoincrement: false;
2869
+ hasRuntimeDefault: false;
2870
+ enumValues: [string, ...string[]];
2871
+ baseColumn: never;
2872
+ identity: undefined;
2873
+ generated: undefined;
2874
+ }, {}, {}>;
2875
+ firstSeenAt: import("drizzle-orm/pg-core").PgColumn<{
2876
+ name: "first_seen_at";
2877
+ tableName: "reporting_errors";
2878
+ dataType: "date";
2879
+ columnType: "PgTimestamp";
2880
+ data: Date;
2881
+ driverParam: string;
2882
+ notNull: true;
2883
+ hasDefault: false;
2884
+ isPrimaryKey: false;
2885
+ isAutoincrement: false;
2886
+ hasRuntimeDefault: false;
2887
+ enumValues: undefined;
2888
+ baseColumn: never;
2889
+ identity: undefined;
2890
+ generated: undefined;
2891
+ }, {}, {}>;
2892
+ lastSeenAt: import("drizzle-orm/pg-core").PgColumn<{
2893
+ name: "last_seen_at";
2894
+ tableName: "reporting_errors";
2895
+ dataType: "date";
2896
+ columnType: "PgTimestamp";
2897
+ data: Date;
2898
+ driverParam: string;
2899
+ notNull: true;
2900
+ hasDefault: false;
2901
+ isPrimaryKey: false;
2902
+ isAutoincrement: false;
2903
+ hasRuntimeDefault: false;
2904
+ enumValues: undefined;
2905
+ baseColumn: never;
2906
+ identity: undefined;
2907
+ generated: undefined;
2908
+ }, {}, {}>;
2909
+ occurrences: import("drizzle-orm/pg-core").PgColumn<{
2910
+ name: "occurrences";
2911
+ tableName: "reporting_errors";
2912
+ dataType: "number";
2913
+ columnType: "PgBigInt53";
2914
+ data: number;
2915
+ driverParam: string | number;
2916
+ notNull: true;
2917
+ hasDefault: true;
2918
+ isPrimaryKey: false;
2919
+ isAutoincrement: false;
2920
+ hasRuntimeDefault: false;
2921
+ enumValues: undefined;
2922
+ baseColumn: never;
2923
+ identity: undefined;
2924
+ generated: undefined;
2925
+ }, {}, {}>;
2926
+ state: import("drizzle-orm/pg-core").PgColumn<{
2927
+ name: "state";
2928
+ tableName: "reporting_errors";
2929
+ dataType: "string";
2930
+ columnType: "PgText";
2931
+ data: string;
2932
+ driverParam: string;
2933
+ notNull: true;
2934
+ hasDefault: true;
2935
+ isPrimaryKey: false;
2936
+ isAutoincrement: false;
2937
+ hasRuntimeDefault: false;
2938
+ enumValues: [string, ...string[]];
2939
+ baseColumn: never;
2940
+ identity: undefined;
2941
+ generated: undefined;
2942
+ }, {}, {}>;
2943
+ resolvedAt: import("drizzle-orm/pg-core").PgColumn<{
2944
+ name: "resolved_at";
2945
+ tableName: "reporting_errors";
2946
+ dataType: "date";
2947
+ columnType: "PgTimestamp";
2948
+ data: Date;
2949
+ driverParam: string;
2950
+ notNull: false;
2951
+ hasDefault: false;
2952
+ isPrimaryKey: false;
2953
+ isAutoincrement: false;
2954
+ hasRuntimeDefault: false;
2955
+ enumValues: undefined;
2956
+ baseColumn: never;
2957
+ identity: undefined;
2958
+ generated: undefined;
2959
+ }, {}, {}>;
2960
+ resolvedBy: import("drizzle-orm/pg-core").PgColumn<{
2961
+ name: "resolved_by";
2962
+ tableName: "reporting_errors";
2963
+ dataType: "string";
2964
+ columnType: "PgText";
2965
+ data: string;
2966
+ driverParam: string;
2967
+ notNull: false;
2968
+ hasDefault: false;
2969
+ isPrimaryKey: false;
2970
+ isAutoincrement: false;
2971
+ hasRuntimeDefault: false;
2972
+ enumValues: [string, ...string[]];
2973
+ baseColumn: never;
2974
+ identity: undefined;
2975
+ generated: undefined;
2976
+ }, {}, {}>;
2977
+ tenantId: import("drizzle-orm/pg-core").PgColumn<{
2978
+ name: "tenant_id";
2979
+ tableName: "reporting_errors";
2980
+ dataType: "string";
2981
+ columnType: "PgUUID";
2982
+ data: string;
2983
+ driverParam: string;
2984
+ notNull: false;
2985
+ hasDefault: false;
2986
+ isPrimaryKey: false;
2987
+ isAutoincrement: false;
2988
+ hasRuntimeDefault: false;
2989
+ enumValues: undefined;
2990
+ baseColumn: never;
2991
+ identity: undefined;
2992
+ generated: undefined;
2993
+ }, {}, {}>;
2994
+ requestId: import("drizzle-orm/pg-core").PgColumn<{
2995
+ name: "request_id";
2996
+ tableName: "reporting_errors";
2997
+ dataType: "string";
2998
+ columnType: "PgText";
2999
+ data: string;
3000
+ driverParam: string;
3001
+ notNull: false;
3002
+ hasDefault: false;
3003
+ isPrimaryKey: false;
3004
+ isAutoincrement: false;
3005
+ hasRuntimeDefault: false;
3006
+ enumValues: [string, ...string[]];
3007
+ baseColumn: never;
3008
+ identity: undefined;
3009
+ generated: undefined;
3010
+ }, {}, {}>;
3011
+ };
3012
+ dialect: "pg";
3013
+ }>;
2488
3014
  };
package/dist/tables.js CHANGED
@@ -138,6 +138,29 @@ export const reportingAnalyticsWeekly = pgTable('reporting_analytics_weekly', {
138
138
  columns: [t.week, t.site, t.tenantKey],
139
139
  }),
140
140
  ]);
141
+ /** One row per fingerprint; mirrored from migrations/0003_errors.sql. */
142
+ export const reportingErrors = pgTable('reporting_errors', {
143
+ fingerprint: text('fingerprint').primaryKey(),
144
+ site: text('site').notNull(),
145
+ kind: text('kind').notNull(),
146
+ message: text('message').notNull(),
147
+ stack: text('stack'),
148
+ runtime: text('runtime').notNull(),
149
+ release: text('release'),
150
+ firstSeenAt: timestamp('first_seen_at', { withTimezone: true }).notNull(),
151
+ lastSeenAt: timestamp('last_seen_at', { withTimezone: true }).notNull(),
152
+ occurrences: bigint('occurrences', { mode: 'number' }).notNull().default(1),
153
+ state: text('state').notNull().default('open'),
154
+ resolvedAt: timestamp('resolved_at', { withTimezone: true }),
155
+ resolvedBy: text('resolved_by'),
156
+ tenantId: uuid('tenant_id'),
157
+ requestId: text('request_id'),
158
+ }, (t) => [
159
+ index('reporting_errors_site_open_idx')
160
+ .on(t.site, t.lastSeenAt.desc())
161
+ .where(sql `${t.state} = 'open'`),
162
+ index('reporting_errors_state_idx').on(t.state, t.lastSeenAt.desc()),
163
+ ]);
141
164
  export const tables = {
142
165
  events: reportingEvents,
143
166
  tasks: reportingTasks,
@@ -145,4 +168,5 @@ export const tables = {
145
168
  analytics: reportingAnalytics,
146
169
  analyticsDaily: reportingAnalyticsDaily,
147
170
  analyticsWeekly: reportingAnalyticsWeekly,
171
+ errors: reportingErrors,
148
172
  };
package/dist/types.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
2
2
  import type { RecentEvent, RecentOptions, SeriesOptions, SeriesPoint, WeeklyPoint } from './analytics/reader.js';
3
3
  import type { Device } from './analytics/schema.js';
4
- import type { Actor, EventInput, FlatData, Level } from './schema.js';
5
- import type { ReportingEventRow, tables } from './tables.js';
4
+ import type { Actor, ErrorRuntime, ErrorState, EventInput, FlatData, Level } from './schema.js';
5
+ import type { ReportingErrorRow, ReportingEventRow, tables } from './tables.js';
6
6
  /**
7
7
  * The host's drizzle handle, whatever driver it runs on. postgres-js in the
8
8
  * apps, PGlite in this package's own tests; the queries here use nothing
@@ -82,6 +82,35 @@ export interface EventsPage {
82
82
  readonly id: number;
83
83
  } | null;
84
84
  }
85
+ export interface ErrorsPageOptions {
86
+ readonly limit?: number;
87
+ readonly after?: {
88
+ readonly lastSeenAt: Date;
89
+ readonly fingerprint: string;
90
+ };
91
+ readonly site?: string;
92
+ readonly state?: ErrorState;
93
+ readonly runtime?: ErrorRuntime;
94
+ }
95
+ export interface ErrorsPage {
96
+ readonly items: readonly ReportingErrorRow[];
97
+ readonly next: {
98
+ readonly lastSeenAt: Date;
99
+ readonly fingerprint: string;
100
+ } | null;
101
+ }
102
+ /**
103
+ * What `captureError` knows about an exception's surroundings; every field
104
+ * is optional because a boot-time crash has none of them.
105
+ */
106
+ export interface CaptureContext {
107
+ readonly runtime?: ErrorRuntime;
108
+ readonly tenantId?: string | null;
109
+ readonly requestId?: string | null;
110
+ readonly release?: string | null;
111
+ /** Overrides `errorKind(error)` when the caller already knows the class name better than the thrown value can say — a JSON-serialised browser report, say. */
112
+ readonly kind?: string;
113
+ }
85
114
  export interface Stats {
86
115
  readonly queued: number;
87
116
  readonly dropped: number;
@@ -121,6 +150,8 @@ export interface Reporting {
121
150
  event(input: EventInput): void;
122
151
  /** An `alert.<check>` row at level `alert`, then the host's `onAlert`. */
123
152
  alert(finding: AlertFinding): void;
153
+ /** An uncaught exception, redacted and fingerprinted (./errors/capture.js). Never throws. */
154
+ captureError(error: unknown, context?: CaptureContext): void;
124
155
  /** Drain the queue now. Bounded by `deadlineMs` (default 5,000). Never throws. */
125
156
  flush(opts?: {
126
157
  deadlineMs?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wtfalch/reporting",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "The estate's operational event log and housekeeping tick: a writer that never fails a request, a claim protocol that needs no scheduler, and the readers an operator opens. Per-app Postgres, host-supplied logger, framework-neutral core with a Next entry.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,6 +42,10 @@
42
42
  "types": "./dist/react/charts.d.ts",
43
43
  "default": "./dist/react/charts.js"
44
44
  },
45
+ "./react/errors": {
46
+ "types": "./dist/react/errors.d.ts",
47
+ "default": "./dist/react/errors.js"
48
+ },
45
49
  "./migrations/*.sql": "./dist/migrations/*.sql",
46
50
  "./package.json": "./package.json"
47
51
  },