Overview

Gammal Tech provides per-user JSON storage that automatically syncs across devices. Data is tied to the user's Gammal Tech Passport, not to a specific browser or device.

🔄

Cross-Device Sync

Data follows the user everywhere

🔐

Per-Developer Isolation

Your data is separate from other apps

📝

JSON Format

Store any serializable data

Simple API

Just get() and save()

💡 Privacy First

User data is isolated per developer. You can only access data your app has saved — you cannot access data from other developers' apps, and they cannot access yours.

Quick Start

Basic usage
// Save user data
await GammalTech.user.save({
    theme: 'dark',
    language: 'en',
    notifications: true,
    lastVisit: new Date().toISOString()
});

// Get user data
const data = await GammalTech.user.get();
console.log(data.theme);       // 'dark'
console.log(data.language);    // 'en'

Method Reference

GammalTech.user.get() → Promise<Object>

Retrieves the user's stored data object. Returns an empty object {} if no data has been saved yet. Requires user to be logged in.

Get user data
// Get all user data
const userData = await GammalTech.user.get();

// Use with defaults for missing values
const theme = userData.theme || 'light';
const fontSize = userData.fontSize || 16;

// Check if data exists
if (Object.keys(userData).length === 0) {
    console.log('No saved data yet');
}
GammalTech.user.save(data) → Promise<Object>

Saves the provided object as the user's data. This replaces all existing data — it's not a merge. Requires user to be logged in.

Save user data
// Save new data (replaces existing)
await GammalTech.user.save({
    profile: {
        displayName: 'John Doe',
        avatar: 'avatar-3'
    },
    settings: {
        theme: 'dark',
        notifications: true
    },
    progress: {
        level: 5,
        xp: 1250
    }
});
⚠️ Save Replaces, Not Merges

save() replaces ALL existing data. To update a single field, first get() the data, modify it, then save() the whole object back.

Updating Data

Since save() replaces all data, use this pattern to update specific fields:

Update specific fields
// Helper function to update user data
async function updateUserData(updates) {
    // 1. Get existing data
    const current = await GammalTech.user.get();
    
    // 2. Merge with updates
    const updated = { ...current, ...updates };
    
    // 3. Save merged data
    await GammalTech.user.save(updated);
    
    return updated;
}

// Usage: Update just the theme
await updateUserData({ theme: 'dark' });

// Usage: Update nested object (careful!)
const current = await GammalTech.user.get();
current.settings = { ...current.settings, notifications: false };
await GammalTech.user.save(current);

Data Structure Example

You can store any JSON-serializable data. Here's a typical structure:

{ // User preferences "settings": { "theme": "dark", "language": "en", "notifications": true, "fontSize": 16 }, // App-specific profile "profile": { "displayName": "CoolUser123", "bio": "Love coding!", "avatar": "avatar-7" }, // App state / progress "progress": { "level": 12, "xp": 3450, "completedLessons": [1, 2, 3, 5, 7], "achievements": ["first_login", "streak_7"] }, // Metadata "meta": { "createdAt": "2025-01-01T00:00:00Z", "lastVisit": "2025-01-05T14:30:00Z", "visitCount": 42 } }

Common Use Cases

🎨 Theme & Preferences

Store dark mode, font size, language settings that follow users across devices.

👤 App Profiles

Display names, avatars, bios — separate from their Gammal Tech Passport info.

📊 Progress & State

Game progress, course completion, reading position in articles.

🛒 Cart & Wishlist

Shopping cart items, saved products, favorites lists.

📝 Draft Content

Unsaved form data, draft posts, work in progress.

🔔 Notification Prefs

Email preferences, push notification settings, digest frequency.

Complete Example

Settings page implementation
<script src="https://api.gammal.tech/sdk-web.js"></script>
<script>
// Default settings
const DEFAULTS = {
    theme: 'light',
    language: 'en',
    notifications: true,
    fontSize: 16
};

// Load settings on page load
async function loadSettings() {
    if (!GammalTech.isLoggedIn()) {
        applySettings(DEFAULTS);
        return;
    }
    
    const userData = await GammalTech.user.get();
    const settings = { ...DEFAULTS, ...userData.settings };
    
    applySettings(settings);
    populateForm(settings);
}

// Apply settings to the page
function applySettings(settings) {
    document.body.className = settings.theme;
    document.documentElement.style.fontSize = settings.fontSize + 'px';
}

// Populate settings form
function populateForm(settings) {
    document.getElementById('theme').value = settings.theme;
    document.getElementById('language').value = settings.language;
    document.getElementById('notifications').checked = settings.notifications;
    document.getElementById('fontSize').value = settings.fontSize;
}

// Save settings
async function saveSettings() {
    const newSettings = {
        theme: document.getElementById('theme').value,
        language: document.getElementById('language').value,
        notifications: document.getElementById('notifications').checked,
        fontSize: parseInt(document.getElementById('fontSize').value)
    };
    
    // Get existing data and update settings
    const userData = await GammalTech.user.get();
    userData.settings = newSettings;
    
    // Save
    await GammalTech.user.save(userData);
    
    // Apply immediately
    applySettings(newSettings);
    
    alert('Settings saved!');
}

// Initialize
loadSettings();
</script>

Limitations

⚠️ Storage Limits

User data is limited to 100KB per user per developer. This is plenty for preferences and state, but not for large files or media. Store large assets elsewhere and save references/URLs in user data.

What NOT to Store

❌ Large files or binary data (use cloud storage)

❌ Sensitive credentials (passwords, API keys)

❌ Frequently changing data (use a database instead)

❌ Data that needs server-side validation

What TO Store

✅ User preferences and settings

✅ App state and progress

✅ Small collections (favorites, recent items)

✅ UI customization options

🤖

AI Prompt for Vibe Coding

User Data

Copy this prompt for help with user data storage:

I'm implementing user data storage with Gammal Tech SDK. Methods: - GammalTech.user.get() → Promise Returns user's stored data (empty {} if none) - GammalTech.user.save(data) → Promise Saves data object (REPLACES all existing data) Key Points: - Data is per-user, per-developer (isolated) - Cross-device sync (follows user's Gammal Tech Passport) - JSON format - any serializable data - save() REPLACES, doesn't merge - 100KB limit per user - User must be logged in Update Pattern: ```javascript const current = await GammalTech.user.get(); current.newField = 'value'; await GammalTech.user.save(current); ``` Please help me: [DESCRIBE YOUR USER DATA TASK]