satyamark-react 0.0.12 β†’ 0.0.13

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,144 @@ function App() {
64
44
  }
65
45
  ```
66
46
 
67
- ### 2. Create a Verified Component
68
-
69
- ```tsx
70
- import { useRef, useEffect, useState } from "react";
71
- import { process, registerStatus } from "satyamark-react";
72
-
73
- function PostCard({ post }) {
74
- const contentRef = useRef(null);
75
- const [jobId, setJobId] = useState(null);
76
-
77
- // Process content after render
78
- useEffect(() => {
79
- if (!contentRef.current) return;
80
-
81
- process(contentRef.current, post.id)
82
- .then(setJobId)
83
- .catch(console.error);
84
- }, [post.id]);
85
-
86
- // Register status display
87
- useEffect(() => {
88
- if (!jobId || !contentRef.current) return;
89
- registerStatus(jobId, contentRef.current);
90
- }, [jobId]);
91
-
92
- return (
93
- <div ref={contentRef}>
94
- <p>{post.text}</p>
95
- {post.image && <img src={post.image} alt="Post" />}
96
-
97
- {/* Verification mark appears here */}
98
- <div data-satyamark-status-container />
99
- </div>
100
- );
101
- }
102
- ```
103
-
104
- That's it! The verification mark will automatically appear and update.
105
-
106
- ## Core Concepts
107
-
108
- SatyaMark consists of three core modules that work together:
109
-
110
- ### 1. Connection Layer (`satyamark_connect`)
111
-
112
- Manages the WebSocket connection to the verification server.
113
-
114
- - Authenticates with your `app_id` and `user_id`
115
- - Maintains persistent connection
116
- - Handles incoming verification results
117
- - Supports connection callbacks
118
-
119
- ### 2. Processing Layer (`satyamark_process`)
120
-
121
- Extracts content from rendered DOM elements for verification.
122
-
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
127
-
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
136
-
137
- ### Lifecycle Flow
138
-
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
- ```
146
-
147
- <p align="center">
148
- <img src="https://raw.githubusercontent.com/DhirajKarangale/SatyaMark/main/Assets/NpmCover/NpmCover_1.png" alt="SatyaMark Architecture" width="100%" />
149
- </p>
150
-
151
- ## API Reference
152
-
153
- ### Connection API
47
+ ### Optional: onConnected
154
48
 
155
- #### `init(connectionData, options?)`
49
+ `onConnected` notifies when the connection state changes.
156
50
 
157
- Establishes WebSocket connection to the SatyaMark server.
51
+ Callback receives:
158
52
 
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
53
+ {
54
+ app_id: string;
55
+ user_id: string;
56
+ }
165
57
 
166
- **Returns:** `void`
58
+ If disconnected or closed, it receives `null`.
167
59
 
168
- **Example:**
169
- ```tsx
170
- init({
171
- app_id: "my-social-app",
172
- user_id: "user_12345",
173
- });
174
- ```
175
-
176
- #### `onConnected(callback)`
60
+ ``` tsx
61
+ import { useEffect } from "react";
62
+ import { init, onConnected } from "satyamark-react";
177
63
 
178
- Register a callback for when the connection is established.
64
+ function App() {
65
+ useEffect(() => {
66
+ init({
67
+ app_id: "my-app",
68
+ user_id: "user_123",
69
+ });
179
70
 
180
- **Parameters:**
181
- - `callback` (ConnectedCallback): Function receiving connection data
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
+ });
182
78
 
183
- **Returns:** `void`
79
+ return unsubscribe;
80
+ }, []);
184
81
 
185
- **Example:**
186
- ```tsx
187
- onConnected((data) => {
188
- console.log("Connected:", data);
189
- });
82
+ return <YourApp />;
83
+ }
190
84
  ```
191
85
 
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
86
+ ### 2. Process a Content Element
200
87
 
201
- ---
88
+ ``` tsx
89
+ import { useRef, useEffect } from "react";
90
+ import { process } from "satyamark-react";
202
91
 
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)
92
+ function PostCard({ post }) {
93
+ const ref = useRef(null);
212
94
 
213
- **Returns:** `Promise<string>` - Resolves with `jobId` for tracking
95
+ useEffect(() => {
96
+ if (!ref.current) return;
97
+ process(ref.current, post.id);
98
+ }, [post.id]);
214
99
 
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
100
+ return (
101
+ <div ref={ref}>
102
+ <p>{post.text}</p>
103
+ {post.image && <img src={post.image} alt="" />}
220
104
 
221
- **Example:**
222
- ```tsx
223
- process(ref.current, "post_123")
224
- .then((jobId) => registerStatus(jobId, ref.current))
225
- .catch((error) => console.error(error.message));
105
+ <div data-satyamark-status-container />
106
+ </div>
107
+ );
108
+ }
226
109
  ```
227
110
 
228
- ---
111
+ You can style the `data-satyamark-status-container` element according to
112
+ your UI requirements.
229
113
 
230
- ### Status API
114
+ ------------------------------------------------------------------------
231
115
 
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)
116
+ ## Core Concepts
241
117
 
242
- **Returns:** `void`
118
+ SatyaMark consists of three core modules that work together:
243
119
 
244
- **Requirements:**
245
- - Root element must contain a child with `data-satyamark-status-container` attribute
120
+ ### 1. Connection Layer
246
121
 
247
- **Example:**
248
- ```tsx
249
- registerStatus(jobId, contentRef.current, {
250
- iconSize: 24,
251
- });
252
- ```
122
+ - Authenticates with your `app_id` and `user_id`
123
+ - Maintains persistent WebSocket connection
124
+ - Handles incoming verification results
253
125
 
254
- **HTML Structure:**
255
- ```tsx
256
- <div ref={contentRef}>
257
- {/* Your content */}
258
- <div data-satyamark-status-container />
259
- </div>
260
- ```
126
+ ### 2. Processing Layer
261
127
 
262
- ## Usage Examples
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
263
132
 
264
- ### Basic Setup
133
+ ### 3. Status Layer
265
134
 
266
- ```tsx
267
- import { useEffect } from "react";
268
- import { init, onConnected } from "satyamark-react";
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
269
139
 
270
- function App() {
271
- useEffect(() => {
272
- init({
273
- app_id: "my-app",
274
- user_id: getCurrentUserId(),
275
- });
140
+ ### Lifecycle Flow
276
141
 
277
- onConnected((data) => {
278
- console.log("SatyaMark connected:", data);
279
- });
280
- }, []);
142
+ 1. init() β†’ Establish connection
143
+ 2. render β†’ Display content normally
144
+ 3. process() β†’ Extract content & auto-inject verification status
281
145
 
282
- return <div>{/* Your app */}</div>;
283
- }
284
- ```
146
+ All retries, result handling, and UI updates are managed internally.
285
147
 
286
- ### Complete Component with Error Handling
148
+ ------------------------------------------------------------------------
287
149
 
288
- ```tsx
289
- import { useRef, useEffect, useState } from "react";
290
- import { process, registerStatus } from "satyamark-react";
150
+ ## API Reference
291
151
 
292
- function VerifiedPost({ post }) {
293
- const contentRef = useRef(null);
294
- const [status, setStatus] = useState("idle");
295
- const [error, setError] = useState("");
152
+ ### 1. init(connectionData)
296
153
 
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]);
154
+ Establishes WebSocket connection.
312
155
 
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
- ```
156
+ **Parameters**
331
157
 
332
- ### List of Posts
158
+ - `app_id: string` β€” Unique identifier for your application
159
+ - `user_id: string` β€” Unique identifier for the current user
333
160
 
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
- ```
161
+ ### 2. onConnected(callback)
345
162
 
346
- ### Custom Icon Size
163
+ Listens for connection state changes.
347
164
 
348
- ```tsx
349
- useEffect(() => {
350
- if (!jobId || !ref.current) return;
165
+ Callback receives:
351
166
 
352
- registerStatus(jobId, ref.current, {
353
- iconSize: 32, // Larger icon
354
- });
355
- }, [jobId]);
356
- ```
167
+ {
168
+ app_id: string;
169
+ user_id: string;
170
+ }
357
171
 
358
- ## Best Practices
172
+ Returns `null` if disconnected.
359
173
 
360
- ### βœ… Do
174
+ ### 3. process(rootElement, dataId)
361
175
 
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
176
+ Extracts text and images from a DOM element and submits them for
177
+ verification.
368
178
 
369
- ### ❌ Don't
179
+ **Parameters**
370
180
 
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
181
+ - `rootElement: HTMLElement` β€” DOM element containing the content
182
+ - `dataId: string` β€” Unique identifier for this specific content item
377
183
 
378
- ### ⚑ Performance Tips
379
-
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
184
+ ------------------------------------------------------------------------
384
185
 
385
186
  ## Verification Marks
386
187
 
@@ -400,71 +201,79 @@ SatyaMark displays different marks based on verification results:
400
201
 
401
202
  **Interactive:** After verification completes, clicking the mark opens a detailed results page with sources and evidence.
402
203
 
403
- ## Troubleshooting
204
+ ------------------------------------------------------------------------
404
205
 
405
- ### "Invalid root element"
206
+ ## Best Practices
406
207
 
407
- **Cause:** Calling `process()` with null/undefined ref.
208
+ ### Do
408
209
 
409
- **Solution:** Check ref exists before processing:
410
- ```tsx
411
- if (!contentRef.current) return;
412
- process(contentRef.current, post.id);
413
- ```
210
+ - Initialize `init()` once in your root App component
211
+ - Use a unique and stable `user_id` when calling `init()`
212
+ - Use a stable and unique `dataId` for each content item (database IDs recommended)
213
+ - Call `process()` only after the element is mounted
214
+ - Include `data-satyamark-status-container` where you want status displayed
215
+ - Style the `data-satyamark-status-container` element as per your UI requirements
216
+ - Optionally use `onConnected()` if your UI depends on connection readiness
217
+ - Let SatyaMark manage verification lifecycle and retries internally
414
218
 
415
- ### "No valid text or image found"
219
+ ### Don't
416
220
 
417
- **Cause:** Element contains no extractable content or all images fail to load.
221
+ - Don't call `init()` multiple times or in multiple components
222
+ - Don't use random or changing `user_id` values for the same user session
223
+ - Don't use random or changing `dataId` values for the same content
224
+ - Don't manually retry `process()` in loops
225
+ - Don't call `process()` before the element exists in the DOM
418
226
 
419
- **Solution:** Ensure content has visible text (3+ chars) or valid image URLs.
227
+ ### Performance Tips
420
228
 
421
- ### Status icon not appearing
229
+ - **Debounce Input Changes** - Avoid re-processing content on every keystroke
230
+ - **Process Visible Content Only** - Use Intersection Observer for large feeds
231
+ - **Prevent Re-Render Loops** - Ensure process() isn’t triggered repeatedly by state updates
232
+ - **Use Stable Content Identifiers** - Prevent duplicate or unnecessary verification calls
422
233
 
423
- **Cause:** Missing `data-satyamark-status-container` or `registerStatus()` not called.
234
+ ------------------------------------------------------------------------
424
235
 
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
- ```
236
+ ## Troubleshooting
431
237
 
432
- ### Connection fails or times out
238
+ ### 1. Invalid root element
433
239
 
434
- **Cause:** Network issues, invalid credentials, or server unavailable.
240
+ **Cause:** Calling `process()` with null/undefined ref.
435
241
 
436
- **Solution:** Check console for WebSocket errors. Verify `app_id` and `user_id` are correct.
242
+ **Solution:** Check ref exists before processing:
243
+ ```tsx
244
+ if (!contentRef.current) return;
245
+ process(contentRef.current, post.id);
246
+ ```
437
247
 
438
- ### Multiple verification requests
248
+ ### 2. No valid text or image found
439
249
 
440
- **Cause:** useEffect dependency array causing re-renders.
250
+ **Cause:** Element contains no extractable content or all images fail to load.
441
251
 
442
- **Solution:** Use stable identifiers in dependency array:
443
- ```tsx
444
- useEffect(() => {
445
- // Process logic
446
- }, [post.id]); // Stable dependency
447
- ```
252
+ **Solution:** Ensure content has visible text (3+ chars) or valid image URLs.
448
253
 
449
- ### Verification stuck on "Pending"
254
+ ### 3. Status icon not appearing
450
255
 
451
- **Cause:** Server processing or jobId mismatch.
256
+ **Cause:** Missing `data-satyamark-status-container` or `process()` not executed.
452
257
 
453
- **Solution:** Verification can take 5-30 seconds. Ensure jobId is correctly passed to `registerStatus()`.
258
+ **Solution:** Ensure:
454
259
 
455
- ## Limitations
260
+ - `init()` was called
261
+ - `process()` ran after the element mounted
262
+ - `data-satyamark-status-container` exists inside the processed element
456
263
 
457
- SatyaMark is actively developed. Current limitations:
264
+ ### 4. Connection fails or times out
458
265
 
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
266
+ **Cause:** Network issues, invalid credentials, or server unavailable.
466
267
 
467
- These are being addressed in future releases. Check the [GitHub repository](https://github.com/DhirajKarangale/SatyaMark) for updates.
268
+ **Solution:** Check console for WebSocket errors. Verify `app_id` and `user_id` are correct.
269
+
270
+ ### 5. Verification stuck on "Pending"
271
+
272
+ **Cause:** Server processing delay.
273
+
274
+ **Solution:** Verification can take a few seconds to a few minutes depending on content complexity and system load.
275
+
276
+ ------------------------------------------------------------------------
468
277
 
469
278
  ## Contributing
470
279
 
@@ -486,10 +295,8 @@ SatyaMark is fully open-source and welcomes contributions!
486
295
 
487
296
  All contributions are reviewed for alignment with SatyaMark's principles: transparency, evidence-based verification, and accessibility.
488
297
 
489
- ## License
490
-
491
- MIT Β© SatyaMark Contributors
298
+ ------------------------------------------------------------------------
492
299
 
493
- ---
300
+ ## License
494
301
 
495
- **Need help?** Open an issue on [GitHub](https://github.com/DhirajKarangale/SatyaMark) or check the [live demo](https://satyamark.vercel.app) for examples.
302
+ 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 };