Page types and asynchronous results
Look up configuration, handles, messages, and return types used in public page definitions.
Types, optional fields, and versions
These definitions are generated from the two current page type files and include core communication, resources, transforms, and frontend adapters. A question mark means optional; null is an explicit empty result. They are not interchangeable. readonly values should not be mutated. Generics retain application types but do not validate arbitrary runtime objects. Related snapshot base structures are included.
Understand the return shape first
| Item | Usage and limitations |
|---|---|
| ready | Returns readiness information, not an SDK. Obtain the interface through acquireNexusWebUI. |
| state.get | Contains canonicalKey and snapshot. snapshot.item may be null; lists use items and require truncation checks. |
| state.store | Returns a store synchronously with loading:true initially. Snapshot references are stable; do not mutate them. |
| Subscriptions and events | Subscription creation returns a Promise for a handle. lifecycle.on returns a synchronous handle. |
| Low-level file operations | Wraps operationId and result. Distinguish cancellation from application failure. |
| High-level picking and saving | Import picker cancellation returns null; pickSaveDirectory cancellation returns {cancelled:true}; saves return cancelled/ok. saveFiles returns per-item results normally but only one cancellation result when picking is cancelled. |
| Transform | begin returns a Promise; drag immediately returns a gesture. ready indicates only startup. onCommit, onCancel, and onError report final outcomes; gestures have no finished property. |
Errors are not empty results
export interface WebUIError extends Error {
name: 'WebUIError';
/** Stable wire error code, e.g. 'permission_denied', 'resync_required'. */
code: string;
retryable?: boolean;
debugId?: string;
}export interface WebUIRequestOptions {
/** Wait for an individual request response in milliseconds. Default 5000. */
timeoutMs?: number;
/** Extra automatic retries for pure reads (get/describe). 0-3, default 2. */
retryAttempts?: number;
}On rejection, read code/message and retryable/debugId when present. The default timeout is 5000 ms. retryAttempts applies only to supported pure reads, ranges from 0 to 3, and defaults to 2. Timeout does not guarantee Python rollback. Application ok:false results do not automatically throw.
Complete page definition index
WebUIJSONValue
export type WebUIJSONValue =
| null
| boolean
| number
| string
| WebUIJSONValue[]
| { [key: string]: WebUIJSONValue };WebUIError
export interface WebUIError extends Error {
name: 'WebUIError';
/** Stable wire error code, e.g. 'permission_denied', 'resync_required'. */
code: string;
retryable?: boolean;
debugId?: string;
}WebUIRequestOptions
export interface WebUIRequestOptions {
/** Wait for an individual request response in milliseconds. Default 5000. */
timeoutMs?: number;
/** Extra automatic retries for pure reads (get/describe). 0-3, default 2. */
retryAttempts?: number;
}WebUIStateSortEntry
export type WebUIStateSortEntry =
| string
| { field: string; direction: 'asc' | 'desc' };WebUIStateQuery
export interface WebUIStateQuery {
fields?: readonly string[];
filter?: Record<string, WebUIJSONValue>;
sort?: readonly WebUIStateSortEntry[];
limit?: number;
cursor?: string | null;
/** Detail states: single target id, e.g. 'obj:1024'. */
id?: string;
/** Detail states: batch lookup. */
ids?: readonly string[];
sceneId?: string;
viewLayerId?: string;
[extra: string]: WebUIJSONValue | readonly WebUIStateSortEntry[] | undefined;
}WebUIListSnapshot
export interface WebUIListSnapshot<TItem = Record<string, WebUIJSONValue>> {
snapshotRevision: number;
items: TItem[];
ids?: string[];
truncated?: boolean;
nextCursor?: string | null;
[extra: string]: WebUIJSONValue | TItem[] | undefined;
}WebUIItemSnapshot
export interface WebUIItemSnapshot<TItem = Record<string, WebUIJSONValue>> {
snapshotRevision: number;
item: TItem | null;
[extra: string]: WebUIJSONValue | TItem | undefined;
}WebUISnapshot
export type WebUISnapshot = WebUIListSnapshot | WebUIItemSnapshot;WebUIStateGetResult
export interface WebUIStateGetResult {
canonicalKey: string;
snapshot: WebUISnapshot;
stateRef?: string;
}WebUISubscriptionMeta
export interface WebUISubscriptionMeta {
canonicalKey: string | null;
subscriptionId: string | null;
/** Present when the subscription died with an error frame. */
error?: WebUIError;
}WebUIStateCallback
export type WebUIStateCallback<TSnapshot = WebUISnapshot> = (
snapshot: TSnapshot | null,
meta: WebUISubscriptionMeta,
) => void;WebUIReleaseResult
export interface WebUIReleaseResult {
released: boolean;
}WebUIReleasable
export interface WebUIReleasable {
release(options?: WebUIRequestOptions): Promise<{ unsubscribed: boolean }>;
unsubscribe(options?: WebUIRequestOptions): Promise<{ unsubscribed: boolean }>;
}WebUISubscriptionHandle
export interface WebUISubscriptionHandle<TSnapshot = WebUISnapshot> extends WebUIReleasable {
readonly subscriptionId: string | null;
readonly canonicalKey: string | null;
getSnapshot(): TSnapshot | null;
}WebUIEventMeta
export interface WebUIEventMeta {
name: string;
subscriptionId: string;
/** True when the host dropped older events for this subscription. */
dropped: boolean;
}WebUIEventCallback
export type WebUIEventCallback = (payload: WebUIJSONValue, meta: WebUIEventMeta) => void;WebUIEventHandle
export interface WebUIEventHandle extends WebUIReleasable {
readonly subscriptionId: string | null;
readonly name: string;
}WebUILifecycleHandle
export interface WebUILifecycleHandle {
release(): WebUIReleaseResult;
unsubscribe(): WebUIReleaseResult;
}WebUIWindowCloseOptions
export interface WebUIWindowCloseOptions extends WebUIRequestOptions {
reason?: string;
}WebUIWindowCloseResult
export interface WebUIWindowCloseResult {
closed: true;
}WebUIWindowAPI
export interface WebUIWindowAPI {
close(options?: WebUIWindowCloseOptions): Promise<WebUIWindowCloseResult>;
}WebUILifecycleKind
export type WebUILifecycleKind =
| 'ready'
| 'stale'
| 'disconnected'
| 'reconnected'
| 'session_closed';WebUIReadyInfo
export interface WebUIReadyInfo {
protocolVersion: number;
wireRevision: number;
connectionEpoch: number;
features: string[];
[extra: string]: WebUIJSONValue | string[] | undefined;
}WebUIResourceRef
export interface WebUIResourceRef {
resourceId: string;
kind: string;
mime: string;
byteLength: number;
revision: number;
[extra: string]: WebUIJSONValue;
}WebUIResourceInfoResult
export interface WebUIResourceInfoResult {
resourceRef: WebUIResourceRef;
}WebUIResourceUrlResult
export interface WebUIResourceUrlResult {
resourceRef: WebUIResourceRef;
url: string;
expiresAtUnix: number;
}WebUIResourceUrlOptions
export interface WebUIResourceUrlOptions extends WebUIRequestOptions {
/** Native video playback with byte-range reads. Trusted virtual-local pages only. */
mode?: 'default' | 'media';
}WebUIResourceUploadOptions
export interface WebUIResourceUploadOptions extends WebUIRequestOptions {
mime?: string;
}WebUIResourceUploadResult
export interface WebUIResourceUploadResult {
uploadUrl: string;
resourceId: string;
expiresAtUnix: number;
byteLength: number;
mime: string;
}WebUIResourceUploadBody
export type WebUIResourceUploadBody = Blob | ArrayBuffer | ArrayBufferView;WebUIActionWithResourceInput
export interface WebUIActionWithResourceInput {
resource: WebUIResourceUploadBody;
mime?: string;
params?: Record<string, WebUIJSONValue>;
}NexusResourceMeta
export interface NexusResourceMeta {
resourceId: string;
kind: string;
mime: string;
byteLength: number;
revision: number;
width?: number;
height?: number;
channels?: number;
format?: string;
colorSpace?: string;
publishSource?: string;
originalSourceError?: string;
canvasExportable?: boolean | null;
transport?: 'blob' | 'data_url';
[extra: string]: WebUIJSONValue | undefined;
}NexusResourceImageResult
export interface NexusResourceImageResult {
image: HTMLImageElement;
ref: WebUIResourceRef;
meta: NexusResourceMeta;
}NexusResourceImageBitmapResult
export interface NexusResourceImageBitmapResult {
bitmap: ImageBitmap;
ref: WebUIResourceRef;
meta: NexusResourceMeta;
}NexusResourceHDRBytesResult
export interface NexusResourceHDRBytesResult {
buffer: ArrayBuffer;
ref: WebUIResourceRef;
meta: NexusResourceMeta;
}NexusResourceKitMethods
export interface NexusResourceKitMethods {
loadImage(resourceRef: WebUIResourceRef, options?: WebUIRequestOptions): Promise<NexusResourceImageResult>;
loadImageBitmap(
resourceRef: WebUIResourceRef,
options?: WebUIRequestOptions,
): Promise<NexusResourceImageBitmapResult>;
loadHDRBytes(resourceRef: WebUIResourceRef, options?: WebUIRequestOptions): Promise<NexusResourceHDRBytesResult>;
}NexusResourceKitModule
export interface NexusResourceKitModule {
readonly NEXUS_RESOURCE_KIT_VERSION: string;
readonly version: string;
/** `resourceIO` is present only when nexus-resource-io.js was also loaded before this file. */
attach<TWebUI extends NexusWebUI>(webui: TWebUI): TWebUI & { resource: TWebUI['resource'] & NexusResourceKitMethods; resourceIO?: NexusResourceIO };
createResourceKit(webui: NexusWebUI): NexusResourceKitMethods;
}WebUIStoreError
export interface WebUIStoreError {
code: string;
message: string;
}WebUIStoreSnapshotBase
interface WebUIStoreSnapshotBase {
/** State key this store was created for. */
key: string;
/** True until the first real host snapshot (or error) arrives. */
loading: boolean;
error: WebUIStoreError | null;
snapshotRevision: number;
}WebUIListStoreSnapshot
export interface WebUIListStoreSnapshot<TItem = Record<string, WebUIJSONValue>>
extends WebUIStoreSnapshotBase {
items: TItem[];
ids: string[];
entities: Record<string, TItem>;
truncated: boolean;
nextCursor: string | null;
}WebUIItemStoreSnapshot
export interface WebUIItemStoreSnapshot<TItem = Record<string, WebUIJSONValue>>
extends WebUIStoreSnapshotBase {
item: TItem | null;
}WebUIStoreSnapshot
export type WebUIStoreSnapshot<TItem = Record<string, WebUIJSONValue>> =
| WebUIListStoreSnapshot<TItem>
| WebUIItemStoreSnapshot<TItem>;WebUIStoreOptions
export interface WebUIStoreOptions extends WebUIRequestOptions {
/**
* Snapshot shape of the underlying state: 'list' (default) yields
* items/ids snapshots, 'item' yields a single-item snapshot.
*/
shape?: 'list' | 'item';
}WebUIStoreListener
export type WebUIStoreListener<TSnapshot> = (
snapshot: TSnapshot,
meta: { key: string; canonicalKey: string | null; subscriptionId: string | null },
) => void;WebUIStoreMeta
export type WebUIStoreMeta = { key: string; canonicalKey: string | null; subscriptionId: string | null };WebUIStoreSelector
export type WebUIStoreSelector<TSnapshot, TSelected> = (snapshot: TSnapshot) => TSelected;WebUIStoreSelectorListener
export type WebUIStoreSelectorListener<TSelected> = (
selected: TSelected,
previous: TSelected | undefined,
meta: WebUIStoreMeta,
) => void;WebUIStoreEquality
export type WebUIStoreEquality<TSelected> = (previous: TSelected, next: TSelected) => boolean;WebUIStoreUnsubscriber
export interface WebUIStoreUnsubscriber {
(): WebUIReleaseResult;
unsubscribe(): WebUIReleaseResult;
release(): WebUIReleaseResult;
}WebUIStateStore
export interface WebUIStateStore<TSnapshot extends WebUIStoreSnapshotBase = WebUIStoreSnapshot> {
readonly key: string;
readonly shape: 'list' | 'item';
readonly disposed: boolean;
/**
* Current snapshot, synchronously. Reference-stable: equivalent content
* keeps the exact same object, so shallow compares can bail out.
*/
getSnapshot(): TSnapshot;
/** Calls listener immediately with the current snapshot, then on changes. */
subscribe(listener: WebUIStoreListener<TSnapshot>): WebUIStoreUnsubscriber;
/** Calls listener immediately, then only when selected value or store meta changes. */
select<TSelected>(
selector: WebUIStoreSelector<TSnapshot, TSelected>,
listener: WebUIStoreSelectorListener<TSelected>,
equalityFn?: WebUIStoreEquality<TSelected>,
): WebUIStoreUnsubscriber;
dispose(): void;
}WebUITransformPropertyPath
export type WebUITransformPropertyPath = 'location' | 'rotation_euler' | 'scale';WebUIVector3
export type WebUIVector3 = readonly [number, number, number];WebUITransformTarget
export interface WebUITransformTarget {
targetId: string;
propertyPath: WebUITransformPropertyPath;
}WebUITransformUpdate
export interface WebUITransformUpdate extends WebUITransformTarget {
value: WebUIVector3;
}WebUITransformBeginOptions
export interface WebUITransformBeginOptions extends WebUIRequestOptions {
interactionId?: string;
targets: readonly WebUITransformTarget[];
requestOptions?: WebUIRequestOptions;
}WebUITransformCommitResult
export interface WebUITransformCommitResult {
interactionId: string;
action: 'commit';
targetCount: number;
previewErrors: number;
writeErrors: number;
undoPushed: boolean;
lastPreviewErrorCode?: string;
lastWriteErrorCode?: string;
undoErrorCode?: string;
[extra: string]: WebUIJSONValue | undefined;
}WebUITransformCancelResult
export interface WebUITransformCancelResult {
interactionId: string;
action: 'cancel';
targetCount?: number;
previewErrors?: number;
writeErrors?: number;
cancelled?: boolean;
lastPreviewErrorCode?: string;
lastWriteErrorCode?: string;
[extra: string]: WebUIJSONValue | undefined;
}WebUITransformInteraction
export interface WebUITransformInteraction {
readonly interactionId: string;
readonly targets: readonly WebUITransformTarget[];
readonly beginResult: Record<string, WebUIJSONValue> | null;
readonly active: boolean;
/** Accumulates changed target/property values; each send includes every pair updated in this operation. */
update(updates: readonly WebUITransformUpdate[]): boolean;
/** Requires all begin targets, using the accumulated preview when updates is omitted. */
commit(
updates?: readonly WebUITransformUpdate[],
options?: WebUIRequestOptions,
): Promise<WebUITransformCommitResult>;
cancel(options?: WebUIRequestOptions): Promise<WebUITransformCancelResult>;
dispose(): void;
isSuppressed(targetId: string, propertyPath: WebUITransformPropertyPath): boolean;
}WebUITransformDragContext
export interface WebUITransformDragContext {
phase: 'start' | 'move' | 'end';
interactionId: string;
targets: readonly WebUITransformTarget[];
startEvent: PointerEvent;
}WebUITransformPreviewMeta
export interface WebUITransformPreviewMeta {
phase: 'start' | 'move' | 'end';
interactionId: string;
coalescedEvents: readonly PointerEvent[];
}WebUITransformDragOptions
export interface WebUITransformDragOptions {
interactionId?: string;
element?: EventTarget & {
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
setPointerCapture?(pointerId: number): void;
releasePointerCapture?(pointerId: number): void;
};
targets: readonly WebUITransformTarget[];
requestOptions?: WebUIRequestOptions;
beginOptions?: WebUIRequestOptions;
commitOptions?: WebUIRequestOptions;
cancelOptions?: WebUIRequestOptions;
updates(event: PointerEvent, context: WebUITransformDragContext): readonly WebUITransformUpdate[] | WebUIVector3;
onPreview?(updates: readonly WebUITransformUpdate[], meta: WebUITransformPreviewMeta): void;
onCommit?(result: WebUITransformCommitResult, meta: { interactionId: string }): void;
onCancel?(result: WebUITransformCancelResult, meta: { phase: string; interactionId: string }): void;
onError?(error: WebUIError, meta: { phase: string; interactionId: string }): void;
}WebUITransformDragGesture
export interface WebUITransformDragGesture {
readonly interactionId: string;
readonly active: boolean;
readonly ready: Promise<WebUITransformInteraction>;
cancel(): void;
}WebUITransformAPI
export interface WebUITransformAPI {
begin(options: WebUITransformBeginOptions): Promise<WebUITransformInteraction>;
drag(pointerEvent: PointerEvent, options: WebUITransformDragOptions): WebUITransformDragGesture;
isSuppressed(targetId: string, propertyPath: WebUITransformPropertyPath): boolean;
}NexusWebUI
export interface NexusWebUI {
/** Host-confirmed handshake; resolves with the negotiated feature set. */
ready(): Promise<WebUIReadyInfo>;
dispose(): void;
action: {
call(
name: string,
payload?: WebUIJSONValue,
options?: WebUIRequestOptions,
): Promise<WebUIJSONValue>;
callWithResource(
name: string,
input: WebUIActionWithResourceInput,
options?: WebUIRequestOptions,
): Promise<WebUIJSONValue>;
};
state: {
get(
key: string,
query?: WebUIStateQuery | null,
options?: WebUIRequestOptions,
): Promise<WebUIStateGetResult>;
subscribe<TSnapshot = WebUISnapshot>(
key: string,
query: WebUIStateQuery | null | undefined,
handler: WebUIStateCallback<TSnapshot>,
options?: WebUIRequestOptions,
): Promise<WebUISubscriptionHandle<TSnapshot>>;
unsubscribe(
target: WebUISubscriptionHandle | string,
options?: WebUIRequestOptions,
): Promise<{ unsubscribed: boolean }>;
describe(
key?: string | null,
options?: WebUIRequestOptions,
): Promise<Record<string, WebUIJSONValue>>;
store<TItem = Record<string, WebUIJSONValue>>(
key: string,
query?: WebUIStateQuery | null,
options?: WebUIStoreOptions & { shape?: 'list' },
): WebUIStateStore<WebUIListStoreSnapshot<TItem>>;
store<TItem = Record<string, WebUIJSONValue>>(
key: string,
query: WebUIStateQuery | null | undefined,
options: WebUIStoreOptions & { shape: 'item' },
): WebUIStateStore<WebUIItemStoreSnapshot<TItem>>;
};
lifecycle: {
on(kind: WebUILifecycleKind, handler: (payload: Record<string, WebUIJSONValue>) => void): WebUILifecycleHandle;
};
event: {
on(name: string, handler: WebUIEventCallback, options?: WebUIRequestOptions): Promise<WebUIEventHandle>;
};
externalFiles: WebUIExternalFilesAPI;
window: WebUIWindowAPI;
resource: {
info(resourceId: string, options?: WebUIRequestOptions): Promise<WebUIResourceInfoResult>;
upload(resource: WebUIResourceUploadBody, options?: WebUIResourceUploadOptions): Promise<WebUIResourceUploadResult>;
url(resourceRef: WebUIResourceRef, options?: WebUIResourceUrlOptions): Promise<WebUIResourceUrlResult>;
arrayBuffer(resourceRef: WebUIResourceRef, options?: WebUIRequestOptions): Promise<ArrayBuffer>;
// The first six low-level Resource IO operations resolve an operation
// envelope. Its result uses the shared item/outcome shapes declared in
// nexus-resource-io.d.ts; save operations never return a real path.
// timeoutMs covers the start response only. The completion event, native
// dialog and save work have no operation timeout. A timeout leaves the
// outcome unknown, including whether a save already wrote files.
pickFiles(options?: WebUIResourceIORequestOptions): Promise<WebUIResourceOperationEnvelope<WebUICancelledOutcome | WebUIExternalFilesImportEvent>>;
importDirectory(options?: { initialPath?: string } & WebUIRequestOptions): Promise<WebUIResourceOperationEnvelope<WebUICancelledOutcome | WebUIExternalFilesImportEvent>>;
pickSaveTarget(options?: WebUISaveTargetOptions): Promise<WebUIResourceOperationEnvelope<WebUICancelledOutcome | { destinationRef: WebUIDestinationRef }>>;
pickSaveDirectory(options?: { initialPath?: string } & WebUIRequestOptions): Promise<WebUIResourceOperationEnvelope<WebUICancelledOutcome | { destinationRef: WebUIDestinationRef }>>;
commitSaveResource(item: WebUISaveCommitItem, options?: WebUIRequestOptions): Promise<WebUIResourceOperationEnvelope<WebUISaveCommitOutcome>>;
commitSaveResources(request: { items: readonly WebUISaveCommitItem[] }, options?: WebUIRequestOptions): Promise<WebUIResourceOperationEnvelope<WebUISaveCommitOutcome[]>>;
/** A successful response resolves {cancelled: true} and rejects the still-pending operation with code 'cancelled'. */
cancelOperation(operationId: string, options?: WebUIRequestOptions): Promise<{ cancelled: boolean }>;
reportImport(records: readonly WebUIImportReceiptRecord[], options?: WebUIRequestOptions): Promise<{ recorded: boolean }>;
} & Partial<NexusResourceKitMethods>;
interaction: {
transform: WebUITransformAPI;
schedule?(): void;
dispose?(): void;
};
}ReactLikeForWebUI
export interface ReactLikeForWebUI {
useSyncExternalStore<T>(subscribe: (onStoreChange: () => void) => () => void, getSnapshot: () => T): T;
useRef<T>(initial: T | null): { current: T | null };
useCallback<T extends (...args: never[]) => unknown>(callback: T, deps: readonly unknown[]): T;
}NexusWebUIReactHooks
export interface NexusWebUIReactHooks {
useWebUIState<TItem = Record<string, WebUIJSONValue>>(
key: string,
query?: WebUIStateQuery | null,
options?: WebUIStoreOptions & { shape?: 'list' },
): WebUIListStoreSnapshot<TItem>;
useWebUIState<TItem = Record<string, WebUIJSONValue>>(
key: string,
query: WebUIStateQuery | null | undefined,
options: WebUIStoreOptions & { shape: 'item' },
): WebUIItemStoreSnapshot<TItem>;
}NexusWebUIReactModule
export interface NexusWebUIReactModule {
createWebUIHooks(react: ReactLikeForWebUI, webui?: NexusWebUI): NexusWebUIReactHooks;
}VueLikeForWebUI
export interface VueLikeForWebUI {
shallowRef<T>(value: T): { value: T };
getCurrentScope?(): unknown;
onScopeDispose?(fn: () => void): void;
}NexusWebUIVueState
export interface NexusWebUIVueState<TSnapshot extends WebUIStoreSnapshotBase = WebUIStoreSnapshot> {
snapshot: { value: TSnapshot };
store: WebUIStateStore<TSnapshot>;
dispose(): void;
}NexusWebUIVueComposables
export interface NexusWebUIVueComposables {
useWebUIState<TItem = Record<string, WebUIJSONValue>>(
key: string,
query?: WebUIStateQuery | null,
options?: WebUIStoreOptions & { shape?: 'list' },
): NexusWebUIVueState<WebUIListStoreSnapshot<TItem>>;
useWebUIState<TItem = Record<string, WebUIJSONValue>>(
key: string,
query: WebUIStateQuery | null | undefined,
options: WebUIStoreOptions & { shape: 'item' },
): NexusWebUIVueState<WebUIItemStoreSnapshot<TItem>>;
}NexusWebUIVueModule
export interface NexusWebUIVueModule {
createWebUIComposables(vue: VueLikeForWebUI, webui?: NexusWebUI): NexusWebUIVueComposables;
}NexusWebUISvelteStore
export interface NexusWebUISvelteStore<TSnapshot extends WebUIStoreSnapshotBase = WebUIStoreSnapshot> {
subscribe(run: (snapshot: TSnapshot) => void): () => void;
getSnapshot(): TSnapshot;
dispose(): void;
}NexusWebUISvelteStores
export interface NexusWebUISvelteStores {
stateStore<TItem = Record<string, WebUIJSONValue>>(
key: string,
query?: WebUIStateQuery | null,
options?: WebUIStoreOptions & { shape?: 'list' },
): NexusWebUISvelteStore<WebUIListStoreSnapshot<TItem>>;
stateStore<TItem = Record<string, WebUIJSONValue>>(
key: string,
query: WebUIStateQuery | null | undefined,
options: WebUIStoreOptions & { shape: 'item' },
): NexusWebUISvelteStore<WebUIItemStoreSnapshot<TItem>>;
}NexusWebUISvelteModule
export interface NexusWebUISvelteModule {
createWebUIStores(webui?: NexusWebUI): NexusWebUISvelteStores;
}WebUIExternalFileSource
export type WebUIExternalFileSource =
| 'drop'
| 'paste'
| 'paste_files'
| 'paste_image'
| 'pick_files'
| 'import_directory';WebUIExternalFilePoint
export interface WebUIExternalFilePoint {
x: number;
y: number;
}WebUIExternalFileItem
export interface WebUIExternalFileItem {
itemId: string;
name: string;
mime: string;
byteLength: number;
width?: number | null;
height?: number | null;
resourceRef: WebUIResourceRef;
}WebUIExternalFileRejectedItem
export interface WebUIExternalFileRejectedItem {
name: string;
code: string;
message: string;
}WebUIExternalFilesImportEvent
export interface WebUIExternalFilesImportEvent {
importId: string;
source: WebUIExternalFileSource;
clientPoint: WebUIExternalFilePoint | null;
files: WebUIExternalFileItem[];
rejected: WebUIExternalFileRejectedItem[];
}WebUIExternalFilesImportCallback
export type WebUIExternalFilesImportCallback = (
event: WebUIExternalFilesImportEvent,
meta: WebUIEventMeta,
) => void;WebUIExternalFilesAPI
export interface WebUIExternalFilesAPI {
onImport(handler: WebUIExternalFilesImportCallback, options?: WebUIRequestOptions): Promise<WebUIEventHandle>;
}NexusTakeoverModule
export interface NexusTakeoverModule {
readonly version: string;
enable(): void;
disable(): void;
}WebUIResourceOperationEnvelope
export interface WebUIResourceOperationEnvelope<TResult> {
operationId: string;
result: TResult;
}WebUICancelledOutcome
export interface WebUICancelledOutcome {
cancelled: true;
}WebUIResourceIORequestOptions
export interface WebUIResourceIORequestOptions extends WebUIRequestOptions {
/** Native file dialog filter, e.g. "*.png;*.jpg". Display-only: never a security boundary. */
filterGlob?: string;
initialPath?: string;
}WebUISaveTargetOptions
export interface WebUISaveTargetOptions extends WebUIResourceIORequestOptions {
suggestedName?: string;
}WebUIDestinationRef
export interface WebUIDestinationRef {
destinationId: string;
kind: 'file' | 'directory';
}WebUISaveConflictPolicy
export type WebUISaveConflictPolicy = 'confirm' | 'overwrite' | 'rename' | 'error';WebUISaveCommitItem
export interface WebUISaveCommitItem {
destinationId: string;
resourceId: string;
suggestedName?: string;
onConflict?: WebUISaveConflictPolicy;
}WebUISaveCommitOutcome
export interface WebUISaveCommitOutcome {
ok: boolean;
code: string | null;
fileName: string | null;
byteLength: number | null;
message: string;
}WebUIImportReceiptKind
export type WebUIImportReceiptKind = 'resource_loaded' | 'failed' | 'released';WebUIImportReceiptRecord
export interface WebUIImportReceiptRecord {
importId: string;
traceId: string;
receipt: WebUIImportReceiptKind;
itemIds: readonly string[];
ok: boolean;
message?: string | null;
error?: string | null;
}NexusImportPoint
export interface NexusImportPoint {
x: number;
y: number;
}NexusPlacementFallbackReason
export type NexusPlacementFallbackReason = 'missing' | 'invalid' | 'out_of_bounds' | null;NexusImportPlacement
export interface NexusImportPlacement {
coordinateSpace: 'css';
clientPoint: NexusImportPoint | null;
viewportCenter: NexusImportPoint;
/** Always usable: clientPoint when valid and in-bounds, otherwise viewportCenter. */
fallbackPoint: NexusImportPoint;
fallbackReason: NexusPlacementFallbackReason;
}NexusImportedImage
export interface NexusImportedImage {
item: WebUIExternalFileItem;
image: HTMLImageElement;
ref: WebUIResourceRef;
meta: NexusResourceMeta;
}NexusImportedText
export interface NexusImportedText {
item: WebUIExternalFileItem;
text: string;
ref: WebUIResourceRef;
}NexusImportedBinary
export interface NexusImportedBinary {
item: WebUIExternalFileItem;
ref: WebUIResourceRef;
}NexusImportEvent
export interface NexusImportEvent {
importId: string | null;
/** Derived by the kit (defaults to importId); the host never sends one. */
traceId: string;
source: WebUIExternalFileSource;
/** Shorthand for placement.fallbackPoint. */
point: NexusImportPoint;
placement: NexusImportPlacement;
/** Raw wire items, unclassified. */
files: WebUIExternalFileItem[];
/** Successfully decoded images in their relative order from files. */
images: NexusImportedImage[];
/** Successfully decoded text in its relative order from files. */
texts: NexusImportedText[];
binaries: NexusImportedBinary[];
rejected: WebUIExternalFileRejectedItem[];
/** Nearest ancestor with [data-nexus-import] (or a bare <canvas>) at `point`; computed by the kit, never sent by the host. */
targetElement: Element | null;
/** The untouched (already-sanitized) wire payload this event was built from. */
raw: WebUIJSONValue;
}NexusImportEventMeta
export type NexusImportEventMeta = WebUIEventMeta | {
name: 'nexus.external_files.import';
subscriptionId: null;
dropped: false;
};NexusImportEventCallback
export type NexusImportEventCallback = (event: NexusImportEvent, meta: NexusImportEventMeta) => void;NexusResourceIOSubscriptionHandle
export interface NexusResourceIOSubscriptionHandle {
release(): Promise<{ unsubscribed: boolean }>;
unsubscribe(): Promise<{ unsubscribed: boolean }>;
}NexusPickOptions
export interface NexusPickOptions extends WebUIRequestOptions {
/** Extensions ("['.png']"), mime types ("image/png"), or "image/*"; narrows the native dialog filter only. */
accept?: string | readonly string[];
initialPath?: string;
}NexusSaveOptions
export interface NexusSaveOptions extends WebUIRequestOptions {
name?: string;
mime?: string;
accept?: string | readonly string[];
initialPath?: string;
onConflict?: WebUISaveConflictPolicy;
}NexusSaveFilesItem
export interface NexusSaveFilesItem {
bytes: WebUIResourceUploadBody;
mime?: string;
name?: string;
onConflict?: WebUISaveConflictPolicy;
}NexusSaveResult
export interface NexusSaveResult {
ok: boolean;
/** True when the user dismissed the save-target dialog; the other fields are then all null/default. */
cancelled: boolean;
fileName: string | null;
byteLength: number | null;
code: string | null;
message: string;
}NexusResourceAdapterContext
export interface NexusResourceAdapterContext {
element: Element;
importEvent: NexusImportEvent;
point: NexusImportPoint;
placement: NexusImportPlacement;
webui: NexusWebUI;
/** Converts a page CSS point (defaults to placement.fallbackPoint) into target-element-local coordinates. */
localPoint(target?: Element): NexusImportPoint;
}NexusResourceAdapterExportContext
export interface NexusResourceAdapterExportContext {
element: Element;
webui: NexusWebUI;
}NexusResourceAdapter
export interface NexusResourceAdapter {
id: string;
/** Higher runs first. Built-ins: canvas=10, DOM default=0. User adapters default to 50. */
priority?: number;
canHandle(ctx: NexusResourceAdapterContext): boolean;
import(ctx: NexusResourceAdapterContext): void | Promise<void>;
export?(ctx: NexusResourceAdapterExportContext): Promise<{ blob: Blob; mime: string; suggestedName?: string }>;
dispose?(): void;
}NexusResourceAdapterHandle
export interface NexusResourceAdapterHandle {
unregister(): void;
}NexusFabricObjectLike
export interface NexusFabricObjectLike {
set(options: Record<string, string | number>): void;
}NexusFabricPromiseImageFactoryLike
export interface NexusFabricPromiseImageFactoryLike {
fromURL(url: string): Promise<NexusFabricObjectLike | null | undefined>;
}NexusFabricCallbackImageFactoryLike
export interface NexusFabricCallbackImageFactoryLike {
fromURL(
url: string,
callback: (image: NexusFabricObjectLike | null | undefined) => void,
): void;
}NexusFabricCanvasLike
export interface NexusFabricCanvasLike {
lowerCanvasEl?: HTMLCanvasElement;
upperCanvasEl?: HTMLCanvasElement;
wrapperEl?: Element;
getZoom?(): number;
add(object: object): void;
requestRenderAll?(): void;
getElement?(): HTMLCanvasElement;
}NexusFabricNamespaceLike
export interface NexusFabricNamespaceLike {
Image?: NexusFabricCallbackImageFactoryLike | NexusFabricPromiseImageFactoryLike;
FabricImage?: NexusFabricPromiseImageFactoryLike;
Textbox?: new (text: string, options: Record<string, string | number>) => object;
}NexusResourceAdapterFabricOptions
export interface NexusResourceAdapterFabricOptions {
canvas: NexusFabricCanvasLike;
fabric?: NexusFabricNamespaceLike;
id?: string;
priority?: number;
}NexusResourceAdapterFabricModule
export interface NexusResourceAdapterFabricModule {
readonly NEXUS_RESOURCE_ADAPTER_FABRIC_VERSION: string;
readonly version: string;
readonly ADAPTED_LIBRARY: 'fabric';
readonly ADAPTED_LIBRARY_VERSION_RANGE: string;
create(options: NexusResourceAdapterFabricOptions): NexusResourceAdapter;
}NexusEnableDOMOptions
export interface NexusEnableDOMOptions {
/** Rebinds click delegation to this root instead of `document`. */
root?: Document | Element;
/** false tears down click delegation without rebinding (opt out of zero-code entirely). */
enabled?: boolean;
}NexusResourceIO
export interface NexusResourceIO {
onImport(handler: NexusImportEventCallback): Promise<NexusResourceIOSubscriptionHandle>;
/** Fires only when the delivered event has at least one file. */
onFiles(handler: NexusImportEventCallback): Promise<NexusResourceIOSubscriptionHandle>;
/** Fires only when the delivered event has at least one image. */
onImages(handler: NexusImportEventCallback): Promise<NexusResourceIOSubscriptionHandle>;
/** Fires only when the delivered event has at least one text item. */
onText(handler: NexusImportEventCallback): Promise<NexusResourceIOSubscriptionHandle>;
/** Resolves null (not an error) when the user cancels the native dialog. */
pickFiles(options?: NexusPickOptions): Promise<NexusImportEvent | null>;
pickImages(options?: NexusPickOptions): Promise<NexusImportEvent | null>;
importDirectory(options?: NexusPickOptions): Promise<NexusImportEvent | null>;
pickSaveDirectory(options?: NexusPickOptions): Promise<WebUICancelledOutcome | { destinationRef: WebUIDestinationRef }>;
saveFile(bytes: WebUIResourceUploadBody, options?: NexusSaveOptions): Promise<NexusSaveResult>;
saveFiles(items: readonly NexusSaveFilesItem[], options?: NexusSaveOptions): Promise<NexusSaveResult[]>;
saveText(text: string, options?: NexusSaveOptions): Promise<NexusSaveResult>;
saveJSON(value: WebUIJSONValue, options?: NexusSaveOptions): Promise<NexusSaveResult>;
saveCanvas(canvas: HTMLCanvasElement, options?: NexusSaveOptions): Promise<NexusSaveResult>;
callActionWithResource(
actionName: string,
options: WebUIActionWithResourceInput & { requestOptions?: WebUIRequestOptions },
): Promise<WebUIJSONValue>;
/** Rejects with code 'unsupported_feature' unless nexus-resource-dom.js was also loaded. */
registerAdapter(adapter: NexusResourceAdapter): Promise<NexusResourceAdapterHandle>;
/** Rejects with code 'unsupported_feature' unless nexus-resource-dom.js was also loaded. */
enableDOM(options?: NexusEnableDOMOptions): Promise<boolean>;
dispose(): void;
}NexusResourceIOModule
export interface NexusResourceIOModule {
readonly NEXUS_RESOURCE_IO_VERSION: string;
readonly version: string;
createResourceIO(webui: NexusWebUI): NexusResourceIO;
}NexusResourceDOMExtension
export interface NexusResourceDOMExtension {
dispatch(ctx: { element: Element; event: NexusImportEvent; webui: NexusWebUI }): Promise<void>;
disposeDom(): void;
registerAdapter(adapter: NexusResourceAdapter): Promise<NexusResourceAdapterHandle>;
enableDOM(options?: NexusEnableDOMOptions): Promise<boolean>;
}NexusResourceDOMModule
export interface NexusResourceDOMModule {
readonly NEXUS_RESOURCE_DOM_VERSION: string;
readonly version: string;
installInto(resourceIO: NexusResourceIO, ctx: Record<string, unknown>): NexusResourceDOMExtension;
}From definitions to usage
Connection, state, and events · Transform interactions · Resources and file tools · Frontend adapters. Obtain helper scripts with the framework copy. Updating only type files does not give an older runtime new capabilities.