satyamark-react 0.0.13 → 0.0.15
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 +16 -4
- package/dist/index.js +45 -41
- package/dist/index.mjs +45 -41
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,8 +93,12 @@ function PostCard({ post }) {
|
|
|
93
93
|
const ref = useRef(null);
|
|
94
94
|
|
|
95
95
|
useEffect(() => {
|
|
96
|
-
if (!
|
|
97
|
-
|
|
96
|
+
if (!cardRef.current) return;
|
|
97
|
+
try {
|
|
98
|
+
process(cardRef.current, postData.id);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.log(error);
|
|
101
|
+
}
|
|
98
102
|
}, [post.id]);
|
|
99
103
|
|
|
100
104
|
return (
|
|
@@ -145,6 +149,10 @@ SatyaMark consists of three core modules that work together:
|
|
|
145
149
|
|
|
146
150
|
All retries, result handling, and UI updates are managed internally.
|
|
147
151
|
|
|
152
|
+
<p align="center">
|
|
153
|
+
<img src="https://raw.githubusercontent.com/DhirajKarangale/SatyaMark/main/Assets/NpmCover/NpmCover_1.png" alt="SatyaMark Architecture" width="100%" />
|
|
154
|
+
</p>
|
|
155
|
+
|
|
148
156
|
------------------------------------------------------------------------
|
|
149
157
|
|
|
150
158
|
## API Reference
|
|
@@ -241,8 +249,12 @@ SatyaMark displays different marks based on verification results:
|
|
|
241
249
|
|
|
242
250
|
**Solution:** Check ref exists before processing:
|
|
243
251
|
```tsx
|
|
244
|
-
if (!
|
|
245
|
-
|
|
252
|
+
if (!cardRef.current) return;
|
|
253
|
+
try {
|
|
254
|
+
process(cardRef.current, postData.id);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
console.log(error);
|
|
257
|
+
}
|
|
246
258
|
```
|
|
247
259
|
|
|
248
260
|
### 2. No valid text or image found
|
package/dist/index.js
CHANGED
|
@@ -42,7 +42,7 @@ var SocketClient = class {
|
|
|
42
42
|
}
|
|
43
43
|
send(payload) {
|
|
44
44
|
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
45
|
-
throw new Error("
|
|
45
|
+
throw new Error("notready");
|
|
46
46
|
}
|
|
47
47
|
this.socket.send(JSON.stringify(payload));
|
|
48
48
|
}
|
|
@@ -58,13 +58,10 @@ var SocketClient = class {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
// src/utils/generateIds.ts
|
|
61
|
-
function generateTimestamp() {
|
|
62
|
-
const now = /* @__PURE__ */ new Date();
|
|
63
|
-
return now.getFullYear().toString() + String(now.getMonth() + 1).padStart(2, "0") + String(now.getDate()).padStart(2, "0") + String(now.getHours()).padStart(2, "0") + String(now.getMinutes()).padStart(2, "0") + String(now.getSeconds()).padStart(2, "0") + String(now.getMilliseconds()).padStart(3, "0") + Math.floor(Math.random() * 1e3).toString().padStart(3, "0");
|
|
64
|
-
}
|
|
65
61
|
function generateJobId(app_id, user_id, dataId) {
|
|
66
|
-
const timestamp =
|
|
67
|
-
const
|
|
62
|
+
const timestamp = Date.now().toString(36);
|
|
63
|
+
const random = crypto.getRandomValues(new Uint32Array(1))[0].toString(36);
|
|
64
|
+
const jobId = `${app_id}_${user_id}_${dataId}_${timestamp}_${random}`;
|
|
68
65
|
return jobId;
|
|
69
66
|
}
|
|
70
67
|
|
|
@@ -197,7 +194,7 @@ function clearSession() {
|
|
|
197
194
|
}
|
|
198
195
|
|
|
199
196
|
// src/core/connectionManager.ts
|
|
200
|
-
var isDev =
|
|
197
|
+
var isDev = true;
|
|
201
198
|
var context = null;
|
|
202
199
|
var socketClient = null;
|
|
203
200
|
var isConnecting = false;
|
|
@@ -215,37 +212,31 @@ async function resolveWsUrl() {
|
|
|
215
212
|
const data = await res.json();
|
|
216
213
|
const wsUrl = data.wsUrl;
|
|
217
214
|
if (!wsUrl)
|
|
218
|
-
throw new Error("WebSocket URL resolution failed");
|
|
215
|
+
throw new Error("Satyamark: WebSocket URL resolution failed");
|
|
219
216
|
return wsUrl;
|
|
220
217
|
}
|
|
221
218
|
async function init(newContext) {
|
|
222
|
-
if (!(newContext == null ? void 0 : newContext.app_id) || !(newContext == null ? void 0 : newContext.user_id)) {
|
|
223
|
-
throw new Error("init() requires valid app_id and user_id");
|
|
224
|
-
}
|
|
225
|
-
if (isConnecting || isConnected)
|
|
226
|
-
return;
|
|
227
219
|
context = newContext;
|
|
228
220
|
await connect();
|
|
229
221
|
}
|
|
230
222
|
async function connect() {
|
|
231
|
-
if (!context)
|
|
232
|
-
return;
|
|
233
223
|
if (isConnecting || isConnected)
|
|
234
224
|
return;
|
|
235
225
|
isConnecting = true;
|
|
236
226
|
const url = await resolveWsUrl();
|
|
237
227
|
socketClient = new SocketClient(url, {
|
|
238
228
|
onOpen: async () => {
|
|
229
|
+
const ctx = getContext();
|
|
239
230
|
const sessionId = await getSessionId();
|
|
240
231
|
socketClient == null ? void 0 : socketClient.send({
|
|
241
232
|
type: "handshake",
|
|
242
|
-
clientId:
|
|
243
|
-
app_id:
|
|
233
|
+
clientId: ctx.user_id,
|
|
234
|
+
app_id: ctx.app_id,
|
|
244
235
|
sessionId
|
|
245
236
|
});
|
|
246
237
|
isConnected = true;
|
|
247
238
|
isConnecting = false;
|
|
248
|
-
emitConnection(
|
|
239
|
+
emitConnection(ctx);
|
|
249
240
|
},
|
|
250
241
|
onMessage: async (data) => {
|
|
251
242
|
if (data.type === "session_created" && data.sessionId) {
|
|
@@ -285,19 +276,18 @@ function scheduleReconnect() {
|
|
|
285
276
|
connect();
|
|
286
277
|
}, 2e3);
|
|
287
278
|
}
|
|
288
|
-
|
|
289
|
-
if (!context)
|
|
290
|
-
throw new Error("Satyamark
|
|
291
|
-
if (!text && !imageUrl) {
|
|
292
|
-
throw new Error("Provide text or imageUrl");
|
|
293
|
-
}
|
|
294
|
-
if (text && text.trim().length < 3) {
|
|
295
|
-
throw new Error("Text must be at least 3 characters");
|
|
279
|
+
function getContext() {
|
|
280
|
+
if (!(context == null ? void 0 : context.app_id) || !(context == null ? void 0 : context.user_id)) {
|
|
281
|
+
throw new Error("Satyamark: Invalid app_id and user_id in init()");
|
|
296
282
|
}
|
|
297
|
-
|
|
283
|
+
return context;
|
|
284
|
+
}
|
|
285
|
+
async function sendJob(text, imageUrl, dataId) {
|
|
286
|
+
const ctx = getContext();
|
|
287
|
+
const jobId = generateJobId(ctx.app_id, ctx.user_id, dataId);
|
|
298
288
|
const sessionId = await getSessionId();
|
|
299
289
|
socketClient == null ? void 0 : socketClient.send({
|
|
300
|
-
clientId:
|
|
290
|
+
clientId: ctx.user_id,
|
|
301
291
|
sessionId,
|
|
302
292
|
jobId,
|
|
303
293
|
text,
|
|
@@ -409,7 +399,7 @@ function updateIcon(containerRef, data) {
|
|
|
409
399
|
}
|
|
410
400
|
|
|
411
401
|
// src/utils/process_data.ts
|
|
412
|
-
var mergeText = (texts) => texts.join("
|
|
402
|
+
var mergeText = (texts) => texts.join(" |#| ");
|
|
413
403
|
var isValidImageUrl = (url) => {
|
|
414
404
|
return new Promise((resolve) => {
|
|
415
405
|
const img = new Image();
|
|
@@ -439,20 +429,20 @@ var extractFromDiv = (root) => {
|
|
|
439
429
|
return { text, images };
|
|
440
430
|
};
|
|
441
431
|
async function process_data(divRef, dataId) {
|
|
442
|
-
if (!divRef) {
|
|
443
|
-
throw new Error("Invalid root element");
|
|
444
|
-
}
|
|
445
432
|
if (!dataId) {
|
|
446
|
-
throw new Error("
|
|
433
|
+
throw new Error("Satyamark: Invalid dataId");
|
|
434
|
+
}
|
|
435
|
+
if (!divRef) {
|
|
436
|
+
throw new Error("Satyamark: Invalid root element");
|
|
447
437
|
}
|
|
448
438
|
const { text, images } = extractFromDiv(divRef);
|
|
449
439
|
const mergedText = mergeText(text);
|
|
450
440
|
const validImage = await getFirstValidImage(images);
|
|
451
441
|
if (!mergedText && !validImage) {
|
|
452
|
-
throw new Error("No valid text or image found in the element");
|
|
442
|
+
throw new Error("Satyamark: No valid text or image found in the element");
|
|
453
443
|
}
|
|
454
444
|
if (mergedText && mergedText.length < 3) {
|
|
455
|
-
throw new Error("Extracted text is too short");
|
|
445
|
+
throw new Error("Satyamark: Extracted text is too short");
|
|
456
446
|
}
|
|
457
447
|
const image_url = validImage ? validImage : "";
|
|
458
448
|
return { text: mergedText, image_url };
|
|
@@ -464,9 +454,20 @@ var isSendingJobs = false;
|
|
|
464
454
|
var jobMap = /* @__PURE__ */ new Map();
|
|
465
455
|
var process_queue = [];
|
|
466
456
|
function process(containerRef, dataId) {
|
|
457
|
+
validateStatusContainer(containerRef);
|
|
467
458
|
process_queue.push({ containerRef, dataId });
|
|
468
459
|
void sendJobs();
|
|
469
460
|
}
|
|
461
|
+
function validateStatusContainer(containerRef) {
|
|
462
|
+
const statusContainer = containerRef.querySelector(
|
|
463
|
+
"[data-satyamark-status-container]"
|
|
464
|
+
);
|
|
465
|
+
if (!statusContainer) {
|
|
466
|
+
throw new Error(
|
|
467
|
+
'Satyamark: Missing element with attribute "data-satyamark-status-container" inside containerRef.'
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
470
471
|
async function sendJobs() {
|
|
471
472
|
if (isSendingJobs || !isConnected2)
|
|
472
473
|
return;
|
|
@@ -483,11 +484,14 @@ async function sendJobs() {
|
|
|
483
484
|
process_queue.shift();
|
|
484
485
|
updateIcon(containerRef, null);
|
|
485
486
|
} catch (error) {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
487
|
+
if (error instanceof Error && error.message === "notready") {
|
|
488
|
+
isSendingJobs = false;
|
|
489
|
+
setTimeout(() => {
|
|
490
|
+
void sendJobs();
|
|
491
|
+
}, 1e3);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
throw error;
|
|
491
495
|
}
|
|
492
496
|
}
|
|
493
497
|
isSendingJobs = false;
|
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ var SocketClient = class {
|
|
|
14
14
|
}
|
|
15
15
|
send(payload) {
|
|
16
16
|
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
17
|
-
throw new Error("
|
|
17
|
+
throw new Error("notready");
|
|
18
18
|
}
|
|
19
19
|
this.socket.send(JSON.stringify(payload));
|
|
20
20
|
}
|
|
@@ -30,13 +30,10 @@ var SocketClient = class {
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
// src/utils/generateIds.ts
|
|
33
|
-
function generateTimestamp() {
|
|
34
|
-
const now = /* @__PURE__ */ new Date();
|
|
35
|
-
return now.getFullYear().toString() + String(now.getMonth() + 1).padStart(2, "0") + String(now.getDate()).padStart(2, "0") + String(now.getHours()).padStart(2, "0") + String(now.getMinutes()).padStart(2, "0") + String(now.getSeconds()).padStart(2, "0") + String(now.getMilliseconds()).padStart(3, "0") + Math.floor(Math.random() * 1e3).toString().padStart(3, "0");
|
|
36
|
-
}
|
|
37
33
|
function generateJobId(app_id, user_id, dataId) {
|
|
38
|
-
const timestamp =
|
|
39
|
-
const
|
|
34
|
+
const timestamp = Date.now().toString(36);
|
|
35
|
+
const random = crypto.getRandomValues(new Uint32Array(1))[0].toString(36);
|
|
36
|
+
const jobId = `${app_id}_${user_id}_${dataId}_${timestamp}_${random}`;
|
|
40
37
|
return jobId;
|
|
41
38
|
}
|
|
42
39
|
|
|
@@ -169,7 +166,7 @@ function clearSession() {
|
|
|
169
166
|
}
|
|
170
167
|
|
|
171
168
|
// src/core/connectionManager.ts
|
|
172
|
-
var isDev =
|
|
169
|
+
var isDev = true;
|
|
173
170
|
var context = null;
|
|
174
171
|
var socketClient = null;
|
|
175
172
|
var isConnecting = false;
|
|
@@ -187,37 +184,31 @@ async function resolveWsUrl() {
|
|
|
187
184
|
const data = await res.json();
|
|
188
185
|
const wsUrl = data.wsUrl;
|
|
189
186
|
if (!wsUrl)
|
|
190
|
-
throw new Error("WebSocket URL resolution failed");
|
|
187
|
+
throw new Error("Satyamark: WebSocket URL resolution failed");
|
|
191
188
|
return wsUrl;
|
|
192
189
|
}
|
|
193
190
|
async function init(newContext) {
|
|
194
|
-
if (!(newContext == null ? void 0 : newContext.app_id) || !(newContext == null ? void 0 : newContext.user_id)) {
|
|
195
|
-
throw new Error("init() requires valid app_id and user_id");
|
|
196
|
-
}
|
|
197
|
-
if (isConnecting || isConnected)
|
|
198
|
-
return;
|
|
199
191
|
context = newContext;
|
|
200
192
|
await connect();
|
|
201
193
|
}
|
|
202
194
|
async function connect() {
|
|
203
|
-
if (!context)
|
|
204
|
-
return;
|
|
205
195
|
if (isConnecting || isConnected)
|
|
206
196
|
return;
|
|
207
197
|
isConnecting = true;
|
|
208
198
|
const url = await resolveWsUrl();
|
|
209
199
|
socketClient = new SocketClient(url, {
|
|
210
200
|
onOpen: async () => {
|
|
201
|
+
const ctx = getContext();
|
|
211
202
|
const sessionId = await getSessionId();
|
|
212
203
|
socketClient == null ? void 0 : socketClient.send({
|
|
213
204
|
type: "handshake",
|
|
214
|
-
clientId:
|
|
215
|
-
app_id:
|
|
205
|
+
clientId: ctx.user_id,
|
|
206
|
+
app_id: ctx.app_id,
|
|
216
207
|
sessionId
|
|
217
208
|
});
|
|
218
209
|
isConnected = true;
|
|
219
210
|
isConnecting = false;
|
|
220
|
-
emitConnection(
|
|
211
|
+
emitConnection(ctx);
|
|
221
212
|
},
|
|
222
213
|
onMessage: async (data) => {
|
|
223
214
|
if (data.type === "session_created" && data.sessionId) {
|
|
@@ -257,19 +248,18 @@ function scheduleReconnect() {
|
|
|
257
248
|
connect();
|
|
258
249
|
}, 2e3);
|
|
259
250
|
}
|
|
260
|
-
|
|
261
|
-
if (!context)
|
|
262
|
-
throw new Error("Satyamark
|
|
263
|
-
if (!text && !imageUrl) {
|
|
264
|
-
throw new Error("Provide text or imageUrl");
|
|
265
|
-
}
|
|
266
|
-
if (text && text.trim().length < 3) {
|
|
267
|
-
throw new Error("Text must be at least 3 characters");
|
|
251
|
+
function getContext() {
|
|
252
|
+
if (!(context == null ? void 0 : context.app_id) || !(context == null ? void 0 : context.user_id)) {
|
|
253
|
+
throw new Error("Satyamark: Invalid app_id and user_id in init()");
|
|
268
254
|
}
|
|
269
|
-
|
|
255
|
+
return context;
|
|
256
|
+
}
|
|
257
|
+
async function sendJob(text, imageUrl, dataId) {
|
|
258
|
+
const ctx = getContext();
|
|
259
|
+
const jobId = generateJobId(ctx.app_id, ctx.user_id, dataId);
|
|
270
260
|
const sessionId = await getSessionId();
|
|
271
261
|
socketClient == null ? void 0 : socketClient.send({
|
|
272
|
-
clientId:
|
|
262
|
+
clientId: ctx.user_id,
|
|
273
263
|
sessionId,
|
|
274
264
|
jobId,
|
|
275
265
|
text,
|
|
@@ -381,7 +371,7 @@ function updateIcon(containerRef, data) {
|
|
|
381
371
|
}
|
|
382
372
|
|
|
383
373
|
// src/utils/process_data.ts
|
|
384
|
-
var mergeText = (texts) => texts.join("
|
|
374
|
+
var mergeText = (texts) => texts.join(" |#| ");
|
|
385
375
|
var isValidImageUrl = (url) => {
|
|
386
376
|
return new Promise((resolve) => {
|
|
387
377
|
const img = new Image();
|
|
@@ -411,20 +401,20 @@ var extractFromDiv = (root) => {
|
|
|
411
401
|
return { text, images };
|
|
412
402
|
};
|
|
413
403
|
async function process_data(divRef, dataId) {
|
|
414
|
-
if (!divRef) {
|
|
415
|
-
throw new Error("Invalid root element");
|
|
416
|
-
}
|
|
417
404
|
if (!dataId) {
|
|
418
|
-
throw new Error("
|
|
405
|
+
throw new Error("Satyamark: Invalid dataId");
|
|
406
|
+
}
|
|
407
|
+
if (!divRef) {
|
|
408
|
+
throw new Error("Satyamark: Invalid root element");
|
|
419
409
|
}
|
|
420
410
|
const { text, images } = extractFromDiv(divRef);
|
|
421
411
|
const mergedText = mergeText(text);
|
|
422
412
|
const validImage = await getFirstValidImage(images);
|
|
423
413
|
if (!mergedText && !validImage) {
|
|
424
|
-
throw new Error("No valid text or image found in the element");
|
|
414
|
+
throw new Error("Satyamark: No valid text or image found in the element");
|
|
425
415
|
}
|
|
426
416
|
if (mergedText && mergedText.length < 3) {
|
|
427
|
-
throw new Error("Extracted text is too short");
|
|
417
|
+
throw new Error("Satyamark: Extracted text is too short");
|
|
428
418
|
}
|
|
429
419
|
const image_url = validImage ? validImage : "";
|
|
430
420
|
return { text: mergedText, image_url };
|
|
@@ -436,9 +426,20 @@ var isSendingJobs = false;
|
|
|
436
426
|
var jobMap = /* @__PURE__ */ new Map();
|
|
437
427
|
var process_queue = [];
|
|
438
428
|
function process(containerRef, dataId) {
|
|
429
|
+
validateStatusContainer(containerRef);
|
|
439
430
|
process_queue.push({ containerRef, dataId });
|
|
440
431
|
void sendJobs();
|
|
441
432
|
}
|
|
433
|
+
function validateStatusContainer(containerRef) {
|
|
434
|
+
const statusContainer = containerRef.querySelector(
|
|
435
|
+
"[data-satyamark-status-container]"
|
|
436
|
+
);
|
|
437
|
+
if (!statusContainer) {
|
|
438
|
+
throw new Error(
|
|
439
|
+
'Satyamark: Missing element with attribute "data-satyamark-status-container" inside containerRef.'
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
442
443
|
async function sendJobs() {
|
|
443
444
|
if (isSendingJobs || !isConnected2)
|
|
444
445
|
return;
|
|
@@ -455,11 +456,14 @@ async function sendJobs() {
|
|
|
455
456
|
process_queue.shift();
|
|
456
457
|
updateIcon(containerRef, null);
|
|
457
458
|
} catch (error) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
459
|
+
if (error instanceof Error && error.message === "notready") {
|
|
460
|
+
isSendingJobs = false;
|
|
461
|
+
setTimeout(() => {
|
|
462
|
+
void sendJobs();
|
|
463
|
+
}, 1e3);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
throw error;
|
|
463
467
|
}
|
|
464
468
|
}
|
|
465
469
|
isSendingJobs = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "satyamark-react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "Official React SDK for SatyaMark — a lightweight UI library to embed transparent content verification marks, confidence indicators, and trust signals into React applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "DK",
|