Silnik: QuickJS (quickjs-ng), ES2020+. API (console, timery, fetch, silver, DOM, polyfille) jest wbudowane
w libsilverjs.a — nie dołączasz żadnych plików. Skrypty ładujesz przez app::load_js([...]) albo <script src> /
<script> w HTML.
const r = await silver.invoke('greet', { name: 'Ala' }); // Promise; odrzucony przy błędzie komendy
const off = silver.listen('moje-zdarzenie', (payload) => { … }); // app::emit(app, "moje-zdarzenie", json)Zdarzenia systemowe: silver://task ({id, output}), silver://drop ({path|text, x, y}), silver://focus, silver://blur, silver://link.
silver.window.* (tytuł, pełny ekran, rozmiar, ikona, powiadomienia…), silver.dialog.* (open, openMultiple, save,
folder, message, confirm), silver.clipboard.readText/writeText. Typy: types/silver.d.ts.
JS widzi kopię drzewa DOM (snapshot przy starcie). Odczyty są synchroniczne; zapisy trafiają wsadowo do H# (jedno wywołanie na mikrozadanie) i przerysowują widok.
Obsługiwane: document.getElementById/querySelector(All)/getElementsBy*, createElement/createTextNode/createComment/ createDocumentFragment, body/head/documentElement/activeElement/title; na elementach: textContent, innerText, innerHTML
(parsowany lokalnie, odczyt synchroniczny), outerHTML, value, checked, disabled, hidden, id, className, classList,
style (kebab/camelCase, cssText), dataset, atrybuty (+NS), children/childNodes/parent*/…Sibling, append/prepend/ insertBefore/appendChild/removeChild/remove/replaceWith/before/after/cloneNode, closest/matches/contains, focus/blur/click,
scrollTop, <template>.content.
Selektory (podzbiór CSS): tag, *, #id, .klasa, [attr], [attr=v|~=|^=|$=|*=||=], kombinatory , >, +, ~,
:first-child/:last-child/:only-child/:nth-child()/:empty/:checked/:disabled/:enabled/:focus/:not(), listy po przecinku.
click, dblclick, mousedown/up, mouseenter/leave, contextmenu, keydown/keyup (key, code, ctrlKey, shiftKey, altKey,
metaKey, repeat), input, change, submit, focus, blur, scroll, drop, resize, DOMContentLoaded, load.
Bąbelkowanie do document i window, stopPropagation, { once: true }.
preventDefault() działa synchronicznie dla click (pomija przełączenie checkboxa/radio, nawigację linku, wysłanie formularza przyciskiem)
i keydown (pomija wpisanie znaku, Tab, Enter/Spację, przewijanie klawiszami): H# wywołuje JS bezpośrednio i odczytuje, czy zdarzenie
zostało anulowane. Dla pozostałych typów zdarzeń preventDefault() jest przyjmowane bez efektu (nie mają domyślnej akcji w Silverze).
Pierwsze wywołanie getBoundingClientRect, offsetWidth itp. (albo new ResizeObserver/IntersectionObserver().observe()) włącza
wysyłanie prostokątów z H# do JS po każdym układzie (tylko po zmianie). Do tego momentu — i dla elementów jeszcze nieułożonych — zwracane są zera,
więc przy pierwszym odczycie tuż po zmianie DOM wartość pochodzi z poprzedniej klatki.
getBoundingClientRect()/getClientRects(), offsetWidth/Height/Left/Top/Parent, clientWidth/Height/Left/Top, scrollWidth/Height,
window.scrollY/pageYOffset. getComputedStyle(el) zwraca prawdziwe wartości (display, position, kolory jako rgb()/rgba(), rozmiary czcionki,
marginesy, paddingi, szerokości ramek, opacity, z-index, transform, …) dla elementów, o które JS już raz zapytał (pierwszy odczyt zwraca
styl inline i wartości domyślne; kolejne — z układu).
MutationObserver (childList, attributes, characterData, subtree, attributeOldValue, attributeFilter, takeRecords),
ResizeObserver (rozmiar zawartości i ramki), IntersectionObserver (root, rootMargin, threshold, odświeżany przy układzie, zmianie rozmiaru okna i przewijaniu dokumentu).
Pliki ładowane przez load_js/<script src> wykrywane są jako moduły (import/export na początku linii albo rozszerzenie .mjs):
względne importy (./x, ../y, z dopisaniem .js/.mjs/index.js), export default, import * as, dynamiczny import(), await na najwyższym poziomie.
Wciąż działają też zwykłe skrypty i bundle IIFE. Brak: importów po URL i import.meta.url.
element.attachShadow({mode}), shadowRoot, <slot> (domyślny i nazwany), slot.assignedNodes(), host.children/childNodes zwracają light DOM.
Silnik nie ma enkapsulacji CSS (style z shadow root są globalne, :host nie jest rozpoznawane, brak treści zapasowej slotu, brak slotchange).
customElements.define/get/whenDefined, class X extends HTMLElement, connectedCallback, disconnectedCallback,
attributeChangedCallback + observedAttributes, upgrade już istniejących elementów. Brak: extends wbudowanych, formAssociated.
console.*, setTimeout/setInterval/clear*, requestAnimationFrame, queueMicrotask, performance.now, matchMedia,
Event/CustomEvent/EventTarget, URL/URLSearchParams (+ URL.createObjectURL dla Blob), TextEncoder/Decoder, AbortController
(reason = AbortError/TimeoutError), atob/btoa, structuredClone, process.env.NODE_ENV.
fetch: nagłówki żądania i odpowiedzi (Headers,Request,Response,clone/json/text/blob/arrayBuffer), dowolna metoda,AbortSignal, adresyblob:oraz pliki lokalne (ścieżka względna wobec katalogu HTML albofile://). Żądania HTTP(S) przechodzą przezcurl(jeśli jest wPATH, bez powłoki) — stąd nagłówki i przekierowania; bezcurldziała uproszczony klient (GET/POST/PUT/DELETE, bez nagłówków). Żądanie blokuje pętlę na czas trwania.localStoragejest trwały (plik JSON w$XDG_DATA_HOME/silver/<aplikacja>/localStorage.json, zapis z opóźnieniem 250 ms i przy zamknięciu);sessionStorageżyje w pamięci. Proxy:localStorage.klucz = 'x',Object.keys(localStorage).Intl:NumberFormat(dziesiętne, procent, waluta,compact),DateTimeFormat(dateStyle/timeStylei opcje składowe),PluralRules(pl, en, fr; zwykłe i porządkowe),Collator(polskie znaki,numeric,sensitivity),ListFormat,RelativeTimeFormat,Segmenter(uproszczony); lokalizacjepl,en,de,fr,es,it;toLocaleString/DateString/TimeStringilocaleComparekorzystają z tych implementacji. To podzbiór bez pełnych danych CLDR.Worker: działa w tym samym wątku (bez izolacji i równoległości):postMessage/onmessage, kolejkowanie do czasu załadowania skryptu,terminate, skrypt z pliku lubblob:;importScriptsniedostępne.WebSocket: natywny klientws://(handshake z weryfikacjąSec-WebSocket-Accept, ramki tekstowe/binarne, fragmentacja, ping/pong, zamknięcie z kodem).wss://(TLS) nie jest obsługiwane — zdarzeniaerror+close(1006). Brak POSIX-owych gniazd w buildzie Windows.- Source mapy: przy ładowaniu skryptu rejestrowana jest mapa z
//# sourceMappingURL=(inlinedata:lub plik) albo sąsiedni<plik>.map; stosy błędów w konsoli i logu wskazują wtedy pliki.ts/.tsx.silver.registerSourceMap(nazwa, json)rejestruje mapę ręcznie.
Pamięć 256 MB, stos 1 MB, budżet czasu 3 s na jedno wejście do JS (pętla nieskończona jest przerywana), kolejka 4096 wywołań
(przepełnienie odrzuca Promise). Komendy z uprawnieniem wymagają app::allow_js. Błędy skryptów → stderr + log H#.
TypeScript, Preact, Svelte 4/5 oraz (od 0.3) React 18, Vue 3 i Solid — render, kliknięcia, pole kontrolowane, listy, efekty
(native/tests/run-ext.sh, npm + esbuild + QuickJS na lustrze DOM). Wymagało to m.in. window.event, właściwości on*,
ownerDocument, input.type, zapisywalnego currentTarget.
Izolowane wątki dla Worker, wss://, enkapsulacja CSS w Shadow DOM, pełne Intl, import() po URL. Szczegóły: ROADMAP.md.