edgevector
Version:
Official TypeScript/JavaScript SDK for EdgeVector - Edge-native multi-paradigm database with AI-first features
217 lines (212 loc) • 6.94 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var index = require('./index');
/**
* EdgeVector Edge Runtime SDK
* Optimized for Cloudflare Workers, Vercel Edge Functions, and other edge runtimes
*/
/**
* Edge-optimized EdgeVector client
*/
class EdgeVectorEdge extends index.EdgeVector {
constructor(config = {}) {
// Extract edge-specific config
const { env, ctx, request: req, ...baseConfig } = config;
// Auto-configure from environment
const edgeConfig = {
apiKey: baseConfig.apiKey || env?.EDGEVECTOR_API_KEY,
endpoint: baseConfig.endpoint || env?.EDGEVECTOR_ENDPOINT || 'https://edgevector-db.finhub.workers.dev',
...baseConfig
};
super(edgeConfig);
this.env = env;
this.ctx = ctx;
this.request = req;
}
/**
* Create instance from Cloudflare Workers environment
*/
static fromWorker(request, env, ctx) {
return new EdgeVectorEdge({
env,
ctx,
request,
apiKey: env.EDGEVECTOR_API_KEY,
endpoint: env.EDGEVECTOR_ENDPOINT
});
}
/**
* Create instance from Vercel Edge Functions
*/
static fromVercel(request) {
return new EdgeVectorEdge({
request,
apiKey: process.env.EDGEVECTOR_API_KEY,
endpoint: process.env.EDGEVECTOR_ENDPOINT
});
}
/**
* Create instance from Next.js Edge Runtime
*/
static fromNextJS(request) {
return new EdgeVectorEdge({
request,
apiKey: process.env.EDGEVECTOR_API_KEY,
endpoint: process.env.EDGEVECTOR_ENDPOINT
});
}
/**
* Get client IP address from edge request
*/
getClientIP() {
if (!this.request)
return null;
// Cloudflare
const cfConnectingIP = this.request.headers.get('cf-connecting-ip');
if (cfConnectingIP)
return cfConnectingIP;
// Vercel
const xForwardedFor = this.request.headers.get('x-forwarded-for');
if (xForwardedFor)
return xForwardedFor.split(',')[0].trim();
// Standard
const xRealIP = this.request.headers.get('x-real-ip');
if (xRealIP)
return xRealIP;
return null;
}
/**
* Get edge location/region
*/
getEdgeLocation() {
if (!this.request)
return null;
// Cloudflare
const cfRay = this.request.headers.get('cf-ray');
if (cfRay)
return cfRay.split('-')[1]; // Extract colo code
// Vercel
const vercelRegion = this.request.headers.get('x-vercel-id');
if (vercelRegion)
return vercelRegion;
return null;
}
/**
* Get country from edge headers
*/
getCountry() {
if (!this.request)
return null;
// Cloudflare
const cfCountry = this.request.headers.get('cf-ipcountry');
if (cfCountry)
return cfCountry;
// Vercel
const vercelCountry = this.request.headers.get('x-vercel-ip-country');
if (vercelCountry)
return vercelCountry;
return null;
}
/**
* Create response with edge optimizations
*/
createResponse(data, options = {}) {
const headers = new Headers(options.headers);
// Add edge-specific headers
headers.set('Content-Type', 'application/json');
headers.set('X-Edge-Runtime', 'EdgeVector');
// Add caching headers for edge
if (!headers.has('Cache-Control')) {
headers.set('Cache-Control', 'public, s-maxage=60, stale-while-revalidate=300');
}
// CORS for edge functions
if (this.request) {
const origin = this.request.headers.get('Origin');
if (origin) {
headers.set('Access-Control-Allow-Origin', origin);
headers.set('Access-Control-Allow-Credentials', 'true');
}
}
return new Response(JSON.stringify(data), {
...options,
headers
});
}
/**
* Handle preflight CORS requests
*/
handleCORS() {
const headers = new Headers();
headers.set('Access-Control-Allow-Origin', '*');
headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key');
headers.set('Access-Control-Max-Age', '86400'); // 24 hours
return new Response(null, { status: 204, headers });
}
/**
* Log analytics event to edge runtime
*/
async logEvent(event, data = {}) {
const logData = {
event,
data,
timestamp: Date.now(),
ip: this.getClientIP(),
country: this.getCountry(),
region: this.getEdgeLocation(),
userAgent: this.request?.headers.get('user-agent')
};
// In Cloudflare Workers, you could send to Analytics Engine
if (this.env && 'ANALYTICS' in this.env) ;
// In Vercel, you could send to their analytics
if (typeof process !== 'undefined' && process.env.VERCEL) ;
console.log('EdgeVector Event:', logData);
}
/**
* Wait for async operations before response (edge runtime utility)
*/
waitUntil(promise) {
if (this.ctx && 'waitUntil' in this.ctx) {
this.ctx.waitUntil(promise);
}
}
}
// Convenience functions for common edge patterns
function createEdgeHandler(apiKey) {
return {
async GET(request, env, ctx) {
const client = new EdgeVectorEdge({
request,
env,
ctx,
apiKey: apiKey || env?.EDGEVECTOR_API_KEY
});
const health = await client.health();
return client.createResponse(health);
},
async POST(request, env, ctx) {
const client = new EdgeVectorEdge({
request,
env,
ctx,
apiKey: apiKey || env?.EDGEVECTOR_API_KEY
});
try {
const body = await request.json();
// Handle the request based on body
return client.createResponse({ success: true, data: body });
}
catch (error) {
return client.createResponse({ error: error.message }, { status: 400 });
}
},
async OPTIONS(request) {
const client = new EdgeVectorEdge({ request });
return client.handleCORS();
}
};
}
exports.EdgeVectorEdge = EdgeVectorEdge;
exports.createEdgeHandler = createEdgeHandler;
exports.default = EdgeVectorEdge;
//# sourceMappingURL=edge.js.map