@diegotsi/flint-react 2.1.3 → 2.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/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  // src/FlintModal.tsx
2
+ import {
3
+ Flint
4
+ } from "@diegotsi/flint-core";
2
5
  import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
3
6
  import { useTranslation } from "react-i18next";
4
7
 
@@ -196,8 +199,6 @@ function injectKeyframes() {
196
199
  document.head.appendChild(s);
197
200
  }
198
201
  function FlintModal({
199
- projectKey,
200
- serverUrl,
201
202
  user,
202
203
  meta,
203
204
  theme,
@@ -217,6 +218,8 @@ function FlintModal({
217
218
  onSuccess,
218
219
  onError
219
220
  }) {
221
+ const config = Flint.getConfig();
222
+ const { projectKey, serverUrl } = config;
220
223
  const { t } = useTranslation();
221
224
  const colors = resolveTheme(theme);
222
225
  const isDark = theme === "dark";
@@ -286,7 +289,8 @@ function FlintModal({
286
289
  severity: isText ? "P3" : severity,
287
290
  url: window.location.href,
288
291
  meta: collectedMeta,
289
- label: isText ? "TEXT" : void 0
292
+ label: isText ? "TEXT" : void 0,
293
+ source: isText ? "text_issue" : "widget"
290
294
  };
291
295
  if (onBeforeSubmit) {
292
296
  const proceed = await onBeforeSubmit(payload);
@@ -1142,25 +1146,13 @@ function CheckIcon({ size = 20 }) {
1142
1146
  }
1143
1147
 
1144
1148
  // src/FlintWidget.tsx
1145
- import { Flint as Flint2 } from "@diegotsi/flint-core";
1149
+ import { Flint as Flint3 } from "@diegotsi/flint-core";
1146
1150
  import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
1147
1151
  import { I18nextProvider, useTranslation as useTranslation2 } from "react-i18next";
1148
1152
 
1149
- // src/collectors/console.ts
1150
- import { createConsoleCollector } from "@diegotsi/flint-core";
1151
-
1152
1153
  // src/collectors/environment.ts
1153
1154
  import { collectEnvironment } from "@diegotsi/flint-core";
1154
1155
 
1155
- // src/collectors/formErrors.ts
1156
- import { createFormErrorCollector } from "@diegotsi/flint-core";
1157
-
1158
- // src/collectors/frustration.ts
1159
- import { createFrustrationCollector } from "@diegotsi/flint-core";
1160
-
1161
- // src/collectors/network.ts
1162
- import { createNetworkCollector } from "@diegotsi/flint-core";
1163
-
1164
1156
  // src/i18n/index.ts
1165
1157
  import { createInstance } from "i18next";
1166
1158
  import { initReactI18next } from "react-i18next";
@@ -1213,14 +1205,13 @@ var i18n_default = widgetI18n;
1213
1205
  // src/store.ts
1214
1206
  import { getSnapshot, subscribe } from "@diegotsi/flint-core";
1215
1207
  import { useSyncExternalStore } from "react";
1216
- import { _setFormErrorCollector, Flint, flint } from "@diegotsi/flint-core";
1208
+ import { _setFormErrorCollector, Flint as Flint2 } from "@diegotsi/flint-core";
1217
1209
  function useFlintStore() {
1218
1210
  return useSyncExternalStore(subscribe, getSnapshot);
1219
1211
  }
1220
1212
 
1221
1213
  // src/FlintWidget.tsx
1222
1214
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1223
- var REPLAY_WINDOW_MS = 6e4;
1224
1215
  function FlintWidget(props) {
1225
1216
  const { locale = "en-US" } = props;
1226
1217
  useEffect3(() => {
@@ -1229,52 +1220,24 @@ function FlintWidget(props) {
1229
1220
  return /* @__PURE__ */ jsx3(I18nextProvider, { i18n: i18n_default, children: /* @__PURE__ */ jsx3(WidgetContent, { ...props }) });
1230
1221
  }
1231
1222
  function WidgetContent({
1232
- projectKey,
1233
- serverUrl,
1234
- user,
1235
- meta,
1236
- extraFields,
1237
1223
  buttonLabel,
1238
1224
  theme = "dark",
1239
1225
  zIndex = 9999,
1240
1226
  statusPageUrl,
1241
- datadogSite,
1242
- enableReplay = true,
1243
1227
  enableScreenshot = true,
1244
- enableConsole = true,
1245
- enableNetwork = true,
1246
1228
  enableTextIssues = true,
1247
- enableFormErrors = true,
1248
- enableFrustration = false,
1249
- autoReportFrustration = false,
1250
1229
  onBeforeSubmit,
1251
1230
  onSuccess,
1252
1231
  onError,
1253
1232
  onOpen,
1254
1233
  onClose
1255
1234
  }) {
1235
+ if (!Flint3.isInitialized()) {
1236
+ throw new Error("[Flint] Call Flint.init() before mounting <FlintWidget />.");
1237
+ }
1238
+ const config = Flint3.getConfig();
1256
1239
  const globalState = useFlintStore();
1257
- const resolvedUser = user ?? globalState.user;
1258
- const resolvedSessionReplay = extraFields?.sessionReplay ?? globalState.sessionReplay;
1259
- const getExternalReplayUrl = () => {
1260
- const src = resolvedSessionReplay;
1261
- const explicit = typeof src === "function" ? src() : src;
1262
- if (explicit) return explicit;
1263
- if (datadogSite) {
1264
- try {
1265
- const ddRum = window.DD_RUM;
1266
- const ctx = ddRum?.getInternalContext?.();
1267
- if (ctx?.session_id) {
1268
- const ts = bugTimestamp.current || Date.now();
1269
- const fromTs = ts - 3e4;
1270
- const toTs = ts + 5e3;
1271
- return `https://${datadogSite}/rum/replay/sessions/${ctx.session_id}?from_ts=${fromTs}&to_ts=${toTs}&tab=replay&live=false`;
1272
- }
1273
- } catch {
1274
- }
1275
- }
1276
- return void 0;
1277
- };
1240
+ const resolvedUser = globalState.user ?? config.user;
1278
1241
  const { t } = useTranslation2();
1279
1242
  const bugTimestamp = useRef3(0);
1280
1243
  const [open, setOpen] = useState3(false);
@@ -1324,92 +1287,11 @@ function WidgetContent({
1324
1287
  setOpen(true);
1325
1288
  onOpen?.();
1326
1289
  };
1327
- const globalInit = Flint2.isInitialized();
1328
- const global = Flint2.getInstance();
1329
- const consoleCollector = useRef3(null);
1330
- const networkCollector = useRef3(null);
1331
- const replayEvents = useRef3([]);
1332
- const stopReplay = useRef3(null);
1333
- const formErrorCollector = useRef3(null);
1334
- const frustrationCollector = useRef3(null);
1335
- if (!globalInit) {
1336
- if (enableConsole && !consoleCollector.current) {
1337
- consoleCollector.current = createConsoleCollector();
1338
- consoleCollector.current.start();
1339
- }
1340
- if (enableNetwork && !networkCollector.current) {
1341
- const flintHost = (() => {
1342
- try {
1343
- return new URL(serverUrl).hostname;
1344
- } catch {
1345
- return "";
1346
- }
1347
- })();
1348
- networkCollector.current = createNetworkCollector(flintHost ? [flintHost] : []);
1349
- networkCollector.current.start();
1350
- }
1351
- if (enableFormErrors && !formErrorCollector.current) {
1352
- formErrorCollector.current = createFormErrorCollector();
1353
- formErrorCollector.current.start();
1354
- _setFormErrorCollector(formErrorCollector.current);
1355
- }
1356
- if (enableFrustration && !frustrationCollector.current) {
1357
- frustrationCollector.current = createFrustrationCollector();
1358
- frustrationCollector.current.start();
1359
- }
1290
+ const didInjectReplay = useRef3(false);
1291
+ if (!didInjectReplay.current && config.enableReplay && !Flint3.getInstance()?.stopReplay) {
1292
+ didInjectReplay.current = true;
1360
1293
  }
1361
- useEffect3(() => {
1362
- if (globalInit) return;
1363
- let cancelled = false;
1364
- if (enableReplay) {
1365
- import("rrweb").then(({ record }) => {
1366
- if (cancelled) return;
1367
- const stopFn = record({
1368
- emit(event) {
1369
- replayEvents.current.push(event);
1370
- const cutoff = Date.now() - REPLAY_WINDOW_MS;
1371
- while (replayEvents.current.length > 0 && replayEvents.current[0].timestamp < cutoff) {
1372
- replayEvents.current.shift();
1373
- }
1374
- }
1375
- });
1376
- stopReplay.current = stopFn ?? null;
1377
- });
1378
- }
1379
- return () => {
1380
- cancelled = true;
1381
- consoleCollector.current?.stop();
1382
- networkCollector.current?.stop();
1383
- formErrorCollector.current?.stop();
1384
- _setFormErrorCollector(null);
1385
- frustrationCollector.current?.stop();
1386
- stopReplay.current?.();
1387
- };
1388
- }, [enableReplay, globalInit]);
1389
- useEffect3(() => {
1390
- if (globalInit) return;
1391
- if (!enableFrustration || !autoReportFrustration || !frustrationCollector.current) return;
1392
- const unsubscribe = frustrationCollector.current.onFrustration(async (event) => {
1393
- const user2 = resolvedUser;
1394
- await submitReport(serverUrl, projectKey, {
1395
- reporterId: user2?.id ?? "anonymous",
1396
- reporterName: user2?.name ?? "Anonymous",
1397
- reporterEmail: user2?.email,
1398
- description: `[Auto-detected] ${event.type.replace(/_/g, " ")}: ${event.details}`,
1399
- severity: event.type === "error_loop" ? "P1" : event.type === "rage_click" ? "P2" : "P3",
1400
- url: event.url,
1401
- meta: {
1402
- environment: collectEnvironment(),
1403
- consoleLogs: consoleCollector.current?.getEntries() ?? [],
1404
- networkErrors: networkCollector.current?.getEntries() ?? [],
1405
- formErrors: formErrorCollector.current?.getEntries() ?? [],
1406
- frustrationEvent: event
1407
- }
1408
- }).catch(() => {
1409
- });
1410
- });
1411
- return unsubscribe;
1412
- }, [enableFrustration, autoReportFrustration, globalInit, projectKey, resolvedUser, serverUrl]);
1294
+ const global = Flint3.getInstance();
1413
1295
  const label = buttonLabel ?? t("buttonLabel");
1414
1296
  return /* @__PURE__ */ jsxs3(Fragment2, { children: [
1415
1297
  /* @__PURE__ */ jsxs3(
@@ -1496,10 +1378,8 @@ function WidgetContent({
1496
1378
  open && /* @__PURE__ */ jsx3(
1497
1379
  FlintModal,
1498
1380
  {
1499
- projectKey,
1500
- serverUrl,
1501
1381
  user: resolvedUser,
1502
- meta,
1382
+ meta: config.meta,
1503
1383
  theme,
1504
1384
  zIndex,
1505
1385
  onClose: () => {
@@ -1508,11 +1388,11 @@ function WidgetContent({
1508
1388
  pendingSelection.current = "";
1509
1389
  },
1510
1390
  getEnvironment: collectEnvironment,
1511
- getConsoleLogs: () => globalInit ? global?.console?.getEntries() ?? [] : consoleCollector.current?.getEntries() ?? [],
1512
- getNetworkErrors: () => globalInit ? global?.network?.getEntries() ?? [] : networkCollector.current?.getEntries() ?? [],
1513
- getFormErrors: () => globalInit ? global?.formErrors?.getEntries() ?? [] : formErrorCollector.current?.getEntries() ?? [],
1514
- getReplayEvents: () => globalInit ? Flint2.getReplayEvents() : [...replayEvents.current],
1515
- getExternalReplayUrl,
1391
+ getConsoleLogs: () => global?.console?.getEntries() ?? [],
1392
+ getNetworkErrors: () => global?.network?.getEntries() ?? [],
1393
+ getFormErrors: () => global?.formErrors?.getEntries() ?? [],
1394
+ getReplayEvents: () => Flint3.getReplayEvents(),
1395
+ getExternalReplayUrl: () => Flint3.getExternalReplayUrl(),
1516
1396
  initialSelection: pendingSelection.current,
1517
1397
  enableScreenshot,
1518
1398
  enableTextIssues,
@@ -1564,9 +1444,8 @@ function SparkIcon2() {
1564
1444
  );
1565
1445
  }
1566
1446
  export {
1567
- Flint,
1447
+ Flint2 as Flint,
1568
1448
  FlintModal,
1569
- FlintWidget,
1570
- flint
1449
+ FlintWidget
1571
1450
  };
1572
1451
  //# sourceMappingURL=index.js.map