{"id":21690086,"url":"https://github.com/timdeputter/purescript-projections","last_synced_at":"2026-05-20T10:39:56.589Z","repository":{"id":58225463,"uuid":"54060519","full_name":"timdeputter/purescript-projections","owner":"timdeputter","description":"Write geteventstore projections in purescript (work in progress)","archived":false,"fork":false,"pushed_at":"2018-05-04T05:53:29.000Z","size":51,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-25T13:07:12.448Z","etag":null,"topics":["eventstore","geteventstore","javascript","purescript"],"latest_commit_sha":null,"homepage":"","language":"PureScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timdeputter.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":"2016-03-16T19:28:13.000Z","updated_at":"2020-05-01T14:59:16.000Z","dependencies_parsed_at":"2022-08-31T04:10:17.486Z","dependency_job_id":null,"html_url":"https://github.com/timdeputter/purescript-projections","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timdeputter%2Fpurescript-projections","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timdeputter%2Fpurescript-projections/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timdeputter%2Fpurescript-projections/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timdeputter%2Fpurescript-projections/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timdeputter","download_url":"https://codeload.github.com/timdeputter/purescript-projections/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244618249,"owners_count":20482316,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["eventstore","geteventstore","javascript","purescript"],"created_at":"2024-11-25T17:28:59.941Z","updated_at":"2026-05-20T10:39:51.545Z","avatar_url":"https://github.com/timdeputter.png","language":"PureScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"purescript-projections [![License](http://img.shields.io/hexpm/l/Rendezvous.svg?style=flat)](https://github.com/timdeputter/purescript-projections/blob/master/LICENSE)\n==========\n\nPurescript bindings to the [geteventstore](http://geteventstore.com) projections library.\n\n## Why\nPurescript is a pure functional strongly typed programming language which compiles to javascript. \nWith purescript-projections you can write your eventstore projections in a pure functional and typesafe\nmanner to guarantee more correctness and safety. And to make awesomeness more awesome, purescript ships\nwith a haskell style quickcheck implementation, which means you can leverage property-based tests to\nmake working with projections even more awesome!\n\n## Installation\nInstall purescript-projections with bower:\n\n```sh\n$ bower install purescript-projections\n```\n\n## Getting started\n\nTo write an eventstore projection in purescript first of all you have to model your events and your state:\n```purescript\n  type UserJoined = {username:: String, id:: Int}\n  type State = {count:: Int}\n```\nthen write a function which takes an event and a state and produces a new state:\n```purescript\n  handler :: State -\u003e UserJoined -\u003e State\n  handler s e = {count: s.count+1}\n```\nIn main call runProjection with name of the eventstream, the inital state and the handler like this:\n```purescript\n  main = runProjection (fromStream \"chatroom\") {count:0} defaultOptions $ when \"UserJoined\" handler \n```\n\nNow build the project to a single javascript output file and upload the file as projection\nto your eventstore installation:\n\n```sh\n$ pulp build -O --to projection.js\n$ curl -i -d @projection.js http://127.0.0.1:2113/projections/transient?enabled=yes -u admin:changeit -H \"Content-Type: application/json\"\n```\n\n\n## Projection properties\nThe projections behaviour is defined by four basic properties, these are:\n\n\n| Property          | description                                   | default  |\n| ----------------- | --------------------------------------------- | -------- |\n| resultstream name | The name of the outputstate stream.            | $projections-{projection-name}-result |\n| include links     | Links to events in the source stream are processed. |   false |\n| reorder events    | Process events by storing a buffer of events ordered by their prepare position.     |    false |\n| processinglag     | \t \tWhen reorderEvents is turned on, this value is used to compare the total milliseconds between the first and last events in the buffer and if the value is equal or greater, the events in the buffer will be processed. The buffer is an ordered list of events.  | 500ms |\n\nThese properties are either controlled via an options parameter passed to runProjections for general configurations (like resultstream name) or they are directly passed to the functions whichs behaviour is altered by the configuration parameter.\n\n### Default Options\nIf you just want the default behaviour of projections pass defaultOptions to runProjections:\n```purescript\n  runProjection source initialState defaultOptions fold\n```\n\n### Output state\nThis controls wether an outputstate stream should be created and which name this stream should have:\n```purescript\n  runProjection source initialState (outputState \"projection-state\") fold\n```\n\n\n## Selecting streams\n\nThere is a variaty of ways to select events from different streams.\n\n### Single stream\nTo select events from a single stream call fromStream with the name of the stream to select the events from:\n```purescript\n  fromStream \"chatroom\"\n```\n\n### Multiple streams\nTo select events from multiple streams call fromStreams with an Array of the names of the streams:\n```purescript\n  fromStreams [\"chatroom\", \"lobby\"]\n```\n\n### From category\nTo select the events from a category call fromCategory with the name of the category. \nTo run a seperate projection for each category call forEachInCategory.\n```purescript\n  fromCategory \"category\"\n  forEachInCategory \"category\"\n```\n\n### From all streams\nThe function fromAll simply runs the projection for all streams in the database.\nForEach runs a seperate projection for each category.\n\n## Handling events\nOnce the source of events is defined we can specifiy how to derive state from them, or - to say it in other words - \nhow to 'fold' the events\n\n### When\nWhen produces eventhandler for events of the given eventname by applying a given function which takes a state s, an event e and produces a new state s. The following example derives the number of created accounts from the 'accountCreated' event.\n```purescript\n  when \"accountCreated\" (\\s e -\u003e {count: s.count+1})\n```\n\n### When any\nWhenAny can be used to define an eventhandler for any event.\n```purescript\n  whenAny (\\s e -\u003e {count: s.count+1})\n```\n\n### Combining eventhandlers\nFoldE is an instance of Semigroup, so \nyou can define multiple eventhandlers and then combine them:\n```purescript\n  when \"accountCreated\" (\\s e -\u003e {count: s.count+1}) \u003c\u003e when \"accountClosed\" (\\s e -\u003e {count: s.count-1})\n```\n\n## License\n\nCheck [LICENSE](LICENSE) file for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimdeputter%2Fpurescript-projections","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimdeputter%2Fpurescript-projections","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimdeputter%2Fpurescript-projections/lists"}