Перейти к содержанию

Frontend module contract

The built-in UI remains a no-build vanilla JavaScript application. Its only intentional application global is window.XferryApp, created by static/ui/bootstrap.js. Workflow files run inside private IIFEs and register their commands and redacted state snapshots through that namespace.

Load and ownership order

The HTML loads classic same-origin scripts synchronously in this order:

  1. bootstrap.js creates the namespace, event bus, DOM contract and registries.
  2. core.js, dialogs.js and inspector.js register shared services.
  3. upload.js, requests.js, files.js, opsec.js and notepad.js register workflows. Requests also registers the shared HTTP service.
  4. app.js initializes inspector states, keyboard shortcuts and server discovery, then emits app.ready.

No Node.js runtime, package manager, bundler or generated frontend artifact is required to serve or modify these files.

Public surface

XferryApp.describe() is the runtime authority for registered services, workflow commands, event names and semantic DOM keys. The stable API methods are:

  • service(name) — resolve a registered shared service;
  • invoke(workflow, command, ...args) — execute a documented workflow command;
  • getState(workflow) — obtain a shallow, non-secret diagnostic snapshot;
  • on(event, listener) / emit(event, detail) — use the closed event contract;
  • element(contractName) — resolve a semantic DOM contract;
  • describe() — enumerate the complete intentional public surface.
  • unexpectedGlobals() — compare the live window with the bootstrap baseline and report accidental globals (the vendored CryptoJS global is allowlisted).

The workflow command groups are upload, requests, files, advanced and notepad. Shared implementation functions and mutable variables are private to their script closure and must not be called through window.

The http service exposes set-adapter and reset-adapter only so browser regressions can inject deterministic failures and delayed responses without reintroducing writable globals. Production workflows call http.request.

Cross-workflow events

Only these application events are accepted:

  • locale.changed — locale-dependent workflow rendering must refresh;
  • server.methods.changed — PING-derived method controls must refresh;
  • workspace.changed — Files and Notepad may perform activation work;
  • app.ready — the complete public surface has been registered.

Unknown events, duplicate services/workflows and unknown commands fail explicitly instead of silently depending on script order.

DOM contract

Cross-module or lifecycle code uses semantic keys from XferryApp.dom, such as panel.send, panel.notepad, files.path and app.version. Workflow-local elements may remain private selectors inside their owning module. Adding a new cross-workflow selector requires adding a semantic contract key and a static test.

Rendering and privacy rules

  • File queues, server file listings and Notepad lists are built with DOM APIs and textContent; user-controlled names and titles are not interpolated into HTML.
  • Technical request/response output must pass through the inspector redaction service before it is stored, copied or downloaded.
  • Workflow state snapshots must expose status/counts only. Session IDs, derived keys, note bodies, filenames and note titles stay private.
  • Async listing/load operations must retain their generation or sequence guard so stale responses cannot overwrite newer user state.