Skip to content

gerzhan/gerzhan-tpl-app-eda_by_qween_coding_agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chat Bookmarks EDA Application

Event-Driven Architecture with Mediator Topology for managing Chat Bookmarks on marketplace.

Architecture Patterns Used

  1. Hexagonal Architecture - Core domain logic isolated from infrastructure
  2. Event-Driven Architecture (EDA) with Mediator Topology
  3. Singleton Pattern - Application and Service Locator
  4. Repository Pattern - Data access abstraction
  5. Strategy Pattern - Switchable storage backends (REST API / LocalStorage)
  6. Gateway Pattern - External API communication
  7. Anti-Corruption Layer (ACL) - Two-Way Mapping for data translation
  8. Actor Model - State management with message passing
  9. Service Locator - Dependency resolution

Project Structure

src/
├── core/
│   ├── singleton/
│   │   └── Application.ts      # Main application singleton
│   └── locator/
│       └── ServiceLocator.ts   # Service locator pattern
├── domain/
│   └── entities.ts             # Domain entities and interfaces
├── infrastructure/
│   ├── gateway/
│   │   └── RestApiGateway.ts   # REST API gateway implementation
│   ├── strategy/
│   │   ├── LocalStorageStrategy.ts
│   │   └── RestApiStrategy.ts
│   ├── acl/
│   │   └── AntiCorruptionLayer.ts  # ACL with two-way mapping
│   └── mapper/
│       └── BookmarkMapper.ts   # Entity-DTO mapper
├── application/
│   └── services/
│       └── BookmarkRepositoryImpl.ts  # Repository implementation
└── ui/
    ├── mediator/
    │   └── EventMediator.ts    # Event mediator (singleton)
    ├── channels/
    │   └── EventChannel.ts     # Event channel for routing
    ├── processors/
    │   └── EventProcessors.ts  # Event processors
    ├── actors/
    │   └── Actors.ts           # Actor model implementation
    └── components/
        └── UIAdapter.ts        # Framework-agnostic UI adapter

Domain Entity: ChatBookmark

interface ChatBookmark {
  id?: string;
  title: string;
  description: string;
  isActual: boolean;
  addTime: Date;
  authorUuid: string;
}

Features

  • CRUD Operations: Create, Read, Update, Delete bookmarks
  • Optimistic Updates: UI updates immediately, syncs with backend asynchronously
  • SessionStorage: UI state persisted in browser SessionStorage
  • Strategy Switching: Toggle between REST API and LocalStorage at runtime
  • Framework Agnostic: Works with React, jQuery, Svelte, or vanilla JS

Usage Examples

Basic Initialization

import { uiAdapter } from './src/index.js';

// Initialize with LocalStorage (default)
await uiAdapter.initialize(false);

// Or initialize with REST API
await uiAdapter.initialize(true);

Subscribe to State Changes

const unsubscribe = uiAdapter.subscribe((state) => {
  console.log('Bookmarks:', state.bookmarks);
  console.log('Loading:', state.isLoading);
  console.log('Error:', state.error);
});

// Later, unsubscribe when needed
unsubscribe();

CRUD Operations

// Create
await uiAdapter.createBookmark({
  title: 'New Bookmark',
  description: 'Description here',
  isActual: true,
  addTime: new Date(),
  authorUuid: 'user-123',
});

// Update
await uiAdapter.updateBookmark('bookmark-id', {
  title: 'Updated Title',
  isActual: false,
});

// Delete
await uiAdapter.deleteBookmark('bookmark-id');

Switch Storage Strategy

// Switch to REST API
await uiAdapter.switchStorageStrategy(true);

// Switch back to LocalStorage
await uiAdapter.switchStorageStrategy(false);

Integration with UI Frameworks

React Example

import { useEffect, useState } from 'react';
import { uiAdapter, type UIState } from './src/index.js';

function BookmarkApp() {
  const [state, setState] = useState<UIState | null>(null);

  useEffect(() => {
    uiAdapter.initialize(false).then(() => {
      const unsubscribe = uiAdapter.subscribe(setState);
      return unsubscribe;
    });
  }, []);

  if (!state) return <div>Loading...</div>;

  return (
    <div>
      <button onClick={() => uiAdapter.switchStorageStrategy(true)}>
        Use REST API
      </button>
      <button onClick={() => uiAdapter.switchStorageStrategy(false)}>
        Use LocalStorage
      </button>
      
      {state.bookmarks.map(bookmark => (
        <div key={bookmark.id}>
          <h3>{bookmark.title}</h3>
          <p>{bookmark.description}</p>
        </div>
      ))}
    </div>
  );
}

jQuery Example

import { uiAdapter } from './src/index.js';

$(async () => {
  await uiAdapter.initialize(false);
  
  uiAdapter.subscribe((state) => {
    $('#bookmarks-list').empty();
    state.bookmarks.forEach(bookmark => {
      $('#bookmarks-list').append(`
        <div class="bookmark">
          <h3>${bookmark.title}</h3>
          <p>${bookmark.description}</p>
        </div>
      `);
    });
  });

  $('#add-bookmark-btn').click(async () => {
    await uiAdapter.createBookmark({
      title: $('#title').val(),
      description: $('#description').val(),
      isActual: true,
      addTime: new Date(),
      authorUuid: 'current-user',
    });
  });
});

Svelte Example

<script lang="ts">
  import { onMount } from 'svelte';
  import { uiAdapter, type UIState } from './src/index.js';

  let state: UIState | null = null;

  onMount(async () => {
    await uiAdapter.initialize(false);
    uiAdapter.subscribe(s => state = s);
  });

  async function createBookmark() {
    await uiAdapter.createBookmark({
      title: 'New',
      description: 'Desc',
      isActual: true,
      addTime: new Date(),
      authorUuid: 'user-1',
    });
  }
</script>

{#if state}
  <button on:click={createBookmark}>Add Bookmark</button>
  {#each state.bookmarks as bookmark}
    <div>{bookmark.title}</div>
  {/each}
{/if}

Event Flow

  1. User Action → UI Adapter publishes event
  2. Event Mediator routes event to appropriate processor
  3. Event Processor handles business logic via Repository
  4. Repository uses current Strategy (REST API or LocalStorage)
  5. Strategy communicates via Gateway or directly stores
  6. ACL translates between external and internal formats
  7. Result Event published back through Mediator
  8. Actors update state optimistically
  9. UI re-renders based on state changes

Installation

npm install
npm run build

License

MIT

About

Qween Coding Agent

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors