Skip to content

Commit 9b34e35

Browse files
authored
refactor(superdoc): add RuntimeDocument typedef for runtime doc shape (SD-2867 phase B) (#3058)
* refactor(superdoc): type createSuperdocVueApp return shape (SD-2867 phase B) `createSuperdocVueApp()` returned `Object` per its JSDoc, so the five fields SuperDoc.js destructures from the call (`app`, `pinia`, `superdocStore`, `commentsStore`, `highContrastModeStore`) all resolved to `Object` for any consumer enabling `// @ts-check`. Five TS2339 'Property does not exist on type Object' errors at SuperDoc.js line 464 — and inside the SD-2867 ratchet that turns each into a gate failure. Promotes the return type to a named `SuperdocVueAppRefs` typedef that imports `vue.App`, `pinia.Pinia`, and the store types via `ReturnType<typeof useSuperdocStore>` etc. The shape is internal-only (this typedef is not on the public Modules / Config surface), so adding it here doesn't widen the customer-visible surface. Verified: pnpm --filter superdoc run check:jsdoc passes (3 gated files clean); the consumer-typecheck matrix passes 31/31; the postbuild declaration audit reports no FAIL findings; pnpm --filter superdoc test passes 944/944. This is groundwork for SD-2867 phase B: closing each cluster of SuperDoc.js TS errors so the file can eventually enroll in `CHECKED_FILES`. Five errors closed; ~133 remain across implicit-any params, strict-null guards, and other type-not-assignable callsites. Each cluster will land as its own focused commit. * refactor(superdoc): add RuntimeDocument typedef for runtime doc shape (SD-2867 phase B) The internal `doc` parameter in SuperDoc.js's private methods (#applyDocumentMode, #attachExternalCollaboration, etc.) is shaped differently from the public `Document` interface: SuperDoc attaches a runtime `role`, `getEditor()`, and `getPresentationEditor()` to each entry during init. Today those methods are typed `@param {Object} doc`, so any attempt to enable `// @ts-check` on SuperDoc.js fails with TS2339 errors at every `doc.getEditor()` / `doc.getPresentationEditor()` / `doc.role` access (~10 sites). Adds a `RuntimeDocument` typedef in core/types/index.ts that extends the public `Document` with the runtime-attached fields. Updates #applyDocumentMode's `@param {Object} doc` to `@param {RuntimeDocument} doc` as the first call site to migrate. The typedef is internal-only and not on the public superdoc surface (not in the public typedef block of packages/superdoc/src/index.js), so consumers cannot import or pass these fields from outside. This is groundwork: subsequent SD-2867 phase B PRs will migrate the remaining `@param {Object} doc` sites and then enable @ts-check on the methods involved. Verified: pnpm --filter superdoc run check:jsdoc passes (3 gated files clean); consumer matrix passes 31/31; declaration audit reports no FAIL findings; published .d.ts surface unchanged (RuntimeDocument is not re-exported from the public superdoc entry).
1 parent 82bb78a commit 9b34e35

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

packages/superdoc/src/core/SuperDoc.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const DEFAULT_AWARENESS_PALETTE = Object.freeze([
5959

6060
/** @typedef {import('./types/index.js').User} User */
6161
/** @typedef {import('./types/index.js').Document} Document */
62+
/** @typedef {import('./types/index.js').RuntimeDocument} RuntimeDocument */
6263
/** @typedef {import('./types/index.js').Modules} Modules */
6364
/** @typedef {import('./types/index.js').Editor} Editor */
6465
/** @typedef {import('./types/index.js').DocumentMode} DocumentMode */
@@ -1304,8 +1305,8 @@ export class SuperDoc extends EventEmitter {
13041305
/**
13051306
* Set the document mode on a document's editor (PresentationEditor or Editor).
13061307
* Tries PresentationEditor first, falls back to Editor for backward compatibility.
1307-
* @param {Object} doc - The document object
1308-
* @param {string} mode - The document mode ('editing', 'viewing', 'suggesting')
1308+
* @param {RuntimeDocument} doc - The document object
1309+
* @param {DocumentMode} mode - The document mode ('editing', 'viewing', 'suggesting')
13091310
*/
13101311
#applyDocumentMode(doc, mode) {
13111312
const presentationEditor = typeof doc.getPresentationEditor === 'function' ? doc.getPresentationEditor() : null;

packages/superdoc/src/core/types/index.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { Ref, ComputedRef } from 'vue';
1717

1818
import type {
1919
Editor as SuperEditor,
20+
PresentationEditor as SuperEditorPresentationEditor,
2021
StoryLocator as SuperEditorStoryLocator,
2122
BookmarkAddress as SuperEditorBookmarkAddress,
2223
BlockNavigationAddress as SuperEditorBlockNavigationAddress,
@@ -86,6 +87,50 @@ export interface Document {
8687
*/
8788
export type CollaborationProvider = SuperEditorCollaborationProvider;
8889

90+
/**
91+
* Internal augmentation of `Document` for runtime-only fields that the
92+
* SuperDoc instance attaches to each document during initialization. The
93+
* public `Document` interface above is what consumers pass in via
94+
* `Config.documents`; this type adds the fields SuperDoc itself sets and
95+
* reads internally (per-document `role` propagation, the live `getEditor`
96+
* and `getPresentationEditor` accessors that the surface manager and
97+
* mode-switch helpers walk).
98+
*
99+
* Internal use only: not part of any public typedef. Consumers cannot
100+
* import this through `superdoc` and should not pass any of these fields
101+
* into `Config.documents` from outside.
102+
*/
103+
export interface RuntimeDocument extends Document {
104+
/**
105+
* Per-document role. `useDocument()` reads `params.role` from the input
106+
* config and exposes it on the smart-doc object; once collaboration
107+
* setup runs, SuperDoc unconditionally writes `doc.role = config.role`,
108+
* silently replacing whatever was passed. SD-2872 removed this from
109+
* the public `Document` interface so consumers stop trying to use it
110+
* as a stable per-document override; it lives on `RuntimeDocument`
111+
* only so internal SuperDoc.js callsites can type the assignment.
112+
*/
113+
role?: 'editor' | 'viewer' | 'suggester';
114+
/**
115+
* Returns the body Editor for this document, when the runtime has
116+
* created one. Set by the editor-create lifecycle.
117+
*
118+
* @deprecated Direct editor access will be removed in a future version.
119+
* Use the Document API (`editor.doc`) instead. This typedef carries the
120+
* deprecation marker forward from the source accessor in
121+
* `packages/superdoc/src/composables/use-document.js`.
122+
*/
123+
getEditor?: () => SuperEditor | null | undefined;
124+
/**
125+
* Returns the PresentationEditor for this document, when the runtime
126+
* has created one. Set by the editor-create lifecycle.
127+
*
128+
* @deprecated Direct editor access will be removed in a future version.
129+
* Use the Document API (`editor.doc`) instead.
130+
*/
131+
getPresentationEditor?: () => SuperEditorPresentationEditor | null | undefined;
132+
}
133+
89134
/** Collaboration module configuration. */
90135
export interface CollaborationConfig {
91136
/** External Yjs document (provider-agnostic mode). */

0 commit comments

Comments
 (0)