@pydantic/genai-prices 0.0.19 → 0.0.21

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.
@@ -1,18 +0,0 @@
1
- import { Provider, PriceDataStorage } from './types.js';
2
- export declare function setStorageBackend(storage: PriceDataStorage): void;
3
- export declare function fetchRemoteData(): Promise<Provider[]>;
4
- export declare function getProvidersAsync(): Promise<Provider[]>;
5
- export declare function enableAutoUpdate(options?: {
6
- url?: string;
7
- ttlMs?: number;
8
- storage?: PriceDataStorage;
9
- }): void;
10
- export declare function isLocalDataOutdated(): Promise<boolean>;
11
- export declare function prefetchAsync(): void;
12
- export declare function getProvidersSync(): Provider[];
13
- export declare function getEnvironmentInfo(): {
14
- environment: "node" | "browser" | "cloudflare" | "deno" | "unknown";
15
- hasFetch: boolean;
16
- hasProcess: boolean;
17
- hasWindow: boolean;
18
- };
@@ -1,146 +0,0 @@
1
- import { data as embeddedData } from './data.js';
2
- const DEFAULT_URL = 'https://raw.githubusercontent.com/pydantic/genai-prices/main/prices/data.json';
3
- const DEFAULT_TTL_MS = 60 * 60 * 1000; // 1 hour
4
- const OUTDATED_THRESHOLD_MS = 24 * 60 * 60 * 1000; // 1 day
5
- const BACKGROUND_REFRESH_MS = 30 * 60 * 1000; // 30 minutes
6
- // environment detection
7
- function detectEnvironment() {
8
- if (typeof globalThis !== 'undefined' && 'caches' in globalThis && 'default' in globalThis.caches) {
9
- return 'cloudflare';
10
- }
11
- if (typeof globalThis.Deno !== 'undefined') {
12
- return 'deno';
13
- }
14
- if (typeof process !== 'undefined' && process.versions && process.versions.node) {
15
- return 'node';
16
- }
17
- if (typeof window !== 'undefined' && typeof document !== 'undefined') {
18
- return 'browser';
19
- }
20
- return 'unknown';
21
- }
22
- async function universalFetch(url, options = {}) {
23
- const env = detectEnvironment();
24
- if (env === 'node') {
25
- const { default: nodeFetch } = await import('node-fetch');
26
- return nodeFetch(url, options);
27
- }
28
- if (typeof fetch !== 'undefined') {
29
- return fetch(url, options);
30
- }
31
- throw new Error(`Fetch not available in environment: ${env}`);
32
- }
33
- // storage implementation
34
- let inMemoryData = null;
35
- let inMemoryLastModified = null;
36
- const universalStorage = {
37
- get: async () => inMemoryData,
38
- set: async (data) => {
39
- inMemoryData = data;
40
- inMemoryLastModified = Date.now();
41
- },
42
- get_last_modified: async () => inMemoryLastModified,
43
- };
44
- let storageBackend = universalStorage;
45
- let asyncProviders = null;
46
- let asyncLastLoaded = 0;
47
- let asyncFetchPromise = null;
48
- let autoUpdate = false;
49
- let remoteUrl = DEFAULT_URL;
50
- let ttlMs = DEFAULT_TTL_MS;
51
- export function setStorageBackend(storage) {
52
- storageBackend = storage;
53
- }
54
- async function loadDataAsync() {
55
- const raw = await storageBackend.get();
56
- if (!raw)
57
- throw new Error('No data found in storage backend');
58
- const data = JSON.parse(raw);
59
- return Array.isArray(data) ? data : [];
60
- }
61
- async function saveDataAsync(data) {
62
- await storageBackend.set(data);
63
- }
64
- export async function fetchRemoteData() {
65
- const res = await universalFetch(remoteUrl, { cache: 'no-store' });
66
- if (!res.ok)
67
- throw new Error(`Failed to fetch data: ${res.statusText}`);
68
- const data = await res.text();
69
- await saveDataAsync(data);
70
- const parsed = JSON.parse(data);
71
- return Array.isArray(parsed) ? parsed : [];
72
- }
73
- export async function getProvidersAsync() {
74
- const now = Date.now();
75
- if (asyncProviders && now - asyncLastLoaded < ttlMs) {
76
- if (now - asyncLastLoaded > BACKGROUND_REFRESH_MS && !asyncFetchPromise) {
77
- asyncFetchPromise = (async () => {
78
- try {
79
- asyncProviders = await fetchRemoteData();
80
- asyncLastLoaded = Date.now();
81
- return asyncProviders;
82
- }
83
- catch (e) {
84
- return asyncProviders;
85
- }
86
- finally {
87
- asyncFetchPromise = null;
88
- }
89
- })();
90
- }
91
- return asyncProviders;
92
- }
93
- if (asyncFetchPromise) {
94
- return asyncFetchPromise;
95
- }
96
- asyncFetchPromise = (async () => {
97
- try {
98
- asyncProviders = await fetchRemoteData();
99
- asyncLastLoaded = Date.now();
100
- return asyncProviders;
101
- }
102
- catch (e) {
103
- asyncProviders = await loadDataAsync();
104
- asyncLastLoaded = Date.now();
105
- return asyncProviders;
106
- }
107
- finally {
108
- asyncFetchPromise = null;
109
- }
110
- })();
111
- return asyncFetchPromise;
112
- }
113
- export function enableAutoUpdate(options) {
114
- autoUpdate = true;
115
- if (options?.url)
116
- remoteUrl = options.url;
117
- if (options?.ttlMs)
118
- ttlMs = options.ttlMs;
119
- if (options?.storage)
120
- setStorageBackend(options.storage);
121
- }
122
- export async function isLocalDataOutdated() {
123
- if (!storageBackend.get_last_modified)
124
- return false;
125
- const ts = await storageBackend.get_last_modified();
126
- if (!ts)
127
- return true;
128
- return Date.now() - ts > OUTDATED_THRESHOLD_MS;
129
- }
130
- export function prefetchAsync() {
131
- if (!asyncFetchPromise) {
132
- asyncFetchPromise = getProvidersAsync();
133
- }
134
- }
135
- // sync function that works everywhere
136
- export function getProvidersSync() {
137
- return embeddedData;
138
- }
139
- export function getEnvironmentInfo() {
140
- return {
141
- environment: detectEnvironment(),
142
- hasFetch: typeof fetch !== 'undefined',
143
- hasProcess: typeof process !== 'undefined',
144
- hasWindow: typeof window !== 'undefined',
145
- };
146
- }