Skip to content

Commit f390043

Browse files
authored
fix(types): drain Tier 4 any from public contract (SD-2834) (#3258)
* fix(types): drain Tier 4 any from EditorTransactionEvent, awareness, ProofingError (SD-2834) Three surgical fixes to the curated public-contract file `packages/superdoc/src/core/types/index.ts`. Each one was visible in the deep audit's tier-4-public-contract bucket and represents direct customer IntelliSense pain on a documented public API. 1. `EditorTransactionEvent.transaction: any` -> `Transaction` from `prosemirror-state`. Anyone hovering over an `onTransaction` callback's transaction param now sees the real ProseMirror type with `.docChanged`, `.steps`, `.selection`, etc., instead of `any`. `prosemirror-state` is already an optional peer dep, consistent with the existing pattern for `@hocuspocus/provider`. 2. `Config.onAwarenessUpdate.states: any[]` -> `AwarenessState[]`. New small public type defines the documented fields SuperDoc populates per remote client (`user`, `clientId`, `color`) plus an index signature for application-specific keys. y-protocols' Awareness type itself uses `Record<string, any>` for the value side, so a precise imported type was not available; defined locally rather than collapsing to `unknown[]` per the audit README's guidance against draining with `unknown` when a real shape is documentable. Removes the existing `eslint-disable @typescript-eslint/no-explicit-any` on the same line. 3. `ProofingError.cause?: any` -> `unknown`. Error causes are genuinely opaque (whatever the proofing provider threw), so `unknown` is the correct level of precision per the Error-cause convention. Consumers narrow with `instanceof` or shape checks before reading. Also re-exports `AwarenessState` via the JSDoc typedef in `packages/superdoc/src/index.js`, adds the AssertNotAny assertion to `tests/consumer-typecheck/src/all-public-types.ts`, and updates the existing modules-config-passthrough fixture to consume the new type through documented field access. Verified: - node tests/consumer-typecheck/typecheck-matrix.mjs: 53/0 - node tests/consumer-typecheck/deep-type-audit.mjs: 1799 -> 1791 (tier-4-public-contract: 26 -> 18) - AssertNotAny<AwarenessState> passes (check-public-types gate) * fix(types): sync React mirror of EditorTransactionEvent (SD-2834) Code review caught that `packages/react/src/types.ts:71` defines a hand-mirrored `SuperDocTransactionEvent` interface that still had `transaction: any` after the canonical `EditorTransactionEvent` was narrowed to `Transaction` in the previous commit. The mirror's JSDoc explicitly says "Mirrors superdoc's EditorTransactionEvent", so React consumers using `@superdoc-dev/react` would have kept seeing `transaction: any` and lost IntelliSense - the exact symptom this PR is meant to fix. Sync the React mirror: - Add `Transaction` to the `import type { ... } from 'superdoc'` (avoids adding `prosemirror-state` as a new dep; superdoc already re-exports the type via JSDoc typedef) - Change `transaction: any` -> `transaction: Transaction` - Drop "or transaction-like payload" from the JSDoc to match the canonical wording Verified the awareness and proofing fixes don't need React mirrors - those flow through `Config` directly (which React extracts from SuperDoc's constructor parameters) so consumers already see them. Verified: - pnpm --filter @superdoc-dev/react run type-check: passes * fix(types): flatten AwarenessState to match runtime spread (SD-2834) Code review caught that the previous AwarenessState shape pointed consumers at fields that don't exist at runtime. The `awarenessStatesToArray` helper at `shared/common/collaboration/awareness.ts` returns `{ clientId, ...value.user, color }` per entry - i.e., the remote user's `name`, `email`, `image` are SPREAD onto the top of the state, not nested under `state.user`. The first cut typed `user?: User`, which made `state.user?.name` typecheck (always undefined at runtime) while real fields like `state.name` and `state.email` only resolved through the `unknown` index signature. That's worse than `any` - it documents the wrong shape. Flip AwarenessState to `extends User`, matching the runtime spread. Update the doc comment to spell out the flatten and point consumers at `state.name` / `state.email` directly. Update the consumer fixture to read the flattened fields (`state.name`, `state.email`, `state.clientId`, `state.color`, plus the index-signature `state['customField']`). Verified: - pnpm --filter superdoc run pack:es: ok - node tests/consumer-typecheck/typecheck-matrix.mjs: 53/0 - node tests/consumer-typecheck/deep-type-audit.mjs: 1791 (unchanged) * test(react): stabilize SuperDocEditor CI readiness waits (SD-2834) * test(react): extend SuperDoc readiness test timeout (SD-2834)
1 parent 1173432 commit f390043

7 files changed

Lines changed: 418 additions & 322 deletions

File tree

0 commit comments

Comments
 (0)