Socket
Book a DemoInstallSign in
Socket

agera

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

agera

A small push-pull based signal library based on alien-signals algorithm.

1.0.0-alpha.2
latest
Source
npmnpm
Version published
Weekly downloads
8
300%
Maintainers
1
Weekly downloads
 
Created
Source

Agera

ESM-only package NPM version Dependencies status Install size Build status Coverage status

A small push-pull based signal library based on alien-signals algorithm.

Was created as reactivity system for nanoviews and Kida.

  • Small. Around 1.37 kB for basic methods (minified and brotlied). Zero dependencies.
  • Super fast as alien-signals.
  • Designed for best Tree-Shaking: only the code you use is included in your bundle.
  • TypeScript-first.
import { signal, computed, effect } from 'agera'

const $count = signal(1)
const $doubleCount = computed(() => count() * 2)

effect(() => {
  console.log(`Count is: ${$count()}`);
}) // Console: Count is: 1

console.log($doubleCount()) // 2

$count(2) // Console: Count is: 2

console.log($doubleCount()) // 4
Install   •   API   •   Why?

Install

pnpm add -D agera
# or
npm i -D agera
# or
yarn add -D agera

API

Signal

Signal is a basic store type. It stores a single value.

import { signal, update } from 'agera'

const $count = signal(0)

$count($count() + 1)
// or
update($count, count => count + 1)

To watch signal changes, use the effect function. Effect will be called immediately and every time the signal changes.

import { signal, effect } from 'agera'

const $count = signal(0)

const stop = effect(() => {
  console.log('Count:', $count())

  return () => {
    // Cleanup function. Will be called before effect update and before effect stop.
  }
})
// later you can stop effect
stop()

Computed

Computed is a signal that computes its value based on other signals.

import { computed } from 'agera'

const $firstName = signal('John')
const $lastName = signal('Doe')
const $fullName = computed(() => `${$firstName()} ${$lastName()}`)

console.log($fullName()) // John Doe

effectScope

effectScope creates a scope for effects. It allows to stop all effects in the scope at once.

import { signal, effectScope, effect } from 'agera'

const $a = signal(0)
const $b = signal(0)
const stop = effectScope(() => {
  effect(() => {
    console.log('A:', $a())
  })

  effectScope(() => {
    effect(() => {
      console.log('B:', $b())
    })
  })
})

stop() // stop all effects

Also there is a possibility to create a lazy scope.

import { signal, effectScope, effect } from 'agera'

const $a = signal(0)
const $b = signal(0)
// All scopes will run immediately, but effects run is delayed
const start = effectScope(() => {
  effect(() => {
    console.log('A:', $a())
  })

  effectScope(() => {
    effect(() => {
      console.log('B:', $b())
    })
  })
}, true) // marks scope as lazy
// start all effects
const stop = start()

stop() // stop all effects

Lifecycles

One of main feature of Agera is that every signal can be active or inactive. It allows to create lazy signals, which will use resources only if signal is really used in the UI.

  • Signal is active when one or more effects is attached to it.
  • Signal is incative when signal has no effects.

onActivate lifecycle method adds callback for activation and deactivation events.

import { signal, onActivate, effect } from 'agera'

const $count = signal(0)

onActivate($count, (active) => {
  console.log('Signal is', active ? 'active' : 'inactive')
})

// will activate signal
const stop = effect(() => {
  console.log('Count:', $count())
})
// will deactivate signal
stop()

Batch updates

To batch updates you should wrap signal updates between startBatch and endBatch.

import { signal, startBatch, endBatch, effect } from 'agera'

const $a = signal(0)
const $b = signal(0)

effect(() => {
  console.log('Sum:', $a() + $b())
})

// Effects will be called only once
startBatch()
$a(1)
$b(2)
endBatch()

Skip tracking

To skip tracking of signal changes you should wrap signal calls between pauseTracking and resumeTracking.

import { signal, pauseTracking, resumeTracking, effect } from 'agera'

const $a = signal(0)
const $b = signal(0)

effect(() => {
  const a = $a()

  pauseTracking()

  const b = $b()

  resumeTracking()

  console.log('Sum:', a + b)
})

// Will trigger effect run
$a(1)

// Will not trigger effect run
$b(2)

Morph

morph methods allows to create signals that can change their getter and setter on the fly.

import { signal, morph, $$get, $$set, $$source } from 'agera'

const $string = signal('')
// Debounce signal updates
const $debouncedString = morph($string, {
  [$$set]: debounce($string, 300)
})
// Lazy initialization
const $lazyString = morph($string, {
  [$$get]() {
    this[$$set]('Lazy string')
    this[$$get] = this[$$source]
    return 'Lazy string'
  }
})

isSignal

isSignal method checks if the value is a signal.

import { isSignal, signal } from 'agera'

isSignal(signal(1)) // true

Why?

Key differences from alien-signals:

  • Tree-shaking. Agera is designed to be tree-shakable. Only the code you use is included in your bundle. Alien-signals is not well tree-shakable.
  • Size. Agera has a little bit smaller size for basic methods than alien-signals.
  • Lifecycles. Agera has lifecycles for signals. You can listen to signal activation and deactivation events.
  • Modificated effectScope. Agera has a possibility to put effect scope inside another effect scope. Also there is a possibility to create a lazy scope.

Keywords

reactivity

FAQs

Package last updated on 12 Apr 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.