This commit is contained in:
465
G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js
vendored
Normal file
465
G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js
vendored
Normal file
@@ -0,0 +1,465 @@
|
||||
/**
|
||||
* SDK Iframe Core
|
||||
* Chạy trong hidden iframe riêng biệt
|
||||
*
|
||||
* Responsibilities:
|
||||
* - Receive data từ parent (preview mode)
|
||||
* - Fetch data từ API (live mode)
|
||||
* - Store answers securely
|
||||
* - Verify answers locally (fast feedback)
|
||||
* - Sync với server (background)
|
||||
* - Report results
|
||||
*/
|
||||
import { checkAnswer, sanitizeForClient, GAME_CODES } from '../kit/GameDataHandler';
|
||||
import { getMockData } from '../client/MockData';
|
||||
import { SDK_MESSAGE_TYPES, createSdkMessage, isSdkMessage, } from './types';
|
||||
// =============================================================================
|
||||
// SDK IFRAME CORE
|
||||
// =============================================================================
|
||||
export class SdkIframeCore {
|
||||
constructor(config = {}) {
|
||||
this.boundMessageHandler = null;
|
||||
this.mode = null;
|
||||
this.gameCode = null;
|
||||
this.assignmentId = null;
|
||||
this.studentId = null;
|
||||
this.apiBaseUrl = '';
|
||||
this.authToken = '';
|
||||
// Data storage
|
||||
this.originalItems = new Map(); // Có đáp án
|
||||
this.clientItems = new Map(); // Shuffled (cho Client)
|
||||
this.sanitizedItems = [];
|
||||
this.userAnswers = new Map();
|
||||
this.completedQuestions = new Set();
|
||||
this.isInitialized = false;
|
||||
this.parentOrigin = null;
|
||||
this.config = {
|
||||
debug: config.debug ?? false,
|
||||
allowedOrigins: config.allowedOrigins ?? ['*'],
|
||||
};
|
||||
this.setupMessageListener();
|
||||
this.log('info', 'SDK Iframe Core initialized');
|
||||
}
|
||||
// ==========================================================================
|
||||
// MESSAGE HANDLING
|
||||
// ==========================================================================
|
||||
setupMessageListener() {
|
||||
this.boundMessageHandler = this.handleMessage.bind(this);
|
||||
window.addEventListener('message', this.boundMessageHandler);
|
||||
}
|
||||
handleMessage(event) {
|
||||
// Validate origin
|
||||
if (!this.isAllowedOrigin(event.origin)) {
|
||||
this.log('warn', `Blocked message from unauthorized origin: ${event.origin}`);
|
||||
return;
|
||||
}
|
||||
const data = event.data;
|
||||
if (!isSdkMessage(data)) {
|
||||
return;
|
||||
}
|
||||
this.log('debug', `Received: ${data.type}`, data.payload);
|
||||
// Store parent origin for responses
|
||||
if (!this.parentOrigin) {
|
||||
this.parentOrigin = event.origin;
|
||||
}
|
||||
switch (data.type) {
|
||||
case SDK_MESSAGE_TYPES.SDK_INIT:
|
||||
this.handleInit(data.payload, data.request_id);
|
||||
break;
|
||||
case SDK_MESSAGE_TYPES.SDK_PUSH_DATA:
|
||||
this.handlePushData(data.payload, data.request_id);
|
||||
break;
|
||||
case SDK_MESSAGE_TYPES.SDK_CHECK_ANSWER:
|
||||
this.handleCheckAnswer(data.payload, data.request_id);
|
||||
break;
|
||||
case SDK_MESSAGE_TYPES.SDK_GET_RESULT:
|
||||
this.handleGetResult(data.request_id);
|
||||
break;
|
||||
case SDK_MESSAGE_TYPES.SDK_RETRY_SYNC:
|
||||
this.handleRetrySync(data.payload, data.request_id);
|
||||
break;
|
||||
default:
|
||||
this.log('warn', `Unknown message type: ${data.type}`);
|
||||
}
|
||||
}
|
||||
isAllowedOrigin(origin) {
|
||||
if (this.config.allowedOrigins.includes('*')) {
|
||||
return true;
|
||||
}
|
||||
return this.config.allowedOrigins.includes(origin);
|
||||
}
|
||||
// ==========================================================================
|
||||
// MESSAGE HANDLERS
|
||||
// ==========================================================================
|
||||
async handleInit(payload, requestId) {
|
||||
try {
|
||||
this.mode = payload.mode;
|
||||
this.gameCode = payload.game_code;
|
||||
this.assignmentId = payload.assignment_id ?? null;
|
||||
this.studentId = payload.student_id ?? null;
|
||||
this.apiBaseUrl = payload.api_base_url ?? '';
|
||||
this.authToken = payload.auth_token ?? '';
|
||||
// Validate game code
|
||||
if (!GAME_CODES[this.gameCode]) {
|
||||
throw new Error(`Invalid game code: ${this.gameCode}`);
|
||||
}
|
||||
this.isInitialized = true;
|
||||
// Send ready
|
||||
this.sendToParent(SDK_MESSAGE_TYPES.SDK_READY, {
|
||||
mode: this.mode,
|
||||
game_code: this.gameCode,
|
||||
}, requestId);
|
||||
this.log('info', `Initialized: mode=${this.mode}, game_code=${this.gameCode}`);
|
||||
// Mode handling
|
||||
if (this.mode === 'live' && this.assignmentId) {
|
||||
await this.fetchLiveData();
|
||||
}
|
||||
else if (this.mode === 'dev') {
|
||||
const mockData = getMockData(this.gameCode);
|
||||
if (mockData) {
|
||||
this.log('info', `[Dev] Loaded mock data for ${this.gameCode}`);
|
||||
this.processData(mockData.data);
|
||||
}
|
||||
else {
|
||||
this.sendError('MOCK_NOT_FOUND', `No mock data found for ${this.gameCode}`, requestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
this.sendError('INIT_ERROR', error.message, requestId);
|
||||
}
|
||||
}
|
||||
handlePushData(payload, requestId) {
|
||||
if (!this.isInitialized) {
|
||||
this.sendError('NOT_INITIALIZED', 'SDK not initialized. Call SDK_INIT first.', requestId);
|
||||
return;
|
||||
}
|
||||
if (this.mode !== 'preview') {
|
||||
this.sendError('INVALID_MODE', 'SDK_PUSH_DATA only allowed in preview mode', requestId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.processData(payload.data, payload.completed_question_ids);
|
||||
}
|
||||
catch (error) {
|
||||
this.sendError('DATA_ERROR', error.message, requestId);
|
||||
}
|
||||
}
|
||||
async handleCheckAnswer(payload, requestId) {
|
||||
if (!this.isInitialized || this.originalItems.size === 0) {
|
||||
this.sendError('NOT_READY', 'No data loaded', requestId);
|
||||
return;
|
||||
}
|
||||
const { question_id, choice, time_spent = 0 } = payload;
|
||||
// ===== RESOLVE CHOICE BY GAME CODE =====
|
||||
// Each game code has its own resolution logic
|
||||
const code = this.gameCode;
|
||||
const clientItem = this.clientItems.get(question_id);
|
||||
let answerValue = choice; // Default: use raw choice
|
||||
switch (code) {
|
||||
// ===== QUIZ VARIANTS (G001-G005): Client sends INDEX -> resolve to VALUE =====
|
||||
case 'G001': // Quiz Text-Text
|
||||
case 'G002': // Quiz Audio-Text
|
||||
case 'G003': // Quiz Text-Audio
|
||||
case 'G004': // Quiz Image-Text
|
||||
case 'G005': // Quiz Text-Image
|
||||
// Sanitizers store __shuffledOptions which contains resolved values (strings)
|
||||
if (clientItem && typeof choice === 'number') {
|
||||
const shuffled = clientItem.__shuffledOptions;
|
||||
if (Array.isArray(shuffled) && choice >= 0 && choice < shuffled.length) {
|
||||
answerValue = shuffled[choice];
|
||||
this.log('debug', `[${code}] Resolved: index ${choice} -> "${answerValue}"`);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// ===== SEQUENCE WORD VARIANTS (G110-G113) =====
|
||||
case 'G110': // Sequence Word
|
||||
case 'G111': // Sequence Word Audio
|
||||
case 'G112': // Sequence Word Audio
|
||||
case 'G113': // Sequence Word Audio
|
||||
// ===== SEQUENCE SENTENCE VARIANTS (G120-G123) =====
|
||||
case 'G120': // Sequence Sentence
|
||||
case 'G121': // Sequence Sentence Audio
|
||||
case 'G122': // Sequence Sentence Audio
|
||||
case 'G123': // Sequence Sentence Audio
|
||||
// Client gửi mảng chữ đã sắp xếp ["H","E","L","L","O"]
|
||||
// Không cần resolve - so trực tiếp với answer
|
||||
this.log('debug', `[${code}] Answer array: ${JSON.stringify(choice)}`);
|
||||
break;
|
||||
default:
|
||||
this.log('warn', `Unknown game code: ${code}, using raw choice`);
|
||||
}
|
||||
// Get original item
|
||||
const originalItem = this.originalItems.get(question_id);
|
||||
if (!originalItem) {
|
||||
this.sendError('QUESTION_NOT_FOUND', `Question ${question_id} not found`, requestId);
|
||||
return;
|
||||
}
|
||||
// =====================================================================
|
||||
// LOCAL VERIFY (Preview / Dev): Verify locally, return immediately
|
||||
// =====================================================================
|
||||
if (this.mode === 'preview' || this.mode === 'dev') {
|
||||
// Verify using RESOLVED VALUE (answerValue)
|
||||
const result = checkAnswer(this.gameCode, originalItem, answerValue);
|
||||
// Store answer
|
||||
const storedAnswer = {
|
||||
question_id,
|
||||
choice,
|
||||
answer_value: answerValue, // Store resolved value for retry
|
||||
correct: result.isCorrect,
|
||||
score: result.score,
|
||||
synced: true, // Local (preview/dev) = always synced
|
||||
time_spent,
|
||||
};
|
||||
this.userAnswers.set(question_id, storedAnswer);
|
||||
// Send result immediately
|
||||
this.sendToParent(SDK_MESSAGE_TYPES.SDK_ANSWER_RESULT, {
|
||||
question_id,
|
||||
correct: result.isCorrect,
|
||||
score: result.score,
|
||||
synced: true,
|
||||
}, requestId);
|
||||
this.log('info', `[Local] Answer checked locally (${this.mode}): ${question_id} = ${result.isCorrect}`);
|
||||
return;
|
||||
}
|
||||
// =====================================================================
|
||||
// LIVE MODE: Submit to server, wait for response, then return result
|
||||
// =====================================================================
|
||||
try {
|
||||
// Submit RESOLVED VALUE (answerValue) to server
|
||||
const serverResult = await this.submitAnswerToServer(question_id, answerValue, time_spent);
|
||||
// Store answer with server result
|
||||
const storedAnswer = {
|
||||
question_id,
|
||||
choice,
|
||||
answer_value: answerValue, // Store resolved value for retry
|
||||
correct: serverResult.correct,
|
||||
score: serverResult.score,
|
||||
synced: true,
|
||||
time_spent,
|
||||
};
|
||||
this.userAnswers.set(question_id, storedAnswer);
|
||||
// Send result from server
|
||||
this.sendToParent(SDK_MESSAGE_TYPES.SDK_ANSWER_RESULT, {
|
||||
question_id,
|
||||
correct: serverResult.correct,
|
||||
score: serverResult.score,
|
||||
synced: true,
|
||||
}, requestId);
|
||||
this.log('info', `[Live] Answer verified by server: ${question_id} = ${serverResult.correct}`);
|
||||
}
|
||||
catch (error) {
|
||||
// Server error - send error to game
|
||||
this.sendError('SUBMIT_ERROR', error.message || 'Failed to submit answer', requestId);
|
||||
this.log('error', `[Live] Failed to submit answer: ${question_id}`, error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Submit answer to server and wait for result (Live mode)
|
||||
*/
|
||||
async submitAnswerToServer(questionId, choice, timeSpent) {
|
||||
if (!this.apiBaseUrl || !this.assignmentId) {
|
||||
throw new Error('Missing apiBaseUrl or assignmentId');
|
||||
}
|
||||
const url = `${this.apiBaseUrl}/submissions/live/answer`;
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
if (this.authToken) {
|
||||
headers['Authorization'] = `Bearer ${this.authToken}`;
|
||||
}
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
assignment_id: this.assignmentId,
|
||||
student_id: this.studentId,
|
||||
question_id: questionId,
|
||||
selected_answer: choice,
|
||||
time_spent: timeSpent,
|
||||
is_timeout: false,
|
||||
}),
|
||||
});
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.message || `Server error: ${response.status}`);
|
||||
}
|
||||
const result = await response.json();
|
||||
return {
|
||||
correct: result.correct ?? false,
|
||||
score: result.score ?? (result.correct ? 1 : 0),
|
||||
};
|
||||
}
|
||||
handleGetResult(requestId) {
|
||||
const details = Array.from(this.userAnswers.values()).map(answer => ({
|
||||
question_id: answer.question_id,
|
||||
choice: answer.choice,
|
||||
correct: answer.correct,
|
||||
synced: answer.synced,
|
||||
time_spent: answer.time_spent,
|
||||
}));
|
||||
const correct = details.filter(d => d.correct).length;
|
||||
const total = this.originalItems.size;
|
||||
const allSynced = details.every(d => d.synced);
|
||||
this.sendToParent(SDK_MESSAGE_TYPES.SDK_FINAL_RESULT, {
|
||||
score: total > 0 ? Math.round((correct / total) * 100) : 0,
|
||||
total,
|
||||
correct,
|
||||
wrong: total - correct,
|
||||
synced: allSynced,
|
||||
details,
|
||||
}, requestId);
|
||||
}
|
||||
async handleRetrySync(payload, requestId) {
|
||||
const answer = this.userAnswers.get(payload.question_id);
|
||||
if (!answer) {
|
||||
this.sendError('ANSWER_NOT_FOUND', `Answer for ${payload.question_id} not found`, requestId);
|
||||
return;
|
||||
}
|
||||
if (answer.synced) {
|
||||
// Already synced
|
||||
this.sendToParent(SDK_MESSAGE_TYPES.SDK_SYNC_STATUS, {
|
||||
question_id: payload.question_id,
|
||||
synced: true,
|
||||
}, requestId);
|
||||
return;
|
||||
}
|
||||
// Retry submit to server - use RESOLVED value, not raw choice
|
||||
try {
|
||||
const serverResult = await this.submitAnswerToServer(answer.question_id, answer.answer_value, // Use resolved value!
|
||||
answer.time_spent);
|
||||
// Update stored answer
|
||||
answer.correct = serverResult.correct;
|
||||
answer.score = serverResult.score;
|
||||
answer.synced = true;
|
||||
// Send success
|
||||
this.sendToParent(SDK_MESSAGE_TYPES.SDK_SYNC_STATUS, {
|
||||
question_id: payload.question_id,
|
||||
synced: true,
|
||||
server_result: serverResult,
|
||||
}, requestId);
|
||||
}
|
||||
catch (error) {
|
||||
this.sendError('RETRY_ERROR', error.message || 'Retry failed', requestId);
|
||||
}
|
||||
}
|
||||
// ==========================================================================
|
||||
// DATA PROCESSING
|
||||
// ==========================================================================
|
||||
processData(items, completedIds) {
|
||||
// Store original items (with answers)
|
||||
this.originalItems.clear();
|
||||
items.forEach(item => {
|
||||
if (item.id) {
|
||||
this.originalItems.set(item.id, item);
|
||||
}
|
||||
});
|
||||
// Track completed questions
|
||||
this.completedQuestions.clear();
|
||||
if (completedIds) {
|
||||
completedIds.forEach(q => this.completedQuestions.add(q.id));
|
||||
}
|
||||
// Sanitize for game (remove answers)
|
||||
this.sanitizedItems = sanitizeForClient(this.gameCode, items);
|
||||
// Store sanitized items for lookup (to map choice index -> value)
|
||||
this.clientItems.clear();
|
||||
this.sanitizedItems.forEach(item => {
|
||||
if (item.id)
|
||||
this.clientItems.set(item.id, item);
|
||||
});
|
||||
// Send data ready
|
||||
this.sendToParent(SDK_MESSAGE_TYPES.SDK_DATA_READY, {
|
||||
items: this.sanitizedItems,
|
||||
total_questions: items.length,
|
||||
completed_count: this.completedQuestions.size,
|
||||
resume_data: completedIds,
|
||||
});
|
||||
this.log('info', `Data processed: ${items.length} items, ${this.completedQuestions.size} completed`);
|
||||
}
|
||||
// ==========================================================================
|
||||
// API CALLS
|
||||
// ==========================================================================
|
||||
async fetchLiveData() {
|
||||
if (!this.apiBaseUrl || !this.assignmentId) {
|
||||
this.sendError('CONFIG_ERROR', 'Missing apiBaseUrl or assignmentId for live mode');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const url = `${this.apiBaseUrl}/games/${this.assignmentId}`;
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
if (this.authToken) {
|
||||
headers['Authorization'] = `Bearer ${this.authToken}`;
|
||||
}
|
||||
this.log('info', `Fetching live data: ${url}`);
|
||||
const response = await fetch(url, { headers });
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
// Extract items from response
|
||||
const items = data.data || data.items || data.questions || [];
|
||||
const completedIds = data.completed_question_ids || [];
|
||||
this.processData(items, completedIds);
|
||||
}
|
||||
catch (error) {
|
||||
this.log('error', 'Failed to fetch live data', error);
|
||||
this.sendError('FETCH_ERROR', error.message);
|
||||
}
|
||||
}
|
||||
// ==========================================================================
|
||||
// HELPERS
|
||||
// ==========================================================================
|
||||
sendToParent(type, payload, requestId) {
|
||||
const message = createSdkMessage(type, payload, requestId);
|
||||
// NOTE: Khi chạy local file://, event.origin có thể là "null" (string) => postMessage sẽ throw nếu dùng làm targetOrigin
|
||||
const origin = this.parentOrigin;
|
||||
const targetOrigin = (!origin || origin === 'null') ? '*' : origin;
|
||||
window.parent.postMessage(message, targetOrigin);
|
||||
this.log('debug', `Sent: ${type}`, payload);
|
||||
}
|
||||
sendError(code, message, requestId) {
|
||||
this.sendToParent(SDK_MESSAGE_TYPES.SDK_ERROR, {
|
||||
code,
|
||||
message,
|
||||
}, requestId);
|
||||
this.log('error', `Error: ${code} - ${message}`);
|
||||
}
|
||||
log(level, message, data) {
|
||||
if (!this.config.debug && level === 'debug')
|
||||
return;
|
||||
const prefix = '[SdkIframe]';
|
||||
switch (level) {
|
||||
case 'debug':
|
||||
case 'info':
|
||||
console.log(prefix, message, data ?? '');
|
||||
break;
|
||||
case 'warn':
|
||||
console.warn(prefix, message, data ?? '');
|
||||
break;
|
||||
case 'error':
|
||||
console.error(prefix, message, data ?? '');
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ==========================================================================
|
||||
// CLEANUP
|
||||
// ==========================================================================
|
||||
destroy() {
|
||||
if (this.boundMessageHandler) {
|
||||
window.removeEventListener('message', this.boundMessageHandler);
|
||||
this.boundMessageHandler = null;
|
||||
}
|
||||
this.originalItems.clear();
|
||||
this.userAnswers.clear();
|
||||
this.log('info', 'SDK Iframe destroyed');
|
||||
}
|
||||
}
|
||||
// Auto-init khi script được load
|
||||
if (typeof window !== 'undefined') {
|
||||
window.SdkIframe = new SdkIframeCore({
|
||||
debug: new URLSearchParams(window.location.search).get('debug') === 'true',
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=SdkIframeCore.js.map
|
||||
1
G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js.map
vendored
Normal file
1
G102-sequence/sdk/package/dist/esm/sdk-iframe/SdkIframeCore.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
11
G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js
vendored
Normal file
11
G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* SDK Iframe exports
|
||||
*/
|
||||
import { SdkIframeCore } from './SdkIframeCore';
|
||||
export * from './types';
|
||||
export { SdkIframeCore };
|
||||
// Export to window for direct browser usage
|
||||
if (typeof window !== 'undefined') {
|
||||
window.SdkIframeCore = SdkIframeCore;
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js.map
vendored
Normal file
1
G102-sequence/sdk/package/dist/esm/sdk-iframe/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sdk-iframe/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,4CAA4C;AAC5C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAC/B,MAAc,CAAC,aAAa,GAAG,aAAa,CAAC;AAClD,CAAC"}
|
||||
38
G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js
vendored
Normal file
38
G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* SDK Iframe Message Types
|
||||
* Shared types cho SDK Iframe và Game Bridge
|
||||
*/
|
||||
// =============================================================================
|
||||
// MESSAGE TYPES
|
||||
// =============================================================================
|
||||
export const SDK_MESSAGE_TYPES = {
|
||||
// Parent/Game → SDK Iframe
|
||||
SDK_INIT: 'SDK_INIT',
|
||||
SDK_PUSH_DATA: 'SDK_PUSH_DATA',
|
||||
SDK_CHECK_ANSWER: 'SDK_CHECK_ANSWER',
|
||||
SDK_GET_RESULT: 'SDK_GET_RESULT',
|
||||
SDK_RETRY_SYNC: 'SDK_RETRY_SYNC',
|
||||
// SDK Iframe → Parent/Game
|
||||
SDK_READY: 'SDK_READY',
|
||||
SDK_DATA_READY: 'SDK_DATA_READY',
|
||||
SDK_ANSWER_RESULT: 'SDK_ANSWER_RESULT',
|
||||
SDK_SYNC_STATUS: 'SDK_SYNC_STATUS',
|
||||
SDK_SYNC_ERROR: 'SDK_SYNC_ERROR',
|
||||
SDK_FINAL_RESULT: 'SDK_FINAL_RESULT',
|
||||
SDK_ERROR: 'SDK_ERROR',
|
||||
};
|
||||
// =============================================================================
|
||||
// HELPER FUNCTIONS
|
||||
// =============================================================================
|
||||
export function createSdkMessage(type, payload, requestId) {
|
||||
return {
|
||||
type,
|
||||
payload,
|
||||
timestamp: Date.now(),
|
||||
request_id: requestId,
|
||||
};
|
||||
}
|
||||
export function isSdkMessage(data) {
|
||||
return data && typeof data === 'object' && 'type' in data && Object.values(SDK_MESSAGE_TYPES).includes(data.type);
|
||||
}
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js.map
vendored
Normal file
1
G102-sequence/sdk/package/dist/esm/sdk-iframe/types.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/sdk-iframe/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC7B,2BAA2B;IAC3B,QAAQ,EAAE,UAAU;IACpB,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;IACpC,cAAc,EAAE,gBAAgB;IAChC,cAAc,EAAE,gBAAgB;IAEhC,2BAA2B;IAC3B,SAAS,EAAE,WAAW;IACtB,cAAc,EAAE,gBAAgB;IAChC,iBAAiB,EAAE,mBAAmB;IACtC,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;IAChC,gBAAgB,EAAE,kBAAkB;IACpC,SAAS,EAAE,WAAW;CAChB,CAAC;AAyGX,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF,MAAM,UAAU,gBAAgB,CAAI,IAAoB,EAAE,OAAU,EAAE,SAAkB;IACpF,OAAO;QACH,IAAI;QACJ,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,UAAU,EAAE,SAAS;KACxB,CAAC;AACN,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAS;IAClC,OAAO,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtH,CAAC"}
|
||||
Reference in New Issue
Block a user