Adapters
Adapters connect explicit Sercrod or application actions to external capabilities. Sercrod core owns host data, directive evaluation, update routing, and DOM rendering. Browser APIs, Capacitor bridges, project bridges, and build tools stay outside the core.
The runtime does not perform the application's job. It enforces the contracts that the application declares: which capability is requested, which adapter role receives the request, which fallback path is allowed, and where the result is placed in host data.
Runtime capability adapters live directly under
dist/adapters/. Environment-specific behavior is selected
inside each capability adapter where practical.
Registry
Sercrod.set_adapter("sercrod.filesystem", adapter);
Sercrod.use_adapter("file", "sercrod.filesystem");
Sercrod._get_adapter("file");
Adapters are also exposed under window.__Sercrod.adapters.
Default role mappings live in window.__Sercrod.adapter_map.
App code may still call capability adapters directly for diagnostics
or app-specific helper flows, while normal Sercrod-owned actions use
the visible directive surface when one exists.
Runtime capability layout
dist/adapters/filesystem.js
dist/adapters/navigation.js
dist/adapters/camera.js
dist/adapters/clipboard.js
dist/adapters/media-playback.js
dist/adapters/audio-capture.js
dist/adapters/geolocation.js
dist/adapters/network-status.js
dist/adapters/screen-state.js
dist/adapters/wake-lock.js
dist/adapters/haptics.js
dist/adapters/device-info.js
dist/adapters/share.js
dist/adapters/notification.js
dist/adapters/barcode.js
dist/adapters/upload.js
Do not add ordinary runtime capability adapters under
dist/adapters/browser/ or
dist/adapters/capacitor/. Playwright SSG support is a
separate build-time concern and remains under
dist/adapters/playwright/.
Design contract
- Sercrod owns host data and rendering behavior.
- Each adapter owns one external capability.
- Backend order is project bridge, Capacitor/native bridge, browser fallback, then explicit no-op.
- Return
falsewhen the request was not handled and caller fallback may continue. - Do not hide global interception or unrelated application state inside an adapter.
- Keep persistence, upload, playback, capture, and navigation as separate responsibilities.
- Expose
diagnose()when platform support or permission state needs inspection.
Filesystem
sercrod.filesystem is the default file role
adapter. It supports the JSON save/load path used by Sercrod and also
exposes explicit file and asset methods for application code.
const fs = window.SercrodFilesystemAdapter;
await fs.save_json(context);
await fs.load_json(context);
await fs.save_file(context);
await fs.load_file(context);
The common adapter selects project bridge, Capacitor Filesystem, or browser fallback internally. It does not upload files.
Navigation
sercrod.navigation.browser handles explicit
*navigate actions and matching *page targets.
It may use the browser Navigation API or history fallback. It is not a
route table, global link interceptor, or Sercrod-owned SPA state manager.
Camera and clipboard
sercrod.camera captures or selects images. It returns image
data and metadata but does not save or upload them. The preferred
template surface is *camera.capture or
*camera.pick, which delegates to this adapter.
sercrod.clipboard reads and writes user clipboard text
through a project bridge, Capacitor Clipboard, browser Clipboard API, or
legacy copy fallback. Use *clipboard.write,
*clipboard.copy, or *clipboard.read as the
visible template surface. Clipboard operations should remain explicit
user actions.
Media playback
sercrod.media_playback controls existing native
<audio> and <video> elements.
It provides play, pause, stop, seek, volume, mute, status, autoplay
probe, and diagnostics.
In a browser, a non-muted playback request blocked with
NotAllowedError can open the shared playback dialog. Its
button retries the same media element inside a user action. Standard
Capacitor playback normally succeeds without this browser-only dialog.
Audio capture
sercrod.audio_capture records microphone input using
getUserMedia() and MediaRecorder.
const capture = window.SercrodAudioCaptureAdapter;
await capture.start({ host });
capture.pause();
capture.resume();
const result = await capture.stop();
audio.src = result.url;
The result contains a Blob, File where supported, Object URL, MIME type,
size, duration, and timestamps. Call release(result) when
the Object URL is no longer needed.
The adapter does not play, persist, upload, transcribe, mix, or record in
the background. Browser microphone capture requires a secure context and
user permission. The Android app declares
RECORD_AUDIO and MODIFY_AUDIO_SETTINGS.
Geolocation
sercrod.geolocation provides foreground current position,
position watch/clear, permission status/request, status, and
diagnostics. It selects a project bridge, Capacitor Geolocation, or the
browser Geolocation API internally.
const geo = window.SercrodGeolocationAdapter;
const current = await geo.current({
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
});
const watch = await geo.watch({}, (position, error) => {
if(position) console.log(position.coords);
});
await geo.clear_watch(watch.watchId);
Results include latitude, longitude, accuracy, altitude, heading,
speed, and timestamp where available. A smaller
coords.accuracy value means a more precise position.
A one-shot current position can return before device accuracy improves;
use a watch when the application should receive improved positions over
time.
The adapter is foreground-only. It does not provide background tracking, map UI, geocoding, IP estimation, route history, persistence, or upload. The sample app displays returned coordinates with Leaflet and OpenStreetMap, but that map remains application-layer UI.
The Capacitor app declares @capacitor/geolocation and the
Android ACCESS_COARSE_LOCATION and
ACCESS_FINE_LOCATION permissions.
Network status
sercrod.network_status reads online/offline status and
connection information through a project bridge, Capacitor Network, or
browser status APIs. The visible template surface is
*network-status.
const network = window.SercrodNetworkStatusAdapter;
const current = await network.status();
const watch = await network.watch({}, (status) => {
console.log(status.online, status.type);
});
await network.clear_watch(watch.watchId);
This adapter owns status and diagnostics only. It does not retry requests, schedule uploads, manage WebSocket reconnection, synchronize app state, install service workers, or make application policy decisions.
Screen state
sercrod.screen_state reads viewport, orientation,
fullscreen, and display-mode state through a project bridge, optional
native/app bridge, or browser state APIs. The visible template surface is
*screen-state.
const screen = window.SercrodScreenStateAdapter;
const current = await screen.current();
const watch = await screen.watch({}, (state) => {
console.log(state.viewportWidth, state.orientation);
});
await screen.clear_watch(watch.watchId);
This adapter owns read-only state and diagnostics only. It does not edit viewport meta tags, replace CSS media/container queries, compute layouts, route pages, persist state, or make application policy decisions.
Wake lock
sercrod.wake_lock requests, releases, and reports screen
wake lock state through a project bridge, optional native/app bridge,
or the browser Screen Wake Lock API. The visible template surface is
*wake-lock.
<button type="button" *wake-lock.request *response="'wake'">Keep awake</button>
<button type="button" *wake-lock.release *response="'wake'">Allow sleep</button>
const wake = window.__Sercrod.adapters.wake_lock;
await wake.request({ type: "screen" });
await wake.status();
await wake.release();
This adapter owns screen-awake intent and diagnostics only. It does not control media playback, timers, notifications, app lifecycle, background execution, or operating-system battery policy.
Haptics
sercrod.haptics triggers tactile feedback through a
project bridge, optional native/app bridge, Capacitor Haptics, or
browser vibration where available. The visible template surface is
*haptics.
<button type="button" *haptics.impact="'medium'">Tap</button>
<button type="button" *haptics.selection>Select</button>
<button type="button" *haptics.notification="'warning'">Warn</button>
const haptics = window.SercrodHapticsAdapter;
await haptics.impact({ style: "medium" });
await haptics.selection();
await haptics.notification({ type: "success" });
This adapter owns tactile feedback and diagnostics only. It does not create gestures, handle pointer events, play sound, animate UI, show notifications, navigate, or make application policy decisions. Notification haptics are platform-defined patterns; warning is not guaranteed to feel stronger than error on every device.
Share
sercrod.share shares text, URLs, or supported files through
a project bridge, Capacitor Share, or the browser Web Share API. The
visible template surface is
*share.
const share = window.SercrodShareAdapter;
await share.share({
title: "Sercrod",
text: "Open Sercrod",
url: "https://sercrod.com/"
});
Sharing remains an explicit user action. The adapter does not save, upload, navigate, persist, write to the clipboard, or turn clipboard into ordinary application data flow.
Notification
sercrod.notification shows local notifications and checks
or requests local notification permission through a project bridge,
Capacitor LocalNotifications, or browser Notification API. The visible
template surface is *notification.
const notification = window.SercrodNotificationAdapter;
await notification.request_permissions();
await notification.show({
title: "Sercrod",
body: "Local notification"
});
This adapter is local only. It does not implement push registration, server delivery, background synchronization, persistence, sharing, or navigation.
Barcode
sercrod.barcode scans or detects barcodes and QR codes
through a project bridge, Capacitor/native scanner bridge, or browser
BarcodeDetector. The visible template surface is
*barcode.
const barcode = window.SercrodBarcodeAdapter;
await barcode.scan({
formats: ["qr_code"]
});
This adapter only owns code detection results. It does not become the camera adapter, upload images, validate inventory/payment workflows, or navigate from scanned values.
Capacitor app sandboxes
Every sandbox/app/<app>/ has an
app.json. Its capacitor.plugins list is the
source of truth for app-specific native packages. Apps without native
plugins use an empty list.
sandbox/app/<app>/www/sercrod.js
sandbox/app/<app>/www/adapters
Those two entries are absolute server-side symlinks to the shared
dist files. The Windows build flow uses
rsync -L, so Capacitor receives ordinary files.
build.bat asks whether to synchronize from Aether before
showing the app list. Sync mode pulls the whole shared app root, safely
updates and restarts build.bat when needed, then lists only
direct child folders containing app.json. Native/generated
directories remain local.
Playwright SSG
dist/adapters/playwright/bridge.js
dist/adapters/playwright/ssg.js
These files support static-site generation and build orchestration. They are not ordinary runtime capability adapters.