Tovább a tartalomhoz

Fejlesztői workflow

Az alkalmazás fejleszthető futó ElyOS példány nélkül is. A @elyos/sdk/dev csomag egy Mock SDK-t biztosít, amely szimulálja az összes SDK szolgáltatást:

SDK szolgáltatásMock viselkedés
ui.toast()console.log-ba ír
ui.dialog()window.confirm / window.prompt (standalone módban)
data.set/get/delete()localStorage-t használ (devapp:{appId}: kulcs prefix alatt)
data.query()Üres tömböt ad vissza
remote.call()Konfigurálható mock handler
i18n.t()A megadott fordítási mapből olvas
notifications.send()console.log-ba ír

A dev szerver indításához szükség van egy index.html fájlra a projekt gyökerében — ezt a Vite keresi belépési pontként. A CLI által generált projektek ezt automatikusan tartalmazzák.

Terminál
bun dev

Az alkalmazás elérhető lesz a http://localhost:5174 címen. A Vite hot reload automatikusan frissíti a böngészőt minden mentéskor.

Ha egyszerre több alkalmazást fejlesztesz, a dev (Vite) és a dev:server (statikus szerver) parancsok alapértelmezetten az 5174-es portot használják. Ez ütközést okoz, ha mindkét alkalmazás egyszerre fut.

A port a PORT környezeti változóval felülírható:

Terminál
# Első alkalmazás — alapértelmezett port
bun run dev:server
# Második alkalmazás — más porton
PORT=5175 bun run dev:server

Az ElyOS Dev Alkalmazások betöltőjében az URL-t ennek megfelelően add meg: http://localhost:5175.

A Mock SDK (@elyos/sdk/dev) egy fejlesztői csomag, amely szimulálja a valódi window.webOS SDK-t — futó ElyOS példány nélkül. Amikor az alkalmazás standalone módban fut (pl. bun dev), a window.webOS még nem létezik, ezért a MockWebOSSDK.initialize() hozza létre és teszi elérhetővé.

A src/main.ts fájlban ez automatikusan megtörténik:

src/main.ts
import { mount } from 'svelte';
import { MockWebOSSDK } from '@elyos/sdk/dev';
import App from './App.svelte';
async function initDevSDK() {
if (typeof window !== 'undefined' && !window.webOS) {
// Csak akkor fut le, ha NEM ElyOS-ben vagyunk
MockWebOSSDK.initialize({
// Fordítások a fejlesztéshez
i18n: {
locale: 'en',
translations: {
en: { title: 'My App', welcome: 'Welcome!' },
hu: { title: 'Alkalmazás', welcome: 'Üdvözöljük!' }
}
},
// Szimulált felhasználó és jogosultságok
context: {
appId: 'my-app',
user: {
id: 'dev-user',
name: 'Developer',
email: 'dev@localhost',
roles: ['admin'],
groups: []
},
permissions: ['database', 'notifications', 'remote_functions']
}
});
}
}
async function init() {
await initDevSDK();
const target = document.getElementById('app');
if (target) mount(App, { target }); // Svelte 5: mount() — nem new App()
}
init();

Az initialize() összes konfigurációs lehetősége:

OpcióTípusLeírás
i18n.localestringAlapértelmezett nyelv (pl. 'hu')
i18n.translationsRecord<string, Record<string, string>>Fordítási kulcsok nyelvenkénti mapje
context.appIdstringSzimulált alkalmazás ID
context.userUserInfoSzimulált bejelentkezett felhasználó
context.permissionsstring[]Szimulált jogosultságok
data.initialDataRecord<string, unknown>Előre feltöltött localStorage adatok
remote.handlersRecord<string, Function>Mock szerver függvény handlerek
assets.baseUrlstringAsset URL prefix

Amikor az ElyOS betölti az alkalmazást élesben, a window.webOS már létezik (a runtime SDK-val feltöltve), ezért az if (!window.webOS) feltétel miatt a Mock SDK nem fut le.

Ha szerver függvényeket is tesztelsz standalone módban:

MockWebOSSDK.initialize({
remote: {
handlers: {
getServerTime: async () => ({
iso: new Date().toISOString(),
locale: new Date().toLocaleString('hu-HU')
}),
calculate: async ({ a, b, operation }) => {
if (operation === 'add') return { result: a + b };
throw new Error('Unsupported operation');
}
}
}
});

A standalone dev mód (Mock SDK) csak a UI-t teszteli. Ha valódi SDK hívásokat, adatbázist vagy szerver függvényeket is tesztelni szeretnél, az alkalmazást be kell tölteni egy futó ElyOS példányba.

A folyamat lényege: buildeld le az alkalmazást, indíts egy statikus HTTP szervert, majd töltsd be az ElyOS-be URL alapján. Nincs automatikus hot reload — ha változtattál a kódon, újra kell buildelni és újra megnyitni az alkalmazás ablakát.

Az elyos-core monorepo gyökerében:

Terminál
# .env.local fájlban engedélyezd a dev alkalmazás betöltést:
# DEV_MODE=true
bun app:dev

Az ElyOS alapértelmezetten a http://localhost:5173 címen érhető el. Jelentkezz be admin fiókkal.

Az alkalmazás projekt mappájában:

Terminál
bun run build

Ez létrehozza a dist/index.iife.js fájlt — ezt tölti be az ElyOS.

3. lépés — Statikus dev szerver indítása

Szekció neve “3. lépés — Statikus dev szerver indítása”
Terminál
bun run dev:server

Ez elindítja a dev-server.ts Bun HTTP szervert a http://localhost:5174 címen. A szerver a dist/ mappából és a projekt gyökeréből szolgálja ki a fájlokat CORS fejlécekkel.

4. lépés — Alkalmazás betöltése az ElyOS-be

Szekció neve “4. lépés — Alkalmazás betöltése az ElyOS-be”
  1. Nyisd meg az ElyOS-t a böngészőben
  2. Start menü → Alkalmazás Manager
  3. A bal oldalsávban kattints a “Dev Alkalmazások” menüpontra
  4. Megjelenik egy URL beviteli mező http://localhost:5174 alapértelmezett értékkel
  5. Kattints a “Load” gombra

Az ElyOS lekéri a manifest.json-t a dev szerverről, majd betölti az IIFE bundle-t és Web Component-ként regisztrálja az alkalmazást.

Terminál
# 1. Újrabuildelés
bun run build
# 2. Az ElyOS-ben: zárd be az alkalmazás ablakát, majd nyisd meg újra
# (a "Load" gombot nem kell újra megnyomni — az alkalmazás már a listában van)
Terminál
# Terminál 1 — ElyOS core
cd elyos-core && bun app:dev
# Terminál 2 — Alkalmazás build + szerver
cd my-app
bun run build # IIFE bundle elkészítése
bun run dev:server # statikus szerver indítása (http://localhost:5174)
# ElyOS-ben: Alkalmazás Manager → Dev Alkalmazások → Load → http://localhost:5174

Az @elyos/sdk teljes TypeScript típusdefiníciókat tartalmaz. A window.webOS típusa automatikusan elérhető:

// Automatikus típus — nincs szükség importra
const sdk = window.webOS!;
sdk.ui.toast('Hello!', 'success'); // ✅ autocomplete
sdk.data.set('key', { value: 123 }); // ✅ típusellenőrzés
sdk.remote.call<MyResult>('fn', params); // ✅ generikus visszatérési típus

Explicit típusimport szükség esetén:

import type { WebOSSDKInterface, UserInfo } from '@elyos/sdk/types';
const user: UserInfo = sdk.context.user;

A plugin Svelte 5 runes-alapú reaktivitást használ. A vite.config.ts-ben a runes: true compiler opció be van kapcsolva:

<script lang="ts">
const sdk = window.webOS!;
let count = $state(0);
let doubled = $derived(count * 2);
$effect(() => {
sdk.ui.toast(`Count: ${count}`, 'info');
});
</script>
<button onclick={() => count++}>
{count} (doubled: {doubled})
</button>

Standalone módban való nyelvváltás (sidebar template)

Szekció neve “Standalone módban való nyelvváltás (sidebar template)”

A sidebar template App.svelte-je beépített nyelvváltó gombot tartalmaz az oldalsáv alján — ez csak akkor jelenik meg, ha a plugin több locale-t definiál. Standalone módban (Mock SDK) a sdk.i18n.setLocale() hívás a Mock SDK belső állapotát frissíti, és a {#key currentLocale} blokk újramountolja az aktív komponenst.

ElyOS-be betöltve a setLocale() a core i18n rendszerét hívja, amely az egész alkalmazás nyelvét váltja — nem csak a plugin nyelvét.

A plugin CSS-e az IIFE build során nem kerül automatikusan a JS bundle-be — a Vite lib módban külön .css fájlba szedi ki. Ha ez a fájl nem töltődik be, a plugin stílusai egyáltalán nem jelennek meg az ElyOS-ben.

Amikor a Vite IIFE bundle-t épít, a Svelte komponensek CSS-ét egy külön fájlba (dist/sample-01-plugin.css) teszi. Az ElyOS csak a JS bundle-t tölti be — a CSS fájlt nem. Ennek eredménye: a plugin stílusai teljesen hiányoznak.

A megoldás a vite.config.ts-ben egy egyedi Vite plugin, amely a generált CSS-t <style> tagként injektálja a JS bundle elejére:

vite.config.ts
function injectCssPlugin(): Plugin {
let cssContent = '';
return {
name: 'inject-css',
apply: 'build',
generateBundle(_, bundle) {
// CSS fájl tartalmának összegyűjtése és eltávolítása a bundle-ből
for (const [fileName, chunk] of Object.entries(bundle)) {
if (fileName.endsWith('.css') && chunk.type === 'asset') {
cssContent += chunk.source as string;
delete bundle[fileName];
}
}
// CSS injektálása a JS bundle elejére
if (cssContent) {
for (const chunk of Object.values(bundle)) {
if (chunk.type === 'chunk' && chunk.fileName.endsWith('.js')) {
const injection = `(function(){var s=document.createElement('style');s.textContent=${JSON.stringify(cssContent)};document.head.appendChild(s);})();`;
chunk.code = injection + chunk.code;
break;
}
}
}
}
};
}

Ez a plugin a create-elyos-app által generált vite.config.ts-ben már benne van — nem kell kézzel hozzáadni.

Még ha a CSS be is töltődik, a core app Tailwind stílusai (base layer resetok) felülírhatják a plugin stílusait. Ez minden betöltési módban (dev URL és telepített .elyospkg) ugyanígy viselkedik.

A Svelte scoped CSS button.svelte-xxxx selectorokat generál, de a Tailwind button { ... } resetje magasabb specificitással töltődik be, így felülírja.

Mindig egy saját konténer osztályon belül definiáld a stílusokat, és kerüld a nyers HTML tag selectorokat:

<!-- ❌ Rossz — a core stílusai felülírják -->
<style>
button {
border: 1px solid #ccc;
padding: 0.5rem 1rem;
}
</style>
<!-- ✅ Helyes — konténer osztályon belül scopelve -->
<style>
.my-plugin button {
border: 1px solid #ccc;
padding: 0.5rem 1rem;
}
</style>

all: revert — core stílusok visszaállítása

Szekció neve “all: revert — core stílusok visszaállítása”

Ha a core stílusai felülírnak egy elemet, az all: revert visszaállítja a böngésző natív stílusát:

<style>
.my-plugin button {
all: revert;
cursor: pointer;
border: 1px solid #ccc;
border-radius: 0.25rem;
padding: 0.5rem 1rem;
background: white;
}
.my-plugin button:hover {
background: #f0f0f0;
}
</style>
SzabályMiért
A vite.config.ts-ben legyen injectCssPlugin()Nélküle a CSS egyáltalán nem töltődik be az ElyOS-ben
Konténer osztályon belül scopelj (.my-plugin button)A core Tailwind stílusai felülírják a nyers tag selectorokat
Szükség esetén használj all: revert-etVisszaállítja a böngésző natív stílusát
Adj egyedi osztálynevet a gyökér konténernekElkerüli az ütközést más pluginok stílusaival