@soeditor/core 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +6 -0
  3. package/dist/commands/command-collection.d.ts +21 -0
  4. package/dist/commands/command-collection.d.ts.map +1 -0
  5. package/dist/commands/command-registry.d.ts +2 -0
  6. package/dist/commands/command-registry.d.ts.map +1 -0
  7. package/dist/commands/command.d.ts +20 -0
  8. package/dist/commands/command.d.ts.map +1 -0
  9. package/dist/config/config.d.ts +16 -0
  10. package/dist/config/config.d.ts.map +1 -0
  11. package/dist/editor/editor.d.ts +75 -0
  12. package/dist/editor/editor.d.ts.map +1 -0
  13. package/dist/errors/errors.d.ts +70 -0
  14. package/dist/errors/errors.d.ts.map +1 -0
  15. package/dist/events/core-events.d.ts +63 -0
  16. package/dist/events/core-events.d.ts.map +1 -0
  17. package/dist/events/event-bus.d.ts +16 -0
  18. package/dist/events/event-bus.d.ts.map +1 -0
  19. package/dist/index.d.ts +19 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +1132 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/internal/value.d.ts +2 -0
  24. package/dist/internal/value.d.ts.map +1 -0
  25. package/dist/plugins/plugin-collection.d.ts +13 -0
  26. package/dist/plugins/plugin-collection.d.ts.map +1 -0
  27. package/dist/plugins/plugin-manager.d.ts +2 -0
  28. package/dist/plugins/plugin-manager.d.ts.map +1 -0
  29. package/dist/plugins/plugin.d.ts +35 -0
  30. package/dist/plugins/plugin.d.ts.map +1 -0
  31. package/dist/services/service-collection.d.ts +31 -0
  32. package/dist/services/service-collection.d.ts.map +1 -0
  33. package/dist/services/service-registry.d.ts +2 -0
  34. package/dist/services/service-registry.d.ts.map +1 -0
  35. package/dist/state/document.d.ts +14 -0
  36. package/dist/state/document.d.ts.map +1 -0
  37. package/dist/state/editor-state.d.ts +15 -0
  38. package/dist/state/editor-state.d.ts.map +1 -0
  39. package/dist/transaction/operation.d.ts +18 -0
  40. package/dist/transaction/operation.d.ts.map +1 -0
  41. package/dist/transaction/transaction.d.ts +36 -0
  42. package/dist/transaction/transaction.d.ts.map +1 -0
  43. package/package.json +48 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/errors/errors.ts","../src/internal/value.ts","../src/config/config.ts","../src/events/event-bus.ts","../src/commands/command-registry.ts","../src/plugins/plugin-manager.ts","../src/services/service-registry.ts","../src/state/document.ts","../src/state/editor-state.ts","../src/transaction/transaction.ts","../src/editor/editor.ts","../src/plugins/plugin.ts","../src/services/service-collection.ts"],"sourcesContent":["/** Base error for failures reported by SoEditor core. */\nexport class SoEditorError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\n/** Thrown when a mutating API is called after editor destruction. */\nexport class EditorDestroyedError extends SoEditorError {\n constructor() {\n super('The editor has been destroyed and can no longer be used.');\n }\n}\n\n/** Thrown when destruction aborts editor startup before creation completes. */\nexport class EditorInitializationAbortedError extends SoEditorError {\n constructor() {\n super(\n 'Editor initialization was aborted because destruction began before startup completed.',\n );\n }\n}\n\n/** Thrown when a listener attempts to dispatch during another dispatch. */\nexport class ReentrantDispatchError extends SoEditorError {\n constructor() {\n super(\n 'Cannot dispatch a transaction while another dispatch is active.',\n );\n }\n}\n\n/** Thrown when a transaction belongs to a different editor. */\nexport class TransactionOwnershipError extends SoEditorError {\n constructor() {\n super('The transaction was not created by this editor.');\n }\n}\n\n/** Thrown when a transaction has already been dispatched. */\nexport class TransactionAlreadyCommittedError extends SoEditorError {\n constructor() {\n super('The transaction has already been committed.');\n }\n}\n\n/** Thrown when editor state changed after a transaction was created. */\nexport class StaleTransactionError extends SoEditorError {\n constructor(baseVersion: number, currentVersion: number) {\n super(\n `Transaction base version ${baseVersion} does not match current editor version ${currentVersion}.`,\n );\n }\n}\n\n/** Thrown when configuration contains a value outside the plain-data contract. */\nexport class UnsupportedConfigValueError extends SoEditorError {\n constructor(path: string, kind: string) {\n super(\n `Configuration value at \"${path}\" has unsupported type \"${kind}\".`,\n );\n }\n}\n\n/** Thrown when configuration contains a cyclic array or object. */\nexport class CyclicConfigurationError extends SoEditorError {\n constructor(path: string) {\n super(`Configuration value at \"${path}\" contains a cycle.`);\n }\n}\n\n/** Thrown when Phase 1 is asked to create a non-HTML document. */\nexport class UnsupportedDocumentFormatError extends SoEditorError {\n constructor(format: string) {\n super(`Document format \"${format}\" is not supported in this release.`);\n }\n}\n\n/** Thrown when a command ID is not registered. */\nexport class CommandNotFoundError extends SoEditorError {\n constructor(id: string) {\n super(`Command \"${id}\" is not registered.`);\n }\n}\n\n/** Thrown when a command ID is registered more than once. */\nexport class CommandAlreadyRegisteredError extends SoEditorError {\n constructor(id: string) {\n super(`Command \"${id}\" is already registered.`);\n }\n}\n\n/** Thrown when a requested plugin is not loaded. */\nexport class PluginNotFoundError extends SoEditorError {\n constructor(id: string) {\n super(`Plugin \"${id}\" is not loaded.`);\n }\n}\n\n/** Thrown when different plugin constructors declare the same ID. */\nexport class PluginDuplicateIdError extends SoEditorError {\n constructor(id: string) {\n super(`Plugin ID \"${id}\" is declared by multiple plugin constructors.`);\n }\n}\n\n/** Thrown when plugin requirements contain a dependency cycle. */\nexport class PluginDependencyCycleError extends SoEditorError {\n readonly path: readonly string[];\n\n constructor(path: readonly string[]) {\n super(`Plugin dependency cycle detected: ${path.join(' -> ')}.`);\n this.path = Object.freeze([...path]);\n }\n}\n\n/** Thrown when a service ID is not registered. */\nexport class ServiceNotFoundError extends SoEditorError {\n constructor(id: string) {\n super(`Service \"${id}\" is not registered.`);\n }\n}\n\n/** Thrown when a service ID is registered more than once. */\nexport class ServiceAlreadyRegisteredError extends SoEditorError {\n constructor(id: string) {\n super(`Service \"${id}\" is already registered.`);\n }\n}\n","import {\n CyclicConfigurationError,\n UnsupportedConfigValueError,\n} from '../errors/errors.js';\n\nfunction isRecord(value: object): value is Record<string, unknown> {\n const prototype = Object.getPrototypeOf(value) as unknown;\n return prototype === Object.prototype || prototype === null;\n}\n\n/** @internal Creates an immutable copy of supported plain configuration data. */\nexport function cloneConfig<T>(\n value: T,\n path = 'config',\n ancestors = new Set<object>(),\n): T {\n if (\n value === null ||\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string'\n ) {\n return value;\n }\n\n if (typeof value !== 'object') {\n throw new UnsupportedConfigValueError(path, typeof value);\n }\n\n if (ancestors.has(value)) {\n throw new CyclicConfigurationError(path);\n }\n\n ancestors.add(value);\n\n if (Array.isArray(value)) {\n try {\n return cloneConfigArray(value, path, ancestors) as T;\n } finally {\n ancestors.delete(value);\n }\n }\n\n if (!isRecord(value)) {\n ancestors.delete(value);\n throw new UnsupportedConfigValueError(path, 'non-plain object');\n }\n\n try {\n if (Object.getOwnPropertySymbols(value).length > 0) {\n throw new UnsupportedConfigValueError(path, 'symbol-keyed object');\n }\n\n const copy: Record<string, unknown> = {};\n\n for (const [key, descriptor] of Object.entries(\n Object.getOwnPropertyDescriptors(value),\n )) {\n if (!('value' in descriptor)) {\n throw new UnsupportedConfigValueError(\n `${path}.${key}`,\n 'accessor',\n );\n }\n\n if (!descriptor.enumerable) {\n continue;\n }\n\n Object.defineProperty(copy, key, {\n enumerable: true,\n value: cloneConfig(\n descriptor.value,\n `${path}.${key}`,\n ancestors,\n ),\n writable: true,\n });\n }\n\n return Object.freeze(copy) as T;\n } finally {\n ancestors.delete(value);\n }\n}\n\nfunction cloneConfigArray(\n value: readonly unknown[],\n path: string,\n ancestors: Set<object>,\n): readonly unknown[] {\n if (Object.getOwnPropertySymbols(value).length > 0) {\n throw new UnsupportedConfigValueError(path, 'symbol-keyed array');\n }\n\n const propertyNames = Object.getOwnPropertyNames(value);\n const indexNames = propertyNames.filter((name) => name !== 'length');\n\n for (const name of indexNames) {\n const index = Number(name);\n\n if (!Number.isInteger(index) || index < 0 || String(index) !== name) {\n throw new UnsupportedConfigValueError(\n `${path}.${name}`,\n 'custom array property',\n );\n }\n }\n\n if (indexNames.length !== value.length) {\n throw new UnsupportedConfigValueError(path, 'sparse array');\n }\n\n const copy: unknown[] = [];\n\n for (let index = 0; index < value.length; index += 1) {\n const descriptor = Object.getOwnPropertyDescriptor(\n value,\n String(index),\n );\n\n if (\n descriptor === undefined ||\n !descriptor.enumerable ||\n !('value' in descriptor)\n ) {\n throw new UnsupportedConfigValueError(\n `${path}[${index}]`,\n descriptor !== undefined && !('value' in descriptor)\n ? 'accessor'\n : 'nonstandard array index',\n );\n }\n\n copy.push(\n cloneConfig(descriptor.value, `${path}[${index}]`, ancestors),\n );\n }\n\n return Object.freeze(copy);\n}\n","import { cloneConfig } from '../internal/value.js';\n\n/** Immutable instance configuration accepted by an editor. */\nexport interface EditorConfig {\n /** Configuration values must be immutable JSON-like plain data. */\n readonly [key: string]: unknown;\n}\n\n/** Read-only access to an editor instance's defensive config copy. */\nexport class Config {\n readonly #values: EditorConfig;\n\n /** Creates an immutable defensive copy of supported configuration data. */\n constructor(values: EditorConfig = {}) {\n this.#values = cloneConfig(values);\n }\n\n /** Returns whether a dotted configuration path exists. */\n has(path: string): boolean {\n return this.#find(path).found;\n }\n\n /** Returns a value at a dotted path, or undefined when absent. */\n get<T = unknown>(path: string): T | undefined {\n const result = this.#find(path);\n return result.found ? (result.value as T) : undefined;\n }\n\n #find(path: string): { found: boolean; value?: unknown } {\n if (path.length === 0) {\n return { found: false };\n }\n\n let current: unknown = this.#values;\n\n for (const segment of path.split('.')) {\n if (\n typeof current !== 'object' ||\n current === null ||\n !Object.prototype.hasOwnProperty.call(current, segment)\n ) {\n return { found: false };\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return { found: true, value: current };\n }\n}\n","/**\n * A synchronous listener for a typed event payload.\n *\n * Returned promises are unsupported, are not awaited, and may produce an\n * unhandled rejection. Event work that must be asynchronous should be started\n * and observed outside the core event pipeline.\n */\nexport type EventListener<Payload> = (payload: Payload) => void;\n\n/** Subscription-only event capabilities exposed by an editor instance. */\nexport interface EditorEvents<Events extends object> {\n /** Registers a listener and returns an idempotent disposer. */\n on<Name extends keyof Events>(\n name: Name,\n listener: EventListener<Events[Name]>,\n ): () => void;\n\n /** Registers a listener that is removed before its first invocation. */\n once<Name extends keyof Events>(\n name: Name,\n listener: EventListener<Events[Name]>,\n ): () => void;\n}\n\ninterface EventBusRecord<Events extends object> {\n readonly assertAvailable: () => void;\n readonly listeners: Map<keyof Events, Set<EventListener<never>>>;\n}\n\nconst records = new WeakMap<object, unknown>();\n\n/** @internal Concrete event storage owned by one editor. */\nexport class EventBus<Events extends object> implements EditorEvents<Events> {\n constructor(assertAvailable: () => void = () => undefined) {\n records.set(this, {\n assertAvailable,\n listeners: new Map(),\n });\n }\n\n on<Name extends keyof Events>(\n name: Name,\n listener: EventListener<Events[Name]>,\n ): () => void {\n const record = getRecord(this);\n record.assertAvailable();\n const listeners = record.listeners.get(name) ?? new Set();\n listeners.add(listener as EventListener<never>);\n record.listeners.set(name, listeners);\n\n return () => {\n listeners.delete(listener as EventListener<never>);\n\n if (listeners.size === 0) {\n record.listeners.delete(name);\n }\n };\n }\n\n once<Name extends keyof Events>(\n name: Name,\n listener: EventListener<Events[Name]>,\n ): () => void {\n let dispose = (): void => undefined;\n const wrapped = (payload: Events[Name]): void => {\n dispose();\n listener(payload);\n };\n dispose = this.on(name, wrapped);\n return dispose;\n }\n\n emit<Name extends keyof Events>(name: Name, payload: Events[Name]): void {\n const record = getRecord(this);\n record.assertAvailable();\n throwListenerErrors(notify(record, name, payload));\n }\n}\n\n/** @internal Creates a subscription-only facade over an owned event bus. */\nexport function createEditorEvents<Events extends object>(\n events: EventBus<Events>,\n): EditorEvents<Events> {\n return Object.freeze({\n on: events.on.bind(events),\n once: events.once.bind(events),\n });\n}\n\nfunction getRecord<Events extends object>(\n events: EventBus<Events>,\n): EventBusRecord<Events> {\n const record = records.get(events) as EventBusRecord<Events> | undefined;\n\n if (record === undefined) {\n throw new Error('Event bus storage is unavailable.');\n }\n\n return record;\n}\n\nfunction notify<Events extends object, Name extends keyof Events>(\n record: EventBusRecord<Events>,\n name: Name,\n payload: Events[Name],\n): readonly unknown[] {\n const listeners = record.listeners.get(name);\n\n if (listeners === undefined) {\n return [];\n }\n\n const errors: unknown[] = [];\n\n for (const listener of [...listeners]) {\n try {\n (listener as EventListener<Events[Name]>)(payload);\n } catch (error: unknown) {\n errors.push(error);\n }\n }\n\n return errors;\n}\n\nfunction throwListenerErrors(errors: readonly unknown[]): void {\n if (errors.length === 1) {\n throw errors[0];\n }\n\n if (errors.length > 1) {\n throw new AggregateError(errors, 'Multiple event listeners failed.');\n }\n}\n\n/** @internal Emits without owner guards and reports failures through event:error. */\nexport function emitSafely<\n Events extends {\n readonly 'event:error': { eventName: string; error: unknown };\n },\n Name extends keyof Events,\n>(\n events: EventBus<Events>,\n name: Name,\n payload: Events[Name],\n): readonly unknown[] {\n const record = getRecord(events);\n const errors = notify(record, name, payload);\n\n if (name !== 'event:error') {\n for (const error of errors) {\n notify(record, 'event:error', {\n eventName: String(name),\n error,\n });\n }\n }\n\n return errors;\n}\n\n/** @internal Emits without owner guards while preserving normal error policy. */\nexport function emitInternally<\n Events extends object,\n Name extends keyof Events,\n>(events: EventBus<Events>, name: Name, payload: Events[Name]): void {\n throwListenerErrors(notify(getRecord(events), name, payload));\n}\n\n/** @internal Clears all listeners without exposing cleanup publicly. */\nexport function clearEvents<Events extends object>(\n events: EventBus<Events>,\n): void {\n getRecord(events).listeners.clear();\n}\n","import type { Editor } from '../editor/editor.js';\nimport {\n CommandAlreadyRegisteredError,\n CommandNotFoundError,\n} from '../errors/errors.js';\nimport type { CoreEventMap } from '../events/core-events.js';\nimport {\n emitInternally,\n emitSafely,\n type EventBus,\n} from '../events/event-bus.js';\nimport type { CommandCollection } from './command-collection.js';\nimport type { Command } from './command.js';\n\ninterface CommandRegistryRecord {\n readonly assertAvailable: () => void;\n readonly commands: Map<string, Command>;\n readonly context: { readonly editor: Editor };\n readonly events: EventBus<CoreEventMap>;\n}\n\nconst records = new WeakMap<CommandRegistry, CommandRegistryRecord>();\n\n/** @internal Per-editor command storage. */\nexport class CommandRegistry implements CommandCollection {\n constructor(\n editor: Editor,\n events: EventBus<CoreEventMap>,\n assertAvailable: () => void,\n ) {\n records.set(this, {\n assertAvailable,\n commands: new Map(),\n context: Object.freeze({ editor }),\n events,\n });\n }\n\n register(command: Command): void {\n const record = getRecord(this);\n record.assertAvailable();\n\n if (record.commands.has(command.id)) {\n throw new CommandAlreadyRegisteredError(command.id);\n }\n\n record.commands.set(command.id, command);\n }\n\n unregister(id: string): boolean {\n const record = getRecord(this);\n record.assertAvailable();\n return record.commands.delete(id);\n }\n\n has(id: string): boolean {\n const record = getRecord(this);\n record.assertAvailable();\n return record.commands.has(id);\n }\n\n get(id: string): Command {\n const record = getRecord(this);\n record.assertAvailable();\n const command = record.commands.get(id);\n\n if (command === undefined) {\n throw new CommandNotFoundError(id);\n }\n\n return command;\n }\n\n ids(): readonly string[] {\n const record = getRecord(this);\n record.assertAvailable();\n return Object.freeze([...record.commands.keys()]);\n }\n\n canExecute(id: string): boolean {\n const record = getRecord(this);\n const command = this.get(id);\n return command.canExecute?.(record.context) ?? true;\n }\n\n isActive(id: string): boolean {\n const record = getRecord(this);\n const command = this.get(id);\n return command.isActive?.(record.context) ?? false;\n }\n\n execute(id: string, ...args: readonly unknown[]): unknown {\n const record = getRecord(this);\n const command = this.get(id);\n\n if (!(command.canExecute?.(record.context) ?? true)) {\n return undefined;\n }\n\n const event = Object.freeze({\n commandId: id,\n args: Object.freeze(args),\n });\n emitInternally(record.events, 'command:beforeExecute', event);\n\n let result: unknown;\n let then: ThenMethod | undefined;\n\n try {\n result = command.execute(record.context, ...args);\n then = getThenMethod(result);\n } catch (error: unknown) {\n emitSafely(\n record.events,\n 'command:error',\n Object.freeze({ ...event, error }),\n );\n throw error;\n }\n\n if (then !== undefined) {\n return assimilateThenable(result, then).then(\n (value) => {\n emitInternally(\n record.events,\n 'command:afterExecute',\n event,\n );\n return value;\n },\n (error: unknown) => {\n emitSafely(\n record.events,\n 'command:error',\n Object.freeze({ ...event, error }),\n );\n throw error;\n },\n );\n }\n\n emitInternally(record.events, 'command:afterExecute', event);\n return result;\n }\n}\n\nfunction getRecord(registry: CommandRegistry): CommandRegistryRecord {\n const record = records.get(registry);\n\n if (record === undefined) {\n throw new Error('Command registry storage is unavailable.');\n }\n\n return record;\n}\n\ntype ThenMethod = (\n onFulfilled: (value: unknown) => void,\n onRejected: (reason: unknown) => void,\n) => unknown;\n\nfunction getThenMethod(value: unknown): ThenMethod | undefined {\n if (\n (typeof value !== 'object' || value === null) &&\n typeof value !== 'function'\n ) {\n return undefined;\n }\n\n const then: unknown = Reflect.get(value, 'then');\n return typeof then === 'function' ? (then as ThenMethod) : undefined;\n}\n\nfunction assimilateThenable(\n value: unknown,\n then: ThenMethod,\n): Promise<unknown> {\n return new Promise((resolve, reject) => {\n try {\n then.call(value, resolve, reject);\n } catch (error: unknown) {\n reject(error);\n }\n });\n}\n\n/** @internal Clears commands without exposing cleanup to consumers. */\nexport function clearCommands(registry: CommandRegistry): void {\n getRecord(registry).commands.clear();\n}\n","import type { Editor } from '../editor/editor.js';\nimport {\n PluginDependencyCycleError,\n PluginDuplicateIdError,\n PluginNotFoundError,\n} from '../errors/errors.js';\nimport type { CoreEventMap, PluginErrorPhase } from '../events/core-events.js';\nimport { emitSafely, type EventBus } from '../events/event-bus.js';\nimport type { PluginCollection } from './plugin-collection.js';\nimport type { Plugin, PluginConstructor } from './plugin.js';\n\ntype PluginStage = 'constructed' | 'initialized' | 'ready' | 'destroyed';\n\ninterface PluginEntry {\n readonly constructor: PluginConstructor;\n readonly instance: Plugin;\n stage: PluginStage;\n}\n\ninterface PluginManagerRecord {\n readonly assertAvailable: () => void;\n readonly editor: Editor;\n readonly events: EventBus<CoreEventMap>;\n readonly instances: Map<string, PluginEntry>;\n order: readonly PluginConstructor[];\n}\n\ninterface PluginStartupControl {\n readonly assertInitializing: () => void;\n readonly destructionStarted: Promise<void>;\n readonly getDestroyPromise: () => Promise<void> | undefined;\n}\n\ntype StartupHookOutcome =\n | { readonly status: 'fulfilled' }\n | { readonly status: 'rejected'; readonly error: unknown }\n | { readonly status: 'destroying' };\n\nconst records = new WeakMap<PluginManager, PluginManagerRecord>();\n\n/** @internal Resolves and stores plugins owned by one editor. */\nexport class PluginManager implements PluginCollection {\n constructor(\n editor: Editor,\n events: EventBus<CoreEventMap>,\n assertAvailable: () => void,\n ) {\n records.set(this, {\n assertAvailable,\n editor,\n events,\n instances: new Map(),\n order: [],\n });\n }\n\n has(key: string | PluginConstructor): boolean {\n const record = getRecord(this);\n record.assertAvailable();\n return record.instances.has(typeof key === 'string' ? key : key.id);\n }\n\n get(id: string): Plugin;\n get<Instance extends Plugin>(\n constructor: PluginConstructor<Instance>,\n ): Instance;\n get<Instance extends Plugin>(\n key: string | PluginConstructor<Instance>,\n ): Plugin | Instance {\n const record = getRecord(this);\n record.assertAvailable();\n const id = typeof key === 'string' ? key : key.id;\n const entry = record.instances.get(id);\n\n if (entry === undefined) {\n throw new PluginNotFoundError(id);\n }\n\n return entry.instance;\n }\n\n tryGet(id: string): Plugin | undefined;\n tryGet<Instance extends Plugin>(\n constructor: PluginConstructor<Instance>,\n ): Instance | undefined;\n tryGet<Instance extends Plugin>(\n key: string | PluginConstructor<Instance>,\n ): Plugin | Instance | undefined {\n const record = getRecord(this);\n record.assertAvailable();\n const id = typeof key === 'string' ? key : key.id;\n return record.instances.get(id)?.instance;\n }\n}\n\nfunction getRecord(manager: PluginManager): PluginManagerRecord {\n const record = records.get(manager);\n\n if (record === undefined) {\n throw new Error('Plugin manager storage is unavailable.');\n }\n\n return record;\n}\n\nfunction emitPluginError(\n record: PluginManagerRecord,\n pluginId: string,\n phase: PluginErrorPhase,\n error: unknown,\n): void {\n emitSafely(\n record.events,\n 'plugin:error',\n Object.freeze({ pluginId, phase, error }),\n );\n}\n\n/** @internal Constructs, initializes, and readies resolved plugins. */\nexport async function initializePlugins(\n manager: PluginManager,\n constructors: readonly PluginConstructor[],\n startup: PluginStartupControl,\n): Promise<void> {\n const record = getRecord(manager);\n const order = resolvePlugins(constructors);\n startup.assertInitializing();\n record.order = order;\n const context = Object.freeze({ editor: record.editor });\n\n for (const constructor of record.order) {\n startup.assertInitializing();\n let instance: Plugin;\n\n try {\n instance = new constructor(context);\n } catch (error: unknown) {\n startup.assertInitializing();\n emitPluginError(record, constructor.id, 'construct', error);\n throw error;\n }\n\n startup.assertInitializing();\n record.instances.set(constructor.id, {\n constructor,\n instance,\n stage: 'constructed',\n });\n }\n\n for (const constructor of record.order) {\n startup.assertInitializing();\n const entry = record.instances.get(constructor.id);\n\n if (entry === undefined) {\n throw new Error(`Plugin \"${constructor.id}\" was not constructed.`);\n }\n\n try {\n await waitForStartupHook(entry.instance.init?.(), startup);\n } catch (error: unknown) {\n startup.assertInitializing();\n emitPluginError(record, constructor.id, 'init', error);\n throw error;\n }\n\n startup.assertInitializing();\n entry.stage = 'initialized';\n }\n\n for (const constructor of record.order) {\n startup.assertInitializing();\n const entry = record.instances.get(constructor.id);\n\n if (entry === undefined) {\n throw new Error(`Plugin \"${constructor.id}\" was not constructed.`);\n }\n\n try {\n await waitForStartupHook(entry.instance.ready?.(), startup);\n } catch (error: unknown) {\n startup.assertInitializing();\n emitPluginError(record, constructor.id, 'ready', error);\n throw error;\n }\n\n startup.assertInitializing();\n entry.stage = 'ready';\n }\n\n startup.assertInitializing();\n}\n\nasync function waitForStartupHook(\n result: void | Promise<void>,\n startup: PluginStartupControl,\n): Promise<void> {\n const hookOutcome: Promise<StartupHookOutcome> = Promise.resolve(\n result,\n ).then(\n () => ({ status: 'fulfilled' }),\n (error: unknown) => ({ status: 'rejected', error }),\n );\n const activeDestroy = startup.getDestroyPromise();\n\n if (activeDestroy !== undefined) {\n await activeDestroy;\n startup.assertInitializing();\n return;\n }\n\n const outcome = await Promise.race([\n hookOutcome,\n startup.destructionStarted.then((): StartupHookOutcome => ({\n status: 'destroying',\n })),\n ]);\n\n if (outcome.status === 'rejected') {\n throw outcome.error;\n }\n\n if (outcome.status === 'destroying') {\n const destroyPromise = startup.getDestroyPromise();\n\n if (destroyPromise === undefined) {\n throw new Error(\n 'Editor destruction started without a shared destroy promise.',\n );\n }\n\n await destroyPromise;\n startup.assertInitializing();\n }\n}\n\n/** @internal Destroys successfully initialized plugins in reverse order. */\nexport async function destroyPlugins(manager: PluginManager): Promise<void> {\n const record = getRecord(manager);\n\n for (const constructor of [...record.order].reverse()) {\n const entry = record.instances.get(constructor.id);\n\n if (\n entry === undefined ||\n entry.stage === 'constructed' ||\n entry.stage === 'destroyed'\n ) {\n continue;\n }\n\n entry.stage = 'destroyed';\n\n try {\n await entry.instance.destroy?.();\n } catch (error: unknown) {\n emitPluginError(record, constructor.id, 'destroy', error);\n }\n }\n\n record.instances.clear();\n record.order = [];\n}\n\nfunction resolvePlugins(\n roots: readonly PluginConstructor[],\n): readonly PluginConstructor[] {\n const byId = new Map<string, PluginConstructor>();\n const visited = new Set<PluginConstructor>();\n const visiting: PluginConstructor[] = [];\n const ordered: PluginConstructor[] = [];\n\n const visit = (constructor: PluginConstructor): void => {\n const existing = byId.get(constructor.id);\n\n if (existing !== undefined && existing !== constructor) {\n throw new PluginDuplicateIdError(constructor.id);\n }\n\n byId.set(constructor.id, constructor);\n const cycleStart = visiting.indexOf(constructor);\n\n if (cycleStart !== -1) {\n const path = visiting.slice(cycleStart).map((item) => item.id);\n path.push(constructor.id);\n throw new PluginDependencyCycleError(path);\n }\n\n if (visited.has(constructor)) {\n return;\n }\n\n visiting.push(constructor);\n\n for (const requirement of constructor.requires ?? []) {\n visit(requirement);\n }\n\n visiting.pop();\n visited.add(constructor);\n ordered.push(constructor);\n };\n\n for (const constructor of roots) {\n visit(constructor);\n }\n\n return Object.freeze(ordered);\n}\n","import {\n ServiceAlreadyRegisteredError,\n ServiceNotFoundError,\n} from '../errors/errors.js';\nimport type { ServiceCollection, ServiceToken } from './service-collection.js';\n\ntype ServiceKey<Service = unknown> = string | ServiceToken<Service>;\n\ninterface ServiceRegistryRecord {\n readonly assertAvailable: () => void;\n readonly services: Map<string, unknown>;\n}\n\nconst records = new WeakMap<ServiceRegistry, ServiceRegistryRecord>();\n\nfunction serviceId<Service>(key: ServiceKey<Service>): string {\n return typeof key === 'string' ? key : key.id;\n}\n\n/** @internal Per-editor service storage. */\nexport class ServiceRegistry implements ServiceCollection {\n constructor(assertAvailable: () => void) {\n records.set(this, { assertAvailable, services: new Map() });\n }\n\n register<Service>(token: ServiceToken<Service>, service: Service): void;\n register<Service>(id: string, service: Service): void;\n register<Service>(key: ServiceKey<Service>, service: Service): void {\n const record = getRecord(this);\n record.assertAvailable();\n const id = serviceId(key);\n\n if (record.services.has(id)) {\n throw new ServiceAlreadyRegisteredError(id);\n }\n\n record.services.set(id, service);\n }\n\n replace<Service>(token: ServiceToken<Service>, service: Service): void;\n replace<Service>(id: string, service: Service): void;\n replace<Service>(key: ServiceKey<Service>, service: Service): void {\n const record = getRecord(this);\n record.assertAvailable();\n record.services.set(serviceId(key), service);\n }\n\n has<Service>(key: ServiceKey<Service>): boolean {\n const record = getRecord(this);\n record.assertAvailable();\n return record.services.has(serviceId(key));\n }\n\n get<Service>(token: ServiceToken<Service>): Service;\n get<Service = unknown>(id: string): Service;\n get<Service>(key: ServiceKey<Service>): Service {\n const record = getRecord(this);\n record.assertAvailable();\n const id = serviceId(key);\n\n if (!record.services.has(id)) {\n throw new ServiceNotFoundError(id);\n }\n\n return record.services.get(id) as Service;\n }\n\n tryGet<Service>(token: ServiceToken<Service>): Service | undefined;\n tryGet<Service = unknown>(id: string): Service | undefined;\n tryGet<Service>(key: ServiceKey<Service>): Service | undefined {\n const record = getRecord(this);\n record.assertAvailable();\n return record.services.get(serviceId(key)) as Service | undefined;\n }\n\n unregister<Service>(key: ServiceKey<Service>): boolean {\n const record = getRecord(this);\n record.assertAvailable();\n return record.services.delete(serviceId(key));\n }\n}\n\nfunction getRecord(registry: ServiceRegistry): ServiceRegistryRecord {\n const record = records.get(registry);\n\n if (record === undefined) {\n throw new Error('Service registry storage is unavailable.');\n }\n\n return record;\n}\n\n/** @internal Clears services without exposing cleanup to consumers. */\nexport function clearServices(registry: ServiceRegistry): void {\n getRecord(registry).services.clear();\n}\n","/** A source format understood by the stable document API. */\nexport type DocumentFormat = 'html' | 'markdown';\n\n/** The canonical source document held by an editor state. */\nexport interface EditorDocument {\n /** Canonical source format. */\n readonly format: DocumentFormat;\n /** Canonical source text preserved by core without parsing. */\n readonly source: string;\n /** Monotonic revision incremented by actual source changes. */\n readonly revision: number;\n /** Immutable document-level metadata. */\n readonly metadata: Readonly<Record<string, unknown>>;\n}\n\n/** @internal Creates an immutable canonical document snapshot. */\nexport function createEditorDocument(\n source: string,\n format: DocumentFormat,\n revision = 0,\n metadata: Readonly<Record<string, unknown>> = {},\n): EditorDocument {\n return Object.freeze({\n format,\n source,\n revision,\n metadata: Object.freeze({ ...metadata }),\n });\n}\n","import type { EditorDocument } from './document.js';\n\n/** The active projection requested from the editor. */\nexport type EditorMode = 'visual' | 'source' | 'markdown' | 'preview';\n\n/** An immutable snapshot of editor state. */\nexport interface EditorState {\n /** Canonical immutable document snapshot. */\n readonly document: EditorDocument;\n /** Requested editor projection. */\n readonly mode: EditorMode;\n /** Editing-policy state for future user-facing editing operations. */\n readonly readonly: boolean;\n /** Whether canonical source has changed since it was marked clean. */\n readonly dirty: boolean;\n}\n\n/** @internal Creates an immutable editor state snapshot. */\nexport function createEditorState(values: EditorState): EditorState {\n return Object.freeze({ ...values });\n}\n","import {\n StaleTransactionError,\n TransactionAlreadyCommittedError,\n TransactionOwnershipError,\n} from '../errors/errors.js';\nimport type { EditorMode } from '../state/editor-state.js';\nimport type { Operation } from './operation.js';\n\n/** Describes the source of a state transaction. */\nexport type TransactionOrigin =\n 'user' | 'command' | 'plugin' | 'source' | 'system';\n\n/** An immutable key/value view of opaque transaction metadata values. */\nexport interface TransactionMetadata {\n readonly [key: string]: unknown;\n}\n\n/** Options used by an editor when creating a transaction. */\nexport interface TransactionOptions {\n /** Identifies the system that initiated the transaction. */\n readonly origin?: TransactionOrigin;\n}\n\n/**\n * A mutable, single-use transaction created by `Editor.createTransaction()`.\n *\n * Metadata values are opaque and retain their original object identity. The\n * metadata container is exposed as an immutable snapshot.\n */\nexport interface Transaction {\n /** The system that initiated this transaction. */\n readonly origin: TransactionOrigin;\n /** A snapshot of operations currently queued for this transaction. */\n readonly operations: readonly Operation[];\n /** A frozen snapshot of the transaction's opaque metadata entries. */\n readonly metadata: TransactionMetadata;\n /** Queues replacement of the canonical document source. */\n replaceDocument(source: string): this;\n /** Queues a change to the editor's requested mode. */\n setMode(mode: EditorMode): this;\n /** Adds or replaces an opaque metadata value. */\n setMeta(key: string, value: unknown): this;\n /** Returns an opaque metadata value, or undefined when absent. */\n getMeta(key: string): unknown;\n}\n\ninterface TransactionRecord {\n readonly baseVersion: number;\n committed: boolean;\n readonly metadata: Map<string, unknown>;\n readonly operations: Operation[];\n readonly origin: TransactionOrigin;\n readonly owner: object;\n}\n\nconst records = new WeakMap<Transaction, TransactionRecord>();\n\nclass EditorTransaction implements Transaction {\n constructor(record: TransactionRecord) {\n records.set(this, record);\n }\n\n get origin(): TransactionOrigin {\n return getRecord(this).origin;\n }\n\n get operations(): readonly Operation[] {\n return [...getRecord(this).operations];\n }\n\n get metadata(): TransactionMetadata {\n return Object.freeze(Object.fromEntries(getRecord(this).metadata));\n }\n\n replaceDocument(source: string): this {\n const record = getMutableRecord(this);\n record.operations.push(\n Object.freeze({ type: 'replace-document', source }),\n );\n return this;\n }\n\n setMode(mode: EditorMode): this {\n const record = getMutableRecord(this);\n record.operations.push(Object.freeze({ type: 'set-mode', mode }));\n return this;\n }\n\n setMeta(key: string, value: unknown): this {\n getMutableRecord(this).metadata.set(key, value);\n return this;\n }\n\n getMeta(key: string): unknown {\n return getRecord(this).metadata.get(key);\n }\n}\n\nfunction getRecord(transaction: Transaction): TransactionRecord {\n const record = records.get(transaction);\n\n if (record === undefined) {\n throw new TransactionOwnershipError();\n }\n\n return record;\n}\n\nfunction getMutableRecord(transaction: Transaction): TransactionRecord {\n const record = getRecord(transaction);\n\n if (record.committed) {\n throw new TransactionAlreadyCommittedError();\n }\n\n return record;\n}\n\n/** @internal Creates an editor-owned transaction. */\nexport function createTransaction(\n owner: object,\n baseVersion: number,\n options: TransactionOptions,\n): Transaction {\n return new EditorTransaction({\n baseVersion,\n committed: false,\n metadata: new Map(),\n operations: [],\n origin: options.origin ?? 'system',\n owner,\n });\n}\n\n/** @internal Validates and consumes a transaction for one dispatch attempt. */\nexport function commitTransaction(\n transaction: Transaction,\n owner: object,\n currentVersion: number,\n): readonly Operation[] {\n const record = getMutableRecord(transaction);\n\n if (record.owner !== owner) {\n throw new TransactionOwnershipError();\n }\n\n if (record.baseVersion !== currentVersion) {\n throw new StaleTransactionError(record.baseVersion, currentVersion);\n }\n\n record.committed = true;\n return Object.freeze([...record.operations]);\n}\n","import type { CommandCollection } from '../commands/command-collection.js';\nimport {\n clearCommands,\n CommandRegistry,\n} from '../commands/command-registry.js';\nimport { Config, type EditorConfig } from '../config/config.js';\nimport {\n EditorDestroyedError,\n EditorInitializationAbortedError,\n ReentrantDispatchError,\n UnsupportedDocumentFormatError,\n} from '../errors/errors.js';\nimport type { CoreEventMap } from '../events/core-events.js';\nimport {\n clearEvents,\n createEditorEvents,\n emitInternally,\n emitSafely,\n EventBus,\n type EditorEvents,\n} from '../events/event-bus.js';\nimport type { PluginCollection } from '../plugins/plugin-collection.js';\nimport {\n destroyPlugins,\n initializePlugins,\n PluginManager,\n} from '../plugins/plugin-manager.js';\nimport type { PluginConstructor } from '../plugins/plugin.js';\nimport type { ServiceCollection } from '../services/service-collection.js';\nimport {\n clearServices,\n ServiceRegistry,\n} from '../services/service-registry.js';\nimport {\n createEditorDocument,\n type DocumentFormat,\n} from '../state/document.js';\nimport {\n createEditorState,\n type EditorMode,\n type EditorState,\n} from '../state/editor-state.js';\nimport type { Operation } from '../transaction/operation.js';\nimport {\n commitTransaction,\n createTransaction,\n type Transaction,\n type TransactionOptions,\n} from '../transaction/transaction.js';\n\n/** Options used to construct an independent editor instance. */\nexport interface EditorCreateOptions {\n /** Initial canonical source in the selected document format. */\n readonly data?: string;\n /** Canonical document format. */\n readonly format?: DocumentFormat;\n /** Editing-policy state exposed to future user-facing editing surfaces. */\n readonly readonly?: boolean;\n /** Initial requested document projection. */\n readonly mode?: EditorMode;\n /** Root plugins whose transitive requirements should be loaded. */\n readonly plugins?: readonly PluginConstructor[];\n /** Immutable, JSON-like instance configuration. */\n readonly config?: EditorConfig;\n}\n\ntype EditorLifecycle = 'initializing' | 'ready' | 'destroying' | 'destroyed';\n\n/** Coordinates immutable state with transactions and per-instance capabilities. */\nexport class Editor {\n /** Commands available to consumers and plugins. */\n readonly commands: CommandCollection;\n /** Immutable instance configuration. */\n readonly config: Config;\n /** Subscription-only access to typed editor events. */\n readonly events: EditorEvents<CoreEventMap>;\n /** Loaded plugin lookup capabilities. */\n readonly plugins: PluginCollection;\n /** Cross-feature service capabilities. */\n readonly services: ServiceCollection;\n\n readonly #commandRegistry: CommandRegistry;\n readonly #destructionStarted: Promise<void>;\n readonly #eventBus: EventBus<CoreEventMap>;\n readonly #owner = Object.freeze({});\n readonly #pluginManager: PluginManager;\n readonly #serviceRegistry: ServiceRegistry;\n #destroyPromise: Promise<void> | undefined;\n #dispatching = false;\n #lifecycle: EditorLifecycle = 'initializing';\n #resolveDestructionStarted!: () => void;\n #state: EditorState;\n #stateVersion = 0;\n\n private constructor(options: EditorCreateOptions) {\n const format = options.format ?? 'html';\n\n if (format !== 'html' && format !== 'markdown') {\n throw new UnsupportedDocumentFormatError(format);\n }\n\n this.#state = createEditorState({\n document: createEditorDocument(options.data ?? '', format),\n mode:\n options.mode ?? (format === 'markdown' ? 'markdown' : 'visual'),\n readonly: options.readonly ?? false,\n dirty: false,\n });\n this.#destructionStarted = new Promise<void>((resolve) => {\n this.#resolveDestructionStarted = resolve;\n });\n this.config = new Config(options.config);\n const assertAvailable = (): void => this.#assertNotDestroyed();\n this.#eventBus = new EventBus<CoreEventMap>(assertAvailable);\n this.#commandRegistry = new CommandRegistry(\n this,\n this.#eventBus,\n assertAvailable,\n );\n this.#serviceRegistry = new ServiceRegistry(assertAvailable);\n this.#pluginManager = new PluginManager(\n this,\n this.#eventBus,\n assertAvailable,\n );\n this.commands = this.#commandRegistry;\n this.events = createEditorEvents(this.#eventBus);\n this.services = this.#serviceRegistry;\n this.plugins = this.#pluginManager;\n }\n\n /** The current immutable state snapshot. */\n get state(): EditorState {\n return this.#state;\n }\n\n /** Creates and initializes an editor and all requested plugins. */\n static async create(options: EditorCreateOptions = {}): Promise<Editor> {\n const editor = new Editor(options);\n\n try {\n await initializePlugins(\n editor.#pluginManager,\n options.plugins ?? [],\n {\n assertInitializing: () => editor.#assertInitializing(),\n destructionStarted: editor.#destructionStarted,\n getDestroyPromise: () => editor.#destroyPromise,\n },\n );\n editor.#transitionToReady();\n\n let readyEventError: unknown;\n let readyEventFailed = false;\n\n try {\n emitInternally(\n editor.#eventBus,\n 'editor:ready',\n Object.freeze({ editor }),\n );\n } catch (error: unknown) {\n readyEventFailed = true;\n readyEventError = error;\n }\n\n editor.#assertCreationCanReturn();\n\n if (readyEventFailed) {\n throw readyEventError;\n }\n\n return editor;\n } catch (error: unknown) {\n await editor.destroy();\n throw error;\n }\n }\n\n /** Creates a mutable transaction owned by the current editor state. */\n createTransaction(options: TransactionOptions = {}): Transaction {\n this.#assertAlive();\n return createTransaction(this.#owner, this.#stateVersion, options);\n }\n\n /**\n * Applies one owned, current, uncommitted transaction.\n *\n * Synchronous reentrant dispatch is rejected with\n * `ReentrantDispatchError` rather than queued.\n */\n dispatch(transaction: Transaction): void {\n this.#assertAlive();\n\n if (this.#dispatching) {\n throw new ReentrantDispatchError();\n }\n\n this.#dispatching = true;\n\n try {\n const operations = commitTransaction(\n transaction,\n this.#owner,\n this.#stateVersion,\n );\n this.#applyOperations(transaction, operations);\n } finally {\n this.#dispatching = false;\n }\n }\n\n /** Builds and dispatches one editor-owned transaction. */\n update(\n callback: (transaction: Transaction) => void,\n options: TransactionOptions = {},\n ): void {\n this.#assertAlive();\n const transaction = this.createTransaction(options);\n callback(transaction);\n this.dispatch(transaction);\n }\n\n /** Executes a registered command through this editor's command collection. */\n execute(commandId: string, ...args: readonly unknown[]): unknown {\n this.#assertAlive();\n return this.#commandRegistry.execute(commandId, ...args);\n }\n\n /** Returns canonical source, including after editor destruction. */\n getData(): string {\n return this.#state.document.source;\n }\n\n /**\n * Administratively replaces canonical source through a transaction.\n *\n * This remains allowed when `readonly` is true; future user-facing editing\n * surfaces must enforce readonly policy before creating user transactions.\n */\n setData(source: string): void {\n this.update((transaction) => transaction.replaceDocument(source), {\n origin: 'source',\n });\n }\n\n /** Marks the current state as saved without changing document revision. */\n markClean(): void {\n this.#assertAlive();\n\n if (!this.#state.dirty) {\n return;\n }\n\n const previous = this.#state;\n const current = createEditorState({ ...previous, dirty: false });\n this.#state = current;\n this.#stateVersion += 1;\n emitInternally(\n this.#eventBus,\n 'state:change',\n Object.freeze({ previous, current }),\n );\n }\n\n /**\n * Destroys initialized plugins and clears all owned infrastructure.\n *\n * Calls made while destruction is pending return the same promise.\n */\n destroy(): Promise<void> {\n if (this.#destroyPromise !== undefined) {\n return this.#destroyPromise;\n }\n\n this.#lifecycle = 'destroying';\n let resolveDestroy!: () => void;\n let rejectDestroy!: (reason: unknown) => void;\n const destroyPromise = new Promise<void>((resolve, reject) => {\n resolveDestroy = resolve;\n rejectDestroy = reject;\n });\n this.#destroyPromise = destroyPromise;\n this.#resolveDestructionStarted();\n\n void this.#performDestroy().then(resolveDestroy, rejectDestroy);\n return destroyPromise;\n }\n\n #applyOperations(\n transaction: Transaction,\n operations: readonly Operation[],\n ): void {\n const previous = this.#state;\n let source = previous.document.source;\n let mode = previous.mode;\n\n for (const operation of operations) {\n switch (operation.type) {\n case 'replace-document':\n source = operation.source;\n break;\n case 'set-mode':\n mode = operation.mode;\n break;\n default:\n assertNever(operation);\n }\n }\n\n const documentChanged = source !== previous.document.source;\n const modeChanged = mode !== previous.mode;\n\n if (!documentChanged && !modeChanged) {\n return;\n }\n\n const document = documentChanged\n ? createEditorDocument(\n source,\n previous.document.format,\n previous.document.revision + 1,\n previous.document.metadata,\n )\n : previous.document;\n const current = createEditorState({\n document,\n mode,\n readonly: previous.readonly,\n dirty: documentChanged ? true : previous.dirty,\n });\n\n if (documentChanged) {\n emitInternally(\n this.#eventBus,\n 'document:beforeChange',\n Object.freeze({\n previous: previous.document,\n current: document,\n transaction,\n }),\n );\n }\n\n this.#state = current;\n this.#stateVersion += 1;\n const notificationErrors: unknown[] = [];\n\n if (documentChanged) {\n attemptNotification(notificationErrors, () =>\n emitInternally(\n this.#eventBus,\n 'document:change',\n Object.freeze({\n previous: previous.document,\n current: document,\n transaction,\n }),\n ),\n );\n }\n\n if (modeChanged) {\n attemptNotification(notificationErrors, () =>\n emitInternally(\n this.#eventBus,\n 'mode:change',\n Object.freeze({\n previous: previous.mode,\n current: mode,\n transaction,\n }),\n ),\n );\n }\n\n attemptNotification(notificationErrors, () =>\n emitInternally(\n this.#eventBus,\n 'state:change',\n Object.freeze({ previous, current, transaction }),\n ),\n );\n throwNotificationErrors(notificationErrors);\n }\n\n async #performDestroy(): Promise<void> {\n try {\n await destroyPlugins(this.#pluginManager);\n } finally {\n this.#lifecycle = 'destroyed';\n\n try {\n emitSafely(\n this.#eventBus,\n 'editor:destroy',\n Object.freeze({ editor: this }),\n );\n } finally {\n clearCommands(this.#commandRegistry);\n clearServices(this.#serviceRegistry);\n clearEvents(this.#eventBus);\n }\n }\n }\n\n #assertAlive(): void {\n if (\n this.#lifecycle === 'destroying' ||\n this.#lifecycle === 'destroyed'\n ) {\n throw new EditorDestroyedError();\n }\n }\n\n #assertInitializing(): void {\n if (this.#lifecycle !== 'initializing') {\n throw new EditorInitializationAbortedError();\n }\n }\n\n #transitionToReady(): void {\n this.#assertInitializing();\n this.#lifecycle = 'ready';\n }\n\n #assertCreationCanReturn(): void {\n if (this.#lifecycle !== 'ready') {\n throw new EditorInitializationAbortedError();\n }\n }\n\n #assertNotDestroyed(): void {\n if (\n this.#lifecycle === 'destroying' ||\n this.#lifecycle === 'destroyed'\n ) {\n throw new EditorDestroyedError();\n }\n }\n}\n\nfunction assertNever(operation: never): never {\n throw new Error(`Unsupported operation: ${JSON.stringify(operation)}.`);\n}\n\nfunction attemptNotification(errors: unknown[], notify: () => void): void {\n try {\n notify();\n } catch (error: unknown) {\n errors.push(error);\n }\n}\n\nfunction throwNotificationErrors(errors: readonly unknown[]): void {\n if (errors.length === 1) {\n throw errors[0];\n }\n\n if (errors.length > 1) {\n throw new AggregateError(\n errors,\n 'Multiple editor state notifications failed.',\n );\n }\n}\n","import type { Editor } from '../editor/editor.js';\n\n/** Context passed to each plugin constructor. */\nexport interface PluginContext {\n /** The editor instance that owns the plugin. */\n readonly editor: Editor;\n}\n\n/** A constructable plugin type with a stable ID and optional requirements. */\nexport interface PluginConstructor<Instance extends Plugin = Plugin> {\n /** Constructs a plugin for one editor instance. */\n new (context: PluginContext): Instance;\n /** Stable ID used for dependency resolution and lookup. */\n readonly id: string;\n /** Plugins that must initialize before this plugin. */\n readonly requires?: readonly PluginConstructor[];\n}\n\n/** Base class for an editor extension with explicit lifecycle hooks. */\nexport abstract class Plugin {\n /** The editor instance that owns this plugin. */\n protected readonly editor: Editor;\n\n /** Creates a plugin owned by the editor in the supplied context. */\n constructor(context: PluginContext) {\n this.editor = context.editor;\n }\n\n /** Initializes resources after every plugin has been constructed. */\n init?(): void | Promise<void>;\n /** Runs only after every plugin has initialized successfully. */\n ready?(): void | Promise<void>;\n /**\n * Releases resources after this plugin initialized successfully.\n *\n * A destroy hook must not await this editor's own `destroy()` promise,\n * because that promise cannot settle until the hook itself completes. The\n * hook may obtain or compare the shared promise without awaiting it.\n */\n destroy?(): void | Promise<void>;\n}\n","/** Internal type brand that does not become an ordinary token property. */\ndeclare const serviceType: unique symbol;\n\n/** A typed identity for a cross-feature service. */\nexport interface ServiceToken<Service> {\n /** Stable service identity shared by registration and lookup. */\n readonly id: string;\n readonly [serviceType]?: (service: Service) => Service;\n}\n\n/** Public service capabilities owned by one editor. */\nexport interface ServiceCollection {\n /** Registers a service and rejects duplicate IDs. */\n register<Service>(token: ServiceToken<Service>, service: Service): void;\n register<Service>(id: string, service: Service): void;\n /** Explicitly inserts or replaces a service. */\n replace<Service>(token: ServiceToken<Service>, service: Service): void;\n replace<Service>(id: string, service: Service): void;\n /** Returns whether a service is registered. */\n has<Service>(key: string | ServiceToken<Service>): boolean;\n /** Gets a service or throws when absent. */\n get<Service>(token: ServiceToken<Service>): Service;\n get<Service = unknown>(id: string): Service;\n /** Gets a service when present. */\n tryGet<Service>(token: ServiceToken<Service>): Service | undefined;\n tryGet<Service = unknown>(id: string): Service | undefined;\n /** Removes a service and reports whether it existed. */\n unregister<Service>(key: string | ServiceToken<Service>): boolean;\n}\n\n/** Creates a typed service token with a stable string identity. */\nexport function createServiceToken<Service>(id: string): ServiceToken<Service> {\n return Object.freeze({ id });\n}\n"],"names":["records","getRecord","notify"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=value.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value.d.ts","sourceRoot":"","sources":["../../src/internal/value.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import type { Plugin, PluginConstructor } from './plugin.js';
2
+ /** Public lookup capabilities for plugins owned by one editor. */
3
+ export interface PluginCollection {
4
+ /** Returns whether a plugin is loaded. */
5
+ has(key: string | PluginConstructor): boolean;
6
+ /** Gets a plugin or throws when it is absent. */
7
+ get(id: string): Plugin;
8
+ get<Instance extends Plugin>(constructor: PluginConstructor<Instance>): Instance;
9
+ /** Gets a plugin when present. */
10
+ tryGet(id: string): Plugin | undefined;
11
+ tryGet<Instance extends Plugin>(constructor: PluginConstructor<Instance>): Instance | undefined;
12
+ }
13
+ //# sourceMappingURL=plugin-collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-collection.d.ts","sourceRoot":"","sources":["../../src/plugins/plugin-collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE7D,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC7B,0CAA0C;IAC1C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,GAAG,OAAO,CAAC;IAC9C,iDAAiD;IACjD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,GAAG,CAAC,QAAQ,SAAS,MAAM,EACvB,WAAW,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GACzC,QAAQ,CAAC;IACZ,kCAAkC;IAClC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvC,MAAM,CAAC,QAAQ,SAAS,MAAM,EAC1B,WAAW,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GACzC,QAAQ,GAAG,SAAS,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-manager.d.ts","sourceRoot":"","sources":["../../src/plugins/plugin-manager.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import type { Editor } from '../editor/editor.js';
2
+ /** Context passed to each plugin constructor. */
3
+ export interface PluginContext {
4
+ /** The editor instance that owns the plugin. */
5
+ readonly editor: Editor;
6
+ }
7
+ /** A constructable plugin type with a stable ID and optional requirements. */
8
+ export interface PluginConstructor<Instance extends Plugin = Plugin> {
9
+ /** Constructs a plugin for one editor instance. */
10
+ new (context: PluginContext): Instance;
11
+ /** Stable ID used for dependency resolution and lookup. */
12
+ readonly id: string;
13
+ /** Plugins that must initialize before this plugin. */
14
+ readonly requires?: readonly PluginConstructor[];
15
+ }
16
+ /** Base class for an editor extension with explicit lifecycle hooks. */
17
+ export declare abstract class Plugin {
18
+ /** The editor instance that owns this plugin. */
19
+ protected readonly editor: Editor;
20
+ /** Creates a plugin owned by the editor in the supplied context. */
21
+ constructor(context: PluginContext);
22
+ /** Initializes resources after every plugin has been constructed. */
23
+ init?(): void | Promise<void>;
24
+ /** Runs only after every plugin has initialized successfully. */
25
+ ready?(): void | Promise<void>;
26
+ /**
27
+ * Releases resources after this plugin initialized successfully.
28
+ *
29
+ * A destroy hook must not await this editor's own `destroy()` promise,
30
+ * because that promise cannot settle until the hook itself completes. The
31
+ * hook may obtain or compare the shared promise without awaiting it.
32
+ */
33
+ destroy?(): void | Promise<void>;
34
+ }
35
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC3B;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM;IAC/D,mDAAmD;IACnD,KAAK,OAAO,EAAE,aAAa,GAAG,QAAQ,CAAC;IACvC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACpD;AAED,wEAAwE;AACxE,8BAAsB,MAAM;IACxB,iDAAiD;IACjD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,oEAAoE;gBACxD,OAAO,EAAE,aAAa;IAIlC,qEAAqE;IACrE,IAAI,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC7B,iEAAiE;IACjE,KAAK,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC9B;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CACnC"}
@@ -0,0 +1,31 @@
1
+ /** Internal type brand that does not become an ordinary token property. */
2
+ declare const serviceType: unique symbol;
3
+ /** A typed identity for a cross-feature service. */
4
+ export interface ServiceToken<Service> {
5
+ /** Stable service identity shared by registration and lookup. */
6
+ readonly id: string;
7
+ readonly [serviceType]?: (service: Service) => Service;
8
+ }
9
+ /** Public service capabilities owned by one editor. */
10
+ export interface ServiceCollection {
11
+ /** Registers a service and rejects duplicate IDs. */
12
+ register<Service>(token: ServiceToken<Service>, service: Service): void;
13
+ register<Service>(id: string, service: Service): void;
14
+ /** Explicitly inserts or replaces a service. */
15
+ replace<Service>(token: ServiceToken<Service>, service: Service): void;
16
+ replace<Service>(id: string, service: Service): void;
17
+ /** Returns whether a service is registered. */
18
+ has<Service>(key: string | ServiceToken<Service>): boolean;
19
+ /** Gets a service or throws when absent. */
20
+ get<Service>(token: ServiceToken<Service>): Service;
21
+ get<Service = unknown>(id: string): Service;
22
+ /** Gets a service when present. */
23
+ tryGet<Service>(token: ServiceToken<Service>): Service | undefined;
24
+ tryGet<Service = unknown>(id: string): Service | undefined;
25
+ /** Removes a service and reports whether it existed. */
26
+ unregister<Service>(key: string | ServiceToken<Service>): boolean;
27
+ }
28
+ /** Creates a typed service token with a stable string identity. */
29
+ export declare function createServiceToken<Service>(id: string): ServiceToken<Service>;
30
+ export {};
31
+ //# sourceMappingURL=service-collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-collection.d.ts","sourceRoot":"","sources":["../../src/services/service-collection.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,OAAO,CAAC,MAAM,WAAW,EAAE,OAAO,MAAM,CAAC;AAEzC,oDAAoD;AACpD,MAAM,WAAW,YAAY,CAAC,OAAO;IACjC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;CAC1D;AAED,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAC9B,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxE,QAAQ,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACtD,gDAAgD;IAChD,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACvE,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACrD,+CAA+C;IAC/C,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC3D,4CAA4C;IAC5C,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACpD,GAAG,CAAC,OAAO,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5C,mCAAmC;IACnC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,SAAS,CAAC;IACnE,MAAM,CAAC,OAAO,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3D,wDAAwD;IACxD,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACrE;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAE7E"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=service-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-registry.d.ts","sourceRoot":"","sources":["../../src/services/service-registry.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ /** A source format understood by the stable document API. */
2
+ export type DocumentFormat = 'html' | 'markdown';
3
+ /** The canonical source document held by an editor state. */
4
+ export interface EditorDocument {
5
+ /** Canonical source format. */
6
+ readonly format: DocumentFormat;
7
+ /** Canonical source text preserved by core without parsing. */
8
+ readonly source: string;
9
+ /** Monotonic revision incremented by actual source changes. */
10
+ readonly revision: number;
11
+ /** Immutable document-level metadata. */
12
+ readonly metadata: Readonly<Record<string, unknown>>;
13
+ }
14
+ //# sourceMappingURL=document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/state/document.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjD,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC3B,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACxD"}
@@ -0,0 +1,15 @@
1
+ import type { EditorDocument } from './document.js';
2
+ /** The active projection requested from the editor. */
3
+ export type EditorMode = 'visual' | 'source' | 'markdown' | 'preview';
4
+ /** An immutable snapshot of editor state. */
5
+ export interface EditorState {
6
+ /** Canonical immutable document snapshot. */
7
+ readonly document: EditorDocument;
8
+ /** Requested editor projection. */
9
+ readonly mode: EditorMode;
10
+ /** Editing-policy state for future user-facing editing operations. */
11
+ readonly readonly: boolean;
12
+ /** Whether canonical source has changed since it was marked clean. */
13
+ readonly dirty: boolean;
14
+ }
15
+ //# sourceMappingURL=editor-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-state.d.ts","sourceRoot":"","sources":["../../src/state/editor-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtE,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CAC3B"}
@@ -0,0 +1,18 @@
1
+ import type { EditorMode } from '../state/editor-state.js';
2
+ /** Replaces the canonical document source. */
3
+ export interface ReplaceDocumentOperation {
4
+ /** Discriminator for canonical source replacement. */
5
+ readonly type: 'replace-document';
6
+ /** Replacement canonical source. */
7
+ readonly source: string;
8
+ }
9
+ /** Changes the current editor mode without changing the document. */
10
+ export interface SetModeOperation {
11
+ /** Discriminator for a requested-mode change. */
12
+ readonly type: 'set-mode';
13
+ /** Requested editor mode. */
14
+ readonly mode: EditorMode;
15
+ }
16
+ /** A document or state operation supported by Phase 1. */
17
+ export type Operation = ReplaceDocumentOperation | SetModeOperation;
18
+ //# sourceMappingURL=operation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation.d.ts","sourceRoot":"","sources":["../../src/transaction/operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,8CAA8C;AAC9C,MAAM,WAAW,wBAAwB;IACrC,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,oCAAoC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC3B;AAED,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC7B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC7B;AAED,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,wBAAwB,GAAG,gBAAgB,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { EditorMode } from '../state/editor-state.js';
2
+ import type { Operation } from './operation.js';
3
+ /** Describes the source of a state transaction. */
4
+ export type TransactionOrigin = 'user' | 'command' | 'plugin' | 'source' | 'system';
5
+ /** An immutable key/value view of opaque transaction metadata values. */
6
+ export interface TransactionMetadata {
7
+ readonly [key: string]: unknown;
8
+ }
9
+ /** Options used by an editor when creating a transaction. */
10
+ export interface TransactionOptions {
11
+ /** Identifies the system that initiated the transaction. */
12
+ readonly origin?: TransactionOrigin;
13
+ }
14
+ /**
15
+ * A mutable, single-use transaction created by `Editor.createTransaction()`.
16
+ *
17
+ * Metadata values are opaque and retain their original object identity. The
18
+ * metadata container is exposed as an immutable snapshot.
19
+ */
20
+ export interface Transaction {
21
+ /** The system that initiated this transaction. */
22
+ readonly origin: TransactionOrigin;
23
+ /** A snapshot of operations currently queued for this transaction. */
24
+ readonly operations: readonly Operation[];
25
+ /** A frozen snapshot of the transaction's opaque metadata entries. */
26
+ readonly metadata: TransactionMetadata;
27
+ /** Queues replacement of the canonical document source. */
28
+ replaceDocument(source: string): this;
29
+ /** Queues a change to the editor's requested mode. */
30
+ setMode(mode: EditorMode): this;
31
+ /** Adds or replaces an opaque metadata value. */
32
+ setMeta(key: string, value: unknown): this;
33
+ /** Returns an opaque metadata value, or undefined when absent. */
34
+ getMeta(key: string): unknown;
35
+ }
36
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/transaction/transaction.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,mDAAmD;AACnD,MAAM,MAAM,iBAAiB,GACzB,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IACxB,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;IAC1C,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,2DAA2D;IAC3D,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,sDAAsD;IACtD,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,iDAAiD;IACjD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,kEAAkE;IAClE,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@soeditor/core",
3
+ "version": "0.5.0",
4
+ "license": "MIT",
5
+ "description": "Framework-agnostic core architecture for SoEditor.",
6
+ "keywords": [
7
+ "content-editor",
8
+ "html",
9
+ "typescript"
10
+ ],
11
+ "homepage": "https://github.com/sohophp/soeditor#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/sohophp/soeditor/issues"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/sohophp/soeditor.git",
18
+ "directory": "packages/core"
19
+ },
20
+ "engines": {
21
+ "node": ">=22.14.0 <23"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public",
25
+ "provenance": true,
26
+ "registry": "https://registry.npmjs.org/"
27
+ },
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js"
37
+ }
38
+ },
39
+ "devDependencies": {
40
+ "@vitest/coverage-v8": "^3.2.4"
41
+ },
42
+ "scripts": {
43
+ "build": "vite build && tsc -p tsconfig.build.json",
44
+ "test": "vitest run",
45
+ "test:coverage": "vitest run --coverage",
46
+ "typecheck": "tsc -p tsconfig.json"
47
+ }
48
+ }