sercrod

Adapters

Adapters are small bridges between Sercrod runtime behavior and an external environment. The core runtime stays focused on HTML attributes, host data, rendering, and browser-native behavior. Device APIs, build tools, test runners, and platform bridges belong in adapters.

Registry

Adapters are registered under window.__Sercrod.adapters. Role selection lives in window.__Sercrod.adapter_map.

window.__Sercrod = window.__Sercrod || {};
window.__Sercrod.adapters = window.__Sercrod.adapters || {};
window.__Sercrod.adapter_map = window.__Sercrod.adapter_map || {};

The runtime exposes helper methods on the Sercrod class.

Sercrod.set_adapter("capacitor.filesystem", adapter);
Sercrod.use_adapter("file", "capacitor.filesystem");
Sercrod._get_adapter("file");

The name capacitor.filesystem resolves to window.__Sercrod.adapters.capacitor.filesystem.

Design contract

File role

The first runtime role is file. *save.file and *load.file check _get_adapter("file") before running the default browser behavior.

const adapter = {
	name: "example.file",
	async save(context){
		return true;
	},
	async load(context){
		return true;
	}
};

For save(context), the context includes the host, rendered element, source template element, raw attribute value, selected properties, selected data, and source object.

For load(context), the context includes the host, rendered element, source template element, raw attribute value, selected properties, accept string, and apply_loaded_data(json, fileName).

Capacitor filesystem adapter

The official Capacitor filesystem adapter lives at dist/adapters/capacitor/filesystem.js.

window.__Sercrod.adapters.capacitor.filesystem
window.__Sercrod.adapter_map.file = "capacitor.filesystem"

It lets *save.file and *load.file use Capacitor Filesystem in a native wrapper while preserving browser fallback when Capacitor is not available. The same adapter works for both Android and iOS; on macOS, open the iOS native project in Xcode for the debug build step.

<script src="./sercrod.js"></script>
<script src="./adapters/capacitor/filesystem.js"></script>

For debugging inside the WebView console:

window.__Sercrod.adapter_map.file
window.SercrodCapacitorFilesystemAdapter.diagnose()
localStorage.getItem("sercrod-capacitor-filesystem:last-file")
localStorage.getItem("sercrod-capacitor-filesystem:last-status")

The file role should be capacitor.filesystem. A working native build should report has_filesystem, has_write_file, and has_read_file as true. The status records show where save wrote, whether it could be read back immediately, and why load failed if no saved file can be read.

On phone builds where the WebView console is inconvenient, the adapter also inserts a small status line after the Save or Load button. This status shows the directory and file name on success, or the plugin error on failure.

Browser storage backends

Browser storage is a backend choice, not a reason to keep adding new directive families. Use the explicit action forms *save.file, *load.file, *save.session, *load.session, *save.store, and *load.store, then place custom backends behind an adapter or a small helper when those built-in forms are not enough.

IndexedDB is a good fit for JSON snapshots, metadata, key-value records, and indexes. Sercrod's built-in *save.store and *load.store use IndexedDB for JSON records. OPFS is a better fit for obvious image payloads, suspiciously large Blob/File values, and larger app-local file-like working directories. A practical design is to store large payloads outside host data and keep only keys, backend names, paths, MIME types, sizes, timestamps, and status fields in the host data.

{
  saved: {
    key: "todo-20260518",
    name: "Todo snapshot",
    size: 2048,
    type: "application/json"
  }
}

For *load.file, the file adapter bridge still converges on the same operation: read JSON or source text from the backend, then pass it into Sercrod's load merge path so Sercrod can merge it into _stage or _data, dispatch sercrod-loaded, and update the host. The built-in *load.session and *load.store forms use that same merge behavior after reading from browser storage.

Playwright SSG adapter

The Playwright SSG adapter is split into a browser bridge and a Node driver.

dist/adapters/playwright/bridge.js
dist/adapters/playwright/ssg.js

The bridge registers window.__Sercrod.adapters.playwright.ssg and exposes render_document(args). The Node driver handles URL/path mapping, partial loading, Playwright orchestration, HTML beautification, and output file writing.

Fallback rules

Adapters should fail open unless the external environment already handled the action. If an adapter cannot run, return false so Sercrod can continue with the browser fallback.

If an adapter starts handling a request and the external operation fails, report the error through host data or events and return a handled value. In that case, browser fallback should not also run.

Related pages