satyamark-react 0.0.12 β†’ 0.0.14

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/README.md CHANGED
@@ -2,53 +2,33 @@
2
2
 
3
3
  > Real-time content verification library for React applications
4
4
 
5
- SatyaMark is a React library that provides real-time verification for text and image content through AI-powered fact-checking and deepfake detection. Display transparent trust signals directly in your UI to help users distinguish between reliable and unreliable information.
6
-
7
- ![npm downloads](https://img.shields.io/npm/dt/satyamark-react)
8
- [![npm version](https://badge.fury.io/js/satyamark-react.svg)](https://www.npmjs.com/package/satyamark-react)
9
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
10
-
11
- ## Features
12
-
13
- - βœ… **Real-time verification** of text content through fact-checking APIs
14
- - πŸ€– **AI-generated media detection** for images
15
- - πŸ”„ **Live status updates** via WebSocket connection
16
- - 🎨 **Automatic UI injection** with verification marks
17
- - ⚑ **Lightweight integration** - minimal code required
18
- - πŸ”— **Interactive results** - click through to detailed evidence
19
- - πŸ“± **Framework agnostic** - works with any React setup
20
-
21
- ## Table of Contents
22
-
23
- - [Installation](#installation)
24
- - [Quick Start](#quick-start)
25
- - [Core Concepts](#core-concepts)
26
- - [API Reference](#api-reference)
27
- - [Usage Examples](#usage-examples)
28
- - [Best Practices](#best-practices)
29
- - [Verification Marks](#verification-marks)
30
- - [Troubleshooting](#troubleshooting)
31
- - [Limitations](#limitations)
32
- - [Contributing](#contributing)
5
+ SatyaMark is a React library that provides real-time verification for
6
+ text and image content through AI-powered fact-checking and deepfake
7
+ detection. It injects transparent trust signals directly into your UI so
8
+ users can distinguish between reliable and unreliable information.
33
9
 
34
- ## Installation
10
+ ![npm downloads](https://img.shields.io/npm/dt/satyamark-react) [![npm
11
+ version](https://badge.fury.io/js/satyamark-react.svg)](https://www.npmjs.com/package/satyamark-react)
12
+ [![License:
13
+ MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
14
+
15
+ ------------------------------------------------------------------------
35
16
 
36
- Install via npm:
17
+ ## Installation
37
18
 
38
- ```bash
19
+ ``` bash
39
20
  npm install satyamark-react
40
21
  ```
41
22
 
42
- **Peer Dependencies:**
43
- - React 18+ (compatible with React 19)
23
+ **Peer Dependency:** React 18+
24
+
25
+ ------------------------------------------------------------------------
44
26
 
45
27
  ## Quick Start
46
28
 
47
29
  ### 1. Initialize Connection
48
30
 
49
- Call `init()` once when your app loads to establish the WebSocket connection:
50
-
51
- ```tsx
31
+ ``` tsx
52
32
  import { useEffect } from "react";
53
33
  import { init } from "satyamark-react";
54
34
 
@@ -56,7 +36,7 @@ function App() {
56
36
  useEffect(() => {
57
37
  init({
58
38
  app_id: "your-app-id",
59
- user_id: "unique-user-id",
39
+ user_id: "unique-user-id", // Use stable unique user id
60
40
  });
61
41
  }, []);
62
42
 
@@ -64,323 +44,148 @@ function App() {
64
44
  }
65
45
  ```
66
46
 
67
- ### 2. Create a Verified Component
47
+ ### Optional: onConnected
68
48
 
69
- ```tsx
70
- import { useRef, useEffect, useState } from "react";
71
- import { process, registerStatus } from "satyamark-react";
49
+ `onConnected` notifies when the connection state changes.
72
50
 
73
- function PostCard({ post }) {
74
- const contentRef = useRef(null);
75
- const [jobId, setJobId] = useState(null);
51
+ Callback receives:
52
+
53
+ {
54
+ app_id: string;
55
+ user_id: string;
56
+ }
57
+
58
+ If disconnected or closed, it receives `null`.
76
59
 
77
- // Process content after render
60
+ ``` tsx
61
+ import { useEffect } from "react";
62
+ import { init, onConnected } from "satyamark-react";
63
+
64
+ function App() {
78
65
  useEffect(() => {
79
- if (!contentRef.current) return;
66
+ init({
67
+ app_id: "my-app",
68
+ user_id: "user_123",
69
+ });
80
70
 
81
- process(contentRef.current, post.id)
82
- .then(setJobId)
83
- .catch(console.error);
84
- }, [post.id]);
71
+ const unsubscribe = onConnected((connection) => {
72
+ if (connection) {
73
+ console.log("Connected:", connection.app_id, connection.user_id);
74
+ } else {
75
+ console.log("Disconnected");
76
+ }
77
+ });
78
+
79
+ return unsubscribe;
80
+ }, []);
81
+
82
+ return <YourApp />;
83
+ }
84
+ ```
85
+
86
+ ### 2. Process a Content Element
87
+
88
+ ``` tsx
89
+ import { useRef, useEffect } from "react";
90
+ import { process } from "satyamark-react";
91
+
92
+ function PostCard({ post }) {
93
+ const ref = useRef(null);
85
94
 
86
- // Register status display
87
95
  useEffect(() => {
88
- if (!jobId || !contentRef.current) return;
89
- registerStatus(jobId, contentRef.current);
90
- }, [jobId]);
96
+ if (!ref.current) return;
97
+ process(ref.current, post.id);
98
+ }, [post.id]);
91
99
 
92
100
  return (
93
- <div ref={contentRef}>
101
+ <div ref={ref}>
94
102
  <p>{post.text}</p>
95
- {post.image && <img src={post.image} alt="Post" />}
96
-
97
- {/* Verification mark appears here */}
103
+ {post.image && <img src={post.image} alt="" />}
104
+
98
105
  <div data-satyamark-status-container />
99
106
  </div>
100
107
  );
101
108
  }
102
109
  ```
103
110
 
104
- That's it! The verification mark will automatically appear and update.
111
+ You can style the `data-satyamark-status-container` element according to
112
+ your UI requirements.
113
+
114
+ ------------------------------------------------------------------------
105
115
 
106
116
  ## Core Concepts
107
117
 
108
118
  SatyaMark consists of three core modules that work together:
109
119
 
110
- ### 1. Connection Layer (`satyamark_connect`)
111
-
112
- Manages the WebSocket connection to the verification server.
120
+ ### 1. Connection Layer
113
121
 
114
- - Authenticates with your `app_id` and `user_id`
115
- - Maintains persistent connection
116
- - Handles incoming verification results
117
- - Supports connection callbacks
122
+ - Authenticates with your `app_id` and `user_id`
123
+ - Maintains persistent WebSocket connection
124
+ - Handles incoming verification results
118
125
 
119
- ### 2. Processing Layer (`satyamark_process`)
126
+ ### 2. Processing Layer
120
127
 
121
- Extracts content from rendered DOM elements for verification.
128
+ - Walks the DOM tree to extract visible text
129
+ - Finds and validates images
130
+ - Sends content to verification service
131
+ - Internally tracks verification jobs
122
132
 
123
- - Walks the DOM tree to extract all visible text
124
- - Finds and validates images
125
- - Sends content to verification service
126
- - Returns a unique `jobId` for tracking
133
+ ### 3. Status Layer
127
134
 
128
- ### 3. Status Layer (`satyamark_status_controller`)
129
-
130
- Manages visual display of verification status.
131
-
132
- - Injects verification icons into your UI
133
- - Updates status in real-time
134
- - Provides tooltips on hover
135
- - Makes icons clickable for detailed results
135
+ - Automatically injects verification icons into your UI
136
+ - Updates status in real-time
137
+ - Provides tooltips on hover
138
+ - Makes icons clickable for detailed results
136
139
 
137
140
  ### Lifecycle Flow
138
141
 
139
- ```
140
- 1. init() β†’ Establish connection
141
- 2. render β†’ Display content normally
142
- 3. process() β†’ Extract and send for verification
143
- 4. registerStatus() β†’ Attach status display
144
- 5. Auto-update β†’ Marks appear and update automatically
145
- ```
142
+ 1. init() β†’ Establish connection
143
+ 2. render β†’ Display content normally
144
+ 3. process() β†’ Extract content & auto-inject verification status
145
+
146
+ All retries, result handling, and UI updates are managed internally.
146
147
 
147
148
  <p align="center">
148
149
  <img src="https://raw.githubusercontent.com/DhirajKarangale/SatyaMark/main/Assets/NpmCover/NpmCover_1.png" alt="SatyaMark Architecture" width="100%" />
149
150
  </p>
150
151
 
151
- ## API Reference
152
-
153
- ### Connection API
154
-
155
- #### `init(connectionData, options?)`
156
-
157
- Establishes WebSocket connection to the SatyaMark server.
158
-
159
- **Parameters:**
160
- - `connectionData` (SatyaMarkConnectionData) - **Required**
161
- - `app_id` (string): Your application's unique identifier
162
- - `user_id` (string): Current user's unique identifier
163
- - `options` (object) - Optional
164
- - `onConnected` (function): Callback when connection succeeds
165
-
166
- **Returns:** `void`
167
-
168
- **Example:**
169
- ```tsx
170
- init({
171
- app_id: "my-social-app",
172
- user_id: "user_12345",
173
- });
174
- ```
175
-
176
- #### `onConnected(callback)`
177
-
178
- Register a callback for when the connection is established.
179
-
180
- **Parameters:**
181
- - `callback` (ConnectedCallback): Function receiving connection data
182
-
183
- **Returns:** `void`
184
-
185
- **Example:**
186
- ```tsx
187
- onConnected((data) => {
188
- console.log("Connected:", data);
189
- });
190
- ```
191
-
192
- #### `onReceive(callback)`
193
-
194
- Subscribe to incoming verification updates. Used internally by status controller.
195
-
196
- **Parameters:**
197
- - `callback` (ReceiveCallback): Function receiving verification data
198
-
199
- **Returns:** Unsubscribe function
200
-
201
- ---
202
-
203
- ### Processing API
204
-
205
- #### `process(divRef, dataId)`
206
-
207
- Extracts content from a DOM element and submits for verification.
208
-
209
- **Parameters:**
210
- - `divRef` (HTMLDivElement): The DOM element containing content
211
- - `dataId` (string): Unique identifier for this content (e.g., post ID)
212
-
213
- **Returns:** `Promise<string>` - Resolves with `jobId` for tracking
214
-
215
- **Throws:**
216
- - `"Invalid root element"` - if divRef is null/undefined
217
- - `"dataId is required"` - if dataId is empty
218
- - `"No valid text or image found"` - if element has no content
219
- - `"Extracted text is too short"` - if text is less than 3 characters
152
+ ------------------------------------------------------------------------
220
153
 
221
- **Example:**
222
- ```tsx
223
- process(ref.current, "post_123")
224
- .then((jobId) => registerStatus(jobId, ref.current))
225
- .catch((error) => console.error(error.message));
226
- ```
227
-
228
- ---
229
-
230
- ### Status API
231
-
232
- #### `registerStatus(jobId, rootElement, options?)`
233
-
234
- Registers a DOM element to display verification status.
235
-
236
- **Parameters:**
237
- - `jobId` (string): Job ID returned from `process()`
238
- - `rootElement` (HTMLElement): Element containing status container
239
- - `options` (StatusOptions) - Optional
240
- - `iconSize` (number): Icon size in pixels (default: 20)
241
-
242
- **Returns:** `void`
243
-
244
- **Requirements:**
245
- - Root element must contain a child with `data-satyamark-status-container` attribute
246
-
247
- **Example:**
248
- ```tsx
249
- registerStatus(jobId, contentRef.current, {
250
- iconSize: 24,
251
- });
252
- ```
253
-
254
- **HTML Structure:**
255
- ```tsx
256
- <div ref={contentRef}>
257
- {/* Your content */}
258
- <div data-satyamark-status-container />
259
- </div>
260
- ```
261
-
262
- ## Usage Examples
263
-
264
- ### Basic Setup
265
-
266
- ```tsx
267
- import { useEffect } from "react";
268
- import { init, onConnected } from "satyamark-react";
269
-
270
- function App() {
271
- useEffect(() => {
272
- init({
273
- app_id: "my-app",
274
- user_id: getCurrentUserId(),
275
- });
276
-
277
- onConnected((data) => {
278
- console.log("SatyaMark connected:", data);
279
- });
280
- }, []);
281
-
282
- return <div>{/* Your app */}</div>;
283
- }
284
- ```
285
-
286
- ### Complete Component with Error Handling
154
+ ## API Reference
287
155
 
288
- ```tsx
289
- import { useRef, useEffect, useState } from "react";
290
- import { process, registerStatus } from "satyamark-react";
156
+ ### 1. init(connectionData)
291
157
 
292
- function VerifiedPost({ post }) {
293
- const contentRef = useRef(null);
294
- const [status, setStatus] = useState("idle");
295
- const [error, setError] = useState("");
158
+ Establishes WebSocket connection.
296
159
 
297
- useEffect(() => {
298
- if (!contentRef.current) return;
299
-
300
- setStatus("processing");
301
-
302
- process(contentRef.current, post.id)
303
- .then((jobId) => {
304
- setStatus("success");
305
- registerStatus(jobId, contentRef.current);
306
- })
307
- .catch((err) => {
308
- setStatus("error");
309
- setError(err.message);
310
- });
311
- }, [post.id]);
160
+ **Parameters**
312
161
 
313
- return (
314
- <div ref={contentRef} className="post-card">
315
- <div className="content">
316
- <p>{post.text}</p>
317
- {post.image && <img src={post.image} alt="" />}
318
- </div>
319
-
320
- {status === "success" && (
321
- <div data-satyamark-status-container />
322
- )}
323
-
324
- {status === "error" && (
325
- <div className="error-badge">{error}</div>
326
- )}
327
- </div>
328
- );
329
- }
330
- ```
331
-
332
- ### List of Posts
333
-
334
- ```tsx
335
- function PostFeed({ posts }) {
336
- return (
337
- <div className="feed">
338
- {posts.map((post) => (
339
- <VerifiedPost key={post.id} post={post} />
340
- ))}
341
- </div>
342
- );
343
- }
344
- ```
162
+ - `app_id: string` β€” Unique identifier for your application
163
+ - `user_id: string` β€” Unique identifier for the current user
345
164
 
346
- ### Custom Icon Size
165
+ ### 2. onConnected(callback)
347
166
 
348
- ```tsx
349
- useEffect(() => {
350
- if (!jobId || !ref.current) return;
167
+ Listens for connection state changes.
351
168
 
352
- registerStatus(jobId, ref.current, {
353
- iconSize: 32, // Larger icon
354
- });
355
- }, [jobId]);
356
- ```
169
+ Callback receives:
357
170
 
358
- ## Best Practices
171
+ {
172
+ app_id: string;
173
+ user_id: string;
174
+ }
359
175
 
360
- ### βœ… Do
176
+ Returns `null` if disconnected.
361
177
 
362
- - **Initialize once** at app startup in your root component
363
- - **Use unique dataIds** for each piece of content (post ID, comment ID, etc.)
364
- - **Process after render** - ensure content exists in DOM before calling `process()`
365
- - **Handle errors gracefully** - short or empty content will throw errors
366
- - **Use refs correctly** - pass actual DOM elements, not null
367
- - **Test with real content** - minimum 3 characters or valid image required
178
+ ### 3. process(rootElement, dataId)
368
179
 
369
- ### ❌ Don't
180
+ Extracts text and images from a DOM element and submits them for
181
+ verification.
370
182
 
371
- - **Don't call init() multiple times** - creates duplicate connections
372
- - **Don't process before render** - ref.current will be null
373
- - **Don't reuse dataIds** - each content piece needs unique identifier
374
- - **Don't forget status container** - `data-satyamark-status-container` is required
375
- - **Don't manually update icons** - library handles it automatically
376
- - **Don't process empty content** - ensure content exists first
183
+ **Parameters**
377
184
 
378
- ### ⚑ Performance Tips
185
+ - `rootElement: HTMLElement` β€” DOM element containing the content
186
+ - `dataId: string` β€” Unique identifier for this specific content item
379
187
 
380
- - **Debounce rapid updates** - don't re-process on every keystroke
381
- - **Process only visible content** - use Intersection Observer for long lists
382
- - **Cache jobIds** - avoid re-processing identical content
383
- - **Lazy load verification** - process when content enters viewport
188
+ ------------------------------------------------------------------------
384
189
 
385
190
  ## Verification Marks
386
191
 
@@ -400,71 +205,79 @@ SatyaMark displays different marks based on verification results:
400
205
 
401
206
  **Interactive:** After verification completes, clicking the mark opens a detailed results page with sources and evidence.
402
207
 
403
- ## Troubleshooting
208
+ ------------------------------------------------------------------------
404
209
 
405
- ### "Invalid root element"
210
+ ## Best Practices
406
211
 
407
- **Cause:** Calling `process()` with null/undefined ref.
212
+ ### Do
408
213
 
409
- **Solution:** Check ref exists before processing:
410
- ```tsx
411
- if (!contentRef.current) return;
412
- process(contentRef.current, post.id);
413
- ```
214
+ - Initialize `init()` once in your root App component
215
+ - Use a unique and stable `user_id` when calling `init()`
216
+ - Use a stable and unique `dataId` for each content item (database IDs recommended)
217
+ - Call `process()` only after the element is mounted
218
+ - Include `data-satyamark-status-container` where you want status displayed
219
+ - Style the `data-satyamark-status-container` element as per your UI requirements
220
+ - Optionally use `onConnected()` if your UI depends on connection readiness
221
+ - Let SatyaMark manage verification lifecycle and retries internally
414
222
 
415
- ### "No valid text or image found"
223
+ ### Don't
416
224
 
417
- **Cause:** Element contains no extractable content or all images fail to load.
225
+ - Don't call `init()` multiple times or in multiple components
226
+ - Don't use random or changing `user_id` values for the same user session
227
+ - Don't use random or changing `dataId` values for the same content
228
+ - Don't manually retry `process()` in loops
229
+ - Don't call `process()` before the element exists in the DOM
418
230
 
419
- **Solution:** Ensure content has visible text (3+ chars) or valid image URLs.
231
+ ### Performance Tips
420
232
 
421
- ### Status icon not appearing
233
+ - **Debounce Input Changes** - Avoid re-processing content on every keystroke
234
+ - **Process Visible Content Only** - Use Intersection Observer for large feeds
235
+ - **Prevent Re-Render Loops** - Ensure process() isn’t triggered repeatedly by state updates
236
+ - **Use Stable Content Identifiers** - Prevent duplicate or unnecessary verification calls
422
237
 
423
- **Cause:** Missing `data-satyamark-status-container` or `registerStatus()` not called.
238
+ ------------------------------------------------------------------------
424
239
 
425
- **Solution:** Add status container and call `registerStatus()` with correct jobId:
426
- ```tsx
427
- <div data-satyamark-status-container />
428
- // ...
429
- registerStatus(jobId, contentRef.current);
430
- ```
240
+ ## Troubleshooting
431
241
 
432
- ### Connection fails or times out
242
+ ### 1. Invalid root element
433
243
 
434
- **Cause:** Network issues, invalid credentials, or server unavailable.
244
+ **Cause:** Calling `process()` with null/undefined ref.
435
245
 
436
- **Solution:** Check console for WebSocket errors. Verify `app_id` and `user_id` are correct.
246
+ **Solution:** Check ref exists before processing:
247
+ ```tsx
248
+ if (!contentRef.current) return;
249
+ process(contentRef.current, post.id);
250
+ ```
437
251
 
438
- ### Multiple verification requests
252
+ ### 2. No valid text or image found
439
253
 
440
- **Cause:** useEffect dependency array causing re-renders.
254
+ **Cause:** Element contains no extractable content or all images fail to load.
441
255
 
442
- **Solution:** Use stable identifiers in dependency array:
443
- ```tsx
444
- useEffect(() => {
445
- // Process logic
446
- }, [post.id]); // Stable dependency
447
- ```
256
+ **Solution:** Ensure content has visible text (3+ chars) or valid image URLs.
448
257
 
449
- ### Verification stuck on "Pending"
258
+ ### 3. Status icon not appearing
450
259
 
451
- **Cause:** Server processing or jobId mismatch.
260
+ **Cause:** Missing `data-satyamark-status-container` or `process()` not executed.
452
261
 
453
- **Solution:** Verification can take 5-30 seconds. Ensure jobId is correctly passed to `registerStatus()`.
262
+ **Solution:** Ensure:
454
263
 
455
- ## Limitations
264
+ - `init()` was called
265
+ - `process()` ran after the element mounted
266
+ - `data-satyamark-status-container` exists inside the processed element
456
267
 
457
- SatyaMark is actively developed. Current limitations:
268
+ ### 4. Connection fails or times out
458
269
 
459
- - **Minimum content:** Text must be at least 3 characters
460
- - **Single image:** Only first valid image is processed per element
461
- - **No offline support:** Requires active WebSocket connection
462
- - **No local caching:** Content sent to server every time (caching planned)
463
- - **Single connection:** Multiple tabs share connection state
464
- - **Limited retry logic:** Manual refresh required if connection drops
465
- - **No client rate limiting:** Apps should implement own throttling
270
+ **Cause:** Network issues, invalid credentials, or server unavailable.
466
271
 
467
- These are being addressed in future releases. Check the [GitHub repository](https://github.com/DhirajKarangale/SatyaMark) for updates.
272
+ **Solution:** Check console for WebSocket errors. Verify `app_id` and `user_id` are correct.
273
+
274
+ ### 5. Verification stuck on "Pending"
275
+
276
+ **Cause:** Server processing delay.
277
+
278
+ **Solution:** Verification can take a few seconds to a few minutes depending on content complexity and system load.
279
+
280
+ ------------------------------------------------------------------------
468
281
 
469
282
  ## Contributing
470
283
 
@@ -486,10 +299,8 @@ SatyaMark is fully open-source and welcomes contributions!
486
299
 
487
300
  All contributions are reviewed for alignment with SatyaMark's principles: transparency, evidence-based verification, and accessibility.
488
301
 
489
- ## License
490
-
491
- MIT Β© SatyaMark Contributors
302
+ ------------------------------------------------------------------------
492
303
 
493
- ---
304
+ ## License
494
305
 
495
- **Need help?** Open an issue on [GitHub](https://github.com/DhirajKarangale/SatyaMark) or check the [live demo](https://satyamark.vercel.app) for examples.
306
+ MIT Β© SatyaMark Contributors
package/dist/index.d.ts CHANGED
@@ -1,22 +1,15 @@
1
- type SatyaMarkConnectionData = {
1
+ type ConnectionContext$1 = {
2
2
  app_id: string;
3
3
  user_id: string;
4
4
  };
5
- type ConnectedCallback = (data: SatyaMarkConnectionData) => void;
6
- type ReceiveCallback = (data: any) => void;
7
- declare function onReceive(cb: ReceiveCallback): () => void;
8
- declare function onConnected(cb: ConnectedCallback): void;
9
- declare function init(connectionData: SatyaMarkConnectionData, options?: {
10
- onConnected?: ConnectedCallback;
11
- }): Promise<void>;
12
- declare function sendData(text: string, image_url: string, dataId: string): string | undefined;
13
- declare function receiveData(data: any): void;
5
+ declare function init(newContext: ConnectionContext$1): Promise<void>;
14
6
 
15
- declare function process(divRef: HTMLDivElement, dataId: string): Promise<string | undefined>;
16
-
17
- type StatusOptions = {
18
- iconSize?: number;
7
+ type ConnectionContext = {
8
+ app_id: string;
9
+ user_id: string;
19
10
  };
20
- declare function registerStatus(jobId: string, rootElement: HTMLElement, options?: StatusOptions): void;
11
+ declare function onConnected(cb: (context: ConnectionContext | null) => void): () => void;
12
+
13
+ declare function process(containerRef: HTMLDivElement, dataId: string): void;
21
14
 
22
- export { SatyaMarkConnectionData, init, onConnected, onReceive, process, receiveData, registerStatus, sendData };
15
+ export { init, onConnected, process };