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

entropic-bond

v2.0.5

Published

Tidy up your messy components

Readme

Entropic Bond

Tidy up your messy components

Entropic Bond helps your TypeScript software development, both in the frontend and the backend. It is composed by several abstractions that make your code fully decoupled from the database, authorization service or cloud storage provider yet easy to use. In addition, it offers an observer based architecture to intercommunicate your business logic entities efficiently.

Who needs to focus on a unique backend provider

Entropic Bond is designed with the serverless and NoSQL models in mind. This doesn't mean you cannot use it in such scenarios. Moreover, it is an excellent tool to develop Functions as a Service (FaaS). With Entropic Bond, you just forget about those implementation details. You only need to focus on developing your domain model.

Who needs a global state

Entropic Bond removes the need to maintain a global state. The underlying architecture is designed in a way that the state is maintained at entity level and the relationship between the entities is provided by a notification infrastructure.

How to use

Typically, you will derive all your business logic entities from the EntropicComponent class. This class provides two main functionalities; persistence and observability.

API

You can find the API documentation in the docs/ directory.

Persistence

The persistence mechanism allows defining which entities and which properties of those entities should be stored in the database. To make an entity persistent, it should derive from the EntropicComponent class or the Persistent class.

In order to allow the persistence mechanism to automatically instantiate entities from the database, you should use the @registerPersistentClass decorator passing the class name as a parameter.

The properties or attributes that you want to be streamed should be preceded by the @persistent decorator in the attribute declaration. The property name must be private and prefixed with an underscore (_). Access to the public attributes should be done by the use of accessors.

@registerPersistentClass( 'MyEntity' )
class MyEntity extends Persistent {
	@persistent private _persistentProp1: string
	@persistent private _persistentProp2: boolean
	@persistent private _persistentProp3: AnotherPersistentObject
	@persistent private _persistentProp4: number[]

	private _nonPersistentProp: unknown
	
	// accessors go here ...
}

Storing and querying the persistent entities

The database abstraction is provided by the Store object.

The Store.getModel method will return an object with methods to access the database.

let foundEntity: MyEntity
const myEntity = new MyEntity()
const entityModel = Store.getModel<MyEntity>( 'MyEntity' )

// fill myEntity object with data here ...

await entityModel.save( myEntity )		// saves myEntity in the database

foundEntity = await entityModel.findById( '0340d-349ab' ) // retrieves from database

foundEntity = await entityModel.find().
									.where( 'persistentProp1', '==', 'foo' )
									.where( 'persistentProp2', '==', true )
									.limit( 10 )
									.orderBy( 'persistentProp1', 'desc' )
									.get()														// retrieves from database

entityModel.delete( '0340d-349ab' )									// deletes from database

Set up the database access

The database access is encapsulated in a DataSource object. A concrete implementation of a JSON DataSource is provided as JsonDataSource. You can use this implementation for testing purposes.

Currently, there is an official plugin to connect to a Firebase Firestore database. To install the plugin, run:

npm i entropic-bond-firebase

You can develop new plugins following the plugin developer's section.

You should instantiate the concrete implementation of the DataSource and pass it to the useDataSource method of the Store object.

Store.useDataSource( new JsonDataSource() )

See the complete example at samples/01-persistence.ts

Observability

The observability mechanism allows entities to notify when their properties change. Derive your class from EntropicComponent (which extends Persistent) and use changeProp in setters or pushAndNotify/removeAndNotify for arrays.

import { EntropicComponent } from 'entropic-bond'

class MyEntity extends EntropicComponent {
  private _name: string = ''

  get name(): string { return this._name }
  set name(value: string) { this.changeProp('name', value) }
}

const entity = new MyEntity()
const unsub = entity.onChange(event => console.log('Changed:', event))

entity.name = 'new value' // triggers the onChange listener
unsub() // removes the listener

You can also directly use the generic Observable<T> class for standalone observer patterns.

import { Observable } from 'entropic-bond'

const observable = new Observable<string>()
const unsubscribe = observable.subscribe(event => console.log(event))
observable.notify('hello')

See the complete example at samples/02-observability.ts

Auth

Authentication is abstracted via AuthService. Register a concrete implementation and use the Auth singleton.

import { Auth, AuthMock } from 'entropic-bond'

Auth.useAuthService(new AuthMock())

async function example() {
  const user = await Auth.instance.login({ authProvider: 'email', email: '[email protected]', password: '123456' })
  console.log(user.id, user.email)

  Auth.instance.onAuthStateChange(credentials => {
    console.log('Auth state changed:', credentials)
  })
}

Plugins exist for production providers (e.g., Firebase Authentication). To create a custom provider, implement the AuthService abstract class.

See the complete example at samples/03-auth.ts

Server Auth

For admin-level user management (list, update, delete users), use ServerAuth.

import { ServerAuth, ServerAuthMock } from 'entropic-bond'

ServerAuth.useServerAuthService(new ServerAuthMock())

const user = await ServerAuth.instance.getUser('user-id')
await ServerAuth.instance.updateUser('user-id', { name: 'Updated Name' })
await ServerAuth.instance.deleteUser('user-id')

See the complete example at samples/04-server-auth.ts

Cloud Storage

File storage is abstracted via CloudStorage. Register a provider and use the singleton, or use the StoredFile persistent entity.

import { CloudStorage, MockCloudStorage, StoredFile } from 'entropic-bond'

CloudStorage.useCloudStorage(new MockCloudStorage())

// Direct usage
const url = await CloudStorage.defaultCloudStorage.save('my-file', fileData)
const downloadUrl = await CloudStorage.defaultCloudStorage.getUrl('my-file')

// Or with StoredFile (persistent entity)
const file = new StoredFile()
file.setDataToStore(someBlob)
await file.save()
console.log(file.url)

See the complete example at samples/05-cloud-storage.ts

Cloud Functions

Call serverless functions through an abstract interface.

import { CloudFunctions, CloudFunctionsMock } from 'entropic-bond'

const mockService = new CloudFunctionsMock({
  myFunction: async (params) => `Hello ${params.name}`
})
CloudFunctions.useCloudFunctionsService(mockService)

const fn = CloudFunctions.instance.getFunction('myFunction')
const result = await fn({ name: 'World' })

See the complete example at samples/06-cloud-functions.ts

Realtime document listeners

The Model supports realtime updates on documents and collections.

const model = Store.getModel<MyEntity>('MyEntity')

// Listen to a single document
const unsubscribe1 = model.onDocumentChange('doc-id', change => {
  console.log('Before:', change.before, 'After:', change.after)
})

// Listen to a collection query
const unsubscribe2 = model.onCollectionChange(
  model.find().where('name', '==', 'foo'),
  change => console.log('Collection changed:', change)
)

// Listen to a wildcard collection template
const unsubscribe3 = model.onCollectionTemplateChange('{userId}/Posts', change => {
  console.log('Post changed in', change.collectionPath)
})

See the complete example at samples/07-realtime-listeners.ts

DataSource plugins

The persistence layer uses a DataSource to communicate with the database. Implement the abstract DataSource class to support new backends.

import { DataSource, Store } from 'entropic-bond'

class MyDatabase extends DataSource {
  // implement all abstract methods: findById, find, save, delete, etc.
}

Store.useDataSource(new MyDatabase())

The official Firebase plugin is available as entropic-bond-firebase.

npm i entropic-bond-firebase

See the complete example at samples/10-datasource-plugin.ts

Cached property references

When a property holds a reference to another persistent entity, you can embed selected primitive fields directly in the reference to avoid extra queries.

@registerPersistentClass('Team')
class Team extends EntropicComponent {
  @persistent private _name: string
}

@registerPersistentClass('User')
class User extends EntropicComponent {
  @persistentReferenceWithCachedProps(['_name'], 'Team')
  private _team: Team
}

The CachedPropsUpdater (installed via DataSource.installCachedPropsUpdater()) will propagate changes to cached props across all referencing documents.

See the complete example at samples/08-cached-props.ts

Utility functions

import { camelCase, snakeCase, replaceValue, getDeepValue } from 'entropic-bond'

camelCase('hello-world')        // 'helloWorld'
snakeCase('helloWorld')         // 'hello-world'
replaceValue('Hi ${name}', { name: 'John' }) // 'Hi John'

See the complete example at samples/09-utils.ts

Samples

Complete, runnable examples are available in the samples/ directory:

| Section | Sample | |---------|--------| | Persistence | 01-persistence.ts | | Observability | 02-observability.ts | | Auth | 03-auth.ts | | Server Auth | 04-server-auth.ts | | Cloud Storage | 05-cloud-storage.ts | | Cloud Functions | 06-cloud-functions.ts | | Realtime listeners | 07-realtime-listeners.ts | | Cached property references | 08-cached-props.ts | | Utility functions | 09-utils.ts | | DataSource plugins | 10-datasource-plugin.ts |