{"id":22367726,"url":"https://github.com/hugojosefson/deno-prevalence","last_synced_at":"2026-04-16T11:04:25.496Z","repository":{"id":173476314,"uuid":"650818293","full_name":"hugojosefson/deno-prevalence","owner":"hugojosefson","description":"Prevalence for Deno, like Prevayler.","archived":false,"fork":false,"pushed_at":"2023-10-08T12:56:21.000Z","size":353,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-26T15:55:21.603Z","etag":null,"topics":["deno","deno-kv","prevalence","prevayler"],"latest_commit_sha":null,"homepage":"https://deno.land/x/prevalence","language":"TypeScript","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/hugojosefson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-07T21:57:47.000Z","updated_at":"2024-03-09T12:07:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"7eed58a9-dc1e-4a9e-adbf-ddfbfb0d9686","html_url":"https://github.com/hugojosefson/deno-prevalence","commit_stats":null,"previous_names":["hugojosefson/deno-prevalence"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/hugojosefson/deno-prevalence","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugojosefson%2Fdeno-prevalence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugojosefson%2Fdeno-prevalence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugojosefson%2Fdeno-prevalence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugojosefson%2Fdeno-prevalence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hugojosefson","download_url":"https://codeload.github.com/hugojosefson/deno-prevalence/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugojosefson%2Fdeno-prevalence/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264502666,"owners_count":23618671,"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":["deno","deno-kv","prevalence","prevayler"],"created_at":"2024-12-04T18:20:43.553Z","updated_at":"2026-04-16T11:04:20.464Z","avatar_url":"https://github.com/hugojosefson.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# prevalence\n\n[System prevalence](https://en.wikipedia.org/wiki/System_prevalence) as a typed\nlibrary, using [Deno.Kv](https://deno.com/kv) for storage.\n\n[![deno.land/x/prevalence](https://shield.deno.dev/x/prevalence)](https://deno.land/x/prevalence)\n[![CI](https://github.com/hugojosefson/deno-prevalence/actions/workflows/ci.yaml/badge.svg)](https://github.com/hugojosefson/deno-prevalence/actions/workflows/ci.yaml)\n\nTypeScript implementation for Deno of the Prevalence design pattern, as\nintroduced by Klaus Wuestefeld in 1998 with [Prevayler](https://prevayler.org/).\n\nSaves periodical snapshots of the whole model for faster startup, and keeps a\njournal of executed actions since last snapshot, using a\n[Persister](https://deno.land/x/prevalence/mod.ts?s=Persister). The `Persister`\nuses a [Marshaller](https://deno.land/x/prevalence/mod.ts?s=Marshaller) to\nserialize/deserialize the model and the journal.\n\n## Requirements\n\nRequires [Deno](https://deno.land/) v1.32 or later, with the `--unstable` flag.\n\n## API\n\nPlease see the\n[auto-generated API documentation](https://deno.land/x/prevalence?doc).\n\n## Example usage\n\n```typescript\nimport {\n  Action,\n  KvPersister,\n  logger,\n  Marshaller,\n  Model,\n  Persister,\n  Prevalence,\n  SerializableClassesContainer,\n  SuperserialMarshaller,\n} from \"https://deno.land/x/prevalence/mod.ts\";\nimport { Serializer } from \"https://deno.land/x/superserial@0.3.4/serializer.ts\";\n\nconst log = logger(import.meta.url);\n\nclass User {\n  constructor(\n    readonly uuid: string,\n    public displayName: string,\n  ) {}\n}\nconst alice: User = new User(\"1\", \"Alice\");\n\ntype Post = {\n  id: string;\n  subject: string;\n};\n\nclass MyModel implements Model\u003cMyModel\u003e {\n  constructor(\n    public posts: Record\u003cstring, Post\u003e,\n    public users: Record\u003cstring, User\u003e,\n  ) {}\n}\n\nclass AddPostAction implements Action\u003cMyModel\u003e {\n  constructor(public post: Post) {}\n  execute(model: MyModel): void {\n    model.posts[this.post.id] = this.post;\n  }\n}\n\nclass RemovePostAction implements Action\u003cMyModel\u003e {\n  constructor(public postId: string) {}\n  execute(model: MyModel): void {\n    delete model.posts[this.postId];\n  }\n}\n\nclass AddUserAction implements Action\u003cMyModel\u003e {\n  constructor(public user: User) {}\n  execute(model: MyModel): void {\n    model.users[this.user.uuid] = this.user;\n  }\n}\n\nclass RemoveUserAction implements Action\u003cMyModel\u003e {\n  constructor(public userId: string) {}\n  execute(model: MyModel): void {\n    delete model.users[this.userId];\n  }\n}\n\nconst classes: SerializableClassesContainer = {\n  User,\n  MyModel,\n  AddPostAction,\n  RemovePostAction,\n  AddUserAction,\n  RemoveUserAction,\n};\n\nconst marshaller: Marshaller\u003cMyModel, string\u003e = new SuperserialMarshaller\u003c\n  MyModel\n\u003e(\n  new Serializer({ classes }),\n);\nconst kv: Deno.Kv = await Deno.openKv(\"example-person-invoice.db\");\nconst persister: Persister\u003cMyModel\u003e = new KvPersister\u003cMyModel, string\u003e(\n  marshaller,\n  kv,\n);\nconst defaultInitialModel: MyModel = { posts: {}, users: {} };\nconst prevalence: Prevalence\u003cMyModel\u003e = await Prevalence.create\u003cMyModel\u003e(\n  defaultInitialModel,\n  { persister, classes },\n);\n\nawait prevalence.execute(new AddPostAction({ id: \"post#1\", subject: \"Lorem\" }));\nawait prevalence.execute(new AddPostAction({ id: \"post#2\", subject: \"Ipsum\" }));\nawait prevalence.execute(new AddPostAction({ id: \"post#3\", subject: \"Dolor\" }));\nawait prevalence.execute(new RemovePostAction(\"post#2\"));\nawait prevalence.execute(new AddUserAction(alice));\n\nconst posts: Post[] = Object.values(prevalence.model.posts);\n\nlog(\"Posts:\");\nfor (const post of posts) {\n  log(`${post.id}: ${post.subject}`);\n}\nlog(\"Users:\");\nfor (const user of Object.values(prevalence.model.users)) {\n  log(`${user.uuid}: ${user.displayName}`);\n}\n\nawait prevalence.execute(new RemoveUserAction(alice.uuid));\nlog(\"Users:\");\nfor (const user of Object.values(prevalence.model.users)) {\n  log(`${user.uuid}: ${user.displayName}`);\n}\n\nawait prevalence.snapshot();\n\nlog(\"Done.\");\n```\n\nYou may run the above example with:\n\n```sh\nDEBUG='*' deno run --unstable --allow-env=DEBUG --reload --allow-write=example-person-invoice.db --allow-read=example-person-invoice.db https://deno.land/x/prevalence/readme/person-invoice.ts\n```\n\nFor further usage examples, see the tests:\n\n- [test/prevalence.test.ts](test/prevalence.test.ts)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhugojosefson%2Fdeno-prevalence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhugojosefson%2Fdeno-prevalence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhugojosefson%2Fdeno-prevalence/lists"}