From 66852efe7d82a70a0d2f67bbae433b3964261782 Mon Sep 17 00:00:00 2001 From: bdbch Date: Fri, 7 Aug 2026 02:32:34 +0200 Subject: [PATCH] refactor(core): flatten directory structure and reorganize type definitions Move core classes (Editor, EventEmitter, ExtensionManager, CommandChain) to src root. Consolidate type definitions into src/types directory with separate files for commands, editor, and extensions. Rename InkwellCommands interface to Commands and move to module augmentation pattern. Reorganize command exports and rename coreExtensions to CommandsExtension. Add tsconfig path alias for @inkwell/core. --- .../core/src/{commands => }/CommandChain.ts | 4 ++-- packages/core/src/{editor => }/Editor.spec.ts | 0 packages/core/src/{editor => }/Editor.ts | 12 ++++++------ .../core/src/{editor => }/EventEmitter.spec.ts | 0 packages/core/src/{editor => }/EventEmitter.ts | 0 .../{extensions => }/ExtensionManager.spec.ts | 4 ++-- .../src/{extensions => }/ExtensionManager.ts | 6 +++--- packages/core/src/commands/coreExtensions.ts | 14 -------------- packages/core/src/commands/cutContent.ts | 6 +++--- packages/core/src/commands/index.ts | 3 +++ packages/core/src/commands/insertContent.ts | 6 +++--- packages/core/src/commands/setContent.ts | 6 +++--- packages/core/src/editor/index.ts | 3 --- packages/core/src/extensions/commands.ts | 10 ++++++++++ packages/core/src/extensions/index.ts | 3 +-- .../helpers/resolveExtensionsOnEditor.spec.ts | 4 ++-- .../helpers/resolveExtensionsOnEditor.ts | 4 ++-- packages/core/src/index.ts | 11 +++++++---- .../{commands/types.ts => types/commands.ts} | 17 ++++------------- .../src/{editor/types.ts => types/editor.ts} | 4 ++-- .../types.ts => types/extensions.ts} | 10 +++------- packages/core/src/types/index.ts | 3 +++ packages/core/tsconfig.json | 5 ++++- 23 files changed, 63 insertions(+), 72 deletions(-) rename packages/core/src/{commands => }/CommandChain.ts (98%) rename packages/core/src/{editor => }/Editor.spec.ts (100%) rename packages/core/src/{editor => }/Editor.ts (91%) rename packages/core/src/{editor => }/EventEmitter.spec.ts (100%) rename packages/core/src/{editor => }/EventEmitter.ts (100%) rename packages/core/src/{extensions => }/ExtensionManager.spec.ts (95%) rename packages/core/src/{extensions => }/ExtensionManager.ts (96%) delete mode 100644 packages/core/src/commands/coreExtensions.ts create mode 100644 packages/core/src/commands/index.ts delete mode 100644 packages/core/src/editor/index.ts create mode 100644 packages/core/src/extensions/commands.ts rename packages/core/src/{extensions => }/helpers/resolveExtensionsOnEditor.spec.ts (97%) rename packages/core/src/{extensions => }/helpers/resolveExtensionsOnEditor.ts (93%) rename packages/core/src/{commands/types.ts => types/commands.ts} (82%) rename packages/core/src/{editor/types.ts => types/editor.ts} (86%) rename packages/core/src/{extensions/types.ts => types/extensions.ts} (71%) create mode 100644 packages/core/src/types/index.ts diff --git a/packages/core/src/commands/CommandChain.ts b/packages/core/src/CommandChain.ts similarity index 98% rename from packages/core/src/commands/CommandChain.ts rename to packages/core/src/CommandChain.ts index 63208ce..8f3fe41 100644 --- a/packages/core/src/commands/CommandChain.ts +++ b/packages/core/src/CommandChain.ts @@ -1,6 +1,6 @@ import type { EditorState, TransactionSpec } from "@codemirror/state"; -import type { Editor } from "../editor/Editor.ts"; -import type { ChainedCommands, Command, CommandContext } from "./types.ts"; +import type { ChainedCommands, Command, CommandContext } from "./types/commands.ts"; +import type { Editor } from "./Editor.ts"; /** One collected chain step: a command impl and the args to call it with. */ type CommandStep = { diff --git a/packages/core/src/editor/Editor.spec.ts b/packages/core/src/Editor.spec.ts similarity index 100% rename from packages/core/src/editor/Editor.spec.ts rename to packages/core/src/Editor.spec.ts diff --git a/packages/core/src/editor/Editor.ts b/packages/core/src/Editor.ts similarity index 91% rename from packages/core/src/editor/Editor.ts rename to packages/core/src/Editor.ts index e8456d2..c0faf5e 100644 --- a/packages/core/src/editor/Editor.ts +++ b/packages/core/src/Editor.ts @@ -1,11 +1,11 @@ import { EditorState, Text } from "@codemirror/state"; import { EditorView } from "@codemirror/view"; import { EventEmitter } from "./EventEmitter.ts"; -import type { EditorEvents, EditorOptions } from "./types.ts"; -import { ExtensionManager } from "../extensions/index.ts"; -import { CommandChain } from "../commands/CommandChain.ts"; -import { coreExtensions } from "../commands/coreExtensions.ts"; -import type { ChainedCommands, SingleCommands } from "../commands/types.ts"; +import type { EditorEvents, EditorOptions } from "./types/editor.ts"; +import { ExtensionManager } from "./ExtensionManager.ts"; +import type { ChainedCommands, SingleCommands } from "./types/commands.ts"; +import { CommandChain } from "./CommandChain.ts"; +import { CommandsExtension } from "./extensions/commands.ts"; export class Editor extends EventEmitter { private _te: TextEncoder = new TextEncoder(); @@ -89,7 +89,7 @@ export class Editor extends EventEmitter { this.options = options; const { element, content } = this.options; this._extensionManager = new ExtensionManager(this, [ - coreExtensions, + CommandsExtension, ...(this.options?.extensions ?? []), ]); diff --git a/packages/core/src/editor/EventEmitter.spec.ts b/packages/core/src/EventEmitter.spec.ts similarity index 100% rename from packages/core/src/editor/EventEmitter.spec.ts rename to packages/core/src/EventEmitter.spec.ts diff --git a/packages/core/src/editor/EventEmitter.ts b/packages/core/src/EventEmitter.ts similarity index 100% rename from packages/core/src/editor/EventEmitter.ts rename to packages/core/src/EventEmitter.ts diff --git a/packages/core/src/extensions/ExtensionManager.spec.ts b/packages/core/src/ExtensionManager.spec.ts similarity index 95% rename from packages/core/src/extensions/ExtensionManager.spec.ts rename to packages/core/src/ExtensionManager.spec.ts index 1181e2c..63ce813 100644 --- a/packages/core/src/extensions/ExtensionManager.spec.ts +++ b/packages/core/src/ExtensionManager.spec.ts @@ -1,9 +1,9 @@ import { EditorState, StateField } from "@codemirror/state"; import { keymap } from "@codemirror/view"; import { describe, expect, it } from "vite-plus/test"; -import type { Editor } from "../editor/Editor.ts"; import { ExtensionManager } from "./ExtensionManager.ts"; -import type { InkwellExtension } from "./types.ts"; +import type { InkwellExtension } from "./types/extensions.ts"; +import type { Editor } from "./Editor.ts"; describe("ExtensionManager", () => { const editor = {} as Editor; diff --git a/packages/core/src/extensions/ExtensionManager.ts b/packages/core/src/ExtensionManager.ts similarity index 96% rename from packages/core/src/extensions/ExtensionManager.ts rename to packages/core/src/ExtensionManager.ts index 715dbfe..82af491 100644 --- a/packages/core/src/extensions/ExtensionManager.ts +++ b/packages/core/src/ExtensionManager.ts @@ -1,8 +1,8 @@ import type { Extension as CMExtension } from "@codemirror/state"; import { type KeyBinding, keymap } from "@codemirror/view"; -import type { Editor } from "../editor/Editor.ts"; -import type { InkwellExtension } from "./types.ts"; -import type { CommandRegistry } from "../commands/CommandChain.ts"; +import type { Editor } from "./Editor.ts"; +import type { InkwellExtension } from "./types/extensions.ts"; +import type { CommandRegistry } from "./CommandChain.ts"; import { resolveExtensionsOnEditor } from "./helpers/resolveExtensionsOnEditor.ts"; /** diff --git a/packages/core/src/commands/coreExtensions.ts b/packages/core/src/commands/coreExtensions.ts deleted file mode 100644 index 8de5985..0000000 --- a/packages/core/src/commands/coreExtensions.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { InkwellExtension } from "../extensions/types.ts"; -import { cutContent } from "./cutContent.ts"; -import { insertContent } from "./insertContent.ts"; -import { setContent } from "./setContent.ts"; - -/** Built-in commands shipped with core. Registered by default. */ -export const coreExtensions: InkwellExtension = { - name: "__tiptap_coreCommands", - addCommands: () => ({ - insertContent, - setContent, - cutContent, - }), -}; diff --git a/packages/core/src/commands/cutContent.ts b/packages/core/src/commands/cutContent.ts index 26bcff9..ed4553a 100644 --- a/packages/core/src/commands/cutContent.ts +++ b/packages/core/src/commands/cutContent.ts @@ -1,7 +1,7 @@ -import type { NamedCommand } from "./types.ts"; +import type { NamedCommand } from "../types/commands.ts"; -declare module "./types.ts" { - interface InkwellCommands { +declare module "@inkwell/core" { + interface Commands { cutContent: { /** * Cuts content from one range and inserts it at another range diff --git a/packages/core/src/commands/index.ts b/packages/core/src/commands/index.ts new file mode 100644 index 0000000..2f1eab6 --- /dev/null +++ b/packages/core/src/commands/index.ts @@ -0,0 +1,3 @@ +export * from "./cutContent.ts"; +export * from "./insertContent.ts"; +export * from "./setContent.ts"; diff --git a/packages/core/src/commands/insertContent.ts b/packages/core/src/commands/insertContent.ts index b6b8d23..d3822f1 100644 --- a/packages/core/src/commands/insertContent.ts +++ b/packages/core/src/commands/insertContent.ts @@ -1,7 +1,7 @@ -import type { NamedCommand } from "./types.ts"; +import type { NamedCommand } from "../types/commands.ts"; -declare module "./types.ts" { - interface InkwellCommands { +declare module "@inkwell/core" { + interface Commands { /** * Inserts content into the document at the specified range. * If to is not provided, it will insert at the from position. diff --git a/packages/core/src/commands/setContent.ts b/packages/core/src/commands/setContent.ts index 2790630..5323cc6 100644 --- a/packages/core/src/commands/setContent.ts +++ b/packages/core/src/commands/setContent.ts @@ -1,8 +1,8 @@ +import type { NamedCommand } from "../types/commands.ts"; import { insertContent } from "./insertContent.ts"; -import type { NamedCommand } from "./types.ts"; -declare module "./types.ts" { - interface InkwellCommands { +declare module "@inkwell/core" { + interface Commands { setContent: { setContent: (content: string) => ReturnType; }; diff --git a/packages/core/src/editor/index.ts b/packages/core/src/editor/index.ts deleted file mode 100644 index 3443179..0000000 --- a/packages/core/src/editor/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./Editor.ts"; -export * from "./EventEmitter.ts"; -export * from "./types.ts"; diff --git a/packages/core/src/extensions/commands.ts b/packages/core/src/extensions/commands.ts new file mode 100644 index 0000000..dc7f0db --- /dev/null +++ b/packages/core/src/extensions/commands.ts @@ -0,0 +1,10 @@ +import * as commands from "../commands/index.ts"; +import type { InkwellExtension } from "../types/extensions.ts"; + +/** Built-in commands shipped with core. Registered by default. */ +export const CommandsExtension: InkwellExtension = { + name: "__tiptap_commands", + addCommands: () => ({ + ...commands, + }), +}; diff --git a/packages/core/src/extensions/index.ts b/packages/core/src/extensions/index.ts index 7e45f11..9246560 100644 --- a/packages/core/src/extensions/index.ts +++ b/packages/core/src/extensions/index.ts @@ -1,2 +1 @@ -export * from "./types.ts"; -export * from "./ExtensionManager.ts"; +export * from "./commands.ts"; diff --git a/packages/core/src/extensions/helpers/resolveExtensionsOnEditor.spec.ts b/packages/core/src/helpers/resolveExtensionsOnEditor.spec.ts similarity index 97% rename from packages/core/src/extensions/helpers/resolveExtensionsOnEditor.spec.ts rename to packages/core/src/helpers/resolveExtensionsOnEditor.spec.ts index 5451808..8d8d0b4 100644 --- a/packages/core/src/extensions/helpers/resolveExtensionsOnEditor.spec.ts +++ b/packages/core/src/helpers/resolveExtensionsOnEditor.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vite-plus/test"; -import type { Editor } from "../../editor/Editor.ts"; -import type { InkwellExtension } from "../types.ts"; import { resolveExtensionsOnEditor } from "./resolveExtensionsOnEditor.ts"; +import type { Editor } from "../Editor.ts"; +import type { InkwellExtension } from "../types/extensions.ts"; describe("resolveExtensionsOnEditor", () => { const editor = {} as Editor; diff --git a/packages/core/src/extensions/helpers/resolveExtensionsOnEditor.ts b/packages/core/src/helpers/resolveExtensionsOnEditor.ts similarity index 93% rename from packages/core/src/extensions/helpers/resolveExtensionsOnEditor.ts rename to packages/core/src/helpers/resolveExtensionsOnEditor.ts index 6a292c6..06d3df5 100644 --- a/packages/core/src/extensions/helpers/resolveExtensionsOnEditor.ts +++ b/packages/core/src/helpers/resolveExtensionsOnEditor.ts @@ -1,5 +1,5 @@ -import type { Editor } from "../../editor/Editor.ts"; -import type { InkwellExtension } from "../types.ts"; +import type { Editor } from "../Editor.ts"; +import type { InkwellExtension } from "../types/extensions.ts"; /** * Resolves the extensions by resolving child extensions and returning a flat list of all extensions + deduplicating by name. diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 1c9d5c3..6e699a3 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,6 +1,9 @@ -export * from "./editor/index.ts"; +export * from "./commands/index.ts"; +export * from "./types/index.ts"; -export * from "./commands/CommandChain.ts"; -export * from "./commands/types.ts"; +export * from "./CommandChain.ts"; +export * from "./EventEmitter.ts"; +export * from "./ExtensionManager.ts"; +export * from "./Editor.ts"; -export { Editor as default } from "./editor/index.ts"; +export { Editor as default } from "./Editor.ts"; diff --git a/packages/core/src/commands/types.ts b/packages/core/src/types/commands.ts similarity index 82% rename from packages/core/src/commands/types.ts rename to packages/core/src/types/commands.ts index 3d0a192..74604d0 100644 --- a/packages/core/src/commands/types.ts +++ b/packages/core/src/types/commands.ts @@ -1,5 +1,5 @@ import type { EditorState, TransactionSpec } from "@codemirror/state"; -import type { Editor } from "../editor/Editor.ts"; +import type { Editor } from "../Editor.ts"; import type { EditorView } from "@codemirror/view"; /** @@ -9,23 +9,14 @@ import type { EditorView } from "@codemirror/view"; * * @example * declare module "@inkwell/core" { - * interface InkwellCommands { + * interface Commands { * myExtension: { * setContent: (args: { content: string }) => ReturnType * } * } * } */ -export interface InkwellCommands { - core: { - /** - * Sets the content of the document. - * @param content The content to set. - * @returns A boolean indicating whether the command was executed successfully. - */ - setContent: (content: string) => ReturnType; - }; -} +export interface Commands {} /** Runtime context handed to a command. State is projected (post prior steps). */ export interface CommandContext { @@ -57,7 +48,7 @@ export type KeysWithTypeOf = { /** Flattens namespaced augmentations into `commandName: (args) => ReturnType`. */ export type UnionCommands = UnionToIntersection< - ValuesOf, KeysWithTypeOf, object>>> + ValuesOf, KeysWithTypeOf, object>>> >; /** What `addCommands` returns: curried impl keyed by command name. */ diff --git a/packages/core/src/editor/types.ts b/packages/core/src/types/editor.ts similarity index 86% rename from packages/core/src/editor/types.ts rename to packages/core/src/types/editor.ts index 8f31e5f..c7dfd46 100644 --- a/packages/core/src/editor/types.ts +++ b/packages/core/src/types/editor.ts @@ -1,6 +1,6 @@ import type { EditorSelection, Transaction } from "@codemirror/state"; -import type { Editor } from "./Editor.ts"; -import type { InkwellExtension } from "../extensions/types.ts"; +import type { InkwellExtension } from "./extensions.ts"; +import type { Editor } from "../Editor.ts"; export type EditorOptions = { element: HTMLElement; diff --git a/packages/core/src/extensions/types.ts b/packages/core/src/types/extensions.ts similarity index 71% rename from packages/core/src/extensions/types.ts rename to packages/core/src/types/extensions.ts index e6225d4..3abf159 100644 --- a/packages/core/src/extensions/types.ts +++ b/packages/core/src/types/extensions.ts @@ -1,8 +1,8 @@ -import type { Editor } from "../editor/index.ts"; import type { Extension as CMExtension } from "@codemirror/state"; -import type { EditorEvents } from "../editor/types.ts"; import type { KeyBinding } from "@codemirror/view"; -import type { Command } from "../commands/types.ts"; +import type { Editor } from "../Editor.ts"; +import type { EditorEvents } from "./editor.ts"; +import type { Command } from "./commands.ts"; export interface EditorContext { editor: Editor; @@ -33,10 +33,6 @@ export type InkwellExtension = ExtensionEventHandlers & { addNodes?: (ctx: EditorContext) => NodeConfig[]; addMarks?: (ctx: EditorContext) => MarkConfig[]; - // Loose: core can't see InkwellCommands augmentations. Authors can annotate - // returns as Partial at the call site for per-command checking. - // Command (not unknown) because args is contravariant — specific command - // types must be assignable to the registry type. addCommands?: (ctx: EditorContext) => Record>; addCodeMirrorExtensions?: (ctx: EditorContext) => CMExtension[]; addExtensions?: (ctx: EditorContext) => InkwellExtension[]; diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts new file mode 100644 index 0000000..f9ad286 --- /dev/null +++ b/packages/core/src/types/index.ts @@ -0,0 +1,3 @@ +export * from "./commands.ts"; +export * from "./editor.ts"; +export * from "./extensions.ts"; diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 8deeb5f..b01e22f 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -15,6 +15,9 @@ "esModuleInterop": true, "isolatedModules": true, "verbatimModuleSyntax": true, - "skipLibCheck": true + "skipLibCheck": true, + "paths": { + "@inkwell/core": ["./src/index.ts"] + } } } -- 2.51.2