@djangocfg/monitor 2.1.228 → 2.1.230

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/monitor",
3
- "version": "2.1.228",
3
+ "version": "2.1.230",
4
4
  "description": "Browser error and event monitoring SDK for django-cfg backends. Captures JS errors, network failures, console logs, and performance metrics.",
5
5
  "keywords": [
6
6
  "django",
@@ -83,7 +83,7 @@
83
83
  }
84
84
  },
85
85
  "devDependencies": {
86
- "@djangocfg/typescript-config": "^2.1.228",
86
+ "@djangocfg/typescript-config": "^2.1.230",
87
87
  "p-retry": "^6.2.0",
88
88
  "@types/node": "^24.7.2",
89
89
  "@types/react": "^19.1.0",
@@ -0,0 +1,70 @@
1
+ 'use client'
2
+
3
+ /**
4
+ * useDebugMode — shared debug mode detection hook.
5
+ *
6
+ * Logic:
7
+ * - development: always true (no localStorage needed)
8
+ * - production:
9
+ * - ?debug=1 in URL → persist to localStorage, remove param from URL
10
+ * - localStorage.__debug_mode__ === '1' → true
11
+ * - otherwise → false
12
+ *
13
+ * @example
14
+ * const isDebug = useDebugMode()
15
+ */
16
+
17
+ import { useEffect, useState } from 'react'
18
+ import { isDevelopment } from '../utils/env'
19
+
20
+ const LS_KEY = '__debug_mode__'
21
+
22
+ function readFromStorage(): boolean {
23
+ try {
24
+ return localStorage.getItem(LS_KEY) === '1'
25
+ } catch {
26
+ return false
27
+ }
28
+ }
29
+
30
+ function persistToStorage(): void {
31
+ try {
32
+ localStorage.setItem(LS_KEY, '1')
33
+ } catch {
34
+ // ignore — private browsing or quota exceeded
35
+ }
36
+ }
37
+
38
+ function consumeDebugParam(): boolean {
39
+ if (typeof window === 'undefined') return false
40
+ const params = new URLSearchParams(window.location.search)
41
+ const value = params.get('debug')
42
+ if (!value) return false
43
+
44
+ persistToStorage()
45
+
46
+ params.delete('debug')
47
+ const newUrl = `${window.location.pathname}${params.toString() ? `?${params.toString()}` : ''}${window.location.hash}`
48
+ window.history.replaceState(null, '', newUrl)
49
+ return true
50
+ }
51
+
52
+ export function useDebugMode(): boolean {
53
+ // In development, always true — no side effects needed
54
+ if (isDevelopment) return true
55
+
56
+ // eslint-disable-next-line react-hooks/rules-of-hooks
57
+ const [isDebug, setIsDebug] = useState(false)
58
+
59
+ // eslint-disable-next-line react-hooks/rules-of-hooks
60
+ useEffect(() => {
61
+ const fromUrl = consumeDebugParam()
62
+ if (fromUrl) {
63
+ setIsDebug(true)
64
+ return
65
+ }
66
+ setIsDebug(readFromStorage())
67
+ }, [])
68
+
69
+ return isDebug
70
+ }
@@ -36,6 +36,8 @@ export type { MonitorProviderProps } from './MonitorProvider'
36
36
  export { initWindowMonitor } from './window'
37
37
  export type { WindowMonitorAPI } from './window'
38
38
  export { monitorStore } from './store'
39
+ export { useDebugMode } from './hooks/useDebugMode'
40
+ export { isDevelopment, isProduction } from './utils/env'
39
41
 
40
42
  let flushInterval: ReturnType<typeof setInterval> | null = null
41
43
  const cleanupFns: Array<() => void> = []
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Environment utilities.
3
+ *
4
+ * Use these constants instead of inline process.env.NODE_ENV checks.
5
+ * Webpack/esbuild replaces process.env.NODE_ENV statically at build time,
6
+ * so these are zero-cost — they tree-shake correctly in both client and server bundles.
7
+ */
8
+
9
+ /** True only in `next dev` / jest / vitest */
10
+ export const isDevelopment = process.env.NODE_ENV === 'development'
11
+
12
+ /** True in production builds and test environments */
13
+ export const isProduction = process.env.NODE_ENV !== 'development'