@merittdev/horus-lens 0.2.1 → 0.3.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.
package/dist/react.cjs CHANGED
@@ -28981,6 +28981,7 @@ var AssetRefSchema = external_exports.object({
28981
28981
  byteSize: external_exports.number().optional()
28982
28982
  });
28983
28983
  var ReportStatusSchema = external_exports.enum(["initiated", "submitted", "triaged", "linked", "resolved"]);
28984
+ var ReportTriggerSchema = external_exports.enum(["user", "api", "error"]);
28984
28985
  var ReportMetadataSchema = external_exports.object({
28985
28986
  comment: external_exports.string().optional(),
28986
28987
  annotations: external_exports.array(AnnotationSchema).default([]),
@@ -28991,6 +28992,13 @@ var ReportMetadataSchema = external_exports.object({
28991
28992
  /** Small inline tails so the report list can render without fetching assets. */
28992
28993
  consoleTail: external_exports.array(ConsoleEntrySchema).default([]),
28993
28994
  networkTail: external_exports.array(NetworkEntrySchema).default([]),
28995
+ /**
28996
+ * How the report was triggered. Optional + non-breaking: this schema is a
28997
+ * plain `z.object` (NOT `.strict()`), so a cloud running an older shared
28998
+ * schema silently strips this unknown key on parse rather than rejecting.
28999
+ * Absent → treat as `user`.
29000
+ */
29001
+ trigger: ReportTriggerSchema.optional(),
28994
29002
  sdk: external_exports.object({ name: external_exports.string(), version: external_exports.string() })
28995
29003
  });
28996
29004
  var ReportSchema = external_exports.object({
@@ -29075,7 +29083,7 @@ var ApiErrorSchema = external_exports.object({
29075
29083
 
29076
29084
  // ../core/dist/index.js
29077
29085
  var SDK_NAME = "@merittdev/horus-lens";
29078
- var SDK_VERSION = true ? "0.2.1" : "0.0.0-dev";
29086
+ var SDK_VERSION = true ? "0.3.0" : "0.0.0-dev";
29079
29087
  var DEFAULT_ENDPOINT = "https://api.horus.sh";
29080
29088
  var DEFAULT_REPLAY_WINDOW_MS = 15e3;
29081
29089
  var DEFAULT_MAX_CONSOLE_ENTRIES = 200;
@@ -29089,9 +29097,85 @@ var MAX_TARGET_TEXT_CHARS = 200;
29089
29097
  var SCREENSHOT_TIMEOUT_MS = 2e4;
29090
29098
  var SCREENSHOT_MAX_SCALE = 2;
29091
29099
  var SCREENSHOT_MAX_PIXELS = 25e5;
29100
+ var AUTO_CAPTURE_COOLDOWN_MS = 10 * 60 * 1e3;
29101
+ var AUTO_CAPTURE_SESSION_CAP = 5;
29092
29102
  var MAX_MANUAL_RECORDING_MS = 12e4;
29093
29103
  var MAX_MANUAL_RECORDING_EVENTS = 1e4;
29094
29104
  var LENS_OVERLAY_HOST_ID = "__lens_root__";
29105
+ function autoCaptureSignature(message) {
29106
+ return message.toLowerCase().replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/g, "<uuid>").replace(/\d+/g, "<n>").replace(/\s+/g, " ").trim();
29107
+ }
29108
+ function reasonToMessage(reason) {
29109
+ if (reason instanceof Error) return reason.message || String(reason);
29110
+ if (typeof reason === "string") return reason;
29111
+ try {
29112
+ const json2 = JSON.stringify(reason);
29113
+ if (json2 && json2 !== "{}") return json2;
29114
+ } catch {
29115
+ }
29116
+ return String(reason);
29117
+ }
29118
+ function isIgnored2(message, ignore) {
29119
+ for (const entry of ignore) {
29120
+ if (typeof entry === "string") {
29121
+ if (message.includes(entry)) return true;
29122
+ } else if (entry.test(message)) {
29123
+ return true;
29124
+ }
29125
+ }
29126
+ return false;
29127
+ }
29128
+ function startAutoCapture(client, options = {}) {
29129
+ if (typeof window === "undefined") return () => {
29130
+ };
29131
+ const sampleRate = options.sampleRate ?? 1;
29132
+ const ignore = options.ignore ?? [];
29133
+ const lastSeen = /* @__PURE__ */ new Map();
29134
+ let sessionCount = 0;
29135
+ let submitting = false;
29136
+ const consider = (rawMessage) => {
29137
+ if (submitting) return;
29138
+ if (!rawMessage) return;
29139
+ if (isIgnored2(rawMessage, ignore)) return;
29140
+ if (sampleRate <= 0) return;
29141
+ if (sampleRate < 1 && Math.random() >= sampleRate) return;
29142
+ const signature = autoCaptureSignature(rawMessage);
29143
+ const now = Date.now();
29144
+ const last = lastSeen.get(signature);
29145
+ if (last !== void 0 && now - last < AUTO_CAPTURE_COOLDOWN_MS) return;
29146
+ if (sessionCount >= AUTO_CAPTURE_SESSION_CAP) return;
29147
+ lastSeen.set(signature, now);
29148
+ sessionCount += 1;
29149
+ submitting = true;
29150
+ options.onCapture?.(signature);
29151
+ void Promise.resolve().then(() => client.submitReport({ trigger: "error", include: { screenshot: false } })).catch(() => {
29152
+ }).finally(() => {
29153
+ submitting = false;
29154
+ });
29155
+ };
29156
+ const onError = (event) => {
29157
+ try {
29158
+ const e = event;
29159
+ const error51 = e.error;
29160
+ const message = e.message || (error51 instanceof Error ? error51.message : error51 != null ? String(error51) : "");
29161
+ consider(message);
29162
+ } catch {
29163
+ }
29164
+ };
29165
+ const onRejection = (event) => {
29166
+ try {
29167
+ const e = event;
29168
+ consider(reasonToMessage(e.reason));
29169
+ } catch {
29170
+ }
29171
+ };
29172
+ window.addEventListener("error", onError);
29173
+ window.addEventListener("unhandledrejection", onRejection);
29174
+ return () => {
29175
+ window.removeEventListener("error", onError);
29176
+ window.removeEventListener("unhandledrejection", onRejection);
29177
+ };
29178
+ }
29095
29179
  var RingBuffer = class {
29096
29180
  constructor(capacity) {
29097
29181
  this.capacity = capacity;
@@ -29937,6 +30021,7 @@ var LensClient = class {
29937
30021
  replayWindowMs;
29938
30022
  debug;
29939
30023
  screenshotEnabled;
30024
+ autoCapture;
29940
30025
  beforeSend;
29941
30026
  app;
29942
30027
  consoleBuffer;
@@ -29951,6 +30036,7 @@ var LensClient = class {
29951
30036
  this.endpoint = (config2.endpoint ?? DEFAULT_ENDPOINT).replace(/\/+$/, "");
29952
30037
  this.debug = config2.debug ?? false;
29953
30038
  this.screenshotEnabled = config2.screenshot ?? true;
30039
+ this.autoCapture = config2.autoCapture;
29954
30040
  this.beforeSend = config2.beforeSend;
29955
30041
  this.app = config2.app ?? {};
29956
30042
  this.replayWindowMs = config2.replay === false ? null : config2.replay?.windowMs ?? DEFAULT_REPLAY_WINDOW_MS;
@@ -29979,6 +30065,15 @@ var LensClient = class {
29979
30065
  this.teardowns.push(installNetwork(this.networkBuffer, this.endpoint));
29980
30066
  this.teardowns.push(installErrors(this.errorBuffer));
29981
30067
  this.replay?.start();
30068
+ if (this.autoCapture?.errors) {
30069
+ this.teardowns.push(
30070
+ startAutoCapture(this, {
30071
+ sampleRate: this.autoCapture.sampleRate,
30072
+ ignore: this.autoCapture.ignore,
30073
+ onCapture: (signature) => this.warn(`auto-capture: submitting report for "${signature}"`)
30074
+ })
30075
+ );
30076
+ }
29982
30077
  }
29983
30078
  stop() {
29984
30079
  if (!this.started) return;
@@ -30039,6 +30134,7 @@ var LensClient = class {
30039
30134
  errors: wantErrors ? errorEntries : [],
30040
30135
  consoleTail: wantConsole ? consoleTail : [],
30041
30136
  networkTail: wantNetwork ? networkTail : [],
30137
+ trigger: input2.trigger ?? "user",
30042
30138
  sdk: { name: SDK_NAME, version: SDK_VERSION }
30043
30139
  };
30044
30140
  if (input2.comment !== void 0) metadata.comment = input2.comment;
@@ -32430,7 +32526,8 @@ var Overlay = class {
32430
32526
  excludeFromScreenshot: this.host,
32431
32527
  screenshotCrop,
32432
32528
  annotationComposite: composite,
32433
- include
32529
+ include,
32530
+ trigger: "user"
32434
32531
  });
32435
32532
  this.target = null;
32436
32533
  this.annotator.clear();
@@ -32664,7 +32761,7 @@ function useLens() {
32664
32761
  setApp: (app) => browser?.client.setApp(app),
32665
32762
  report: async (input2) => {
32666
32763
  if (!browser) return null;
32667
- return browser.client.submitReport({ comment: input2?.comment });
32764
+ return browser.client.submitReport({ comment: input2?.comment, trigger: "api" });
32668
32765
  }
32669
32766
  };
32670
32767
  }