Skip to main content
Syncer is Sonamu’s automatic generation system. It detects file changes, automatically generates necessary code, and synchronizes to target projects (web, app, etc.).

What is Syncer?

File Change Detection

Track Entity, Model, Types file changesEfficient checksum-based detection

Auto Code Generation

Generate types, schemas, API clientsTemplate-based generation

HMR Support

Real-time reflection during developmentFile invalidation and reload

Multi-Target Sync

Sync to web, app, and other projectsAutomatic file copying

Syncer Operation Flow

Watched File Patterns

File patterns that Syncer tracks for changes:
File TypePatternPurpose
Entitysrc/application/**/*.entity.jsonData structure definition
Typessrc/application/**/*.types.tsType definitions
Modelsrc/application/**/*.model.tsBusiness logic
Framesrc/application/**/*.frame.tsFrame logic
Functionssrc/application/**/*.functions.tsUtility functions
Generatedsrc/application/sonamu.generated.tsGenerated base file
Configsrc/sonamu.config.tsSonamu configuration
Workflowsrc/application/**/*.workflow.tsWorkflow definitions
i18nsrc/i18n/**/*.tsInternationalization files
File patterns: Managed in file-patterns.ts, change detection via checksum

Manual Synchronization

You can manually sync without the development server.
# Full sync
pnpm sonamu sync

# Sync only changed files
pnpm sonamu sync --check
Execution result:
πŸ”„ Syncing files...
βœ… Generated: sonamu.generated.ts
βœ… Generated: sonamu.generated.sso.ts
βœ… Copied: web/src/services/user/user.types.ts
βœ… Copied: web/src/services/sonamu.generated.ts
βœ… Generated: services.generated.ts
βœ… Generated: sonamu.generated.http
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  All files are synced!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Automatic Synchronization (HMR)

During development server runtime, file changes are automatically detected and synchronized.
# Start development server
pnpm dev

# File changes are auto-synced
# - user.entity.json change β†’ Type regeneration
# - user.model.ts change β†’ API client regeneration
HMR log example:
πŸ”„ Invalidated:
- src/application/user/user.model.ts (with 5 APIs)
- src/application/user/user.types.ts

βœ… Generated: sonamu.generated.sso.ts
βœ… Copied: web/src/services/user/user.types.ts
βœ… Generated: services.generated.ts

✨ HMR completed in 234ms

Syncer Events

Syncer emits events as an EventEmitter.
import { Sonamu } from "sonamu";

// Subscribe to HMR completed event
Sonamu.syncer.eventEmitter.on("onHMRCompleted", () => {
  console.log("βœ… HMR completed!");
  // Perform additional tasks...
});
Event types:
EventWhen TriggeredUse Case
onHMRCompletedHMR completionTrigger follow-up tasks

Syncer Actions

Different actions execute based on file change type.

1. Entity Change (handleTruthSourceChanges)

Regenerates schemas when Entity file changes. Trigger: *.entity.json file change Actions:
  1. Reload EntityManager
  2. Generate *.types.ts for new Entity
  3. Generate schema files:
    • sonamu.generated.ts
    • sonamu.generated.sso.ts
  4. Copy files to targets
// Syncer internal logic
async handleTruthSourceChanges(diffGroups, diffTypes) {
  await EntityManager.reload();
  
  // Generate new Entity type file
  if (entity.parentId === undefined && !(await exists(typeFilePath))) {
    await generateTemplate("init_types", { entityId });
  }
  
  // Generate schemas
  await SyncerActions.actionGenerateSchemas();
}

2. Types/Functions/Generated Change

Copies type files to targets when they change. Trigger: *.types.ts, *.functions.ts, *.generated.ts change Actions:
  1. Collect changed file list
  2. Copy to each target (web, app)
  3. Transform sonamu import to ./sonamu.shared
// Import transformation on copy
// Before (api)
import { BaseModelClass } from "sonamu";

// After (web/app)
import { BaseModelClass } from "./sonamu.shared";
sonamu.shared.ts: Since web/app don’t have the sonamu package, common utilities are provided via a shared file.

3. Model/Frame Change

Regenerates API clients when Model file changes. Trigger: *.model.ts, *.frame.ts change Actions:
  1. Reload Model, Types, APIs
  2. Generate API client (services.generated.ts)
  3. Generate HTTP test file (sonamu.generated.http)
  4. Regenerate SSR files (queries.generated.ts, entry-server.generated.tsx)
async handleImplementationChanges(diffGroups) {
  // Reload modules
  await this.autoloadModels();
  await this.autoloadTypes();
  await this.autoloadApis();
  
  // Generate services
  await SyncerActions.actionGenerateServices(params);
  await SyncerActions.actionGenerateHttps();
  
  // Regenerate SSR files
  await SyncerActions.actionGenerateSsr();
}

4. Config Change

Synchronizes environment variables when config file changes. Trigger: sonamu.config.ts change Actions:
  1. Create/update .sonamu.env file
  2. Copy to each target
web/.sonamu.env
API_HOST=localhost
API_PORT=3000

5. Workflow Change

Reloads when workflow file changes. Trigger: *.workflow.ts change Actions: Reload and sync workflows

6. i18n Change

Regenerates SD file when i18n file changes. Trigger: src/i18n/**/*.ts change Actions:
  1. Copy Locale files to targets
  2. Generate sd.generated.ts (api, web, app)

7. SSR Config Change

Immediately reloads when SSR route config files change. Trigger: src/ssr/**/*.ts change Actions:
  1. Invalidate changed file (HMR)
  2. Reload all SSR routes (autoloadSSRRoutes)
  3. Emit HMR completed event
SSR config changes are not part of checksum-based sync. The watcher detects them directly and processes them through a separate path.

Checksum-Based Change Detection

Syncer stores file checksums for efficient change detection.
sonamu.lock
[
  { "path": "src/application/user/user.entity.json", "checksum": "a7f4b3e2c1d5..." },
  { "path": "src/application/user/user.types.ts", "checksum": "c3d1e4f5a6b7..." },
  { "path": "src/application/user/user.model.ts", "checksum": "e5f6a7b8c9d0..." }
]
How it works:
  1. Calculate SHA-1 hash of file content
  2. Compare with stored checksum
  3. Consider changed if different
  4. Update checksum after sync
Advantages:
  • Fast change detection (no file content comparison needed)
  • Accurate change tracking (unaffected by timestamp)
  • Handle multiple file changes simultaneously

Syncer API

Syncer can be used programmatically.

Manual Synchronization

import { Sonamu } from "sonamu";

// Full sync
await Sonamu.syncer.sync();

// Sync specific file
await Sonamu.syncer.syncFromWatcher(
  "change",
  "/path/to/user.entity.json"
);

Template Generation

// Create Entity
await Sonamu.syncer.createEntity({
  entityId: "User",
  table: "users",
  props: [
    { name: "id", type: "integer" },
    { name: "email", type: "string" },
  ],
  subsets: {
    A: ["id", "email"],
  },
  enums: {},
  indexes: [],
});

// Generate template
await Sonamu.syncer.generateTemplate(
  "model",
  { entityId: "User" },
  { overwrite: false }
);

// Render custom template
const files = await Sonamu.syncer.renderTemplate(
  "view_list",
  { entityId: "User" }
);

Module Loading

// Load types
await Sonamu.syncer.autoloadTypes();
console.log(Sonamu.syncer.types);

// Load Models
await Sonamu.syncer.autoloadModels();
console.log(Sonamu.syncer.models);

// Load APIs
await Sonamu.syncer.autoloadApis();
console.log(Sonamu.syncer.apis);

// Load Workflows
await Sonamu.syncer.autoloadWorkflows();
console.log(Sonamu.syncer.workflows);

Syncer Configuration

You can configure Syncer behavior in sonamu.config.ts.
api/src/sonamu.config.ts
export default {
  sync: {
    // Target projects for synchronization
    targets: ["web", "app"],
  },
  
  // API server settings (used for environment variable generation)
  server: {
    baseUrl: "http://localhost:3000",
    listen: {
      host: "localhost",
      port: 3000,
    },
  },
};

Development Workflow

Typical development flow using Syncer:
1

Start Development Server

pnpm dev
Syncer watches for file changes.
2

Define Entity

Define Entity in Sonamu UI or modify .entity.json file.Auto-executed:
  • Generate *.types.ts
  • Update sonamu.generated.ts
  • Update sonamu.generated.sso.ts
  • Copy files to targets
3

Write Model

Write business logic in Model and add @api decorator.Auto-executed:
  • Update services.generated.ts
  • Update sonamu.generated.http
  • Update SSR files
4

Frontend Development

Develop UI using generated API clients and Types.
import { useUsers } from "@/services/services.generated";
import type { User } from "@/services/user/user.types";

function UserList() {
  const { data } = useUsers();
  // ...
}
5

Real-time Reflection

Modifying Model or Entity reflects immediately via HMR.Check changes without browser refresh!

Troubleshooting

When Syncer Doesn’t Work

Check:
  1. Confirm development server is running
  2. Verify file matches watched patterns
  3. Delete checksum file and retry
rm sonamu.lock
pnpm sonamu sync
Check:
  1. Verify sync.targets in sonamu.config.ts
  2. Confirm target directory exists
  3. Create src/services/ directory in target
mkdir -p web/src/services
mkdir -p app/src/services
Optimization methods:
  1. Use latest Node.js version (v22+)
  2. Use SSD (HDD is slow)
  3. Exclude unnecessary files
  4. Separate TypeScript projects (monorepo)
Cause: sonamu import not transformed to ./sonamu.sharedSolution:
# Force re-sync
pnpm sonamu sync --force

Next Steps