254 lines
7.9 KiB
JavaScript
254 lines
7.9 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Game Iframe SDK - Core
|
|
* SDK chính - compose các layers: MessageHandler, MessageSender
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.GameIframeSDK = void 0;
|
|
exports.createGameIframeSDK = createGameIframeSDK;
|
|
exports.getGameIframeSDK = getGameIframeSDK;
|
|
exports.destroyGameIframeSDK = destroyGameIframeSDK;
|
|
const EventEmitter_1 = require("./EventEmitter");
|
|
const MessageHandler_1 = require("./MessageHandler");
|
|
const MessageSender_1 = require("./MessageSender");
|
|
const types_1 = require("./types");
|
|
/**
|
|
* GameIframeSDK - Main SDK class
|
|
* Composes MessageHandler và MessageSender
|
|
*/
|
|
class GameIframeSDK extends EventEmitter_1.EventEmitter {
|
|
constructor(config) {
|
|
super();
|
|
this.pendingData = null;
|
|
this.isReady = false;
|
|
this.config = { ...types_1.DEFAULT_CONFIG, ...config };
|
|
// Initialize layers
|
|
this.messageHandler = new MessageHandler_1.MessageHandler({
|
|
acceptedOrigin: this.config.iframeOrigin,
|
|
debug: this.config.debug,
|
|
});
|
|
this.messageSender = new MessageSender_1.MessageSender({
|
|
targetOrigin: this.config.iframeOrigin,
|
|
debug: this.config.debug,
|
|
});
|
|
// Setup event forwarding
|
|
this.setupEventForwarding();
|
|
// Start listening
|
|
this.messageHandler.start();
|
|
this.log('info', 'SDK initialized', { config: this.config });
|
|
}
|
|
// ==========================================================================
|
|
// PUBLIC API - Iframe Management
|
|
// ==========================================================================
|
|
/**
|
|
* Set iframe element reference
|
|
*/
|
|
setIframe(iframe) {
|
|
this.messageSender.setIframe(iframe);
|
|
this.isReady = false;
|
|
this.log('info', 'Iframe set', { hasIframe: !!iframe });
|
|
return this;
|
|
}
|
|
/**
|
|
* Get current iframe
|
|
*/
|
|
getIframe() {
|
|
return this.messageSender.getIframe();
|
|
}
|
|
/**
|
|
* Check if game is ready
|
|
*/
|
|
isGameReady() {
|
|
return this.isReady;
|
|
}
|
|
/**
|
|
* Check if sender is ready (iframe available)
|
|
*/
|
|
isSenderReady() {
|
|
return this.messageSender.isReady();
|
|
}
|
|
// ==========================================================================
|
|
// PUBLIC API - Send Data
|
|
// ==========================================================================
|
|
/**
|
|
* Send game data to iframe
|
|
*/
|
|
sendGameData(data) {
|
|
const result = this.messageSender.sendGameData(data);
|
|
if (!result.success) {
|
|
this.emit('error', {
|
|
message: 'Failed to send game data',
|
|
error: result.error,
|
|
});
|
|
}
|
|
return result.success;
|
|
}
|
|
/**
|
|
* Send leaderboard data to iframe
|
|
*/
|
|
sendLeaderboard(data) {
|
|
const result = this.messageSender.sendLeaderboard(data);
|
|
if (!result.success) {
|
|
this.emit('error', {
|
|
message: 'Failed to send leaderboard',
|
|
error: result.error,
|
|
});
|
|
}
|
|
return result.success;
|
|
}
|
|
// ==========================================================================
|
|
// PUBLIC API - Queue & Auto-send
|
|
// ==========================================================================
|
|
/**
|
|
* Queue data to be sent when game is ready
|
|
*/
|
|
queueGameData(data) {
|
|
this.pendingData = data;
|
|
this.log('info', 'Data queued for when game is ready');
|
|
// If already ready, send immediately
|
|
if (this.isReady) {
|
|
this.sendQueuedData();
|
|
}
|
|
return this;
|
|
}
|
|
/**
|
|
* Clear queued data
|
|
*/
|
|
clearQueuedData() {
|
|
this.pendingData = null;
|
|
return this;
|
|
}
|
|
// ==========================================================================
|
|
// PUBLIC API - Iframe Control
|
|
// ==========================================================================
|
|
/**
|
|
* Force reload iframe
|
|
*/
|
|
reloadIframe() {
|
|
this.isReady = false;
|
|
return this.messageSender.reloadIframe();
|
|
}
|
|
// ==========================================================================
|
|
// PUBLIC API - Lifecycle
|
|
// ==========================================================================
|
|
/**
|
|
* Cleanup and destroy SDK
|
|
*/
|
|
destroy() {
|
|
this.messageHandler.destroy();
|
|
this.removeAllListeners();
|
|
this.pendingData = null;
|
|
this.isReady = false;
|
|
this.log('info', 'SDK destroyed');
|
|
}
|
|
// ==========================================================================
|
|
// PUBLIC API - Direct Layer Access (Advanced)
|
|
// ==========================================================================
|
|
/**
|
|
* Get MessageHandler instance for advanced usage
|
|
*/
|
|
getMessageHandler() {
|
|
return this.messageHandler;
|
|
}
|
|
/**
|
|
* Get MessageSender instance for advanced usage
|
|
*/
|
|
getMessageSender() {
|
|
return this.messageSender;
|
|
}
|
|
// ==========================================================================
|
|
// PRIVATE METHODS
|
|
// ==========================================================================
|
|
/**
|
|
* Setup event forwarding from MessageHandler to SDK events
|
|
*/
|
|
setupEventForwarding() {
|
|
// Forward gameReady
|
|
this.messageHandler.on('gameReady', () => {
|
|
this.isReady = true;
|
|
this.emit('gameReady', undefined);
|
|
// Auto-send queued data if enabled
|
|
if (this.config.autoSendOnReady && this.pendingData) {
|
|
setTimeout(() => {
|
|
this.sendQueuedData();
|
|
}, this.config.readyDelay);
|
|
}
|
|
});
|
|
// Forward answerReport
|
|
this.messageHandler.on('answerReport', (data) => {
|
|
this.emit('answerReport', data);
|
|
});
|
|
// Forward finalResult
|
|
this.messageHandler.on('finalResult', (data) => {
|
|
this.emit('finalResult', data);
|
|
});
|
|
// Forward leaderboardRequest
|
|
this.messageHandler.on('leaderboardRequest', (data) => {
|
|
this.emit('leaderboardRequest', data);
|
|
});
|
|
// Forward errors
|
|
this.messageHandler.on('error', (error) => {
|
|
this.emit('error', error);
|
|
});
|
|
}
|
|
/**
|
|
* Send queued data
|
|
*/
|
|
sendQueuedData() {
|
|
if (this.pendingData) {
|
|
this.sendGameData(this.pendingData);
|
|
this.pendingData = null;
|
|
}
|
|
}
|
|
/**
|
|
* Internal logging
|
|
*/
|
|
log(level, message, data) {
|
|
if (this.config.debug) {
|
|
const prefix = '[GameIframeSDK]';
|
|
switch (level) {
|
|
case 'info':
|
|
console.log(prefix, message, data ?? '');
|
|
break;
|
|
case 'warn':
|
|
console.warn(prefix, message, data ?? '');
|
|
break;
|
|
case 'error':
|
|
console.error(prefix, message, data ?? '');
|
|
break;
|
|
}
|
|
}
|
|
this.emit('log', { level, message, data });
|
|
}
|
|
}
|
|
exports.GameIframeSDK = GameIframeSDK;
|
|
// ==========================================================================
|
|
// FACTORY / SINGLETON HELPERS
|
|
// ==========================================================================
|
|
let defaultInstance = null;
|
|
/**
|
|
* Create SDK instance
|
|
*/
|
|
function createGameIframeSDK(config) {
|
|
return new GameIframeSDK(config);
|
|
}
|
|
/**
|
|
* Get or create default SDK instance
|
|
*/
|
|
function getGameIframeSDK(config) {
|
|
if (!defaultInstance && config) {
|
|
defaultInstance = new GameIframeSDK(config);
|
|
}
|
|
if (!defaultInstance) {
|
|
throw new Error('GameIframeSDK not initialized. Call with config first.');
|
|
}
|
|
return defaultInstance;
|
|
}
|
|
/**
|
|
* Destroy default instance
|
|
*/
|
|
function destroyGameIframeSDK() {
|
|
defaultInstance?.destroy();
|
|
defaultInstance = null;
|
|
}
|
|
//# sourceMappingURL=GameIframeSDK.js.map
|