pythx-cli 0.0.4 → 0.0.5
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/cli.js +129 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
2
7
|
|
|
3
8
|
// src/cli.tsx
|
|
4
9
|
import { render } from "ink";
|
|
@@ -444,6 +449,11 @@ import { drizzle } from "drizzle-orm/postgres-js";
|
|
|
444
449
|
import postgres from "postgres";
|
|
445
450
|
|
|
446
451
|
// ../core/src/db/schema.ts
|
|
452
|
+
var schema_exports = {};
|
|
453
|
+
__export(schema_exports, {
|
|
454
|
+
posts: () => posts,
|
|
455
|
+
snapshots: () => snapshots
|
|
456
|
+
});
|
|
447
457
|
import {
|
|
448
458
|
pgTable,
|
|
449
459
|
serial,
|
|
@@ -507,8 +517,94 @@ var posts = pgTable(
|
|
|
507
517
|
]
|
|
508
518
|
);
|
|
509
519
|
|
|
520
|
+
// ../core/src/db/client.ts
|
|
521
|
+
var db = null;
|
|
522
|
+
function getDb() {
|
|
523
|
+
if (db) return db;
|
|
524
|
+
const connectionString = process.env.POSTGRES_URL;
|
|
525
|
+
if (!connectionString) {
|
|
526
|
+
throw new Error("POSTGRES_URL environment variable is required");
|
|
527
|
+
}
|
|
528
|
+
const client = postgres(connectionString, { prepare: false });
|
|
529
|
+
db = drizzle(client, { schema: schema_exports });
|
|
530
|
+
return db;
|
|
531
|
+
}
|
|
532
|
+
|
|
510
533
|
// ../core/src/db/store.ts
|
|
511
534
|
import { desc, eq } from "drizzle-orm";
|
|
535
|
+
async function persistAnalysis(entityId, snapshot, posts2, modelId) {
|
|
536
|
+
const db2 = getDb();
|
|
537
|
+
await db2.insert(schema_exports.snapshots).values({
|
|
538
|
+
entityId,
|
|
539
|
+
source: null,
|
|
540
|
+
avgScore: snapshot.averageScore,
|
|
541
|
+
positiveCount: snapshot.distribution.positive,
|
|
542
|
+
negativeCount: snapshot.distribution.negative,
|
|
543
|
+
neutralCount: snapshot.distribution.neutral,
|
|
544
|
+
totalCount: snapshot.distribution.total
|
|
545
|
+
});
|
|
546
|
+
for (const breakdown of snapshot.bySource) {
|
|
547
|
+
await db2.insert(schema_exports.snapshots).values({
|
|
548
|
+
entityId,
|
|
549
|
+
source: breakdown.source,
|
|
550
|
+
avgScore: breakdown.averageScore,
|
|
551
|
+
positiveCount: breakdown.distribution.positive,
|
|
552
|
+
negativeCount: breakdown.distribution.negative,
|
|
553
|
+
neutralCount: breakdown.distribution.neutral,
|
|
554
|
+
totalCount: breakdown.distribution.total
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
if (posts2.length > 0) {
|
|
558
|
+
await db2.insert(schema_exports.posts).values(
|
|
559
|
+
posts2.map((post) => ({
|
|
560
|
+
externalId: post.id,
|
|
561
|
+
source: post.source,
|
|
562
|
+
entityId,
|
|
563
|
+
text: post.text,
|
|
564
|
+
authorId: post.authorId,
|
|
565
|
+
authorUsername: post.authorUsername ?? null,
|
|
566
|
+
url: post.url,
|
|
567
|
+
createdAt: new Date(post.createdAt),
|
|
568
|
+
upvotes: post.metrics.upvotes,
|
|
569
|
+
comments: post.metrics.comments,
|
|
570
|
+
shares: post.metrics.shares,
|
|
571
|
+
sentimentLabel: post.sentiment.label,
|
|
572
|
+
sentimentConfidence: post.sentiment.score,
|
|
573
|
+
modelId
|
|
574
|
+
}))
|
|
575
|
+
).onConflictDoNothing({ target: [schema_exports.posts.externalId, schema_exports.posts.source] });
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
async function persistEntityAnalysis(analysis, modelId) {
|
|
579
|
+
await persistAnalysis(
|
|
580
|
+
analysis.entity.id,
|
|
581
|
+
analysis.snapshot,
|
|
582
|
+
analysis.posts,
|
|
583
|
+
modelId
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
async function loadCachedPosts(entityId, limit = 50) {
|
|
587
|
+
const db2 = getDb();
|
|
588
|
+
const rows = await db2.select().from(schema_exports.posts).where(eq(schema_exports.posts.entityId, entityId)).orderBy(desc(schema_exports.posts.createdAt)).limit(limit);
|
|
589
|
+
return rows.map((row) => ({
|
|
590
|
+
id: row.externalId,
|
|
591
|
+
source: row.source,
|
|
592
|
+
text: row.text,
|
|
593
|
+
authorId: row.authorId ?? "",
|
|
594
|
+
authorUsername: row.authorUsername ?? void 0,
|
|
595
|
+
createdAt: row.createdAt.toISOString(),
|
|
596
|
+
url: row.url ?? "",
|
|
597
|
+
metrics: {
|
|
598
|
+
upvotes: row.upvotes ?? 0,
|
|
599
|
+
comments: row.comments ?? 0,
|
|
600
|
+
shares: row.shares ?? 0
|
|
601
|
+
},
|
|
602
|
+
sentiment: {
|
|
603
|
+
label: row.sentimentLabel,
|
|
604
|
+
score: row.sentimentConfidence
|
|
605
|
+
}
|
|
606
|
+
}));
|
|
607
|
+
}
|
|
512
608
|
|
|
513
609
|
// src/hooks/use-live-data.ts
|
|
514
610
|
var POLL_INTERVAL = 30 * 6e4;
|
|
@@ -542,6 +638,21 @@ function useLiveData(apiUrl) {
|
|
|
542
638
|
setLoading(false);
|
|
543
639
|
}
|
|
544
640
|
}, [apiUrl]);
|
|
641
|
+
const loadFromCache = useCallback(async () => {
|
|
642
|
+
const results = [];
|
|
643
|
+
for (const entity of DEFAULT_ENTITIES) {
|
|
644
|
+
const cached = await loadCachedPosts(entity.id, 50);
|
|
645
|
+
if (cached.length === 0) continue;
|
|
646
|
+
const snapshot = aggregate(cached);
|
|
647
|
+
results.push({
|
|
648
|
+
entity,
|
|
649
|
+
snapshot,
|
|
650
|
+
posts: cached,
|
|
651
|
+
fetchedAt: cached[0]?.sentiment ? (/* @__PURE__ */ new Date()).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
return results;
|
|
655
|
+
}, []);
|
|
545
656
|
const fetchDirect = useCallback(async () => {
|
|
546
657
|
try {
|
|
547
658
|
const results = [];
|
|
@@ -554,22 +665,37 @@ function useLiveData(apiUrl) {
|
|
|
554
665
|
allClassified.push(...classified);
|
|
555
666
|
}
|
|
556
667
|
const snapshot = aggregate(allClassified);
|
|
557
|
-
|
|
668
|
+
const analysis = {
|
|
558
669
|
entity,
|
|
559
670
|
snapshot,
|
|
560
671
|
posts: allClassified,
|
|
561
672
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
562
|
-
}
|
|
673
|
+
};
|
|
674
|
+
results.push(analysis);
|
|
675
|
+
try {
|
|
676
|
+
await persistEntityAnalysis(analysis, "hf-default");
|
|
677
|
+
} catch {
|
|
678
|
+
}
|
|
563
679
|
}
|
|
564
680
|
setData(results);
|
|
565
681
|
setLastUpdated(/* @__PURE__ */ new Date());
|
|
566
682
|
setError(null);
|
|
567
683
|
} catch (err) {
|
|
684
|
+
try {
|
|
685
|
+
const cached = await loadFromCache();
|
|
686
|
+
if (cached.length > 0) {
|
|
687
|
+
setData(cached);
|
|
688
|
+
setLastUpdated(/* @__PURE__ */ new Date());
|
|
689
|
+
setError("Live fetch failed \u2014 showing cached data");
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
} catch {
|
|
693
|
+
}
|
|
568
694
|
setError(err instanceof Error ? err.message : "Analysis failed");
|
|
569
695
|
} finally {
|
|
570
696
|
setLoading(false);
|
|
571
697
|
}
|
|
572
|
-
}, []);
|
|
698
|
+
}, [loadFromCache]);
|
|
573
699
|
const fetchData = apiUrl ? fetchViaApi : fetchDirect;
|
|
574
700
|
useEffect2(() => {
|
|
575
701
|
fetchData();
|