{"id":41589723,"url":"https://github.com/irontitan/tardis","last_synced_at":"2026-01-24T09:12:17.582Z","repository":{"id":57119296,"uuid":"151325623","full_name":"irontitan/tardis","owner":"irontitan","description":"Event sourcing toolkit","archived":false,"fork":false,"pushed_at":"2021-08-26T00:14:36.000Z","size":197,"stargazers_count":36,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-21T16:25:10.675Z","etag":null,"topics":["architecture","entity","event-driven","event-management","event-sourcing","events","eventsourcing","hacktoberfest","javascript","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/irontitan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-02T21:26:43.000Z","updated_at":"2024-04-28T14:38:28.000Z","dependencies_parsed_at":"2022-09-02T11:22:54.799Z","dependency_job_id":null,"html_url":"https://github.com/irontitan/tardis","commit_stats":null,"previous_names":["nxcd/tardis"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/irontitan/tardis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irontitan%2Ftardis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irontitan%2Ftardis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irontitan%2Ftardis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irontitan%2Ftardis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/irontitan","download_url":"https://codeload.github.com/irontitan/tardis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irontitan%2Ftardis/sbom","scorecard":{"id":494677,"data":{"date":"2025-08-11","repo":{"name":"github.com/irontitan/tardis","commit":"cd69b998d26eaa1cf68748f9ae343818b9c08d44"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-p84x-5xx8-hff9"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T20:10:46.337Z","repository_id":57119296,"created_at":"2025-08-19T20:10:46.338Z","updated_at":"2025-08-19T20:10:46.338Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28722332,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T08:27:05.734Z","status":"ssl_error","status_checked_at":"2026-01-24T08:27:01.197Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["architecture","entity","event-driven","event-management","event-sourcing","events","eventsourcing","hacktoberfest","javascript","typescript"],"created_at":"2026-01-24T09:12:17.073Z","updated_at":"2026-01-24T09:12:17.576Z","avatar_url":"https://github.com/irontitan.png","language":"TypeScript","readme":"\u003cdiv style='width: 100%; text-align: center;'\u003e\n  \u003cimg style='margin: 0 auto;' src='./assets/tardis-logo.png' width=\"450\" height=\"250\"/\u003e\n\u003c/div\u003e\n\n\u003e Event sourcing library to help developers abstract core concepts\n\n[![Build Status](https://travis-ci.org/irontitan/tardis.svg?branch=master)](https://travis-ci.org/nxcd/tardis)\n[![GitHub license](https://img.shields.io/github/license/irontitan/tardis.svg)](https://github.com/nxcd/tardis/blob/master/LICENSE)\n[![Javascript code Style](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) [![Github All Releases](https://img.shields.io/github/downloads/irontitan/tardis/total.svg)](https://github.com/nxcd/tardis)\n[![GitHub package version](https://img.shields.io/github/package-json/v/irontitan/tardis.svg)](https://github.com/nxcd/tardis) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/506aa959a662461193b1d65e34225016)](https://www.codacy.com/app/khaosdoctor/tardis?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=nxcd/tardis\u0026amp;utm_campaign=Badge_Grade)\n[![Known Vulnerabilities](https://snyk.io/test/github/irontitan/tardis/badge.svg?targetFile=package.json)](https://snyk.io/test/github/nxcd/tardis?targetFile=package.json)\n\n\n## Summary\n\u003c!-- TOC --\u003e\n\n- [Tardis](#tardis)\n  - [Summary](#summary)\n  - [Instalation](#instalation)\n  - [Usage](#usage)\n    - [Javascript:](#javascript)\n    - [Typescript:](#typescript)\n  - [Core concepts](#core-concepts)\n    - [Event](#event)\n      - [Events with custom ID's](#events-with-custom-ids)\n    - [Reducer](#reducer)\n\n\u003c!-- /TOC --\u003e\n\n## Instalation\n\nSimply run\n\n**NPM:**\n```bash\n$ npm install @irontitan/tardis\n```\n\n**Yarn:**\n```bash\n$ yarn add @irontitan/tardis\n```\n\n## Usage\n\n### Javascript:\n\n\u003e Person.js\n\n```js\nconst PersonWasCreated = require('./PersonWasCreatedEvent')\nconst PersonEmailWasAdded = require('./PersonEmailWasAddedEvent')\n\nclass Person {\n  constructor () {\n    this.name = null\n    this.email = null\n    this.updatedAt = null\n    this.updatedBy = null\n  }\n\n  static create (name, user, email) {\n    return [\n      new PersonWasCreated({ name }, user),\n      new PersonEmailWasAdded({ email }, user)\n    ]\n  }\n\n  get state () {\n    return { ...this }\n  }\n}\n\nmodule.exports = Person\n```\n\n\u003e PersonWasCreatedEvent.js\n\n```js\nconst { Event } = require('@irontitan/tardis')\n\nclass PersonWasCreated extends Event {\n  static get eventName () { return 'person-was-created' }\n\n  constructor (data, user) {\n    super(PersonWasCreated.eventName, data)\n    this.user = user\n  }\n\n  static commit (state, event) {\n    state.name = event.data.name\n    state.updatedAt = event.timestamp\n    state.updatedBy = event.user\n    return state\n  }\n}\n\nmodule.exports = PersonWasCreated\n```\n\n\u003e PersonEmailWasAddedEvent.js\n\n```js\nconst { Event } = require('@irontitan/tardis')\n\nclass PersonEmailWasAdded extends Event {\n  static get eventName () { return 'person-email-was-added' }\n\n  constructor (data, user) {\n    super(PersonEmailWasAdded.eventName, data)\n    this.user = user\n  }\n\n  static commit (state, event) {\n    state.email = event.data.email\n    state.updatedAt = event.timestamp\n    state.updatedBy = event.user\n    return state\n  }\n}\n\nmodule.exports = PersonEmailWasAdded\n```\n\n\u003e index.js\n\n```js\nconst { Reducer } = require('@irontitan/tardis')\nconst Person = require('./Person')\nconst PersonWasCreated = require('./PersonWasCreatedEvent')\nconst PersonEmailWasAdded = require('./PersonEmailWasAddedEvent')\n\nconst personReducer = new Reducer({\n  [PersonWasCreated.eventName]: PersonWasCreated.commit,\n  [PersonEmailWasAdded.eventName]: PersonEmailWasAdded.commit\n})\n\nconst events = [ ...Person.create('John Doe', 'jdoe', 'john.doe@company.com') ]\nconsole.log(events)\n/*\n[\n  PersonWasCreated {\n    id: 'd043fc61a0ab5e088a458b6b',\n    name: 'person-was-created',\n    data: { name: 'John Doe' },\n    timestamp: 2018-10-16T22:10:06.022Z,\n    user: 'johndoe'\n  },\n  PersonEmailWasAdded {\n    id: 'a2707db386e25529e25ee882',\n    name: 'person-email-was-added',\n    data: { email: 'john.doe@company.com' },\n    timestamp: 2018-10-16T22:10:06.022Z,\n    user: 'johndoe'\n  }\n]\n*/\n\nconst person = personReducer.reduce(new Person(), events)\nconsole.log(person.state)\n/*\n{\n  name: 'John Doe',\n  email: 'john.doe@company.com',\n  updatedBy: 'johndoe',\n  updatedAt: 2018-10-16T20:54:57.122Z\n}\n*/\n```\n\n### Typescript:\n\n\u003e Person.ts\n\n```ts\nimport PersonWasCreated from './PersonWasCreatedEvent'\nimport PersonEmailWasAdded from './PersonEmailWasAddedEvent'\n\nexport default class Person {\n  name: string | null = null\n  email: string | null = null\n  updatedAt: Date | null = null\n  updatedBy: string | null = null\n\n  static create(name: string, user: string, email: string) {\n    return [\n      new PersonWasCreated({ name }, user),\n      new PersonEmailWasAdded({ email }, user)\n    ]\n  }\n\n  public get state() {\n    return {\n      name: this.name,\n      email: this.email,\n      updatedAt: this.updatedAt,\n      updatedBy: this.updatedBy\n    }\n  }\n}\n```\n\n\u003e PersonWasCreatedEvent.ts\n\n```ts\nimport { Event } from '@irontitan/tardis'\n\nexport interface IPersonCreationParams {\n  name: string\n}\n\nexport default class PersonWasCreated extends Event\u003cIPersonCreationParams\u003e {\n  static eventName = 'person-was-created'\n  user: string\n\n  constructor(data: IPersonCreationParams, user: string) {\n    super(PersonWasCreated.eventName, data)\n    this.user = user\n  }\n\n  static commit(state: Person, event: PersonWasCreated): Person {\n    state.name = event.data.name\n    state.updatedAt = event.timestamp\n    state.updatedBy = event.user\n    return state\n  }\n}\n```\n\n\u003e PersonEmailWasAddedEvent.ts\n\n```ts\nimport { Event } from '@irontitan/tardis'\n\nexport default class PersonEmailWasAdded extends Event\u003cany\u003e {\n  static eventName = 'person-email-was-added'\n  user: string\n\n  constructor(data: { email: string }, user: string) {\n    super(PersonEmailWasAdded.eventName, data)\n    this.user = user\n  }\n\n  static commit(state: Person, event: PersonEmailWasAdded): Person {\n    state.email = event.data.email\n    state.updatedAt = event.timestamp\n    state.updatedBy = event.user\n    return state\n  }\n}\n```\n\n\u003e index.ts\n\n```ts\nimport { Reducer } from '@irontitan/tardis'\nimport Person from './Person'\nimport PersonWasCreated from './PersonWasCreatedEvent'\nimport PersonEmailWasAdded from './PersonEmailWasAddedEvent'\n\nconst personReducer = new Reducer\u003cPerson\u003e({\n  [PersonWasCreated.eventName]: PersonWasCreated.commit,\n  [PersonEmailWasAdded.eventName]: PersonEmailWasAdded.commit\n})\n\nconst events = [ ...Person.create('John Doe', 'jdoe', 'john.doe@company.com') ]\nconsole.log(events)\n/*\n[\n  PersonWasCreated {\n    id: 'd043fc61a0ab5e088a458b6b',\n    name: 'person-was-created',\n    data: { name: 'John Doe' },\n    timestamp: 2018-10-16T22:10:06.022Z,\n    user: 'johndoe'\n  },\n  PersonEmailWasAdded {\n    id: 'a2707db386e25529e25ee882',\n    name: 'person-email-was-added',\n    data: { email: 'john.doe@company.com' },\n    timestamp: 2018-10-16T22:10:06.022Z,\n    user: 'johndoe'\n  }\n]\n*/\n\nconst person = personReducer.reduce(new Person(), events)\nconsole.log(person.state)\n/*\n{\n  name: 'John Doe',\n  email: 'john.doe@company.com',\n  updatedBy: 'johndoe',\n  updatedAt: 2018-10-16T20:54:57.122Z\n}\n*/\n```\n\n## Core concepts\n\nThe core idea behind Tardis is to implement a generic and easy-to-use interface to interact with the [Event Sourcing architecture](https://martinfowler.com/eaaDev/EventSourcing.html).\n\nIn this architecture there are two core concepts: The **Event** and the **Reducer**, and we'll call anything from our business logic **Entity**, it can be a car, a person, a ship or anything else.\n\n### Event\n\nAn event represents something that happened to your entity. For instance \"The Person was created at the database\", or even \"The person has visited Amsterdam\" and so on. Every event receives two arguments: The event name string (lowercase and hyphenated, so `Person was created` becomes `person-was-created`), and all the data for that event. It also contains a `timestamp` and an `id` property which will be automatically generated.\n\nAll events must also include **a static `name` property** and **a static `commit` method**. The commit method is a function with the following signature:\n\n```js\nstatic commit (state, event) {\n\n}\n```\n\nThe `commit` method is where the state will be updated and sent back to the reducer.\n\nLet's say we have this entity:\n\n```js\nconst { PersonWasCreated } = require('../your/path/to/events')\n\nclass Person {\n  constructor () {\n    this.name = null\n    this.updatedBy = null\n    this.updatedAt = null\n  }\n\n  // This method will return every event needed to create the user\n  static create (name, user) {\n    return [\n      new PersonWasCreated({ name }, user)\n    ]\n  }\n\n  get state () {\n    return { ...this }\n  }\n}\n```\n\nSo, let's construct an Event:\n\n**Typescript**:\n\n```ts\nimport { Event } from '@irontitan/tardis'\n\nclass PersonWasCreated extends Event { // Our event's class\n  static eventName = 'person-was-created' // Event name\n  public user: string // A custom user property belonging to the event itself\n\n  // The event constructor takes as many arguments as your event needs\n  // In our case, we only have two: The data which is related to the entity \"Person\" and the user who generated the event\n  constructor (data: { name: string }, user: string) {\n    super(PersonWasCreated.eventName, data) // Calling the parent class with the name and entity data\n    this.user = user\n  }\n\n  // Commit method which will update the current received state\n  // State is an instance of your own entity with all the properties you need\n  // Our entity has only the property \"name\"\n  static commit (state: Person, event: PersonWasCreated) {\n    // Updating the state\n    state.name = event.data.name\n    state.updatedAt = event.timestamp\n    state.updatedBy = event.user\n    return state\n  }\n}\n```\n\n**Javascript**\n\n```js\nconst { Event } = require('@irontitan/tardis')\n\nclass PersonWasCreated extends Event {\n  static get eventName () { return 'person-was-created' }\n\n  constructor (data, user) {\n    super(PersonWasCreated.eventName, data)\n    this.user = user\n  }\n\n  static commit (state, event) {\n    state.name = event.data.name\n    state.updatedAt = event.timestamp\n    state.updatedBy = event.user\n    return state\n  }\n}\n```\n\n#### Events with custom ID's\n\nBy default, the Event class will generate a MongoDB-Like ObjectID. If you wish to use your own ID function, then it is needed to supply it to the third optional parameter in the `super` method inside your event:\n\n**Typescript**\n\n```ts\nimport { Event } from '@irontitan/tardis'\nimport crypto from 'crypto'\n\nfunction createId (): string {\n  return crypto.randomBytes(12).toString('hex')\n}\n\nclass PersonWasCreated extends Event {\n  static eventName = 'person-was-created'\n  public user: string\n\n  constructor (data: { name: string }, user: string) {\n    super(PersonWasCreated.eventName, data, createId())\n    this.user = user\n  }\n\n  static commit (state: Person, event: PersonWasCreated) {\n    state.name = event.data.name\n    state.updatedAt = event.timestamp\n    state.updatedBy = event.user\n    return state\n  }\n}\n```\n\n**Javascript**\n\n```js\nconst crypto = require('crypto')\nconst { Event } = require('@irontitan/tardis')\n\nfunction createId () {\n  return crypto.randomBytes(12).toString('hex')\n}\n\nclass PersonWasCreated extends Event {\n  static get eventName () { return 'person-was-created' }\n\n  constructor (data, user) {\n    super(PersonWasCreated.eventName, data, createId())\n    this.user = user\n  }\n\n  static commit (state, event) {\n    state.name = event.data.name\n    state.updatedAt = event.timestamp\n    state.updatedBy = event.user\n    return state\n  }\n}\n```\n\n### Reducer\n\nThe reducer is a structure that represents the applied state. It will be the reducer which will receive an initial state and recursively apply all the `commit` functions present in events, passing the resulting state to the initial state of the next call, essentially, reducing an array of events to a single final event.\n\nAll reducers must be instantiated by passing an object of known events and it's respective commit functions, for instance, let's get our Person's events:\n\n**Typescript**\n\n```ts\nimport { Person } from './your/entity/path'\nimport { Reducer } from '@irontitan/tardis'\nimport { PersonWasCreated, PersonWasUpdated } from './your/path/to/events'\n\nconst personReducer = new Reducer\u003cPerson\u003e({\n  [PersonWasCreated.eventName]: PersonWasCreated.commit,\n  [PersonWasUpdated.eventName]: PersonWasUpdated.commit\n})\n```\n\n**Javascript**\n\n```js\nconst { Person } = require('./your/entity/path')\nconst { Reducer } = require('@irontitan/tardis')\nconst { PersonWasCreated, PersonWasUpdated } = require('./your/path/to/events')\n\nconst personReducer = new Reducer({\n  [PersonWasCreated.eventName]: PersonWasCreated.commit,\n  [PersonEmailWasAdded.eventName]: PersonEmailWasAdded.commit\n})\n```\n\nNow we have an instance of the reducer which will only apply commits to that specific known events. Now we can create an event and pass to it so it will update our entity:\n\n**Typescript**\n\n```ts\nimport { Person } from './your/entity/path'\nimport { Reducer } from '@irontitan/tardis'\nimport { PersonWasCreated, PersonWasUpdated } from './your/path/to/events'\n\nconst events = [...Person.create('John Doe', 'jdoe')]\n\nconsole.log(events)\n/*\n[\n  PersonWasCreated {\n    id: 'd043fc61a0ab5e088a458b6b',\n    name: 'person-was-created',\n    data: { name: 'John Doe' },\n    timestamp: 2018-10-16T22:10:06.022Z,\n    user: 'jdoe'\n  }\n]\n*/\n\nlet initialState = new Person()\nconsole.log(initialState.state)\n/*\n{\n  name: null\n  updatedBy: null\n  updatedAt: null\n}\n*/\n\nconst person = personReducer.reduce(initialState, events)\nconsole.log(person.state)\n/*\n{\n  name: 'John Doe',\n  updatedBy: 'jdoe',\n  updatedAt: 2018-10-16T20:54:57.122Z\n}\n*/\n```\n\n**Javascript**\n\n```js\nconst { Person } = require('./your/entity/path')\nconst { Reducer } = require('@irontitan/tardis')\nconst { PersonWasCreated, PersonWasUpdated } = require('./your/path/to/events')\n\nconst events = [...Person.create('John Doe', 'jdoe')]\n\nconsole.log(events)\n/*\n[\n  PersonWasCreated {\n    id: 'd043fc61a0ab5e088a458b6b',\n    name: 'person-was-created',\n    data: { name: 'John Doe' },\n    timestamp: 2018-10-16T22:10:06.022Z,\n    user: 'jdoe'\n  }\n]\n*/\n\nlet initialState = new Person()\nconsole.log(initialState.state)\n/*\n{\n  name: null\n  updatedBy: null\n  updatedAt: null\n}\n*/\n\nconst person = personReducer.reduce(initialState, events)\nconsole.log(person.state)\n/*\n{\n  name: 'John Doe',\n  updatedBy: 'jdoe',\n  updatedAt: 2018-10-16T20:54:57.122Z\n}\n*/\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firontitan%2Ftardis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Firontitan%2Ftardis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firontitan%2Ftardis/lists"}