effect-ts architecture

Effect-TS 7-Layer Architecture

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "effect-ts architecture" with this command: npx skills add happenings-community/requests-and-offers/happenings-community-requests-and-offers-effect-ts-architecture

Effect-TS 7-Layer Architecture

Architecture patterns for this Holochain hApp's frontend: Service → Store → Schema → Errors → Composables → Components → Testing.

Key Reference Files

  • Service template: ui/src/lib/services/zomes/serviceTypes.service.ts

  • Store template: ui/src/lib/stores/serviceTypes.store.svelte.ts

  • Store helpers: ui/src/lib/utils/store-helpers/ (withLoadingState, createGenericCacheSyncHelper, etc.)

  • Zome helpers: ui/src/lib/utils/zome-helpers.ts (wrapZomeCallWithErrorFactory)

  • Error contexts: ui/src/lib/errors/error-contexts.ts

  • Cache service: ui/src/lib/utils/cache.svelte (CacheServiceTag, CacheServiceLive)

Service Layer Pattern

Services use Context.Tag for DI and wrapZomeCallWithErrorFactory to wrap Promise-based zome calls into Effects:

import { HolochainClientServiceTag } from '$lib/services/HolochainClientService.svelte'; import { Effect as E, Layer, Context } from 'effect'; import { wrapZomeCallWithErrorFactory } from '$lib/utils/zome-helpers'; import { MyDomainError } from '$lib/errors/my-domain.errors'; import { MY_DOMAIN_CONTEXTS } from '$lib/errors/error-contexts';

export interface MyDomainService { readonly createEntity: (input: EntityInDHT) => E.Effect<Record, MyDomainError>; // ... other methods }

export class MyDomainServiceTag extends Context.Tag('MyDomainService')< MyDomainServiceTag, MyDomainService

() {}

export const MyDomainServiceLive: Layer.Layer< MyDomainServiceTag, never, HolochainClientServiceTag

= Layer.effect( MyDomainServiceTag, E.gen(function* () { const holochainClient = yield* HolochainClientServiceTag;

const wrapZomeCall = &#x3C;T>(zomeName: string, fnName: string, payload: unknown, context: string) =>
  wrapZomeCallWithErrorFactory&#x3C;T, MyDomainError>(
    holochainClient, zomeName, fnName, payload, context, MyDomainError.fromError
  );

const createEntity = (input: EntityInDHT) =>
  wrapZomeCall('my_zome', 'create_entity', { entity: input }, MY_DOMAIN_CONTEXTS.CREATE);

return MyDomainServiceTag.of({ createEntity });

}) );

Store Layer Pattern

Stores use Svelte 5 Runes ($state() , $derived() ), import helpers from $lib/utils/store-helpers , and file extension is .store.svelte.ts :

import { withLoadingState, createGenericCacheSyncHelper, createStatusAwareEventEmitters, createUIEntityFromRecord, createStatusTransitionHelper, processMultipleRecordCollections, type LoadingStateSetter } from '$lib/utils/store-helpers'; import { CacheServiceTag, CacheServiceLive } from '$lib/utils/cache.svelte';

export const createMyDomainStore = () => E.gen(function* () { const service = yield* MyDomainServiceTag; const cacheService = yield* CacheServiceTag;

// Svelte 5 Runes for reactive state const entities: UIEntity[] = $state([]); let loading: boolean = $state(false); let error: string | null = $state(null);

const setters: LoadingStateSetter = { setLoading: (v) => { loading = v; }, setError: (v) => { error = v; } };

// Use standardized helpers const { syncCacheToState } = createGenericCacheSyncHelper({ all: entities }); const eventEmitters = createStatusAwareEventEmitters<UIEntity>('myDomain'); // ... withLoadingState(() => pipe(...)) pattern for operations });

// Store instance creation const store = pipe( createMyDomainStore(), E.provide(CacheServiceLive), E.provide(MyDomainServiceLive), E.provide(HolochainClientServiceLive), E.runSync ); export default store;

Validation

Run npx tsx .claude/skills/effect-ts-7layer-architecture/validation/architecture-check.ts ServiceType to validate a domain's architectural compliance.

9 Store Helper Functions

All imported from $lib/utils/store-helpers :

  • createUIEntityFromRecord — Entity creation from Holochain records

  • createGenericCacheSyncHelper — Cache-to-state synchronization

  • createStatusAwareEventEmitters — Type-safe event emission

  • withLoadingState — Loading/error state management

  • createStatusTransitionHelper — Status workflow (pending/approved/rejected)

  • processMultipleRecordCollections — Multi-collection response handling

  • createStandardEventEmitters — Basic CRUD event emission

  • LoadingStateSetter (type) — Setter interface for loading state

  • EntityStatus (type) — Status type for status transitions

Architecture Rules

  • Services return E.Effect<T, DomainError> , never raw Promises

  • Stores use $state() and $derived() (Svelte 5), never writable /readable

  • Store files must have .store.svelte.ts extension

  • All domain errors extend tagged error pattern with fromError static method

  • Error contexts defined in $lib/errors/error-contexts.ts

  • DI via E.provide() / E.provideService() chains

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Web3

holochain development

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

deployment automation

No summary provided by upstream source.

Repository SourceNeeds Review
General

Trunkate AI

Semantically optimizes context history and large text blocks via the Trunkate AI API. Includes proactive context pruning hooks for automated token management.

Registry SourceRecently Updated
General

Long-term Task Progress Manager

Manages multi-session, multi-stage projects by maintaining and syncing MISSION.md, PROGRESS.md, and NEXT_STEPS.md for seamless long-term progress tracking.

Registry SourceRecently Updated