CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ckeditor--ckeditor5-autosave

Autosave feature for CKEditor 5 that automatically saves editor content when changes occur.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

CKEditor 5 Autosave

CKEditor 5 Autosave is a plugin that automatically saves editor content when changes occur. It provides configurable debouncing, integration with CKEditor 5's pending actions system, and support for both callback and adapter-based save implementations.

Package Information

  • Package Name: @ckeditor/ckeditor5-autosave
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install ckeditor5 (this plugin is part of the main ckeditor5 package)

Core Imports

import { Autosave } from '@ckeditor/ckeditor5-autosave';

For type definitions:

import { Autosave, type AutosaveConfig, type AutosaveAdapter } from '@ckeditor/ckeditor5-autosave';

Basic Usage

Configuration-based Usage

import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic';
import { Autosave } from '@ckeditor/ckeditor5-autosave';

ClassicEditor
  .create(document.querySelector('#editor'), {
    plugins: [Autosave, /* other plugins */],
    autosave: {
      save(editor) {
        // Must return a promise
        return fetch('/save', {
          method: 'POST',
          body: JSON.stringify({ content: editor.getData() }),
          headers: { 'Content-Type': 'application/json' }
        });
      },
      waitingTime: 2000 // Wait 2 seconds after last change (default: 1000ms)
    }
  })
  .then(editor => {
    // Access autosave plugin
    const autosave = editor.plugins.get('Autosave');
    console.log(autosave.state); // 'synchronized', 'waiting', 'saving', or 'error'
  });

Adapter-based Usage

import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic';
import { Autosave, type AutosaveAdapter } from '@ckeditor/ckeditor5-autosave';

class CustomSaveAdapter implements AutosaveAdapter {
  save(editor) {
    return new Promise(resolve => {
      // Custom save logic
      localStorage.setItem('editor-content', editor.getData());
      setTimeout(resolve, 100);
    });
  }
}

ClassicEditor
  .create(document.querySelector('#editor'), {
    plugins: [Autosave, /* other plugins */]
  })
  .then(editor => {
    const autosave = editor.plugins.get('Autosave');
    autosave.adapter = new CustomSaveAdapter();
  });

Manual Save

// Trigger manual save
await editor.plugins.get('Autosave').save();

State Monitoring

const autosave = editor.plugins.get('Autosave');

// Monitor save state changes
autosave.on('change:state', () => {
  switch (autosave.state) {
    case 'synchronized':
      console.log('All changes saved');
      break;
    case 'waiting':
      console.log('Waiting to save changes...');
      break;
    case 'saving':
      console.log('Saving in progress...');
      break;
    case 'error':
      console.log('Save failed, will retry...');
      break;
  }
});

Core Types

// Core CKEditor 5 types used by Autosave plugin
interface Editor {
  readonly model: {
    readonly document: ModelDocument;
  };
  readonly config: EditorConfig;
  readonly plugins: PluginCollection;
  getData(): string;
}

abstract class Plugin {
  readonly editor: Editor;
  constructor(editor: Editor);
  init?(): void;
  destroy?(): void;
}

interface PendingActions extends Plugin {
  add(message: string): PendingAction;
  remove(action: PendingAction): void;
}

interface PendingAction {
  readonly message: string;
}

interface ModelDocument {
  readonly version: number;
}

interface PluginCollection {
  get<T extends Plugin>(plugin: string | { new(...args: any[]): T }): T;
}

interface EditorConfig {
  get(configName: string): any;
  autosave?: AutosaveConfig;
}

Capabilities

Autosave Plugin

The main plugin class that handles automatic saving of editor content.

class Autosave extends Plugin {
  /** Plugin identifier */
  static get pluginName(): 'Autosave';
  
  /** Marks this as an official CKEditor plugin */
  static get isOfficialPlugin(): true;
  
  /** Required plugin dependencies */
  static get requires(): [typeof PendingActions];
  
  /** Custom save adapter instance */
  adapter?: AutosaveAdapter;
  
  /** Current plugin state - observable and readonly */
  readonly state: 'synchronized' | 'waiting' | 'saving' | 'error';
  
  /** Initialize the plugin */
  constructor(editor: Editor);
  
  /** Set up event listeners and start autosave functionality */
  init(): void;
  
  /** Clean up resources when plugin is destroyed */
  destroy(): void;
  
  /** Manually trigger a save operation */
  save(): Promise<void>;
}

Save Adapter Interface

Interface for implementing custom save adapters.

interface AutosaveAdapter {
  /**
   * Save method called when editor data changes
   * @param editor - The editor instance containing the data to save
   * @returns Promise that resolves when save operation completes
   */
  save(editor: Editor): Promise<unknown>;
}

Configuration Interface

Configuration options for the autosave feature.

interface AutosaveConfig {
  /**
   * Callback function executed when data needs to be saved.
   * Must return a promise that resolves when save operation completes.
   */
  save?(editor: Editor): Promise<unknown>;
  
  /**
   * Minimum time in milliseconds to wait after last change before saving.
   * @default 1000
   */
  waitingTime?: number;
}

Plugin Behavior

The Autosave plugin operates with the following behavior:

  • Automatic Triggering: Listens to editor.model.document#change:data events to detect content changes
  • Debouncing: Uses configurable waitingTime (default 1000ms) to avoid excessive save calls
  • Browser Integration: Listens to window#beforeunload events to save before page unload
  • Pending Actions: Integrates with CKEditor 5's pending actions system to track save operations
  • State Management: Maintains observable state: synchronized, waiting, saving, or error
  • Error Handling: Automatically retries failed saves with exponential backoff
  • Dual Save Methods: Supports both configuration-based and adapter-based save implementations

States

The plugin maintains four distinct states:

  • synchronized: All changes have been successfully saved
  • waiting: Plugin is waiting for the debounce period before initiating save
  • saving: Save operation is currently in progress
  • error: Save operation failed, plugin will automatically retry

Integration Requirements

To use the Autosave plugin:

  1. Include in plugins array: Add Autosave to your editor's plugins configuration
  2. Provide save method: Either set config.autosave.save or assign an adapter to the plugin instance
  3. Handle promises: Save functions must return promises that resolve when the operation completes
  4. Error handling: Save functions should reject promises or throw errors for failed operations

Editor Types

The plugin extends the CKEditor 5 type system:

// Adds Autosave to the plugins map
declare module '@ckeditor/ckeditor5-core' {
  interface PluginsMap {
    Autosave: Autosave;
  }
}

docs

index.md

tile.json