npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@everystate/angular

v1.0.1

Published

EveryState Angular adapter: usePath, useIntent, useWildcard, useAsync - bridges the reactive store to Angular signals

Downloads

221

Readme

@everystate/angular

Angular adapter for EveryState. Four functions that bridge the reactive store to Angular's signal-based reactivity system. ~30 lines, zero dependencies beyond Angular and the core store.

npm install @everystate/angular @everystate/core

Peer dependencies: @angular/core >=17.0.0 and @everystate/core >=1.0.5.

Why an Angular Adapter?

Angular has dependency injection, services, RxJS, and signals. You might ask: does it need an adapter?

Yes. Without one, every team reinvents the bridge differently. Some try RxJS subjects. Some try Zone.js tricks. Some give up. The adapter standardizes the pattern and gives Angular the same first-class EveryState integration that React and Vue already have.

What it eliminates

  • @Input() / @Output() drilling - Components read from the store directly. No props, no event emitters, no forwarding.
  • BehaviorSubject + service methods - Logic lives in subscribers, not service methods welded to Angular.
  • NgRx ceremony - Actions, reducers, effects, selectors, feature modules. EveryState: store + subscribers + adapter.
  • State fragmentation - No more deciding between class properties, BehaviorSubjects, NgRx, or signals. It's a dot-path. Always.

The API

usePath(store, path)

Subscribe to a dot-path. Returns a read-only Angular signal that updates when the store value changes. Only components reading this signal re-render - no Zone.js overhead.

import { usePath } from '@everystate/angular';

@Component({
  selector: 'app-header',
  standalone: true,
  template: `<span>{{ count() }} tasks</span>`
})
export class HeaderComponent {
  count: Signal<number>;
  constructor(private store: StoreService) {
    this.count = usePath<number>(store, 'state.taskCount');
  }
}

useIntent(store, path)

Returns a stable function that publishes a value to a path.

import { useIntent } from '@everystate/angular';

@Component({
  selector: 'app-task-input',
  standalone: true,
  template: `
    <input [(ngModel)]="text" (keydown.enter)="addTask()" />
    <button (click)="addTask()">Add</button>
  `
})
export class TaskInputComponent {
  text = '';
  private add: (text: string) => void;
  constructor(private store: StoreService) {
    this.add = useIntent(store, 'intent.addTask');
  }
  addTask(): void {
    this.add(this.text);
    this.text = '';
  }
}

useWildcard(store, path)

Subscribe to a wildcard path. Returns a read-only signal that updates when any child changes.

const user = useWildcard(store, 'state.user.*');
// Re-renders when state.user.name, state.user.email, etc. change

useAsync(store, path)

Async data fetching with automatic status tracking. Auto-aborts previous in-flight requests.

const { data, status, error, execute, cancel } = useAsync(store, 'users');
execute((signal) => fetch('/api/users', { signal }).then(r => r.json()));

The StoreService Pattern

The adapter provides functions, not an Angular service. You create the service:

@Injectable({ providedIn: 'root' })
export class StoreService {
  private store = createEveryState({
    state: { tasks: [], taskCount: 0, filter: 'all' },
    derived: { tasks: { filtered: [] } }
  });

  get = this.store.get.bind(this.store);
  set = this.store.set.bind(this.store);
  subscribe = this.store.subscribe.bind(this.store);
  setAsync = this.store.setAsync.bind(this.store);
  cancel = this.store.cancel.bind(this.store);

  constructor() {
    // Business logic in subscribers, not component methods
    this.store.subscribe('intent.addTask', (text: string) => {
      const t = String(text || '').trim();
      if (!t) return;
      const tasks = this.store.get('state.tasks') || [];
      const next = [...tasks, { id: Date.now().toString(36), text: t, completed: false }];
      this.store.set('state.tasks', next);
      this.store.set('state.taskCount', next.length);
    });
  }
}

Why separate the adapter from the service? Because the store logic is identical across React, Vue, and Angular. Only the bridge changes.

Angular-Specific Advantages

Signals are the perfect bridge

Angular 17+ signals provide fine-grained reactivity. usePath creates a signal and subscribes to the store. Changes propagate surgically.

  • No Zone.js overhead: Signals bypass zone-based change detection
  • Surgical updates: Only components consuming a specific signal re-render
  • Zoneless-ready: Angular 19+ without Zone.js works identically

DI is genuinely excellent

Angular's DI is arguably a stronger integration point than React's Context. The framework wants you to inject singletons, and that's exactly what the store is. StoreService fits naturally into @Injectable({ providedIn: 'root' }).

Clean templates

Before:

<app-task-list [tasks]="tasks" (toggle)="toggle($event)" (delete)="delete($event)">

After:

<app-task-list></app-task-list>

Testing without Angular

test('adding a task increments taskCount', () => {
  const service = new StoreService();
  service.set('intent.addTask', 'test task');
  expect(service.get('state.taskCount')).toBe(1);
});

No TestBed. No ComponentFixture. No fakeAsync. Just state in, state out.

Comparison to NgRx

NgRx: actions + reducers + effects + selectors + feature modules. Each is a separate file, concept, and thing to name.

EveryState: intents published to subscribers. Subscribers read and write state directly. Derived state is another subscription, not a separate selector abstraction.

For teams that need strict guardrails, NgRx remains solid. For teams that want the same separation of concerns with fewer moving parts, EveryState offers a lighter path.

Documentation

Full documentation available at everystate.dev.

Cross-Framework Story

The same store code runs unchanged across Angular, React, Solid, and Vue:

| Framework | Bridge | Read | Write | |-----------|--------|------|-------| | Angular | signal() + subscribe() | usePath(store, path) | useIntent(store, path) | | React | useSyncExternalStore() | usePath(path) | useIntent(path) | | Solid | createSignal() + subscribe() | usePath(store, path) | useIntent(store, path) | | Vue | ref() + subscribe() | usePath(path) | useIntent(path) |

The store code, intent handlers, and derived state are identical. Only the 3-line bridge function changes per framework.

Ecosystem

| Package | Description | License | |---|---|---| | @everystate/aliases | Ergonomic single-character and short-name DOM aliases for vanilla JS | MIT | | @everystate/angular | Angular adapter: usePath, useIntent, useWildcard, useAsync - bridges store to Angular signals | MIT | | @everystate/core | Path-based state management with wildcard subscriptions and async support. Core state engine (you are here). | MIT | | @everystate/css | Reactive CSSOM engine: design tokens, typed validation, WCAG enforcement, all via path-based state | MIT | | @everystate/examples | Example applications and patterns | MIT | | @everystate/perf | Performance monitoring overlay | MIT | | @everystate/react | React hooks adapter: usePath, useIntent, useAsync hooks and EventStateProvider | MIT | | @everystate/renderer | Direct-binding reactive renderer: bind-*, set, each attributes. Zero build step | MIT | | @everystate/router | SPA routing as state | MIT | | @everystate/solid | Solid adapter: usePath, useIntent, useWildcard, useAsync - bridges store to Solid signals | MIT | | @everystate/test | Event-sequence testing for UIstate stores. Zero dependency. | MIT | | @everystate/types | Typed dot-path autocomplete for EveryState stores (you are here) | MIT | | @everystate/view | State-driven view: DOMless resolve + surgical DOM projector. View tree as first-class state | MIT | | @everystate/vue | Vue 3 composables adapter: provideStore, usePath, useIntent, useWildcard, useAsync | MIT |

License

MIT (c) Ajdin Imsirovic