Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/5213-widget-ts-retired-spec-anchor-history.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
---
'@object-ui/types': patch
---

`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired
`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a
live schema (objectui#5213).

Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a
field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the
local types were "renamed off the spec's name", in the present tense, and the
manifest block enumerated the spec shape key by key (`fieldTypes`, `category`,
`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`,
`aria`, `performance`). Protocol 17 retired that entire widget-registration
vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed
`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone
records why there is nothing to migrate — no schema ever declared a carrier key
of a widget shape, so the record is the D3 `SemanticMigration`
`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in
`RETIRED_DEFS_BY_MAJOR` for major 17.

A per-key description of a schema that no longer exists is the ADR-0033 failure:
an AI author reads a published docblock as present-tense fact and builds on it.
The enumeration is dropped rather than re-dated, and the blocks now say what is
true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is
objectui's only widget-registration contract, and the `Runtime` prefix is kept
BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a
second breaking rename taking it back; the unlock is recorded, not taken, in
objectui#4164). The `inline` collision that made the `WidgetSource` rename
urgent is kept, in the past tense, because it is the reason the prefix exists.
Both blocks now point at the live assertion instead of restating it: the "the
spec no longer owns" rows in
`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what
goes red if the spec ever re-publishes either name.

Comments only. No type, signature, member or test changed, and the parity test
that owns this fact was already correct — it moved both rows to its "spec no
longer owns" table on the 17.0.0-rc.6 bump.

Declared a `patch` for `@object-ui/types` alone because the emit was measured,
not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt
from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by
SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…`
(a consumer reads this text on hover and in the API docs), while
`dist/widget.js` is byte-identical across the rebuild
(`a3de34c54213a269…` both sides), so nothing runtime moved.
67 changes: 46 additions & 21 deletions packages/types/src/widget.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js';
* A manifest provides all metadata needed to discover, load, and render
* a widget without requiring an upfront import of its code.
*
* Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's
* is the **field-widget plugin** manifest that sits beside its
* `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor,
* lifecycle: { onMount, onValidate, … }, events, properties, implementation,
* screenshots, license, aria, performance }`. This one is the **SDUI component**
* manifest: `type` is a schema-renderer component key, and it carries `source`,
* `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the
* spec's models. The only keys the two share are `name`/`label`/`version`/
* `icon`/`description`.
* Today this is objectui's ONLY widget-registration contract: no published
* `@objectstack/spec` schema models one.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* HISTORY — why the `Runtime` prefix exists, and why it stays.
* `@objectstack/spec/ui` ONCE exported a **field-widget plugin**
* `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was
* renamed off that name to end the collision (objectstack#4115). ⚠️ That schema
* is GONE — its keys are deliberately no longer enumerated here, and the
* prefix is not evidence that a spec twin exists: protocol 17 retired the whole
* widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`,
* `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049
* enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is
* no tombstone key to migrate, because there was never a carrier key: the
* record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus
* `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry
* states the relationship these two types always had, verbatim: "objectui's
* registry has always carried its own runtime manifest for that
* (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`,
* objectui#3161 / #4115), which models different keys and never derived from
* these". `field.widget` is still what it always was — a `z.string()` naming a
* component the RENDERER has registered.
*
* So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a
* freed word is not a reason to spend a second breaking rename taking it back
* (objectstack#4988 precedent; the unlock is recorded, not taken —
* objectui#4164).
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no
* longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy —
* read it, not this comment, for what the spec owns today; it goes red if the
* spec ever re-publishes the name while this package holds it.
*
* @example
* ```ts
Expand DownExpand Up@@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest {
/**
* Describes how to load the widget's code at runtime.
*
* Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are
* discriminated unions on `type`, which is what makes the collision dangerous:
* they share the member name `inline` and mean opposite things by it. The
* spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code:
* string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members do not overlap at all — the
* spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union is never a valid value of the other.
* HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more
* dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE
* exported a `WidgetSource` union too (objectstack#4115). Both WERE
* discriminated unions on `type` that shared the member name `inline` and meant
* opposite things by it:
* the spec's `inline` carried source **code** to evaluate (`{ type: 'inline',
* code: string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members never overlapped — the spec
* had `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union was never a valid value of the other. ⚠️ The spec's union was retired
* with the rest of the widget-registration vocabulary (objectstack#5055): the
* union declared below is objectui's own, and never derived from it.
*
* The variant interfaces keep their `WidgetSource…` names: the spec does not
* export those, and renaming them would churn the public surface without
* The variant interfaces keep their `WidgetSource…` names: the spec never
* exported those, and renaming them would churn the public surface without
* removing a collision.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no
* longer owns `WidgetSource`" row pins the vacancy.
*/
export type RuntimeWidgetSource =
| WidgetSourceModule
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/5213-widget-ts-retired-spec-anchor-history.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
---
'@object-ui/types': patch
---

`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired
`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a
live schema (objectui#5213).

Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a
field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the
local types were "renamed off the spec's name", in the present tense, and the
manifest block enumerated the spec shape key by key (`fieldTypes`, `category`,
`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`,
`aria`, `performance`). Protocol 17 retired that entire widget-registration
vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed
`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone
records why there is nothing to migrate — no schema ever declared a carrier key
of a widget shape, so the record is the D3 `SemanticMigration`
`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in
`RETIRED_DEFS_BY_MAJOR` for major 17.

A per-key description of a schema that no longer exists is the ADR-0033 failure:
an AI author reads a published docblock as present-tense fact and builds on it.
The enumeration is dropped rather than re-dated, and the blocks now say what is
true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is
objectui's only widget-registration contract, and the `Runtime` prefix is kept
BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a
second breaking rename taking it back; the unlock is recorded, not taken, in
objectui#4164). The `inline` collision that made the `WidgetSource` rename
urgent is kept, in the past tense, because it is the reason the prefix exists.
Both blocks now point at the live assertion instead of restating it: the "the
spec no longer owns" rows in
`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what
goes red if the spec ever re-publishes either name.

Comments only. No type, signature, member or test changed, and the parity test
that owns this fact was already correct — it moved both rows to its "spec no
longer owns" table on the 17.0.0-rc.6 bump.

Declared a `patch` for `@object-ui/types` alone because the emit was measured,
not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt
from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by
SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…`
(a consumer reads this text on hover and in the API docs), while
`dist/widget.js` is byte-identical across the rebuild
(`a3de34c54213a269…` both sides), so nothing runtime moved.
67 changes: 46 additions & 21 deletions packages/types/src/widget.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js';
* A manifest provides all metadata needed to discover, load, and render
* a widget without requiring an upfront import of its code.
*
* Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's
* is the **field-widget plugin** manifest that sits beside its
* `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor,
* lifecycle: { onMount, onValidate, … }, events, properties, implementation,
* screenshots, license, aria, performance }`. This one is the **SDUI component**
* manifest: `type` is a schema-renderer component key, and it carries `source`,
* `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the
* spec's models. The only keys the two share are `name`/`label`/`version`/
* `icon`/`description`.
* Today this is objectui's ONLY widget-registration contract: no published
* `@objectstack/spec` schema models one.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* HISTORY — why the `Runtime` prefix exists, and why it stays.
* `@objectstack/spec/ui` ONCE exported a **field-widget plugin**
* `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was
* renamed off that name to end the collision (objectstack#4115). ⚠️ That schema
* is GONE — its keys are deliberately no longer enumerated here, and the
* prefix is not evidence that a spec twin exists: protocol 17 retired the whole
* widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`,
* `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049
* enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is
* no tombstone key to migrate, because there was never a carrier key: the
* record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus
* `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry
* states the relationship these two types always had, verbatim: "objectui's
* registry has always carried its own runtime manifest for that
* (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`,
* objectui#3161 / #4115), which models different keys and never derived from
* these". `field.widget` is still what it always was — a `z.string()` naming a
* component the RENDERER has registered.
*
* So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a
* freed word is not a reason to spend a second breaking rename taking it back
* (objectstack#4988 precedent; the unlock is recorded, not taken —
* objectui#4164).
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no
* longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy —
* read it, not this comment, for what the spec owns today; it goes red if the
* spec ever re-publishes the name while this package holds it.
*
* @example
* ```ts
Expand DownExpand Up@@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest {
/**
* Describes how to load the widget's code at runtime.
*
* Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are
* discriminated unions on `type`, which is what makes the collision dangerous:
* they share the member name `inline` and mean opposite things by it. The
* spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code:
* string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members do not overlap at all — the
* spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union is never a valid value of the other.
* HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more
* dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE
* exported a `WidgetSource` union too (objectstack#4115). Both WERE
* discriminated unions on `type` that shared the member name `inline` and meant
* opposite things by it:
* the spec's `inline` carried source **code** to evaluate (`{ type: 'inline',
* code: string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members never overlapped — the spec
* had `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union was never a valid value of the other. ⚠️ The spec's union was retired
* with the rest of the widget-registration vocabulary (objectstack#5055): the
* union declared below is objectui's own, and never derived from it.
*
* The variant interfaces keep their `WidgetSource…` names: the spec does not
* export those, and renaming them would churn the public surface without
* The variant interfaces keep their `WidgetSource…` names: the spec never
* exported those, and renaming them would churn the public surface without
* removing a collision.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no
* longer owns `WidgetSource`" row pins the vacancy.
*/
export type RuntimeWidgetSource =
| WidgetSourceModule
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/5213-widget-ts-retired-spec-anchor-history.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
---
'@object-ui/types': patch
---

`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired
`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a
live schema (objectui#5213).

Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a
field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the
local types were "renamed off the spec's name", in the present tense, and the
manifest block enumerated the spec shape key by key (`fieldTypes`, `category`,
`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`,
`aria`, `performance`). Protocol 17 retired that entire widget-registration
vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed
`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone
records why there is nothing to migrate — no schema ever declared a carrier key
of a widget shape, so the record is the D3 `SemanticMigration`
`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in
`RETIRED_DEFS_BY_MAJOR` for major 17.

A per-key description of a schema that no longer exists is the ADR-0033 failure:
an AI author reads a published docblock as present-tense fact and builds on it.
The enumeration is dropped rather than re-dated, and the blocks now say what is
true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is
objectui's only widget-registration contract, and the `Runtime` prefix is kept
BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a
second breaking rename taking it back; the unlock is recorded, not taken, in
objectui#4164). The `inline` collision that made the `WidgetSource` rename
urgent is kept, in the past tense, because it is the reason the prefix exists.
Both blocks now point at the live assertion instead of restating it: the "the
spec no longer owns" rows in
`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what
goes red if the spec ever re-publishes either name.

Comments only. No type, signature, member or test changed, and the parity test
that owns this fact was already correct — it moved both rows to its "spec no
longer owns" table on the 17.0.0-rc.6 bump.

Declared a `patch` for `@object-ui/types` alone because the emit was measured,
not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt
from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by
SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…`
(a consumer reads this text on hover and in the API docs), while
`dist/widget.js` is byte-identical across the rebuild
(`a3de34c54213a269…` both sides), so nothing runtime moved.
67 changes: 46 additions & 21 deletions packages/types/src/widget.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js';
* A manifest provides all metadata needed to discover, load, and render
* a widget without requiring an upfront import of its code.
*
* Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's
* is the **field-widget plugin** manifest that sits beside its
* `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor,
* lifecycle: { onMount, onValidate, … }, events, properties, implementation,
* screenshots, license, aria, performance }`. This one is the **SDUI component**
* manifest: `type` is a schema-renderer component key, and it carries `source`,
* `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the
* spec's models. The only keys the two share are `name`/`label`/`version`/
* `icon`/`description`.
* Today this is objectui's ONLY widget-registration contract: no published
* `@objectstack/spec` schema models one.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* HISTORY — why the `Runtime` prefix exists, and why it stays.
* `@objectstack/spec/ui` ONCE exported a **field-widget plugin**
* `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was
* renamed off that name to end the collision (objectstack#4115). ⚠️ That schema
* is GONE — its keys are deliberately no longer enumerated here, and the
* prefix is not evidence that a spec twin exists: protocol 17 retired the whole
* widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`,
* `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049
* enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is
* no tombstone key to migrate, because there was never a carrier key: the
* record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus
* `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry
* states the relationship these two types always had, verbatim: "objectui's
* registry has always carried its own runtime manifest for that
* (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`,
* objectui#3161 / #4115), which models different keys and never derived from
* these". `field.widget` is still what it always was — a `z.string()` naming a
* component the RENDERER has registered.
*
* So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a
* freed word is not a reason to spend a second breaking rename taking it back
* (objectstack#4988 precedent; the unlock is recorded, not taken —
* objectui#4164).
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no
* longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy —
* read it, not this comment, for what the spec owns today; it goes red if the
* spec ever re-publishes the name while this package holds it.
*
* @example
* ```ts
Expand DownExpand Up@@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest {
/**
* Describes how to load the widget's code at runtime.
*
* Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are
* discriminated unions on `type`, which is what makes the collision dangerous:
* they share the member name `inline` and mean opposite things by it. The
* spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code:
* string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members do not overlap at all — the
* spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union is never a valid value of the other.
* HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more
* dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE
* exported a `WidgetSource` union too (objectstack#4115). Both WERE
* discriminated unions on `type` that shared the member name `inline` and meant
* opposite things by it:
* the spec's `inline` carried source **code** to evaluate (`{ type: 'inline',
* code: string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members never overlapped — the spec
* had `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union was never a valid value of the other. ⚠️ The spec's union was retired
* with the rest of the widget-registration vocabulary (objectstack#5055): the
* union declared below is objectui's own, and never derived from it.
*
* The variant interfaces keep their `WidgetSource…` names: the spec does not
* export those, and renaming them would churn the public surface without
* The variant interfaces keep their `WidgetSource…` names: the spec never
* exported those, and renaming them would churn the public surface without
* removing a collision.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no
* longer owns `WidgetSource`" row pins the vacancy.
*/
export type RuntimeWidgetSource =
| WidgetSourceModule
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/5213-widget-ts-retired-spec-anchor-history.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
---
'@object-ui/types': patch
---

`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired
`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a
live schema (objectui#5213).

Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a
field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the
local types were "renamed off the spec's name", in the present tense, and the
manifest block enumerated the spec shape key by key (`fieldTypes`, `category`,
`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`,
`aria`, `performance`). Protocol 17 retired that entire widget-registration
vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed
`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone
records why there is nothing to migrate — no schema ever declared a carrier key
of a widget shape, so the record is the D3 `SemanticMigration`
`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in
`RETIRED_DEFS_BY_MAJOR` for major 17.

A per-key description of a schema that no longer exists is the ADR-0033 failure:
an AI author reads a published docblock as present-tense fact and builds on it.
The enumeration is dropped rather than re-dated, and the blocks now say what is
true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is
objectui's only widget-registration contract, and the `Runtime` prefix is kept
BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a
second breaking rename taking it back; the unlock is recorded, not taken, in
objectui#4164). The `inline` collision that made the `WidgetSource` rename
urgent is kept, in the past tense, because it is the reason the prefix exists.
Both blocks now point at the live assertion instead of restating it: the "the
spec no longer owns" rows in
`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what
goes red if the spec ever re-publishes either name.

Comments only. No type, signature, member or test changed, and the parity test
that owns this fact was already correct — it moved both rows to its "spec no
longer owns" table on the 17.0.0-rc.6 bump.

Declared a `patch` for `@object-ui/types` alone because the emit was measured,
not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt
from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by
SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…`
(a consumer reads this text on hover and in the API docs), while
`dist/widget.js` is byte-identical across the rebuild
(`a3de34c54213a269…` both sides), so nothing runtime moved.
67 changes: 46 additions & 21 deletions packages/types/src/widget.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js';
* A manifest provides all metadata needed to discover, load, and render
* a widget without requiring an upfront import of its code.
*
* Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's
* is the **field-widget plugin** manifest that sits beside its
* `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor,
* lifecycle: { onMount, onValidate, … }, events, properties, implementation,
* screenshots, license, aria, performance }`. This one is the **SDUI component**
* manifest: `type` is a schema-renderer component key, and it carries `source`,
* `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the
* spec's models. The only keys the two share are `name`/`label`/`version`/
* `icon`/`description`.
* Today this is objectui's ONLY widget-registration contract: no published
* `@objectstack/spec` schema models one.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* HISTORY — why the `Runtime` prefix exists, and why it stays.
* `@objectstack/spec/ui` ONCE exported a **field-widget plugin**
* `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was
* renamed off that name to end the collision (objectstack#4115). ⚠️ That schema
* is GONE — its keys are deliberately no longer enumerated here, and the
* prefix is not evidence that a spec twin exists: protocol 17 retired the whole
* widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`,
* `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049
* enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is
* no tombstone key to migrate, because there was never a carrier key: the
* record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus
* `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry
* states the relationship these two types always had, verbatim: "objectui's
* registry has always carried its own runtime manifest for that
* (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`,
* objectui#3161 / #4115), which models different keys and never derived from
* these". `field.widget` is still what it always was — a `z.string()` naming a
* component the RENDERER has registered.
*
* So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a
* freed word is not a reason to spend a second breaking rename taking it back
* (objectstack#4988 precedent; the unlock is recorded, not taken —
* objectui#4164).
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no
* longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy —
* read it, not this comment, for what the spec owns today; it goes red if the
* spec ever re-publishes the name while this package holds it.
*
* @example
* ```ts
Expand DownExpand Up@@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest {
/**
* Describes how to load the widget's code at runtime.
*
* Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are
* discriminated unions on `type`, which is what makes the collision dangerous:
* they share the member name `inline` and mean opposite things by it. The
* spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code:
* string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members do not overlap at all — the
* spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union is never a valid value of the other.
* HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more
* dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE
* exported a `WidgetSource` union too (objectstack#4115). Both WERE
* discriminated unions on `type` that shared the member name `inline` and meant
* opposite things by it:
* the spec's `inline` carried source **code** to evaluate (`{ type: 'inline',
* code: string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members never overlapped — the spec
* had `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union was never a valid value of the other. ⚠️ The spec's union was retired
* with the rest of the widget-registration vocabulary (objectstack#5055): the
* union declared below is objectui's own, and never derived from it.
*
* The variant interfaces keep their `WidgetSource…` names: the spec does not
* export those, and renaming them would churn the public surface without
* The variant interfaces keep their `WidgetSource…` names: the spec never
* exported those, and renaming them would churn the public surface without
* removing a collision.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no
* longer owns `WidgetSource`" row pins the vacancy.
*/
export type RuntimeWidgetSource =
| WidgetSourceModule
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/5213-widget-ts-retired-spec-anchor-history.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
---
'@object-ui/types': patch
---

`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired
`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a
live schema (objectui#5213).

Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a
field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the
local types were "renamed off the spec's name", in the present tense, and the
manifest block enumerated the spec shape key by key (`fieldTypes`, `category`,
`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`,
`aria`, `performance`). Protocol 17 retired that entire widget-registration
vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed
`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone
records why there is nothing to migrate — no schema ever declared a carrier key
of a widget shape, so the record is the D3 `SemanticMigration`
`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in
`RETIRED_DEFS_BY_MAJOR` for major 17.

A per-key description of a schema that no longer exists is the ADR-0033 failure:
an AI author reads a published docblock as present-tense fact and builds on it.
The enumeration is dropped rather than re-dated, and the blocks now say what is
true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is
objectui's only widget-registration contract, and the `Runtime` prefix is kept
BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a
second breaking rename taking it back; the unlock is recorded, not taken, in
objectui#4164). The `inline` collision that made the `WidgetSource` rename
urgent is kept, in the past tense, because it is the reason the prefix exists.
Both blocks now point at the live assertion instead of restating it: the "the
spec no longer owns" rows in
`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what
goes red if the spec ever re-publishes either name.

Comments only. No type, signature, member or test changed, and the parity test
that owns this fact was already correct — it moved both rows to its "spec no
longer owns" table on the 17.0.0-rc.6 bump.

Declared a `patch` for `@object-ui/types` alone because the emit was measured,
not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt
from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by
SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…`
(a consumer reads this text on hover and in the API docs), while
`dist/widget.js` is byte-identical across the rebuild
(`a3de34c54213a269…` both sides), so nothing runtime moved.
67 changes: 46 additions & 21 deletions packages/types/src/widget.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js';
* A manifest provides all metadata needed to discover, load, and render
* a widget without requiring an upfront import of its code.
*
* Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's
* is the **field-widget plugin** manifest that sits beside its
* `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor,
* lifecycle: { onMount, onValidate, … }, events, properties, implementation,
* screenshots, license, aria, performance }`. This one is the **SDUI component**
* manifest: `type` is a schema-renderer component key, and it carries `source`,
* `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the
* spec's models. The only keys the two share are `name`/`label`/`version`/
* `icon`/`description`.
* Today this is objectui's ONLY widget-registration contract: no published
* `@objectstack/spec` schema models one.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* HISTORY — why the `Runtime` prefix exists, and why it stays.
* `@objectstack/spec/ui` ONCE exported a **field-widget plugin**
* `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was
* renamed off that name to end the collision (objectstack#4115). ⚠️ That schema
* is GONE — its keys are deliberately no longer enumerated here, and the
* prefix is not evidence that a spec twin exists: protocol 17 retired the whole
* widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`,
* `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049
* enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is
* no tombstone key to migrate, because there was never a carrier key: the
* record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus
* `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry
* states the relationship these two types always had, verbatim: "objectui's
* registry has always carried its own runtime manifest for that
* (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`,
* objectui#3161 / #4115), which models different keys and never derived from
* these". `field.widget` is still what it always was — a `z.string()` naming a
* component the RENDERER has registered.
*
* So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a
* freed word is not a reason to spend a second breaking rename taking it back
* (objectstack#4988 precedent; the unlock is recorded, not taken —
* objectui#4164).
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no
* longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy —
* read it, not this comment, for what the spec owns today; it goes red if the
* spec ever re-publishes the name while this package holds it.
*
* @example
* ```ts
Expand DownExpand Up@@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest {
/**
* Describes how to load the widget's code at runtime.
*
* Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are
* discriminated unions on `type`, which is what makes the collision dangerous:
* they share the member name `inline` and mean opposite things by it. The
* spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code:
* string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members do not overlap at all — the
* spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union is never a valid value of the other.
* HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more
* dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE
* exported a `WidgetSource` union too (objectstack#4115). Both WERE
* discriminated unions on `type` that shared the member name `inline` and meant
* opposite things by it:
* the spec's `inline` carried source **code** to evaluate (`{ type: 'inline',
* code: string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members never overlapped — the spec
* had `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union was never a valid value of the other. ⚠️ The spec's union was retired
* with the rest of the widget-registration vocabulary (objectstack#5055): the
* union declared below is objectui's own, and never derived from it.
*
* The variant interfaces keep their `WidgetSource…` names: the spec does not
* export those, and renaming them would churn the public surface without
* The variant interfaces keep their `WidgetSource…` names: the spec never
* exported those, and renaming them would churn the public surface without
* removing a collision.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no
* longer owns `WidgetSource`" row pins the vacancy.
*/
export type RuntimeWidgetSource =
| WidgetSourceModule
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/5213-widget-ts-retired-spec-anchor-history.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
---
'@object-ui/types': patch
---

`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired
`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a
live schema (objectui#5213).

Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a
field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the
local types were "renamed off the spec's name", in the present tense, and the
manifest block enumerated the spec shape key by key (`fieldTypes`, `category`,
`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`,
`aria`, `performance`). Protocol 17 retired that entire widget-registration
vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed
`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone
records why there is nothing to migrate — no schema ever declared a carrier key
of a widget shape, so the record is the D3 `SemanticMigration`
`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in
`RETIRED_DEFS_BY_MAJOR` for major 17.

A per-key description of a schema that no longer exists is the ADR-0033 failure:
an AI author reads a published docblock as present-tense fact and builds on it.
The enumeration is dropped rather than re-dated, and the blocks now say what is
true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is
objectui's only widget-registration contract, and the `Runtime` prefix is kept
BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a
second breaking rename taking it back; the unlock is recorded, not taken, in
objectui#4164). The `inline` collision that made the `WidgetSource` rename
urgent is kept, in the past tense, because it is the reason the prefix exists.
Both blocks now point at the live assertion instead of restating it: the "the
spec no longer owns" rows in
`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what
goes red if the spec ever re-publishes either name.

Comments only. No type, signature, member or test changed, and the parity test
that owns this fact was already correct — it moved both rows to its "spec no
longer owns" table on the 17.0.0-rc.6 bump.

Declared a `patch` for `@object-ui/types` alone because the emit was measured,
not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt
from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by
SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…`
(a consumer reads this text on hover and in the API docs), while
`dist/widget.js` is byte-identical across the rebuild
(`a3de34c54213a269…` both sides), so nothing runtime moved.
67 changes: 46 additions & 21 deletions packages/types/src/widget.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js';
* A manifest provides all metadata needed to discover, load, and render
* a widget without requiring an upfront import of its code.
*
* Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's
* is the **field-widget plugin** manifest that sits beside its
* `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor,
* lifecycle: { onMount, onValidate, … }, events, properties, implementation,
* screenshots, license, aria, performance }`. This one is the **SDUI component**
* manifest: `type` is a schema-renderer component key, and it carries `source`,
* `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the
* spec's models. The only keys the two share are `name`/`label`/`version`/
* `icon`/`description`.
* Today this is objectui's ONLY widget-registration contract: no published
* `@objectstack/spec` schema models one.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* HISTORY — why the `Runtime` prefix exists, and why it stays.
* `@objectstack/spec/ui` ONCE exported a **field-widget plugin**
* `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was
* renamed off that name to end the collision (objectstack#4115). ⚠️ That schema
* is GONE — its keys are deliberately no longer enumerated here, and the
* prefix is not evidence that a spec twin exists: protocol 17 retired the whole
* widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`,
* `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049
* enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is
* no tombstone key to migrate, because there was never a carrier key: the
* record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus
* `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry
* states the relationship these two types always had, verbatim: "objectui's
* registry has always carried its own runtime manifest for that
* (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`,
* objectui#3161 / #4115), which models different keys and never derived from
* these". `field.widget` is still what it always was — a `z.string()` naming a
* component the RENDERER has registered.
*
* So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a
* freed word is not a reason to spend a second breaking rename taking it back
* (objectstack#4988 precedent; the unlock is recorded, not taken —
* objectui#4164).
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no
* longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy —
* read it, not this comment, for what the spec owns today; it goes red if the
* spec ever re-publishes the name while this package holds it.
*
* @example
* ```ts
Expand DownExpand Up@@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest {
/**
* Describes how to load the widget's code at runtime.
*
* Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are
* discriminated unions on `type`, which is what makes the collision dangerous:
* they share the member name `inline` and mean opposite things by it. The
* spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code:
* string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members do not overlap at all — the
* spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union is never a valid value of the other.
* HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more
* dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE
* exported a `WidgetSource` union too (objectstack#4115). Both WERE
* discriminated unions on `type` that shared the member name `inline` and meant
* opposite things by it:
* the spec's `inline` carried source **code** to evaluate (`{ type: 'inline',
* code: string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members never overlapped — the spec
* had `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union was never a valid value of the other. ⚠️ The spec's union was retired
* with the rest of the widget-registration vocabulary (objectstack#5055): the
* union declared below is objectui's own, and never derived from it.
*
* The variant interfaces keep their `WidgetSource…` names: the spec does not
* export those, and renaming them would churn the public surface without
* The variant interfaces keep their `WidgetSource…` names: the spec never
* exported those, and renaming them would churn the public surface without
* removing a collision.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no
* longer owns `WidgetSource`" row pins the vacancy.
*/
export type RuntimeWidgetSource =
| WidgetSourceModule
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/5213-widget-ts-retired-spec-anchor-history.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
---
'@object-ui/types': patch
---

`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired
`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a
live schema (objectui#5213).

Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a
field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the
local types were "renamed off the spec's name", in the present tense, and the
manifest block enumerated the spec shape key by key (`fieldTypes`, `category`,
`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`,
`aria`, `performance`). Protocol 17 retired that entire widget-registration
vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed
`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone
records why there is nothing to migrate — no schema ever declared a carrier key
of a widget shape, so the record is the D3 `SemanticMigration`
`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in
`RETIRED_DEFS_BY_MAJOR` for major 17.

A per-key description of a schema that no longer exists is the ADR-0033 failure:
an AI author reads a published docblock as present-tense fact and builds on it.
The enumeration is dropped rather than re-dated, and the blocks now say what is
true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is
objectui's only widget-registration contract, and the `Runtime` prefix is kept
BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a
second breaking rename taking it back; the unlock is recorded, not taken, in
objectui#4164). The `inline` collision that made the `WidgetSource` rename
urgent is kept, in the past tense, because it is the reason the prefix exists.
Both blocks now point at the live assertion instead of restating it: the "the
spec no longer owns" rows in
`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what
goes red if the spec ever re-publishes either name.

Comments only. No type, signature, member or test changed, and the parity test
that owns this fact was already correct — it moved both rows to its "spec no
longer owns" table on the 17.0.0-rc.6 bump.

Declared a `patch` for `@object-ui/types` alone because the emit was measured,
not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt
from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by
SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…`
(a consumer reads this text on hover and in the API docs), while
`dist/widget.js` is byte-identical across the rebuild
(`a3de34c54213a269…` both sides), so nothing runtime moved.
67 changes: 46 additions & 21 deletions packages/types/src/widget.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js';
* A manifest provides all metadata needed to discover, load, and render
* a widget without requiring an upfront import of its code.
*
* Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's
* is the **field-widget plugin** manifest that sits beside its
* `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor,
* lifecycle: { onMount, onValidate, … }, events, properties, implementation,
* screenshots, license, aria, performance }`. This one is the **SDUI component**
* manifest: `type` is a schema-renderer component key, and it carries `source`,
* `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the
* spec's models. The only keys the two share are `name`/`label`/`version`/
* `icon`/`description`.
* Today this is objectui's ONLY widget-registration contract: no published
* `@objectstack/spec` schema models one.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* HISTORY — why the `Runtime` prefix exists, and why it stays.
* `@objectstack/spec/ui` ONCE exported a **field-widget plugin**
* `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was
* renamed off that name to end the collision (objectstack#4115). ⚠️ That schema
* is GONE — its keys are deliberately no longer enumerated here, and the
* prefix is not evidence that a spec twin exists: protocol 17 retired the whole
* widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`,
* `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049
* enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is
* no tombstone key to migrate, because there was never a carrier key: the
* record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus
* `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry
* states the relationship these two types always had, verbatim: "objectui's
* registry has always carried its own runtime manifest for that
* (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`,
* objectui#3161 / #4115), which models different keys and never derived from
* these". `field.widget` is still what it always was — a `z.string()` naming a
* component the RENDERER has registered.
*
* So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a
* freed word is not a reason to spend a second breaking rename taking it back
* (objectstack#4988 precedent; the unlock is recorded, not taken —
* objectui#4164).
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no
* longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy —
* read it, not this comment, for what the spec owns today; it goes red if the
* spec ever re-publishes the name while this package holds it.
*
* @example
* ```ts
Expand DownExpand Up@@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest {
/**
* Describes how to load the widget's code at runtime.
*
* Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are
* discriminated unions on `type`, which is what makes the collision dangerous:
* they share the member name `inline` and mean opposite things by it. The
* spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code:
* string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members do not overlap at all — the
* spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union is never a valid value of the other.
* HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more
* dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE
* exported a `WidgetSource` union too (objectstack#4115). Both WERE
* discriminated unions on `type` that shared the member name `inline` and meant
* opposite things by it:
* the spec's `inline` carried source **code** to evaluate (`{ type: 'inline',
* code: string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members never overlapped — the spec
* had `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union was never a valid value of the other. ⚠️ The spec's union was retired
* with the rest of the widget-registration vocabulary (objectstack#5055): the
* union declared below is objectui's own, and never derived from it.
*
* The variant interfaces keep their `WidgetSource…` names: the spec does not
* export those, and renaming them would churn the public surface without
* The variant interfaces keep their `WidgetSource…` names: the spec never
* exported those, and renaming them would churn the public surface without
* removing a collision.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no
* longer owns `WidgetSource`" row pins the vacancy.
*/
export type RuntimeWidgetSource =
| WidgetSourceModule
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .changeset/5213-widget-ts-retired-spec-anchor-history.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
---
'@object-ui/types': patch
---

`RuntimeWidgetManifest` / `RuntimeWidgetSource` document the spec's retired
`WidgetManifest` / `WidgetSource` as HISTORY, instead of describing them as a
live schema (objectui#5213).

Both JSDoc blocks were written while `@objectstack/spec/ui` still exported a
field-widget-plugin `WidgetManifest` and a `WidgetSource` union — they said the
local types were "renamed off the spec's name", in the present tense, and the
manifest block enumerated the spec shape key by key (`fieldTypes`, `category`,
`lifecycle`, `events`, `properties`, `implementation`, `screenshots`, `license`,
`aria`, `performance`). Protocol 17 retired that entire widget-registration
vocabulary under ADR-0049 enforce-or-remove (objectstack#5055): the installed
`@objectstack/spec` 17.2.0 exports none of those names, and its own tombstone
records why there is nothing to migrate — no schema ever declared a carrier key
of a widget shape, so the record is the D3 `SemanticMigration`
`ui-widget-i18n-family-retired` plus `ui/WidgetManifest` in
`RETIRED_DEFS_BY_MAJOR` for major 17.

A per-key description of a schema that no longer exists is the ADR-0033 failure:
an AI author reads a published docblock as present-tense fact and builds on it.
The enumeration is dropped rather than re-dated, and the blocks now say what is
true today — the bare names are owned by NOBODY, `RuntimeWidgetManifest` is
objectui's only widget-registration contract, and the `Runtime` prefix is kept
BY CHOICE (objectstack#4988's precedent: a freed word is not a reason to spend a
second breaking rename taking it back; the unlock is recorded, not taken, in
objectui#4164). The `inline` collision that made the `WidgetSource` rename
urgent is kept, in the past tense, because it is the reason the prefix exists.
Both blocks now point at the live assertion instead of restating it: the "the
spec no longer owns" rows in
`packages/types/src/__tests__/page-nav-misc-spec-parity.test.ts`, which are what
goes red if the spec ever re-publishes either name.

Comments only. No type, signature, member or test changed, and the parity test
that owns this fact was already correct — it moved both rows to its "spec no
longer owns" table on the 17.0.0-rc.6 bump.

Declared a `patch` for `@object-ui/types` alone because the emit was measured,
not assumed: both blocks sit on EXPORTED declarations, so they publish. Rebuilt
from a cleared `dist` and `tsconfig.tsbuildinfo` on both sides and compared by
SHA-256 — `dist/widget.d.ts` `bb4f2fd702cac02a…` -> `db1d5fbd53d305f5…`
(a consumer reads this text on hover and in the API docs), while
`dist/widget.js` is byte-identical across the rebuild
(`a3de34c54213a269…` both sides), so nothing runtime moved.
67 changes: 46 additions & 21 deletions packages/types/src/widget.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,17 +27,37 @@ import type { ComponentInputControlType } from './base.js';
* A manifest provides all metadata needed to discover, load, and render
* a widget without requiring an upfront import of its code.
*
* Renamed off the spec's `WidgetManifest` name (objectstack#4115): the spec's
* is the **field-widget plugin** manifest that sits beside its
* `FieldWidgetProps` — `{ fieldTypes, category: input|display|picker|editor,
* lifecycle: { onMount, onValidate, … }, events, properties, implementation,
* screenshots, license, aria, performance }`. This one is the **SDUI component**
* manifest: `type` is a schema-renderer component key, and it carries `source`,
* `defaultProps`, `inputs`, `isContainer` and `capabilities`, none of which the
* spec's models. The only keys the two share are `name`/`label`/`version`/
* `icon`/`description`.
* Today this is objectui's ONLY widget-registration contract: no published
* `@objectstack/spec` schema models one.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* HISTORY — why the `Runtime` prefix exists, and why it stays.
* `@objectstack/spec/ui` ONCE exported a **field-widget plugin**
* `WidgetManifest` (beside its `FieldWidgetProps`), and this interface was
* renamed off that name to end the collision (objectstack#4115). ⚠️ That schema
* is GONE — its keys are deliberately no longer enumerated here, and the
* prefix is not evidence that a spec twin exists: protocol 17 retired the whole
* widget-registration vocabulary — `WidgetManifest`, `WidgetLifecycle`,
* `WidgetEvent`, `WidgetProperty`, `WidgetSource` — under ADR-0049
* enforce-or-remove (objectstack#5055, maintainer ruling 2026-08-06). There is
* no tombstone key to migrate, because there was never a carrier key: the
* record is the D3 `SemanticMigration` `ui-widget-i18n-family-retired` plus
* `ui/WidgetManifest` in the spec's `RETIRED_DEFS_BY_MAJOR` for 17. That entry
* states the relationship these two types always had, verbatim: "objectui's
* registry has always carried its own runtime manifest for that
* (`RuntimeWidgetManifest` / `RuntimeWidgetSource` in `@object-ui/types`,
* objectui#3161 / #4115), which models different keys and never derived from
* these". `field.widget` is still what it always was — a `z.string()` naming a
* component the RENDERER has registered.
*
* So the bare name is now owned by NOBODY, and the prefix is kept BY CHOICE: a
* freed word is not a reason to spend a second breaking rename taking it back
* (objectstack#4988 precedent; the unlock is recorded, not taken —
* objectui#4164).
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`. Its "the spec no
* longer owns `WidgetManifest`" row is the LIVE assertion of that vacancy —
* read it, not this comment, for what the spec owns today; it goes red if the
* spec ever re-publishes the name while this package holds it.
*
* @example
* ```ts
Expand DownExpand Up@@ -106,20 +126,25 @@ export interface RuntimeWidgetManifest {
/**
* Describes how to load the widget's code at runtime.
*
* Renamed off the spec's `WidgetSource` name (objectstack#4115). Both are
* discriminated unions on `type`, which is what makes the collision dangerous:
* they share the member name `inline` and mean opposite things by it. The
* spec's `inline` carries source **code** to evaluate (`{ type: 'inline', code:
* string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members do not overlap at all — the
* spec has `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union is never a valid value of the other.
* HISTORY — the same rename as {@link RuntimeWidgetManifest}, and the more
* dangerous half of the collision it ended. `@objectstack/spec/ui` ONCE
* exported a `WidgetSource` union too (objectstack#4115). Both WERE
* discriminated unions on `type` that shared the member name `inline` and meant
* opposite things by it:
* the spec's `inline` carried source **code** to evaluate (`{ type: 'inline',
* code: string }`), objectui's carries an **already-resolved component**
* ({@link WidgetSourceInline}). The other members never overlapped — the spec
* had `npm`/`remote`, objectui has `module`/`registry` — so a value of one
* union was never a valid value of the other. ⚠️ The spec's union was retired
* with the rest of the widget-registration vocabulary (objectstack#5055): the
* union declared below is objectui's own, and never derived from it.
*
* The variant interfaces keep their `WidgetSource…` names: the spec does not
* export those, and renaming them would churn the public surface without
* The variant interfaces keep their `WidgetSource…` names: the spec never
* exported those, and renaming them would churn the public surface without
* removing a collision.
*
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts`.
* Tripwire: `__tests__/page-nav-misc-spec-parity.test.ts` — its "the spec no
* longer owns `WidgetSource`" row pins the vacancy.
*/
export type RuntimeWidgetSource =
| WidgetSourceModule
Expand Down
Loading