Tovább a tartalomhoz

Szerver függvények

Az alkalmazás szerver oldali logikája a server/functions.js (vagy .ts) fájlban él. Ezek a függvények a szerveren futnak, és a kliensről a sdk.remote.call() segítségével hívhatók.

Szükséges jogosultság: remote_functions a manifest.json-ban.

server/functions.js
/**
* Szerver idő lekérdezése
* @param {Object} params - Kliens által küldött paraméterek
* @param {Object} context - Execution context (pluginId, userId, db)
*/
export async function getServerTime(params, context) {
const now = new Date();
return {
iso: now.toISOString(),
locale: now.toLocaleString('hu-HU'),
timestamp: now.getTime()
};
}

TypeScript-tel:

server/functions.ts
interface Context {
pluginId: string;
userId: string;
db: {
execute: (sql: string, params?: unknown[]) => Promise<{ rows: unknown[] }>;
};
}
export async function getServerTime(
params: { format?: 'ISO' | 'locale' | 'timestamp' },
context: Context
) {
const now = new Date();
return {
iso: now.toISOString(),
locale: now.toLocaleString('hu-HU'),
timestamp: now.getTime()
};
}

Minden szerver függvény megkapja a context paramétert:

MezőTípusLeírás
pluginIdstringA plugin azonosítója
userIdstringA hívó felhasználó ID-ja
dbobjectAdatbázis kapcsolat (csak database jogosultsággal)
export async function myFunction(params, context) {
const { pluginId, userId, db } = context;
console.log(`[${pluginId}] Called by user: ${userId}`);
// ...
}

A db objektum a plugin saját sémájához (plugin_{plugin_id}) biztosít hozzáférést. Szükséges jogosultság: database.

export async function getItems(params, context) {
const { db, pluginId } = context;
// A plugin saját sémájában lévő tábla lekérdezése
const result = await db.execute(`
SELECT id, name, created_at
FROM plugin_${pluginId}.items
WHERE active = $1
ORDER BY created_at DESC
LIMIT $2
`, [true, params.limit ?? 20]);
return {
items: result.rows,
total: result.rows.length
};
}
server/functions.js
export async function createItem(params, context) {
const { db, pluginId, userId } = context;
const { name, description } = params;
if (!name || name.trim().length === 0) {
throw new Error('A név megadása kötelező');
}
const result = await db.execute(`
INSERT INTO plugin_${pluginId}.items (name, description, created_by)
VALUES ($1, $2, $3)
RETURNING id, name, created_at
`, [name.trim(), description ?? null, userId]);
return { item: result.rows[0] };
}
export async function updateItem(params, context) {
const { db, pluginId } = context;
const { id, name, description } = params;
await db.execute(`
UPDATE plugin_${pluginId}.items
SET name = $1, description = $2, updated_at = NOW()
WHERE id = $3
`, [name, description, id]);
return { success: true };
}
export async function deleteItem(params, context) {
const { db, pluginId } = context;
await db.execute(`
DELETE FROM plugin_${pluginId}.items WHERE id = $1
`, [params.id]);
return { success: true };
}
<script lang="ts">
const sdk = window.webOS!;
interface Item {
id: number;
name: string;
created_at: string;
}
let items = $state<Item[]>([]);
let loading = $state(false);
async function loadItems() {
loading = true;
try {
const result = await sdk.remote.call<{ items: Item[] }>('getItems', {
limit: 50
});
items = result.items;
} catch (error) {
sdk.ui.toast('Nem sikerült betölteni az elemeket', 'error');
} finally {
loading = false;
}
}
async function addItem(name: string) {
try {
await sdk.remote.call('createItem', { name });
sdk.ui.toast('Elem létrehozva', 'success');
await loadItems();
} catch (error) {
sdk.ui.toast((error as Error).message, 'error');
}
}
</script>

A szerver függvényekből dobott hibák automatikusan propagálódnak a kliensre:

export async function riskyOperation(params, context) {
if (!params.id) {
throw new Error('Az ID megadása kötelező');
}
try {
const result = await context.db.execute(
`SELECT * FROM plugin_${context.pluginId}.items WHERE id = $1`,
[params.id]
);
if (result.rows.length === 0) {
throw new Error('Az elem nem található');
}
return { item: result.rows[0] };
} catch (error) {
// Naplózás szerver oldalon
console.error(`[${context.pluginId}] Error in riskyOperation:`, error);
// Hiba továbbítása a kliensnek
throw error;
}
}

A kliensen:

try {
const result = await sdk.remote.call('riskyOperation', { id: 123 });
} catch (error) {
// error.message tartalmazza a szerver által dobott hibaüzenetet
sdk.ui.toast(error.message, 'error');
}

A remote hívásoknak alapértelmezetten 30 másodperces timeoutjuk van. Hosszabb műveleteknél adj meg egyedi timeoutot:

const result = await sdk.remote.call('longRunningTask', params, {
timeout: 120000 // 2 perc
});

A Mock SDK-val szimulálhatod a szerver függvényeket fejlesztés közben:

src/main.ts
MockWebOSSDK.initialize({
remote: {
handlers: {
getItems: async () => ({
items: [
{ id: 1, name: 'Teszt elem', created_at: new Date().toISOString() }
]
}),
createItem: async ({ name }) => ({
item: { id: Date.now(), name, created_at: new Date().toISOString() }
})
}
}
});