All files / backend/src/sync sync-factory.ts

9.09% Statements 1/11
0% Branches 0/9
50% Functions 1/2
9.09% Lines 1/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108                                                                                                                  9x                                                                                                    
/**
 * Sync Factory
 *
 * Factory for creating sync service instances based on publisher configuration type.
 * Routes to the appropriate sync implementation (folder, github, sysgit).
 */
 
import type { PublConf } from '@quiqr/types';
import type { PathHelper } from '../utils/path-helper.js';
import type { OutputConsole, WindowAdapter } from '../adapters/types.js';
import type { ConfigurationDataProvider } from '../services/configuration/index.js';
import type { Embgit } from '../embgit/embgit.js';
import type { AppContainer } from '../config/container.js';
import { FolderSync } from './folder/folder-sync.js';
import { GithubSync } from './github/github-sync.js';
import { SysgitSync } from './sysgit/sysgit-sync.js';
import { GitSync } from './git/git-sync.js';
 
/**
 * Generic sync service interface
 * All sync implementations must implement this interface
 */
export interface SyncService {
  actionDispatcher(action: string, parameters?: unknown): Promise<unknown>;
}
 
/**
 * Progress callback for streaming sync progress via SSE
 */
export type SyncProgressCallback = (message: string, progress: number) => void;
 
/**
 * Dependencies required by sync services
 */
export interface SyncServiceDependencies {
  pathHelper: PathHelper;
  outputConsole: OutputConsole;
  windowAdapter: WindowAdapter;
  configurationProvider: ConfigurationDataProvider;
  embgit: Embgit;
  container: AppContainer;
  workspaceKey?: string; // Optional - provided when creating publisher instance
  /** Optional callback for streaming progress updates (used by SSE endpoints) */
  progressCallback?: SyncProgressCallback;
}
 
/**
 * SyncFactory creates sync service instances based on publisher configuration
 */
export class SyncFactory {
  private dependencies?: SyncServiceDependencies;
 
  /**
   * Set dependencies for sync services
   * This should be called once during app initialization
   */
  setDependencies(dependencies: SyncServiceDependencies): void {
    this.dependencies = dependencies;
  }
 
  /**
   * Get a sync service instance for the given publisher configuration
   *
   * @param publisherConfig - The publisher configuration (folder, github, or sysgit)
   * @param siteKey - The site key
   * @param workspaceKey - The workspace key
   * @param progressCallback - Optional callback for streaming progress (overrides default)
   * @returns A sync service instance
   * @throws Error if the sync type is not implemented or dependencies not set
   */
  getPublisher(
    publisherConfig: PublConf,
    siteKey: string,
    workspaceKey: string,
    progressCallback?: SyncProgressCallback
  ): SyncService {
    if (!this.dependencies) {
      throw new Error('SyncFactory dependencies not set. Call setDependencies() first.');
    }
 
    // Create dependencies with optional progress callback override and workspaceKey
    const deps: SyncServiceDependencies = {
      ...this.dependencies,
      workspaceKey,
      progressCallback: progressCallback ?? this.dependencies.progressCallback,
    };
 
    const type = publisherConfig.type;
 
    switch (type) {
      case 'folder':
        return new FolderSync(publisherConfig, siteKey, deps);
 
      case 'github':
        return new GithubSync(publisherConfig, siteKey, deps);
 
      case 'sysgit':
        return new SysgitSync(publisherConfig, siteKey, deps);
 
      case 'git':
        return new GitSync(publisherConfig, siteKey, deps);
 
      default:
        throw new Error(`Unknown sync type: ${type}`);
    }
  }
}