From ee0537fdb51551393a240d9a39d4b77bc4ef840c Mon Sep 17 00:00:00 2001 From: Connor Byrne Date: Wed, 20 May 2026 16:09:45 -0700 Subject: [PATCH] =?UTF-8?q?chore(ext-api):=20hygiene=20cleanup=20=E2=80=94?= =?UTF-8?q?=20D-design-review-hygiene-cleanup=20(wave-11)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the (a)+(b) propagation legs for five design-review-12142 rows: - Row #1 (Comments hygiene): strip 25 HR-style section dividers (`// ── XYZ ──`) across widget.ts/node.ts/registrations.ts/events.ts/ index.ts; strip ~30 sites of decision archaeology refs (D5, D20, D-immutability-enforcement (Hybrid C), D-bootstrap-hooks (W6.P6.C), D-shell-ui-entrypoints (W6.P5.C), etc.) from per-export JSDoc; preserve PHASE_A_EXCLUDED axiom-ref blocks (functional — tells axiom-checker + future readers WHY surfaces are absent); preserve AXIOMS.md §A1/A14/A15/A16/A12 cross-refs; delete shell.ts "What changed in W6.P5" wave-history banner. - Row #2 (@stability stable): already DONE in code (0 stable hits); this ADR closes leg (b). - Row #4 (apiVersion drop): already DONE in code (0 hits); this ADR closes leg (b). - Row #5 (defineNode/defineWidget short-form): D11 ACCEPTED 2026-05-12; one stale JSDoc @example in lifecycle.ts:113,115 fixed (defineWidgetExtension → defineWidget). - Row #6 (Widget-prefixed methods): already DONE via D-bootstrap-hooks (unprefixed onMounted/onUnmounted etc.); this ADR closes leg (b). Also drops two now-unused imports in node.ts (WidgetHandle, WidgetOptions were only referenced in commented-out A14-deferred surfaces). ADR: decisions/D-design-review-hygiene-cleanup.md Net diff: -62 lines, zero behavior change. Quality gates: lint + format:check + axiom-compliance all green. --- src/extension-api/events.ts | 6 ++-- src/extension-api/imperatives.ts | 2 +- src/extension-api/index.ts | 13 ++++---- src/extension-api/lifecycle.ts | 6 ++-- src/extension-api/node.ts | 37 +++++++---------------- src/extension-api/registrations.ts | 8 +---- src/extension-api/shell.ts | 34 +++++---------------- src/extension-api/types.ts | 4 +-- src/extension-api/widget.ts | 48 +++++++++--------------------- 9 files changed, 48 insertions(+), 110 deletions(-) diff --git a/src/extension-api/events.ts b/src/extension-api/events.ts index e35b7b4177..67d6fccf20 100644 --- a/src/extension-api/events.ts +++ b/src/extension-api/events.ts @@ -37,9 +37,7 @@ export type AsyncHandler = (event: E) => void | Promise */ export type Unsubscribe = () => void -// ───────────────────────────────────────────────────────────────────────────── -// D-bootstrap-hooks (W6.P6.C) — Event-namespace facades -// ───────────────────────────────────────────────────────────────────────────── +// Event-namespace facades // // Four typed event-namespace handles (`graph` / `execution` / `server` / // `workbench`) replace the ad-hoc `api.addEventListener('execution_start', ...)` @@ -206,7 +204,7 @@ export const server: EventNamespace = makeNamespace( * * Canonical events today: `'notification'`. Future: `'themeChanged'`, * `'panelToggled'`, `'commandInvoked'`. NOT a DI container — see - * D-bootstrap-hooks §Decision for the "thin event-namespace handle only" + * the bootstrap-hooks design for the "thin event-namespace handle only" * scope-back. * * @publicAPI diff --git a/src/extension-api/imperatives.ts b/src/extension-api/imperatives.ts index 65a8c67130..60f90e5ef3 100644 --- a/src/extension-api/imperatives.ts +++ b/src/extension-api/imperatives.ts @@ -1,6 +1,6 @@ /** * Inline imperative shell APIs — `toast` + `notify` - * (D-shell-ui-entrypoints, W6.P5.C carve-out). + *. * * Per the ACCEPTED PICK (option (ii) "separate entries" with an * inline-imperative carve-out), `toast` and `notify` are NOT exposed as diff --git a/src/extension-api/index.ts b/src/extension-api/index.ts index 115d97f14f..e9cf9929ea 100644 --- a/src/extension-api/index.ts +++ b/src/extension-api/index.ts @@ -59,7 +59,6 @@ export type { WidgetExtensionOptions } from './types' -// ── Registration function implementations ──────────────────────────────────── // Runtime implementations live in the service; the types above are the // public contract. The barrel re-exports the concrete fns from the service // so `import { defineNode } from '@comfyorg/extension-api'` works @@ -76,7 +75,7 @@ export { export { onNodeMounted, onNodeRemoved } from './lifecycle' -// D-bootstrap-hooks (W6.P6.C) — context-scoped Vue-idiomatic lifecycle hooks +// context-scoped Vue-idiomatic lifecycle hooks // usable inside `defineExtension.setup` / `defineSidebarTab.setup` / // `defineBottomPanelTab.setup` bodies. export { @@ -87,7 +86,7 @@ export { onDeactivated } from './lifecycle' -// D-bootstrap-hooks (W6.P6.C) — four typed event-namespace handles. +// four typed event-namespace handles. // Payload types default to `unknown` and are tightened via D5 module // augmentation in a follow-on PR. Custom-node events ride `server.on(...)`. export { graph, execution, server, workbench } from './events' @@ -135,7 +134,7 @@ export type { Handler, AsyncHandler, Unsubscribe } from './events' // ingredients of SidebarTabExtension / BottomPanelExtension and are NOT // part of the public surface. // -// Per W6.P5.B (D-shell-ui-entrypoints): ExtensionManager + CommandManager are +// Note: ExtensionManager + CommandManager are // DROPPED from the public surface — the v2 model uses per-surface defineX // entries (defineSidebarTab, defineCommand, …) each returning a disposable, // not a centralized umbrella handle. Internal callers continue importing @@ -146,7 +145,7 @@ export type { BottomPanelExtension, ToastMessageOptions, ToastManager, - // Net-new W6.P5 arg types + // Shell-UI arg types CommandDefinition, HotkeyExtension, AboutBadgeExtension, @@ -154,7 +153,7 @@ export type { ToolbarButtonExtension } from './shell' -// D-shell-ui-entrypoints (W6.P5.C) — per-surface defineX entries. Each +// per-surface defineX entries. Each // returns a DisposableHandle; carve-out: toast + notify remain inline // imperative (exported below from ./imperatives), NOT as defineX wrappers. export { @@ -168,7 +167,7 @@ export { } from './registrations' export type { DisposableHandle } from './registrations' -// D-shell-ui-entrypoints (W6.P5.C) — inline imperative carve-out. Fire-and-forget; +// inline imperative carve-out. Fire-and-forget; // no defineX wrapper, no DisposableHandle. Call from any setup() body or // hook closure. export { toast, notify } from './imperatives' diff --git a/src/extension-api/lifecycle.ts b/src/extension-api/lifecycle.ts index 4d56a9850d..1eddf091dc 100644 --- a/src/extension-api/lifecycle.ts +++ b/src/extension-api/lifecycle.ts @@ -110,9 +110,9 @@ export declare function defineExtension( * @publicAPI * @example * ```ts - * import { defineWidgetExtension } from '@comfyorg/extension-api' + * import { defineWidget } from '@comfyorg/extension-api' * - * export default defineWidgetExtension({ + * export default defineWidget({ * name: 'my-org.color-picker', * type: 'COLOR_PICKER' * }) @@ -165,7 +165,7 @@ export declare function defineWidget( */ /** - * ## Context-Scoped Bootstrap Hooks (D-bootstrap-hooks, W6.P6.C) + * ## Context-Scoped Bootstrap Hooks * * In addition to the node-level `onNodeMounted` / `onNodeRemoved` hooks above, * the v2 API exposes Vue-idiomatic context-scoped hooks for diff --git a/src/extension-api/node.ts b/src/extension-api/node.ts index 4823b985f2..3a490cf93e 100644 --- a/src/extension-api/node.ts +++ b/src/extension-api/node.ts @@ -9,7 +9,6 @@ */ import type { AsyncHandler, Handler, Unsubscribe } from './events' -import type { WidgetHandle, WidgetOptions } from './widget' import type { NodeEntityId } from '@/world/entityIds' /** @@ -27,7 +26,7 @@ export type { NodeEntityId } /** * A 2D point as `[x, y]`. * - * **Immutable tuple per D-immutability-enforcement (Hybrid C).** Attempts to + * **Immutable tuple.** Attempts to * mutate via `node.getPosition()[0] = X` raise a TypeScript error. Use * {@link NodeHandle.setPosition} to move the node. */ @@ -36,7 +35,7 @@ export type Point = readonly [x: number, y: number] /** * A 2D size as `[width, height]`. * - * **Immutable tuple per D-immutability-enforcement (Hybrid C).** Attempts to + * **Immutable tuple.** Attempts to * mutate via `node.getSize()[0] = X` raise a TypeScript error. Use * {@link NodeHandle.setSize} to resize the node. */ @@ -138,8 +137,6 @@ export interface NodeBeforeSerializeEvent { * ``` */ export interface NodeHandle { - // ── IDENTITY ────────────────────────────────────────────────────────────── - /** * Opaque identifier for this node. Stable for the lifetime of the node * entity. Treat as a string token: do not parse, slice, or compare its @@ -147,7 +144,7 @@ export interface NodeHandle { * another handle. * * @remarks - * Per D20, the underlying value is a branded `NodeEntityId` at runtime + * The underlying value is a branded `NodeEntityId` at runtime * but is narrowed to `string` on the public surface so authors never * need to import a brand to type a local variable. */ @@ -176,26 +173,21 @@ export interface NodeHandle { */ readonly comfyClass: string - // ── SPATIAL STATE ───────────────────────────────────────────────────────── // PHASE_A_EXCLUDED per AXIOMS.md A14: Deferred pending A13 coord-space stabilization. // getPosition(): Point // setPosition(pos: Point): void // getSize(): Size // setSize(size: Size): void - // ── VISUAL STATE ────────────────────────────────────────────────────────── // PHASE_A_EXCLUDED per AXIOMS.md A14: Uncertain use case. // getTitle(): string // setTitle(title: string): void // isSelected(): boolean - // ── EXECUTION MODE ──────────────────────────────────────────────────────── // PHASE_A_EXCLUDED per AXIOMS.md A14: nodeMode has "egregious" use patterns. // getMode(): NodeMode // setMode(mode: NodeMode): void - // ── PROPERTIES (migration shim) ─────────────────────────────────────────── - /** * Returns a per-node-instance property by key. * @@ -221,9 +213,7 @@ export interface NodeHandle { */ setProperty(key: string, value: unknown): void - // ── WIDGETS ─────────────────────────────────────────────────────────────── - - // COMMENTED OUT per AXIOMS.md A1 + A2 (D-no-node-widget-access, 2026-05-19): + // COMMENTED OUT per AXIOMS.md A1 + A2: // Nodes cannot reference or enumerate their widgets. Bilateral (node→widget) // direction is closed; the widget→node direction (`widget.parentNode`) // remains the sole channel. Extensions needing per-widget coordination @@ -246,7 +236,7 @@ export interface NodeHandle { // /** // * Returns all widgets on this node as `WidgetHandle` instances. // * - // * **Immutable view per D-immutability-enforcement (Hybrid C).** The returned + // * **Immutable view.** The returned // * array cannot be mutated (`push`, `splice`, `length =`, index assignment // * all raise TS errors). Each `WidgetHandle` is also surface-frozen — use // * the `WidgetHandle` setter methods (`setValue`, `setHidden`, etc.) to @@ -276,18 +266,15 @@ export interface NodeHandle { // hook against a per-widget host `
` it owns. See `WidgetMountFn` and // `WidgetMountContext` in `./widget` for the lifecycle contract. - // ── SLOTS ───────────────────────────────────────────────────────────────── - /** * Returns all input slots on this node. * - * **Immutable view per D-immutability-enforcement (Hybrid C).** The returned + * **Immutable view.** The returned * array and each slot are `Readonly` — `node.getInputs().push(...)`, * `node.getInputs()[i] = X`, and `node.getInputs()[i].name = "x"` all raise * TypeScript errors at compile time. Per-slot mutators (`setInputName`, * `replaceInput`, bulk field setters) are tracked under - * W6.P8.UNMIGRATABLE / D-input-output-shape. - * + * * * @example * ```ts * // ❌ TS-ERR — readonly array; v1 patterns no longer compile @@ -303,28 +290,26 @@ export interface NodeHandle { /** * Returns all output slots on this node. * - * **Immutable view per D-immutability-enforcement (Hybrid C).** Same + * **Immutable view.** Same * read-only semantics as {@link NodeHandle.getInputs}. Per-slot mutators - * tracked under W6.P8.UNMIGRATABLE / D-input-output-shape. + * tracked separately. */ getOutputs(): ReadonlyArray> /** * @deprecated Use {@link NodeHandle.getInputs} instead. Renamed to align - * with the `getX()` accessor convention (D11/D-immutability-enforcement). + * with the `getX()` accessor convention. * Will be removed in v1.0. */ inputs(): ReadonlyArray> /** * @deprecated Use {@link NodeHandle.getOutputs} instead. Renamed to align - * with the `getX()` accessor convention (D11/D-immutability-enforcement). + * with the `getX()` accessor convention. * Will be removed in v1.0. */ outputs(): ReadonlyArray> - // ── EVENTS ──────────────────────────────────────────────────────────────── - /** * Subscribe to node removal (graph deletion, not subgraph promotion). * diff --git a/src/extension-api/registrations.ts b/src/extension-api/registrations.ts index 28ac2812ea..851a737e94 100644 --- a/src/extension-api/registrations.ts +++ b/src/extension-api/registrations.ts @@ -1,6 +1,6 @@ /** * Per-surface shell UI registration entry points - * (D-shell-ui-entrypoints, W6.P5.C). + *. * * Each `defineX` function in this module is the v2 replacement for one slot * of the v1 `app.registerExtension({ commands, keybindings, settings, … })` @@ -64,10 +64,7 @@ export interface DisposableHandle { dispose(): void } -// ───────────────────────────────────────────────────────────────────────────── // Internal mount-queue infrastructure -// ───────────────────────────────────────────────────────────────────────────── - /** * Registration side effect: registers something into a store and returns a * cleanup. May be async (most registrations dynamic-import their store at @@ -198,10 +195,7 @@ export function _clearShellRegistrationsForTesting(): void { _systemStarted = false } -// ───────────────────────────────────────────────────────────────────────────── // Public defineX entry points -// ───────────────────────────────────────────────────────────────────────────── - /** * Register a sidebar tab. Returns a {@link DisposableHandle} — call * `handle.dispose()` to remove the tab. diff --git a/src/extension-api/shell.ts b/src/extension-api/shell.ts index 971f5dfd64..e33218c223 100644 --- a/src/extension-api/shell.ts +++ b/src/extension-api/shell.ts @@ -2,44 +2,26 @@ * Shell UI extension types — sidebar tabs, bottom panels, commands, hotkeys, * settings, about badges, toolbar buttons, toasts. * - * Re-exported from `src/types/extensionTypes.ts` with no shape changes. The - * original module remains the source of truth; this barrel makes the shell - * types available from the single `@comfyorg/extension-api` package entry - * point. - * - * ## What changed in W6.P5 (D-shell-ui-entrypoints) - * - * The v2 public surface follows option (ii) "separate entries" — every - * registerable shell UI surface gets its own `defineX` entry point in - * `@/extension-api/registrations`, and the **arg types** for those entries - * are re-exported here. `ExtensionManager` and `CommandManager` are no - * longer part of the public API (they were v1 umbrella handles); per-surface - * disposable handles returned by each `defineX` replace them. - * - * Toast + notification surfaces remain inline-imperative (see - * `@/extension-api/imperatives`) — the carve-out per the ACCEPTED ADR. + * Re-exported from `src/types/extensionTypes.ts` with no shape changes. Each + * registerable shell UI surface has its own `defineX` entry point in + * `@/extension-api/registrations`; the arg types for those entries are + * re-exported here. Toast + notification surfaces remain inline-imperative + * (see `@/extension-api/imperatives`). * * @packageDocumentation */ -// VueExtension and CustomExtension are deliberately NOT re-exported per D19 — -// they are discriminated-union ingredients of SidebarTabExtension / +// VueExtension and CustomExtension are intentionally NOT re-exported — they +// are discriminated-union ingredients of SidebarTabExtension / // BottomPanelExtension, not author-facing entry points. Internal callers // (ExtensionSlot.vue) import them directly from '@/types/extensionTypes'. -// -// Per W6.P5.B (D-shell-ui-entrypoints) the public surface adds 5 net-new -// argument types (HotkeyExtension, AboutBadgeExtension, SettingDefinition, -// ToolbarButtonExtension, CommandDefinition) and DROPS ExtensionManager + -// CommandManager from the v2 public re-export — the legacy umbrella handles -// have no role under option (ii) since each defineX returns its own -// per-surface disposable. export type { // Pre-existing types (unchanged shape) SidebarTabExtension, BottomPanelExtension, ToastMessageOptions, ToastManager, - // Net-new W6.P5 arg types + // Net-new shell-UI arg types CommandDefinition, HotkeyExtension, AboutBadgeExtension, diff --git a/src/extension-api/types.ts b/src/extension-api/types.ts index 8c20f0d95f..2e35e0ec46 100644 --- a/src/extension-api/types.ts +++ b/src/extension-api/types.ts @@ -107,7 +107,7 @@ export interface ExtensionOptions { * Runs once during app initialization (after the app is mounted but before * the first workflow is loaded). Equivalent to the v1 `ComfyExtension.init`. * - * @deprecated Per D-bootstrap-hooks (W6.P6.C, ACCEPTED 2026-05-14): move the + * @deprecated move the * `init` body into `setup()`. The body of `setup()` runs at the same point * `init` used to run (early lifecycle); use `onMounted(() => ...)` inside * `setup()` for what `init` did via late-lifecycle assumptions. A codemod @@ -121,7 +121,7 @@ export interface ExtensionOptions { * to the v1 `ComfyExtension.setup`. Safe to call shell UI registration APIs * (`ExtensionManager`, `CommandManager`) here. * - * @deprecated Per D-bootstrap-hooks (W6.P6.C, ACCEPTED 2026-05-14): the + * @deprecated the * `setup` property name is retained, but the v1 semantic "fires after all * core extensions ready" now lives in `onMounted(() => ...)` *inside* the * `setup()` body. The `setup()` body itself now runs at the earlier diff --git a/src/extension-api/widget.ts b/src/extension-api/widget.ts index ccf53c16a8..d9a6941f5f 100644 --- a/src/extension-api/widget.ts +++ b/src/extension-api/widget.ts @@ -74,7 +74,7 @@ export interface WidgetOptionChangeEvent { readonly newValue: unknown } -// PHASE_A_EXCLUDED per AXIOMS.md A14 + A16 (D-widget-serialization-simplification, wave-9): +// PHASE_A_EXCLUDED per AXIOMS.md A14 + A16: // `WidgetPropertyChangeEvent` is vacuous after `'serialize'` was removed from // the property union (A16: authors cannot disable serialization). The other // historical members ('hidden', 'disabled') were already A14-deferred. @@ -126,7 +126,7 @@ export interface WidgetOptionChangeEvent { * ``` */ export interface WidgetBeforeSerializeEvent { - // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16 (D-widget-serialization-simplification, wave-9): + // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16: // The 4-way transport discriminator inverted the direction of knowledge // flow — framework owns transport, extensions own value. Workflow JSON // and API prompt converge to a single serialized payload; clone and @@ -151,7 +151,7 @@ export interface WidgetBeforeSerializeEvent { */ setSerializedValue(v: unknown): void - // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16 (D-widget-serialization-simplification, wave-9): + // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16: // `skip()` IS a per-call disable — authors cannot disable serialization // (A16). If a widget should not contribute to the payload, it should not // be a widget (A15). Restoration requires axiom amendments to A15 + A16. @@ -215,7 +215,7 @@ export interface WidgetBeforeQueueEvent { * ```ts * import { defineWidget } from '@comfyorg/extension-api' * - * // Per AXIOMS.md A1 (D-no-node-widget-access, 2026-05-19), nodes cannot + * // Per AXIOMS.md A1, nodes cannot * // enumerate or reference widgets — `node.getWidget(name)` was removed. * // To react to a specific widget's lifecycle and value changes, register * // a widget type and use the `mount` context's `ctx.widget` handle: @@ -232,8 +232,6 @@ export interface WidgetBeforeQueueEvent { * ``` */ export interface WidgetHandle { - // ── IDENTITY ─────────────────────────────────────────────────────────────── - /** * Opaque identifier for this widget. Stable for the lifetime of the * widget entity. Treat as a string token: do not parse, slice, or compare @@ -241,7 +239,7 @@ export interface WidgetHandle { * another handle. * * @remarks - * Per D20, the underlying value is a branded `WidgetEntityId` at runtime + * The underlying value is a branded `WidgetEntityId` at runtime * but is narrowed to `string` on the public surface so authors never need * to import a brand to type a local variable. */ @@ -269,8 +267,6 @@ export interface WidgetHandle { */ readonly widgetType: string - // ── VALUE — first-class, every-widget ───────────────────────────────────── - /** * Returns the widget's current user-edited value. * @@ -278,8 +274,7 @@ export interface WidgetHandle { * @example * ```ts * // Inside `defineWidget({mount})` — `ctx.widget` is the only legal - * // path to a `WidgetHandle` (D-no-node-widget-access removed - * // `node.getWidget(name)`). + * // path to a `WidgetHandle` (nodes cannot enumerate widgets per A1). * const value = widget.getValue() * ``` */ @@ -292,18 +287,14 @@ export interface WidgetHandle { */ setValue(value: T): void - // ── VISIBILITY — first-class, every-widget ──────────────────────────────── // PHASE_A_EXCLUDED per AXIOMS.md A14: Deferred pending serialization convergence. // isHidden(): boolean // setHidden(hidden: boolean): void - // ── DISABLED — first-class, every-widget ───────────────────────────────── // PHASE_A_EXCLUDED per AXIOMS.md A14: Deferred pending serialization convergence. // isDisabled(): boolean // setDisabled(disabled: boolean): void - // ── LABEL — first-class, every-widget ──────────────────────────────────── - /** * The widget's display label shown to the user. Defaults to the widget name. * Read-only invariant (set at creation, never changes after). @@ -313,8 +304,6 @@ export interface WidgetHandle { */ readonly label: string - // ── HEIGHT — reserved layout slot for mount-lifecycle widgets ──────────── - /** * Updates the reserved height for this widget and triggers a node relayout. * @@ -332,7 +321,7 @@ export interface WidgetHandle { */ setHeight(px: number): void - // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16 (D-widget-serialization-simplification, wave-9): + // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16: // Authors cannot disable serialization at the widget level (A16). If a // widget should not contribute to the serialized payload, it should not // be a widget (A15) — use a boxed/composed widget (BBOX-style), a @@ -344,12 +333,10 @@ export interface WidgetHandle { // isSerializeEnabled(): boolean // setSerializeEnabled(enabled: boolean): void - // ── OPTIONS BAG — type-specific overrides ───────────────────────────────── - /** * Read-only snapshot of the full options bag for this widget. * - * **Immutable per D-immutability-enforcement (Hybrid C).** The returned + * **Immutable.** The returned * object is `Readonly` — `widget.options.min = 0`, * `widget.options = {...}`, and `widget.options.values = [...]` all raise * TypeScript errors at compile time. To mutate, use @@ -360,7 +347,7 @@ export interface WidgetHandle { * §A16, `serialize` is no longer a writable option (and no longer a key * on this bag) — there is no widget-level serialization disable. * `widget.options.values = [...]` (combo refresh) migrates to a future - * `setValues` mutator (tracked under W6.P8.UNMIGRATABLE). + * `setValues` mutator. * * @example * ```ts @@ -408,17 +395,15 @@ export interface WidgetHandle { */ setOption(key: string, value: unknown): void - // ── SERIALIZE VALUE — read-only accessor; D5 is the write path ─────────── - /** * The widget's current `serializeValue` function (or `undefined` if none is * registered). * - * **Accessor-only per D-immutability-enforcement (Hybrid C).** The setter + * **Accessor-only.** The setter * intentionally does not exist on the public type — assignment * (`widget.serializeValue = fn`) raises a TypeScript error. The v2 * migration target is the {@link WidgetHandle.on | `on('beforeSerialize', fn)`} - * event (per D5), which is typed, async-capable, and composable across + * event, which is typed, async-capable, and composable across * multiple extensions on the same widget. * * @deprecated v1 callers reading `widget.serializeValue` to invoke the @@ -443,8 +428,6 @@ export interface WidgetHandle { */ readonly serializeValue: ((...args: unknown[]) => unknown) | undefined - // ── EVENTS ──────────────────────────────────────────────────────────────── - /** * Subscribe to the widget's value changes. * @@ -472,7 +455,7 @@ export interface WidgetHandle { handler: Handler ): Unsubscribe - // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16 (D-widget-serialization-simplification, wave-9): + // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16: // `WidgetPropertyChangeEvent` is vacuous — the only property the event // ever surfaced was `'serialize'`, which is gone per A16. `setHidden` / // `setDisabled` were already A14-deferred. Restoration requires a new @@ -521,8 +504,6 @@ export interface WidgetHandle { ): Unsubscribe } -// ── MOUNT LIFECYCLE — the sole DOM seam per D-widget-converge / Axiom A12 ── - /** * Cleanup function returned from a widget's `mount()`. Fires exactly once, * when the widget entity is destroyed. **Does NOT fire on host remount** @@ -612,10 +593,9 @@ export interface WidgetOptions { hidden?: boolean /** If `true`, the widget is rendered read-only (no user editing). */ readonly?: boolean - // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16 (D-widget-serialization-simplification, wave-9): + // PHASE_A_EXCLUDED per AXIOMS.md A14 + A16: // `serialize` contradicted A16 even as a read-only key — there is no - // widget-level serialization disable. Already write-blocked by - // D-immutability-enforcement; now removed from the type entirely. + // widget-level serialization disable. Removed from the type entirely. // // serialize?: boolean /** Display label override. Defaults to the widget `name`. */