Incremental Complexity 
1. Start with simple state 
StateAdapt stores can be as simple as RxJS BehaviorSubjects:
typescript
export class NameComponent {
  nameStore = adapt('Bob');
}angular-html
<h1>Hello {{ nameStore.state$ | async }}!</h1>
<button (click)="nameStore.set('Bilbo')">Change Name</button>2. Add selectors for derived state 
typescript
export class NameComponent {
  nameStore = adapt('Bob', {
    selectors: {
      yelledName: name => name.toUpperCase(), // Will be memoized
    },
  });
}angular-html
<h1>Hello {{ nameStore.state$ | async }}!</h1>
<h1>Hello {{ nameStore.yelledName$ | async }}!</h1>
<button (click)="nameStore.set('Bilbo')">Change Name</button>3. Define state changes declaratively in stores 
Maintain separation of concerns by keeping state logic together instead of scattered.
typescript
export class NameComponent {
  nameStore = adapt('Bob', {
    reverseName: name => name.split('').reverse().join(''), // [!code +]
    selectors: {
      yelledName: name => name.toUpperCase(), // Will be memoized
    },
  });
}angular-html
 <h1>Hello {{ nameStore.yelledName$ | async }}!</h1>
 <button (click)="nameStore.set('Bilbo')">Change Name</button>
 <button (click)="nameStore.reverseName()">Reverse Name</button>4. Reuse state patterns with state adapters 
If you need to reuse state logic, it's as simple as dragging it outside the adapt call into a createAdapter call.
typescript
export class NameComponent {
  nameStore = adapt('Bob', { 
  nameAdapter = createAdapter<string>()({ 
    reverseName: name => name.split('').reverse().join(''),
    selectors: {
      yelledName: name => name.toUpperCase(), // Will be memoized
    },
  });
  name1Store = adapt('Bob', this.nameAdapter); 
  name2Store = adapt('Bob', this.nameAdapter); 
}angular-html
 <h1>Hello {{ name1Store.yelledName$ | async }}!</h1>
 <button (click)="name1Store.set('Bilbo')">Change Name</button>
 <button (click)="name1Store.reverseName()">Reverse Name</button>
 <h1>Hello {{ name2Store.yelledName$ | async }}!</h1>
 <button (click)="name2Store.set('Bilbo')">Change Name</button>
 <button (click)="name2Store.reverseName()">Reverse Name</button>5. React to observable data sources 
Multiple stores might need to react to the same observable, so it needs independent annotation.
typescript
export class NameComponent {
  nameAdapter = createAdapter<string>()({
    reverseName: name => name.split('').reverse().join(''),
    concatName: (name, anotherName: string) => `${name} ${anotherName}`, 
    selectors: {
      yelledName: name => name.toUpperCase(), // Will be memoized
    },
  });
  nameFromServer$ = timer(3000).pipe(map(() => 'Joel')); 
  name1Store = adapt('Bob', this.nameAdapter); 
  name1Store = adapt('Bob', {
    adapter: this.nameAdapter, 
    sources: this.nameFromServer$, // Set state
  }); 
  name2Store = adapt('Bob', this.nameAdapter); 
  name2Store = adapt('Bob', {
    adapter: this.nameAdapter, 
    sources: {
      concatName: this.nameFromServer$, // Trigger a specific state reaction
    }, 
  }); 
}angular-html
<h1>Hello {{ name1Store.yelledName$ | async }}!</h1>
<button (click)="name1Store.set('Bilbo')">Change Name</button>
<button (click)="name1Store.reverseName()">Reverse Name</button>
<h1>Hello {{ name2Store.yelledName$ | async }}!</h1>
<button (click)="name2Store.set('Bilbo')">Change Name</button>
<button (click)="name2Store.reverseName()">Reverse Name</button>6. Share DOM event sources with multiple stores 
Don't write callback functions to imperatively change state in multiple stores. Instead, declare the DOM event as an independent source that multiple stores can react to.
typescript
export class NameComponent {
  nameAdapter = createAdapter<string>()({
    reverseName: name => name.split('').reverse().join(''),
    concatName: (name, anotherName: string) => `${name} ${anotherName}`,
    selectors: {
      yelledName: name => name.toUpperCase(), // Will be memoized
    },
  });
  resetBoth$ = source(); 
  nameFromServer$ = timer(3000).pipe(map(() => 'Joel'));
  name1Store = adapt('Bob', {
    adapter: this.nameAdapter,
    sources: this.nameFromServer$, // Set state
    sources: {
      set: this.nameFromServer$, // `set` is provided with all adapters
      reset: this.resetBoth$, // `reset` is provided with all adapters
    }, 
  });
  name2Store = adapt('Bob', {
    adapter: this.nameAdapter,
    sources: {
      concatName: this.nameFromServer$, // Trigger a specific state reaction
      reset: this.resetBoth$, // `reset` is provided with all adapters
    },
  });
}angular-html
 <h1>Hello {{ name1Store.yelledName$ | async }}!</h1>
 <button (click)="name1Store.set('Bilbo')">Change Name</button>
 <button (click)="name1Store.reverseName()">Reverse Name</button>
 <h1>Hello {{ name2Store.yelledName$ | async }}!</h1>
 <button (click)="name2Store.set('Bilbo')">Change Name</button>
 <button (click)="name2Store.reverseName()">Reverse Name</button>
 <button (click)="resetBoth$.next()">Reset Both</button>7. Select state from multiple stores 
typescript
export class NameComponent {
  nameAdapter = createAdapter<string>()({
    reverseName: name => name.split('').reverse().join(''),
    concatName: (name, anotherName: string) => `${name} ${anotherName}`,
    selectors: {
      yelledName: name => name.toUpperCase(), // Will be memoized
    },
  });
  resetBoth$ = source();
  nameFromServer$ = timer(3000).pipe(map(() => 'Joel'));
  name1Store = adapt('Bob', {
    adapter: this.nameAdapter,
    sources: {
      set: this.nameFromServer$, // `set` is provided with all adapters
      reset: this.resetBoth$, // `reset` is provided with all adapters
    },
  });
  name2Store = adapt('Bob', {
    adapter: this.nameAdapter,
    sources: {
      concatName: this.nameFromServer$, // Trigger a specific state reaction
      reset: this.resetBoth$, // `reset` is provided with all adapters
    },
  });
  bothBobs$ = joinStores({
    name1: this.name1Store, 
    name2: this.name2Store, 
  })({
    bothBobs: s => s.name1 === 'Bob' && s.name2 === 'Bob', 
  })().bothBobs$; 
}angular-html
 <h1>Hello {{ name1Store.yelledName$ | async }}!</h1>
 <button (click)="name1Store.set('Bilbo')">Change Name</button>
 <button (click)="name1Store.reverseName()">Reverse Name</button>
 <h1>Hello {{ name2Store.yelledName$ | async }}!</h1>
 <button (click)="name2Store.set('Bilbo')">Change Name</button>
 <button (click)="name2Store.reverseName()">Reverse Name</button>
 <button (click)="resetBoth$.next()">Reset Both</button>
 <h2 *ngIf="bothBobs$ | async">Hello Bobs!</h2>