1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* This tool fetches real-time data from various free APIs to create a JSON object
* representing the current state of the world from different perspectives.
* Data is cached for 30 minutes using Val Town's SQLite database to reduce API calls and improve performance.
*/
import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
const CACHE_DURATION = 30 * 60 * 1000; // 30 minutes in milliseconds
const KEY = new URL(import.meta.url).pathname.split("/").at(-1);
// Ensure the table exists
async function ensureTableExists() {
await sqlite.execute(`
CREATE TABLE IF NOT EXISTS ${KEY}_world_state (
id INTEGER PRIMARY KEY AUTOINCREMENT,
data TEXT NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
}
// Utility function for fetching JSON data
async function fetchJSON(url: string) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(`Error fetching ${url}:`, error);
return null;
}
}
// Convert Celsius to Fahrenheit
function celsiusToFahrenheit(celsius: number): number {
return (celsius * 9) / 5 + 32;
}
// Utility function for fetching Wolfram Alpha data
async function fetchWolframData(query: string) {
const appId = 'K8UTGR-8Y5G3A3VTP';
const url = `http://api.wolframalpha.com/v1/result?appid=${appId}&i=${encodeURIComponent(query)}`;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.text();
} catch (error) {
console.error(`Error fetching Wolfram data for query "${query}":`, error);
return null;
}
}
// Utility function for fetching Alpha Vantage stock data
async function fetchStockData(symbol: string) {
const apiKey = 'TD7I78XY3N2AGKWP';
const url = `https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=${symbol}&interval=5min&apikey=${apiKey}`;
try {
const data = await fetchJSON(url);
if (data && data['Time Series (5min)']) {
const latestTimestamp = Object.keys(data['Time Series (5min)'])[0];
return data['Time Series (5min)'][latestTimestamp]['4. close'];
} else {
console.error(`No price data found for symbol ${symbol}`);
return null;
}
} catch (error) {
console.error(`Error fetching stock data for symbol ${symbol}:`, error);
return null;
}
}
async function getWorldState(): Promise<object> {
// Ensure the table exists
await ensureTableExists();
// Check if we have a valid cached state
const cachedState = await sqlite.execute(`
SELECT data, timestamp FROM ${KEY}_world_state
WHERE timestamp > datetime('now', '-30 minutes')
ORDER BY timestamp DESC LIMIT 1
`);
if (cachedState.rows.length > 0) {
return JSON.parse(cachedState.rows[0].data);
}
// If no valid cache, fetch new data
const issData = await fetchJSON('http://api.open-notify.org/iss-now.json');
const weatherData = await fetchJSON('https://api.open-meteo.com/v1/forecast?latitude=40.71&longitude=-74.01&current_weather=true&temperature_unit=celsius&daily=temperature_2m_max,temperature_2m_min,sunrise,sunset&timezone=America%2FNew_York');
const airQualityData = await fetchJSON('https://api.waqi.info/feed/geo:40.71;-74.01/?token=demo');
const cryptoData = await fetchJSON('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,dogecoin,ripple,cardano,polkadot,litecoin&vs_currencies=usd');
const peopleInSpaceData = await fetchJSON('http://api.open-notify.org/astros.json');
const timeData = await fetchJSON('https://worldtimeapi.org/api/timezone/America/New_York,Europe/London,Asia/Tokyo');
const exchangeRateData = await fetchJSON('https://api.exchangerate-api.com/v4/latest/USD');
const usaCovidData = await fetchJSON('https://disease.sh/v3/covid-19/countries/USA');