npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

luma-sdk

v2.0.2

Published

A simple iframe postMessage wrapper with request/response support using UUIDs.

Readme

Faranex IframeClient

برقراری ارتباط بین اپلیکیشن شما و پنل لوما

ویژگی‌ها

ویژگی‌های کلیدی:

  • 🔒 پیاده‌سازی TypeScript با پشتیبانی کامل از نوع‌ها
  • 📨 ارتباط دوطرفه با iframe
  • 🔑 ردیابی درخواست/پاسخ بر اساس UUID
  • ⌨️ مدیریت خودکار رویدادهای کیبورد
  • ⏱️ مدیریت timeout قابل تنظیم
  • 🎯 API ساده و قابل فهم
  • 📦 بدون وابستگی خارجی (به جز UUID)

نصب

npm install luma-sdk

یا با استفاده از pnpm:

pnpm add luma-sdk

یا با استفاده از yarn:

yarn add luma-sdk

شروع سریع

استفاده پایه

import { IframeClient } from "luma-sdk";

// ایجاد یک نمونه از کلاینت
const client = new IframeClient();

// ارسال پیام و انتظار برای پاسخ
try {
  const response = await client.sendMessage({
    type: "AUTH_TOKEN",
    data: "",
  });
  console.log("پاسخ دریافت شد:", response);
} catch (error) {
  console.error("خطا:", error);
}

راه‌اندازی

ایجاد نمونه IframeClient

برای استفاده از کتابخانه، ابتدا باید یک نمونه از کلاس IframeClient ایجاد کنید:

import { IframeClient } from "luma-sdk";

const iframeElement = document.getElementById("myIframe") as HTMLIFrameElement;
const client = new IframeClient(
  window.parent, // پنجره iframe
  "https://trusted-domain.com", // origin مورد اعتماد (اختیاری)
  50000 // timeout به میلی‌ثانیه (اختیاری)
);

پارامترهای سازنده

new IframeClient(
  iframeWindow: Window,
  targetOrigin?: string,
  timeout?: number
)

پارامترها:

  • iframeWindow (الزامی) - پنجره iframe که می‌خواهید با آن ارتباط برقرار کنید. معمولاً iframeElement.contentWindow یا window.parent است.
  • targetOrigin (اختیاری، پیش‌فرض: "https://kiosk.luma360.ir") - origin مورد اعتماد برای امنیت. در production حتماً یک origin مشخص کنید و از "*" استفاده نکنید.
  • timeout (اختیاری، پیش‌فرض: 50000) - زمان انتظار برای پاسخ به میلی‌ثانیه. باید بین 40000 تا 60000 باشد.

مثال:

const client = new IframeClient();

const client = new IframeClient(window.parent, "https://my-trusted-domain.com");

const client = new IframeClient(
  window.parent,
  "https://my-trusted-domain.com",
  55000
);

انواع پیام‌ها

کتابخانه از انواع پیام‌های زیر پشتیبانی می‌کند:

type MessageType =
  | "AUTH_TOKEN" // دریافت توکن احراز هویت
  | "PRINT_DATA" // ارسال داده برای چاپ
  | "PAYMENT" // ارسال اطلاعات پرداخت
  | "KEYBOARD_EVENT"; // رویدادهای کیبورد

1. AUTH_TOKEN

برای دریافت توکن احراز هویت از اپلیکیشن والد:

try {
  const response = await client.sendMessage({
    type: "AUTH_TOKEN",
    data: "", // null or undefined
  });

  console.log("توکن دریافت شد:", response.token);
} catch (error) {
  console.error("خطا در دریافت توکن:", error);
}

2. PRINT_DATA

برای ارسال داده‌ها به منظور چاپ:

try {
  const printData = {
    content: "متن یا تصویر مورد نظر برای چاپ مورد نظر برای چاپ", // base64 image
  };

  const response = await client.sendMessage({
    type: "PRINT_DATA",
    data: encrypt(printData),
  });

  console.log("نتیجه چاپ:", response);
} catch (error) {
  console.error("خطا در چاپ:", error);
}

3. PAYMENT

برای ارسال اطلاعات پرداخت:

try {
  const paymentData = {
    amount: 100000,
  };

  const response = await client.sendMessage({
    type: "PAYMENT",
    data: encrypt(paymentData),
  });

  console.log("نتیجه پرداخت:", response);
} catch (error) {
  console.error("خطا در پرداخت:", error);
}

4. KEYBOARD_EVENT

برای مدیریت رویدادهای کیبورد. این نوع پیام به صورت خودکار توسط KeyboardManager مدیریت می‌شود و معمولاً نیازی به ارسال دستی ندارد.

مدیریت کیبورد

کتابخانه به صورت خودکار رویدادهای کیبورد را مدیریت می‌کند. وقتی کاربر روی یک input یا textarea در iframe فوکوس می‌کند، کتابخانه به صورت خودکار:

  1. رویداد FOCUSED را ارسال می‌کند
  2. input را به حالت readonly تبدیل می‌کند تا کیبورد مجازی نمایش داده شود
  3. رویدادهای کیبورد را از اپلیکیشن والد دریافت و پردازش می‌کند

رویدادهای کیبورد

کتابخانه از رویدادهای زیر پشتیبانی می‌کند:

  • insert_text: وارد کردن متن در موقعیت cursor
  • backspace: حذف کاراکتر قبل از cursor
  • enter: ارسال فرم (submit)

این رویدادها به صورت خودکار مدیریت می‌شوند و نیازی به کدنویسی اضافی ندارید.

API مرجع

IframeClient

متدها

sendMessage(data: RequestData): Promise<any>

ارسال پیام به iframe و انتظار برای پاسخ.

پارامترها:

  • data - داده درخواست شامل type و data

برمی‌گرداند: Promise که با داده پاسخ resolve می‌شود یا در صورت خطا/timeout reject می‌شود

مثال:

try {
  const result = await client.sendMessage({
    type: "PAYMENT",
    data: encrypt({ amount: 100 }),
  });
  console.log("پرداخت موفق:", result);
} catch (error) {
  if (error.message === "Response timed out") {
    console.error("درخواست timeout شد");
  } else {
    console.error("خطا:", error);
  }
}
getTargetOrigin(): string

دریافت origin هدف تنظیم شده.

getTimeout(): number

دریافت مقدار timeout تنظیم شده.

مدیریت خطاها

خطاهای رایج

1. Timeout

اگر درخواست در زمان مشخص شده پاسخ نگیرد:

try {
  const response = await client.sendMessage({
    type: "PAYMENT",
    data: "payment-data",
  });
} catch (error) {
  if (error.message === "Response timed out") {
    console.error("درخواست timeout شد. لطفاً دوباره تلاش کنید.");
  }
}

2. خطای اعتبارسنجی Timeout

اگر timeout خارج از محدوده مجاز تنظیم شود:

try {
  const client = new IframeClient(window.parent, "*", 30000); // ❌ خطا
} catch (error) {
  if (error.message.includes("Timeout must be")) {
    console.error("مقدار timeout باید بین 40000 تا 60000 میلی‌ثانیه باشد");
  }
}

3. خطای Origin

اگر origin پیام با origin تنظیم شده مطابقت نداشته باشد، پیام نادیده گرفته می‌شود.

بهترین روش‌های مدیریت خطا

async function communicateWithIframe() {
  try {
    const response = await client.sendMessage({
      type: "PRINT_DATA",
      data: "document content",
    });
    console.log("موفق:", response);
  } catch (error) {
    if (error.message === "Response timed out") {
      console.error("ifram در زمان مشخص شده پاسخ نداد");
      // می‌توانید منطق retry را اینجا پیاده‌سازی کنید
    } else if (error.message.startsWith("Timeout must be")) {
      console.error("پیکربندی timeout نامعتبر است");
    } else {
      console.error("خطای غیرمنتظره:", error.message);
    }
  }
}

امنیت

استفاده از Target Origin

برای امنیت بیشتر، همیشه یک origin مورد اعتماد مشخص کنید:

// ❌ بد - استفاده از '*' در production
const client = new IframeClient(window.parent, "*");

// ✅ خوب - استفاده از origin مشخص
const client = new IframeClient(
  window.parent,
  "https://trusted-iframe.example.com"
);

اعتبارسنجی داده‌ها

قبل از ارسال داده‌ها، حتماً آن‌ها را اعتبارسنجی کنید:

function sendPayment(amount: number, currency: string) {
  // اعتبارسنجی داده‌ها
  if (amount <= 0) {
    throw new Error("مقدار پرداخت باید بیشتر از صفر باشد");
  }

  return client.sendMessage({
    type: "PAYMENT",
    data: encrypt({ amount }),
  });
}

فرایند Encryption

برای امنیت بیشتر در ارتباطات، می‌توانید از encryption استفاده کنید. کتابخانه از الگوریتم AES-256-CBC پشتیبانی می‌کند.

الگوریتم Encryption

  • الگوریتم: AES-256-CBC
  • Key Derivation: SHA-256 از key string
  • IV: 16 بایت (pad یا truncate می‌شود)
  • Padding: PKCS7
  • Encoding: Base64

مثال‌های پیاده‌سازی

TypeScript/JavaScript

import forge from "node-forge";

export function deriveKeyAndIv(keyStr: string, ivStr: string) {
  const key = forge.md.sha256.create();
  key.update(keyStr);
  const keyBytes = key.digest().getBytes(); // 32 bytes

  const ivUtf8 = forge.util.encodeUtf8(ivStr);
  const ivPadded = (ivUtf8 + "\0".repeat(16)).slice(0, 16);

  return { key: keyBytes, iv: ivPadded };
}

export function encryptAes256Cbc(
  plainText: string,
  keyStr: string,
  ivStr: string
) {
  const { key, iv } = deriveKeyAndIv(keyStr, ivStr);
  const cipher = forge.cipher.createCipher("AES-CBC", key);
  cipher.start({ iv });
  cipher.update(forge.util.createBuffer(plainText, "utf8"));
  cipher.finish();
  return forge.util.encode64(cipher.output.getBytes());
}

export function decryptAes256Cbc(
  cipherBase64: string,
  keyStr: string,
  ivStr: string
) {
  const { key, iv } = deriveKeyAndIv(keyStr, ivStr);
  const decipher = forge.cipher.createDecipher("AES-CBC", key);
  decipher.start({ iv });
  decipher.update(forge.util.createBuffer(forge.util.decode64(cipherBase64)));
  decipher.finish();
  return decipher.output.toString("utf8");
}

// استفاده
const encrypted = encryptAes256Cbc(
  "متن مورد نظر",
  "my-secret-key",
  "my-iv-string"
);
const decrypted = decryptAes256Cbc(encrypted, "my-secret-key", "my-iv-string");

Python

import base64
import hashlib
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

def derive_key_and_iv(key_str, iv_str):
    key = hashlib.sha256(key_str.encode("utf-8")).digest()  # 32 bytes
    iv = iv_str.encode("utf-8")[:16].ljust(16, b"\0")       # pad or truncate
    return key, iv

def encrypt_aes256_cbc(plain_text, key_str, iv_str):
    key, iv = derive_key_and_iv(key_str, iv_str)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded = pad(plain_text.encode("utf-8"), AES.block_size)
    encrypted = cipher.encrypt(padded)
    return base64.b64encode(encrypted).decode("utf-8")

def decrypt_aes256_cbc(cipher_base64, key_str, iv_str):
    key, iv = derive_key_and_iv(key_str, iv_str)
    cipher_data = base64.b64decode(cipher_base64)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = unpad(cipher.decrypt(cipher_data), AES.block_size)
    return decrypted.decode("utf-8")

# استفاده
encrypted = encrypt_aes256_cbc("متن مورد نظر", "my-secret-key", "my-iv-string")
decrypted = decrypt_aes256_cbc(encrypted, "my-secret-key", "my-iv-string")

PHP

function deriveKeyAndIv($keyStr, $ivStr) {
    $key = hash('sha256', $keyStr, true); // 32 bytes binary
    $iv = substr(str_pad($ivStr, 16, "\0"), 0, 16); // pad or truncate
    return [$key, $iv];
}

function encryptAes256Cbc($plainText, $keyStr, $ivStr) {
    list($key, $iv) = deriveKeyAndIv($keyStr, $ivStr);
    $encrypted = openssl_encrypt($plainText, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($encrypted);
}

function decryptAes256Cbc($cipherBase64, $keyStr, $ivStr) {
    list($key, $iv) = deriveKeyAndIv($keyStr, $ivStr);
    $cipher = base64_decode($cipherBase64);
    return openssl_decrypt($cipher, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
}

// استفاده
$encrypted = encryptAes256Cbc("متن مورد نظر", "my-secret-key", "my-iv-string");
$decrypted = decryptAes256Cbc($encrypted, "my-secret-key", "my-iv-string");

Java

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;

public class AESCrypto {
    public static byte[] deriveKey(String keyStr) throws Exception {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        return digest.digest(keyStr.getBytes("UTF-8"));
    }

    public static byte[] deriveIv(String ivStr) throws Exception {
        byte[] iv = new byte[16];
        byte[] bytes = ivStr.getBytes("UTF-8");
        System.arraycopy(bytes, 0, iv, 0, Math.min(bytes.length, 16));
        return iv;
    }

    public static String encryptAes256Cbc(String plainText, String keyStr, String ivStr) throws Exception {
        byte[] key = deriveKey(keyStr);
        byte[] iv = deriveIv(ivStr);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
        byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encrypted);
    }

    public static String decryptAes256Cbc(String cipherBase64, String keyStr, String ivStr) throws Exception {
        byte[] key = deriveKey(keyStr);
        byte[] iv = deriveIv(ivStr);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherBase64));
        return new String(decrypted, "UTF-8");
    }
}

// استفاده
String encrypted = AESCrypto.encryptAes256Cbc("متن مورد نظر", "my-secret-key", "my-iv-string");
String decrypted = AESCrypto.decryptAes256Cbc(encrypted, "my-secret-key", "my-iv-string");

Go

package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/sha256"
	"encoding/base64"
)

func deriveKeyAndIv(keyStr, ivStr string) ([]byte, []byte) {
	key := sha256.Sum256([]byte(keyStr)) // 32 bytes

	iv := make([]byte, 16)
	copy(iv, []byte(ivStr)) // pad or truncate

	return key[:], iv
}

func pkcs7Pad(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padText...)
}

func pkcs7Unpad(data []byte) []byte {
	length := len(data)
	unpadding := int(data[length-1])
	return data[:(length - unpadding)]
}

func encryptAes256Cbc(plainText, keyStr, ivStr string) (string, error) {
	key, iv := deriveKeyAndIv(keyStr, ivStr)
	block, _ := aes.NewCipher(key)
	padded := pkcs7Pad([]byte(plainText), aes.BlockSize)

	cipherText := make([]byte, len(padded))
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(cipherText, padded)

	return base64.StdEncoding.EncodeToString(cipherText), nil
}

func decryptAes256Cbc(cipherBase64, keyStr, ivStr string) (string, error) {
	key, iv := deriveKeyAndIv(keyStr, ivStr)
	block, _ := aes.NewCipher(key)

	cipherData, _ := base64.StdEncoding.DecodeString(cipherBase64)
	decrypted := make([]byte, len(cipherData))
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(decrypted, cipherData)

	unpadded := pkcs7Unpad(decrypted)
	return string(unpadded), nil
}

// استفاده
encrypted, _ := encryptAes256Cbc("متن مورد نظر", "my-secret-key", "my-iv-string")
decrypted, _ := decryptAes256Cbc(encrypted, "my-secret-key", "my-iv-string")

C#

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public static class AESCrypto
{
    private static void DeriveKeyAndIv(string keyStr, string ivStr, out byte[] key, out byte[] iv)
    {
        using (SHA256 sha = SHA256.Create())
        {
            key = sha.ComputeHash(Encoding.UTF8.GetBytes(keyStr));
        }
        iv = new byte[16];
        byte[] ivBytes = Encoding.UTF8.GetBytes(ivStr);
        Array.Copy(ivBytes, iv, Math.Min(ivBytes.Length, 16));
    }

    public static string EncryptAes256Cbc(string plainText, string keyStr, string ivStr)
    {
        DeriveKeyAndIv(keyStr, ivStr, out byte[] key, out byte[] iv);

        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            using var encryptor = aes.CreateEncryptor();
            byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
            byte[] cipherBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
            return Convert.ToBase64String(cipherBytes);
        }
    }

    public static string DecryptAes256Cbc(string cipherBase64, string keyStr, string ivStr)
    {
        DeriveKeyAndIv(keyStr, ivStr, out byte[] key, out byte[] iv);

        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            using var decryptor = aes.CreateDecryptor();
            byte[] cipherBytes = Convert.FromBase64String(cipherBase64);
            byte[] plainBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
            return Encoding.UTF8.GetString(plainBytes);
        }
    }
}

// استفاده
string encrypted = AESCrypto.EncryptAes256Cbc("متن مورد نظر", "my-secret-key", "my-iv-string");
string decrypted = AESCrypto.DecryptAes256Cbc(encrypted, "my-secret-key", "my-iv-string");

استفاده از Encryption در ارتباطات

برای استفاده از encryption در ارتباطات با iframe:

import { IframeClient } from "luma-sdk";
import { encryptAes256Cbc, decryptAes256Cbc } from "./encryption";

const client = new IframeClient(iframeWindow);

// ارسال داده encrypted
async function sendEncryptedData(data: any) {
  const plainText = JSON.stringify(data);
  const encrypted = encryptAes256Cbc(
    plainText,
    "my-secret-key",
    "my-iv-string"
  );

  const response = await client.sendMessage({
    type: "PAYMENT",
    data: encrypted,
  });

  // اگر پاسخ هم encrypted است
  const decryptedResponse = decryptAes256Cbc(
    response.data,
    "my-secret-key",
    "my-iv-string"
  );
  return JSON.parse(decryptedResponse);
}

مثال‌های عملی

مثال 1: دریافت توکن و استفاده از آن

import { IframeClient } from "luma-sdk";

const iframeElement = document.getElementById("myIframe") as HTMLIFrameElement;
const client = new IframeClient(iframeElement.contentWindow);

async function initializeApp() {
  try {
    // دریافت توکن
    const authResponse = await client.sendMessage({
      type: "AUTH_TOKEN",
      data: "",
    });

    const token = authResponse.token;
    console.log("توکن دریافت شد:", token);

    // استفاده از توکن برای درخواست‌های بعدی
    // ...
  } catch (error) {
    console.error("خطا در دریافت توکن:", error);
  }
}

مثال 2: پرداخت

async function processPayment(amount: number, retries = 3) {
  const paymentData = {
    amount,
  };

  try {
    const response = await client.sendMessage({
      type: "PAYMENT",
      data: encrypt(paymentData),
    });

    if (response.success) {
      return response;
    }

    throw new Error(response.message || "پرداخت ناموفق بود");
  } catch (error) {
    if (error.message === "Response timed out" && i < retries - 1) {
      console.log(`تلاش ${i + 1} ناموفق بود. تلاش مجدد...`);
      await new Promise((resolve) => setTimeout(resolve, 1000)); // انتظار 1 ثانیه
      continue;
    }
    throw error;
  }

  throw new Error("پرداخت پس از چندین تلاش ناموفق بود");
}

مثال 3: استفاده در React Component

import { useEffect, useRef } from "react";
import { IframeClient } from "luma-sdk";

function MyIframeComponent() {
  const clientRef = useRef<IframeClient | null>(null);
  const iframeRef = useRef<HTMLIFrameElement>(null);

  useEffect(() => {
    if (iframeRef.current) {
      clientRef.current = new IframeClient();
    }

    return () => {
      // Cleanup اگر نیاز باشد
    };
  }, []);

  const handlePayment = async () => {
    if (!clientRef.current) return;

    try {
      const response = await clientRef.current.sendMessage({
        type: "PAYMENT",
        data: encrypt({ amount: 100000 }),
      });
      console.log("پرداخت موفق:", response);
    } catch (error) {
      console.error("خطا در پرداخت:", error);
    }
  };

  return (
    <div>
      <button onClick={handlePayment}>پرداخت</button>
    </div>
  );
}

تنظیمات Timeout

مقدار timeout باید بین 40000 تا 60000 میلی‌ثانیه باشد:

// ✅ معتبر
new IframeClient(window, "*", 40000); // 40 ثانیه
new IframeClient(window, "*", 50000); // 50 ثانیه (پیش‌فرض)
new IframeClient(window, "*", 60000); // 60 ثانیه

// ❌ نامعتبر - خطا می‌دهد
new IframeClient(window, "*", 30000); // خیلی کم
new IframeClient(window, "*", 70000); // خیلی زیاد

بهترین روش‌ها

  1. همیشه origin مشخص کنید - در production از "*" استفاده نکنید
  2. خطاها را مدیریت کنید - منطق retry برای timeout پیاده‌سازی کنید
  3. داده‌ها را اعتبارسنجی کنید - قبل از ارسال، داده‌ها را بررسی کنید
  4. از TypeScript استفاده کنید - از مزایای type safety بهره ببرید
  5. پیام‌ها را کوچک نگه دارید - از ارسال payload‌های بزرگ خودداری کنید
  6. از encryption استفاده کنید - برای داده‌های حساس از encryption استفاده کنید
  7. Cleanup کنید - در صورت نیاز، event listener‌ها را پاک کنید

پشتیبانی از مرورگرها

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 15+
  • هر مرورگر مدرنی که از API postMessage پشتیبانی کند

ساختار پروژه

src/
├── index.ts              # نقطه ورود اصلی
├── types.ts              # تعاریف نوع
├── iframe-client.ts      # کلاس IframeClient
└── keyboard-manager.ts   # کلاس KeyboardManager
dist/
├── index.js              # JavaScript کامپایل شده
├── index.d.ts            # تعاریف TypeScript

Type Definitions

همه type‌ها از کتابخانه export می‌شوند:

import {
  IframeClient,
  KeyboardManager,
  RequestData,
  ResponseMessage,
  MessageType,
  FocusableElement,
  PendingRequest,
  KeyboardEventData,
} from "luma-sdk";

RequestData

type RequestData = {
  uuid?: string;
  type: MessageType;
  data: any;
};

ResponseMessage

interface ResponseMessage {
  type: MessageType | "ERROR" | "KEYBOARD_ON" | "KEYBOARD_OFF";
  uuid: string;
  data?: any;
  error?: string;
}

مجوز

MIT

نویسنده

Ali Abolfathi From Faranex