@gftdcojp/gftd-orm
Version:
Enterprise-grade real-time data platform with ksqlDB, inspired by Supabase architecture
145 lines • 4.58 kB
JavaScript
/**
* ブラウザ専用クライアント(Next.js Client Components用)
*/
// Mock DatabaseClient implementation
// @todo [P2] Replace with actual DatabaseClient implementation
class DatabaseClient {
constructor(config) {
console.log('[MOCK] DatabaseClient created:', config);
}
async initialize() {
console.log('[MOCK] DatabaseClient initialized');
}
from(table) {
return {
select: () => ({
eq: () => ({
execute: () => Promise.resolve({ data: [], error: null })
})
}),
insert: (data) => Promise.resolve({ data: [], error: null }),
update: (data) => Promise.resolve({ data: [], error: null }),
delete: () => Promise.resolve({ data: [], error: null }),
execute: () => Promise.resolve({ data: [], error: null })
};
}
async sql(query, params) {
return { data: [], queryId: 'mock-query' };
}
async health() {
return { status: 'ok' };
}
}
import { RealtimeClient } from './realtime-client';
/**
* ブラウザ専用のGFTD-ORMクライアント
*/
export class BrowserClient {
constructor(config) {
this._database = null;
this._realtime = null;
this.initialized = false;
if (typeof globalThis === 'undefined' || typeof globalThis.window === 'undefined') {
throw new Error('BrowserClient can only be used in browser environment');
}
this.config = config;
}
/**
* データベースクライアントを取得
*/
get database() {
if (!this._database) {
throw new Error('Database not initialized. Call initialize() first.');
}
return this._database;
}
/**
* リアルタイムクライアントを取得
*/
get realtime() {
if (!this._realtime) {
throw new Error('Realtime not initialized. Call initialize() first.');
}
return this._realtime;
}
/**
* クライアントを初期化
*/
async initialize() {
if (this.initialized)
return;
try {
// Database初期化(ブラウザ版)
this._database = new DatabaseClient({
ksql: {
url: this.config.database.ksql.url,
apiKey: this.config.database.ksql.apiKey,
headers: this.config.database.ksql.headers,
},
schemaRegistry: {
url: this.config.database.schemaRegistry.url,
apiKey: this.config.database.schemaRegistry.apiKey,
},
});
await this._database.initialize();
// Realtime初期化(ブラウザ版)
if (this.config.realtime) {
this._realtime = new RealtimeClient(this.config.realtime);
}
this.initialized = true;
}
catch (error) {
console.error('Failed to initialize browser client:', error);
throw error;
}
}
/**
* Supabaseライクなテーブルアクセス
*/
from(table) {
return this.database.from(table);
}
/**
* リアルタイムチャンネル
*/
channel(name) {
if (!this._realtime) {
throw new Error('Realtime not configured. Please provide realtime config when creating the client.');
}
return this._realtime.channel(name);
}
/**
* SQL クエリを直接実行
*/
async sql(query, params) {
return this.database.sql(query, params);
}
/**
* ヘルスチェック
*/
async health() {
const results = await Promise.allSettled([
this.database.health(),
this._realtime ? Promise.resolve({ status: 'ok' }) : Promise.resolve({ status: 'disabled' }),
]);
return {
database: results[0].status === 'fulfilled' ? results[0].value : { status: 'error', details: results[0].reason },
realtime: results[1].status === 'fulfilled' ? results[1].value : { status: 'error' },
};
}
/**
* すべての接続を閉じる
*/
async disconnect() {
if (this._realtime) {
this._realtime.disconnect();
}
}
}
/**
* ブラウザ専用クライアント作成関数
*/
export function createBrowserClient(config) {
return new BrowserClient(config);
}
//# sourceMappingURL=browser-client.js.map