Files
upstream-mirror 702cc698a7
Some checks failed
Build & Test / Analyze (javascript, affine) (push) Failing after 4s
Build & Test / Analyze (typescript, affine) (push) Failing after 3s
Build & Test / Rust test filter (push) Failing after 4s
Build & Test / Check yarn binary (push) Failing after 3s
Build & Test / E2E BlockSuite Test (3) (push) Failing after 3s
Build & Test / Analyze (javascript, blocksuite) (push) Failing after 3s
Build & Test / Analyze (typescript, blocksuite) (push) Failing after 3s
Build & Test / Mobile native build filter (push) Failing after 3s
Build & Test / E2E BlockSuite Test (1) (push) Failing after 4s
Build & Test / E2E BlockSuite Test (2) (push) Failing after 4s
Build & Test / E2E Mobile Test (1) (push) Failing after 3s
Build & Test / Unit Test (1) (push) Has been skipped
Build & Test / Unit Test (2) (push) Has been skipped
Build & Test / Unit Test (3) (push) Has been skipped
Build & Test / Unit Test (4) (push) Has been skipped
Build & Test / Unit Test (5) (push) Has been skipped
Build & Test / Native Unit Test (push) Has been skipped
Build & Test / E2E BlockSuite Test (4) (push) Failing after 3s
Build & Test / E2E BlockSuite Test (5) (push) Failing after 3s
Build & Test / E2E BlockSuite Cross Browser Test (push) Failing after 3s
Build & Test / E2E Mobile Test (2) (push) Failing after 3s
Build & Test / Build AFFiNE native (x86_64-unknown-linux-gnu) (push) Failing after 3s
Build & Test / Build Server native (push) Failing after 3s
Build & Test / Check Git Status (push) Has been skipped
Build & Test / Server Test (0, 4) (push) Has been skipped
Build & Test / Server Test (1, 4) (push) Has been skipped
Build & Test / Server Test (2, 4) (push) Has been skipped
Build & Test / Server Test (3, 4) (push) Has been skipped
Build & Test / Server Test with Elasticsearch (push) Has been skipped
Build & Test / Build @affine/electron renderer (push) Failing after 3s
Build & Test / Copilot test filter (push) Failing after 4s
Build & Test / Lint Rust (push) Has been skipped
Build & Test / Server Test with Embedded Search (push) Has been skipped
Build & Test / Server Test with Manticore Search (push) Has been skipped
Build & Test / Server E2E Test (push) Has been skipped
Build & Test / Cloud Desktop E2E Test (push) Has been skipped
Build & Test / Cloud E2E Test 1/2 (push) Has been skipped
Build & Test / Cloud E2E Test 2/2 (push) Has been skipped
Build & Test / Build Android app (push) Has been skipped
Build & Test / Test Android app (push) Has been skipped
Build & Test / Run native tests (push) Has been skipped
Build & Test / Server Copilot Api Test (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (1, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (2, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (3, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (4, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (5, 5) (push) Has been skipped
Release / Canary Gate (push) Has been skipped
Build & Test / Build AFFiNE native (aarch64-apple-darwin) (push) Has been cancelled
Build & Test / Lint (push) Has been cancelled
Build & Test / Typecheck (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-apple-darwin) (push) Has been cancelled
Build & Test / Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true) (push) Has been cancelled
Build & Test / Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true) (push) Has been cancelled
Build & Test / E2E Test (1) (push) Has been cancelled
Build & Test / E2E Test (2) (push) Has been cancelled
Build & Test / E2E Test (3) (push) Has been cancelled
Build & Test / E2E Test (4) (push) Has been cancelled
Build & Test / E2E Test (5) (push) Has been cancelled
Build & Test / Build AFFiNE native (aarch64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, x64, x86_64-apple-darwin, false) (push) Has been cancelled
Build & Test / 3, 2, 1 Launch (push) Has been cancelled
Build & Test / Build iOS app (push) Has been cancelled
Copilot Test Automatically / Setup Test (push) Failing after 2s
Release / Prepare (push) Failing after 1s
Release / Release Mobile (push) Has been skipped
Release / Release Desktop (push) Has been skipped
Release / Release Docker Image (push) Has been skipped
Release / Release Cloud (push) Has been skipped
snapshot of https://github.com/toeverything/AFFiNE.git (canary, 2026-09-16; blobs > 131072B omitted)
2026-09-16 04:01:20 +05:00
..

@blocksuite/affine-ext-loader

Blocksuite extension loader system for AFFiNE, providing a structured way to manage and load extensions in different contexts.

Usage

Basic Extension Provider

import { BaseExtensionProvider } from '@blocksuite/affine-ext-loader';
import { z } from 'zod';

// Create a custom provider with options
class MyProvider extends BaseExtensionProvider<
  'my-scope',
  { enabled: boolean }
> {
  name = 'MyProvider';

  schema = z.object({
    enabled: z.boolean(),
  });

  setup(context: Context<'my-scope'>, options?: { enabled: boolean }) {
    super.setup(context, options);
    // Custom setup logic
  }
}

Store Extensions

import {
  StoreExtensionProvider,
  StoreExtensionManager,
} from '@blocksuite/affine-ext-loader';
import { z } from 'zod';

// Create a store provider with custom options
class MyStoreProvider extends StoreExtensionProvider<{ cacheSize: number }> {
  override name = 'MyStoreProvider';

  override schema = z.object({
    cacheSize: z.number().min(0),
  });

  override setup(
    context: StoreExtensionContext,
    options?: { cacheSize: number }
  ) {
    super.setup(context, options);
    context.register([Ext1, Ext2, Ext3]);
  }
}

// Create and use the store extension manager
const manager = new StoreExtensionManager([MyStoreProvider]);
manager.configure(MyStoreProvider, { cacheSize: 100 });
const extensions = manager.get('store');

View Extensions

import {
  ViewExtensionProvider,
  ViewExtensionManager,
} from '@blocksuite/affine-ext-loader';
import { z } from 'zod';

// Create a view provider with custom options
class MyViewProvider extends ViewExtensionProvider<{ theme: string }> {
  override name = 'MyViewProvider';

  override schema = z.object({
    theme: z.enum(['light', 'dark']),
  });

  override setup(context: ViewExtensionContext, options?: { theme: string }) {
    super.setup(context, options);

    context.register([CommonExt]);
    if (context.scope === 'page') {
      context.register([PageExt]);
    } else if (context.scope === 'edgeless') {
      context.register([EdgelessExt]);
    }
    if (options?.theme === 'dark') {
      context.register([DarkModeExt]);
    }
  }

  // Override effect to run one-time initialization logic
  override effect() {
    // This will only run once per provider class
    console.log('Initializing MyViewProvider');
    // Register lit elements
    this.registerLitElements();
  }
}

// Create and use the view extension manager
const manager = new ViewExtensionManager([MyViewProvider]);
manager.configure(MyViewProvider, { theme: 'dark' });

// Get extensions for different view scopes
const pageExtensions = manager.get('page');
const edgelessExtensions = manager.get('edgeless');

One-time Initialization with Effect

View extensions support one-time initialization through the effect method. This method is called automatically during setup, but only once per provider class. It's useful for:

  • Initializing global state
  • Registering lit elements
  • Setting up shared resources
class MyViewProvider extends ViewExtensionProvider {
  override effect() {
    // This will only run once, even if multiple instances are created
    initializeGlobalState();
    registerLitElements();
    setupGlobalEventListeners();
  }
}

Available View Scopes

The view extension system supports the following scopes:

  • page - Standard page view
  • edgeless - Edgeless (whiteboard) view
  • preview-page - Page preview view
  • preview-edgeless - Edgeless preview view
  • mobile-page - Mobile page view
  • mobile-edgeless - Mobile edgeless view

Extension Configuration

Extensions can be configured using the configure method:

// Set configuration directly
manager.configure(MyProvider, { enabled: true });

// Update configuration using a function
manager.configure(MyProvider, prev => {
  if (!prev) return prev;
  return {
    ...prev,
    enabled: !prev.enabled,
  };
});

// Remove configuration
manager.configure(MyProvider, undefined);

Dependency Injection

Both store and view extension managers support dependency injection:

// Access the manager through the di container
const viewManager = std.get(ViewExtensionManagerIdentifier);
const pagePreviewExtension = viewManager.get('preview-page');