GithubHelp home page GithubHelp logo

event-driven-io / emmett Goto Github PK

View Code? Open in Web Editor NEW
171.0 171.0 16.0 2.21 MB

Emmett - a Node.js library taking your event-driven applications back to the future!

Home Page: https://event-driven-io.github.io/emmett/

TypeScript 98.69% Vue 0.05% PowerShell 0.02% Shell 0.02% CSS 0.11% Gherkin 1.11%
event-driven event-sourcing event-store nodejs typescript

emmett's People

Contributors

alex-laycalvert avatar bicatu avatar d3spis3d avatar futpib avatar mkubasz avatar oskardudycz avatar thiagomini avatar watfordsuzy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

emmett's Issues

Fix: Importing emmet package as an ECMAScript module doesn't work yet

Description

When installing emmet on a project that uses ECMAScript module syntax (package.json with type: module), it throws the following error:

file:///home/thiago/Development/pessoal/emmet-example/dist/src/index.js:1
import { getInMemoryEventStore } from '@event-driven-io/emmett';
         ^^^^^^^^^^^^^^^^^^^^^
SyntaxError: Named export 'getInMemoryEventStore' not found. The requested module '@event-driven-io/emmett' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@event-driven-io/emmett';
const { getInMemoryEventStore } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:132:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:214:5)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v20.11.1

We need to investigate what's causing that and fix it.

Acceptance Criteria

On a fresh new repository / project, after installing emmet, we should be able to import artifacts from emmet as follows:

import { CommandHandler, getInMemoryEventStore } from '@event-driven-io/emmett';

const es = getInMemoryEventStore();

console.log(es);

Additional information

@event-driven-io/emmett version 5.0.1
Node.js version 20.11.0
OS WSL 2.1.4.0
Package Manager yarn 4.0.2

Add webapi integration testing tool

Add WebApi integration tool like in the testing projections article. It should be:

  • using given/when/then pattern
  • take events in given and supertest request in when,
  • Then can tests events like command handling tests, but also should allow to doqueries etc,
    It should enable testing idempotency and optimistic concurrency, so running requests twice.
  • in the future, it could be testing OTel spans as Martin Thwaites shown in his talks,
  • This is not perfect with an in-memory event store but should be fine for business logic and integration tests in the ports/adapters style.

Use Node's Native Test Runner instead of Jest

Hey there, Oskar - I really appreciate the effort of creating a Node version of Marten, which is something I've been missing in the JS ecosystem. As a fellow TS programmer and Event-sourcing enthusiast, I'd like to contribute to this tool - and my first suggestion is to use Node's native test runner to run its tests. It is way faster than Jest, and it's one less dependency in the repo, which is always great.

I've created a repo showing how easy it is to set it up with Typescript, and you'll see that it's API is basically the same as Jest or other famous test runners (like Vitest). The idea is to improve the DevEx for the contributors of this package by leveraging native tools.

I can create a PR to configure the repo to use it - just let me know if you agree!

Fix: ESM problem in Nuxt

Description

I'm getting the following error when doing import { CommandHandler } from "@event-driven-io/emmett" in a Nuxt project. Somehow Nuxt redirects incorrectly to /dist/index.js instead of /dist/index.mjs.

import { CommandHandler, getInMemoryEventStore } from 'node_modules/@event-driven-io/emmett/dist/index.js';   ^^^^^^^^^^^^^^   SyntaxError: The requested module 'node_modules/@event-driven-io/emmett/dist/index.js' does not provide an export named 'CommandHandler'

Reproduction

Here's the repo with the minimal reproduction: https://stackblitz.com/edit/nuxt-starter-nef6w3?file=app%2Fcounter.ts

Solution to above-mentioned issue

I managed to get rid of that error when I built locally emmet with a field inside package.json

{
 "exports": {
   ".": {
     "require": "/dist/index.js",
     "import": "/dist/index.mjs"
   }
 }
}

But after that I got the following error:

Directory import 'emmett/packages/emmett/dist/commandHandling' is not supported resolving ES modules imported from emmett/packages/emmett/dist/index.mjs

Missing Dependency `test` when attempting to use `@event-driven-io/emmett`

When attempting to use Emmett (originally found when running tests with Jest but occurs when importing from Emmett at all) I keep getting the below error:

Node: v21.7.2 (happened for v20 and I'm assuming all other versions)
Emmett: v0.7.0

$ node ./index.js

node:internal/modules/cjs/loader:1145
  throw err;
  ^

Error: Cannot find module 'test'
Require stack:
- /home/alex/git/emmett-jest-example/node_modules/@event-driven-io/emmett/dist/chunk-6WITJBGG.js
- /home/alex/git/emmett-jest-example/node_modules/@event-driven-io/emmett/dist/index.js
- /home/alex/git/emmett-jest-example/index.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1142:15)
    at Module._load (node:internal/modules/cjs/loader:983:27)
    at Module.require (node:internal/modules/cjs/loader:1230:19)
    at require (node:internal/modules/helpers:179:18)
    at Object.<anonymous> (/home/alex/git/emmett-jest-example/node_modules/@event-driven-io/emmett/dist/chunk-
6WITJBGG.js:1:348)
    at Module._compile (node:internal/modules/cjs/loader:1368:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1426:10)
    at Module.load (node:internal/modules/cjs/loader:1205:32)
    at Module._load (node:internal/modules/cjs/loader:1021:12)
    at Module.require (node:internal/modules/cjs/loader:1230:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/alex/git/emmett-jest-example/node_modules/@event-driven-io/emmett/dist/chunk-6WITJBGG.js',
    '/home/alex/git/emmett-jest-example/node_modules/@event-driven-io/emmett/dist/index.js',
    '/home/alex/git/emmett-jest-example/index.js'
  ]
}

Node.js v21.7.2

Looked into the issue and looks like a missing dependency of test. Will probably have a PR up soon but wanted to document.

Test: Devise a testing strategy that we can use to reduce duplication among emmet packages

Description

As we noted in this PR, some test cases are duplicated among our packages. Therefore, when we want to fix them or change something, we have to repeat the same code in multiple files, which is unnecessary and prone to human error. We need to create some sort of matrix testing or a testing utility that can be reused across packages to execute the same logical test.

A few things to discuss:

  • Each of these "duplicated" tests are located in different packages. For instance, inMemoryTest in emmet package and eventStoreTest in the emmet-esdb one. Should we keep them separated?
  • What is common between these tests, and what's different? What can we abstract away to facilitate creating tests for future integrations?

Acceptance Criteria

  1. Definition and agreement of a testing strategy that can reduce the boilerplate / duplicate code between tests
  2. Implementation of the aforementioned strategy in existing tests

Additional Information

To inspire this, we can use ESLint's Testing Helper. They've created a tool to facilitate creating tests that are usually very similar.

Append Events with an expected version

I'm looking through the API Docs while playing with Emmett and am wondering about the elision of expectedVersion on the EventStore interface:

// #region event-store
export interface EventStore {
aggregateStream<Entity, E extends Event>(
streamName: string,
options: {
evolve: (currentState: Entity, event: E) => Entity;
getInitialState: () => Entity;
},
): Promise<Entity | null>;
readStream<E extends Event>(streamName: string): Promise<E[]>;
appendToStream<E extends Event, NextExpectedVersion = bigint>(
streamId: string,
...events: E[]
): Promise<NextExpectedVersion>;
}
// #endregion event-store

It is my assumption this interface would instead look something like:

// #region event-store
export interface EventStore {
  aggregateStream<Entity, E extends Event, NextExpectedVersion = bigint>(
    streamName: string,
    options: {
      evolve: (currentState: Entity, event: E) => Entity;
      getInitialState: () => Entity;
      startingVersion?: NextExpectedVersion | undefined,
    },
  ): Promise<{ entity: Entity | null, nextExpectedVersion: NextExpectedVersion }>;

  readStream<E extends Event, NextExpectedVersion = bigint>(
    streamName: string,
    startingVersion?: NextExpectedVersion | undefined
  ): Promise<E[]>;

  appendToStream<E extends Event, NextExpectedVersion = bigint>(
    streamId: string,
    expectedVersion?: NextExpectedVersion | undefined,
    ...events: E[]
  ): Promise<NextExpectedVersion>;
}
// #endregion event-store

Is this a conscious design choice to represent a simpler model of event sourcing?

Add ability to setup integration tests through HTTP requests

Currently, integration test data can be set up only by providing the initial set of events. That should be enough for most cases, but some people prefer to do it fully through the Web API, treating the application as a black box.

The entry point of that is located here:

...givenStreams: TestEventStream<EventType>[]
.

It should be done in a similar way as with asserts but allowing to pass multiple setups. Setup should use the same structure as when passing the supertest setup

when: (setupRequest: (request: TestAgent<supertest.Test>) => Test) => {
.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.