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.
Files changed (2) hide show
  1. package/dist/cli.js +129 -3
  2. 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
- results.push({
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pythx-cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Real-time sentiment intelligence terminal for prediction markets",
5
5
  "type": "module",
6
6
  "bin": {