{"id":37034491,"url":"https://github.com/accelatrix/accelatrix","last_synced_at":"2026-01-14T04:02:29.100Z","repository":{"id":247100392,"uuid":"824987656","full_name":"accelatrix/accelatrix","owner":"accelatrix","description":"A parallel functional programming framework for in-browser processing of enumerations of business entities","archived":false,"fork":false,"pushed_at":"2025-08-25T14:18:10.000Z","size":1907,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-26T08:58:21.958Z","etag":null,"topics":["browser","javascript","javascript-framework","linq","linq-expressions","linq-to-objects","parallel-processing","parallel-programming","strong-typed","type-application","typescript","typescript-library","web-workers"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/accelatrix.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":"2024-07-06T13:15:21.000Z","updated_at":"2025-08-25T14:18:13.000Z","dependencies_parsed_at":"2024-10-24T14:19:55.361Z","dependency_job_id":null,"html_url":"https://github.com/accelatrix/accelatrix","commit_stats":null,"previous_names":["accelatrix/accelatrix"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/accelatrix/accelatrix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accelatrix%2Faccelatrix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accelatrix%2Faccelatrix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accelatrix%2Faccelatrix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accelatrix%2Faccelatrix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/accelatrix","download_url":"https://codeload.github.com/accelatrix/accelatrix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/accelatrix%2Faccelatrix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["browser","javascript","javascript-framework","linq","linq-expressions","linq-to-objects","parallel-processing","parallel-programming","strong-typed","type-application","typescript","typescript-library","web-workers"],"created_at":"2026-01-14T04:02:28.447Z","updated_at":"2026-01-14T04:02:29.087Z","avatar_url":"https://github.com/accelatrix.png","language":null,"readme":"# Accelatrix\r\n\r\n\u003e A parallel functional programming framework for in-browser processing of enumerations of business entities.\r\n\u003e v1.7.3 is compatible with ECMAScript 5, ES6, TypeScript, React, Angular and Vue.\r\n\r\nIf you would like to have a typed C#-like runtime in the browser capable of type introspection at runtime instead of just at designtime with TypeScript, you reached the right place.\r\n\r\nIf you are a fan of LINQ for Objects and enumerations, you definitely reached the right place.\r\n\r\nIf you are looking for a low-friction way to tackle multithreading in the browser, this is your ticket in.\r\n\r\nAccelatrix is free for non-commercial use, evaluation purposes, or commercial use without a user login wall. Detailed license at https://github.com/accelatrix/accelatrix/blob/main/LICENSE.md\r\n\r\n\r\n## Putting Accelatrix to use\r\n\r\nYou can host the minified file yourself or simply include the latest version hosted by the author:\r\n```html\r\n\u003cscript src=\"https://ferreira-family.org/accelatrix/accelatrix.min.js\"\u003e\u003c/script\u003e\r\n```\r\n\r\nOr you can install this package as a Node module using:\r\n```sh\r\nnpm install accelatrix\r\n```\r\n\r\nOr add it to your .Net project using NuGet:\r\n```sh\r\ndotnet add package Accelatrix\r\n```\r\n\r\nYou can then import Accelatrix in your TS file:\r\n```js\r\nimport Accelatrix from \"accelatrix/accelatrix\";\r\n```\r\n\r\nThe CommonJS syntax is also supported:\r\n```js\r\nconst Accelatrix = require(\"accelatrix/accelatrix\");\r\n```\r\n\r\nIf you are using Vite as your package manager, tell it not to attempt to rename symbols in your vite.config.js file, e.g.:\r\n```js\r\nimport { defineConfig } from 'vite';\r\nimport angular from 'vite-plugin-angular';\r\n\r\nexport default defineConfig({\r\n  plugins: [angular()],\r\n  build: {\r\n    minify: 'esbuild',\r\n    esbuild: {\r\n      legalComments: 'none',\r\n      preserveSymbols: true,\r\n    },\r\n  },\r\n});\r\n```\r\n\r\nIf you are compiling to ES5, make sure to make the compiler aware of the ES6 library in your ts.config file, e.g.:\r\n```json\r\n{\r\n    \"compilerOptions\":\r\n    {\r\n        \"target\": \"es5\",\r\n        \"module\": \"es6\",\r\n        \"moduleResolution\": \"classic\",\r\n        \"typeRoots\": [\"node_modules/@types\"],\r\n        \"lib\": [\"es5\", \"es6\", \"dom\"],\r\n    },\r\n    \"exclude\": [\"node_modules\", \"typings/browser\", \"typings/browser.d.ts\"],\r\n}\r\n```\r\n\r\nIf you are using Visual Studio and compiling to ES5, change your .csproj to include ES6 types, e.g.:\r\n```xml\r\n\u003cPropertyGroup\u003e\r\n  \u003c!-- compile target --\u003e\r\n  \u003cTypeScriptTarget\u003eES5\u003c/TypeScriptTarget\u003e\r\n\r\n  \u003c!-- comma-separated list of libs --\u003e\r\n  \u003cTypeScriptLib\u003ees5,es6,dom\u003c/TypeScriptLib\u003e\r\n\u003c/PropertyGroup\u003e\r\n```\r\n\r\n\r\n## A type introspection system\r\n\r\nThe type system of JavaScript is enhanced to include the four fundamental operations:\r\n\r\n    - GetHashCode()\r\n    - GetType()\r\n    - Equals()\r\n    - ToString()\r\n\r\nYou can now deal with classes in JavaScript at runtime as you would in C#, e.g.:\r\n\r\n```js\r\nvar myDog = new Bio.Mammal(8);  \r\nvar myCat = new Bio.Feline(8, 9);\r\n\r\nvar timeIsSame = (new Date()).Equals(new Date());                //true           \r\nvar areEqual = myDog.Equals(myCat);                              // false           \r\nvar myCatType = myCat.GetType();                                 // Bio.Feline           \r\nvar myCatBaseType = myCat.GetType().BaseType;                    // Bio.Mammal           \r\nvar isAnimal = myCat.GetType().IsAssignableFrom(Bio.Animal);     // true           \r\nvar enums = Bio.TypesOfLocomotion.GetType();                     // Accelatrix.EnumType \r\n```\r\n\r\n**********************************************\r\n// sample classes in TypeScript:\r\n\r\n```js\r\nexport namespace Bio\r\n{           \r\n    export enum TypesOfLocomotion           \r\n    {           \r\n        Crawl,           \r\n        Swim,           \r\n        Walk,           \r\n        Fly,           \r\n    }\r\n\r\n    abstract class LivingBeing\r\n    {\r\n        public isExtinct = false;\r\n    }\r\n\r\n    export abstract class Eukaryotes extends LivingBeing\r\n    {\r\n        private locomotion: TypesOfLocomotion = null;\r\n\r\n        public get Locomotion(): TypesOfLocomotion\r\n        {\r\n            return this.locomotion;\r\n        }\r\n        public set Locomotion(value: TypesOfLocomotion)\r\n        {\r\n            this.locomotion = value;\r\n        }\r\n    }\r\n\r\n    export class Animal extends Eukaryotes\r\n    {\r\n        public isAnimal = true;\r\n\r\n        public constructor()\r\n        {\r\n            super();\r\n        }\r\n    }\r\n    \r\n    export class Mammal extends Animal\r\n    {\r\n        private readonly numberOfTits: number;\r\n\r\n        public constructor(numberOfTits: number)\r\n        {\r\n            super();\r\n            this.numberOfTits = numberOfTits;\r\n        }\r\n\r\n        public get NumberOfTits(): number\r\n        {\r\n            return this.numberOfTits;\r\n        }\r\n\r\n        public SayHello(): string\r\n        {\r\n            return \"Hello\";\r\n        }\r\n    }\r\n\r\n    export class Feline extends Mammal\r\n    {\r\n        private readonly numberOfLives: number;\r\n\r\n        public constructor(numberOfTits: number, numberOfLives: number)\r\n        {\r\n            super(numberOfTits);\r\n            this.numberOfLives = numberOfLives == null ? 9 : numberOfLives;\r\n            this.Locomotion = TypesOfLocomotion.Walk;\r\n        }\r\n\r\n        public get NumberOfLives(): number\r\n        {\r\n            return this.numberOfLives;\r\n        }\r\n    }\r\n\r\n    export class Canine extends Mammal\r\n    {\r\n        private readonly numberOfTeeth: number;\r\n\r\n        public constructor(numberOfTits: number, numberOfTeeth: number)\r\n        {\r\n            super(numberOfTits);\r\n\r\n            if (numberOfTeeth == null)\r\n                throw new self[\"Accelatrix\"].ArgumentNullException(\"numberOfTeeth\");\r\n\r\n            this.numberOfTeeth = numberOfTeeth;\r\n            this.Locomotion = TypesOfLocomotion.Walk;\r\n        }\r\n\r\n        public get NumberOfTeeth(): number\r\n        {\r\n            return this.numberOfTeeth;\r\n        }\r\n\r\n        public static Wolf =  class Wolf extends Canine\r\n                               {\r\n                                   constructor()\r\n                                   {\r\n                                        super(8, 42);\r\n                                   }\r\n                               }\r\n\r\n        public static Dog =  class Dog extends Canine\r\n                               {\r\n                                   constructor()\r\n                                   {\r\n                                        super(8, 42);\r\n                                   }\r\n                               }\r\n    }        \r\n}\r\n```\r\n\r\n\r\n## Enumerations and Functional Programming\r\n\r\nYou can now use your favourite LINQ functions operating on enumerations, not collections, and arrays are now enumerations as well, e.g.:\r\n\r\n```js\r\n  var myEnumeration = Accelatrix.Collections.Enumerable.Range(0, 10000000)\r\n                                            .Select(z =\u003e z % 2 == 0\r\n                                                         ? new Bio.Feline(z % 10, 9)\r\n                                                         : new Bio.Mammal(z % 10))\r\n                                            .OfType(Bio.Mammal)\r\n                                            .Where(z =\u003e z.NumberOfTits != 1)\r\n                                            .GroupBy(z =\u003e z.NumberOfTits)\r\n\r\n  var myResult = myEnumeration.Skip(2)\r\n                              .Take(4)\r\n                              .ToList()\r\n                              .OrderBy(z =\u003e z.NumberOfTits);\r\n```                              \r\n\r\n\r\n## Async Enumerations and Functional Programming\r\n\r\nYou can now use your favourite LINQ functions operating on enumerations where members are calculated async and are (cancellable) promises e.g.:\r\n\r\n```js\r\n  var myEnumeration = new Accelatrix.Collections.AsyncEnumerable(Accelatrix.Collections.Enumerable.Range(0, 10000000))\r\n                                                .Select(z =\u003e Accelatrix.Async.AsPromise(z)) // creates a self-resolving promise\r\n                                                .Skip(2)\r\n                                                .Take(4)\r\n                                            \r\n  await myEnumeration.ToList();\r\n\r\n```                              \r\n\r\n\r\n## Typed JSON deserialization \r\n\r\nThe typed JSON deserializer deserializes your JSON response into your own class types instead of plain Object.\r\nYou can also control the serialization process by making use of the following decorators:\r\n\r\n    - @KnownType\r\n    - @DataMember\r\n    - @OnSerializing\r\n    - @OnSerialized    \r\n    - @OnDeserializing\r\n    - @OnDeserialized\r\n\r\nThis allows class properties to be stringified, but keep the underlying attributes out.\r\n\r\nThe deserialization respects [$type] when present and can cope with functions and arrow functions.\r\n\r\n\r\n```js\r\nvar x = Accelatrix.Serialization.ToJSON(SerializationTests.GetClassInstance())\r\n\r\n// '{\"$type\":\"SerializableClass\",\"NameProp\":\"Test Sat Jul 13 2024 09:12:03 GMT+0200 (Central European Summer Time)\",\"Time\":\"2024-07-13T09:12:03.527\"}'\r\n\r\n\r\nvar y = Accelatrix.Serialization.FromJSON(x)\r\nconsole.log(y.GetType())  // SerializableClass\r\n\r\n```\r\n\r\nEven Enumerations with their functions can be serialized and deserialized:\r\n\r\n```js\r\nvar myEnumerable = Accelatrix.Collections.Enumerable\r\n                             .Range(0, 10)\r\n                             .Select(z =\u003e new Bio.Canine(z, 2))\r\n                             .OfType(Bio.Mammal)\r\n                             .Where(z =\u003e z.NumberOfTits % 2 == 0);  // enumeration not executed\r\n\r\nvar serialised = Accelatrix.Serialization.ToJSON(myEnumerable);     // enumeration not executed\r\n\r\nvar newEnumeration = Accelatrix.Serialization.FromJSON(serialised); // enumeration not executed\r\n\r\nconsole.log(newEnumeration);\r\nconsole.log(newEnumeration.ToList());  // enumeration executed\r\n\r\n```\r\n\r\nTry it yourself with these classes:\r\n\r\n```js\r\nexport module SerializationTests\r\n{\r\n    export function GetClassInstance()\r\n    {\r\n        return new SerializableClass(\"Test \" + (new Date()).toString());\r\n    }\r\n\r\n    class BaseSerializableClass\r\n    {\r\n        @Accelatrix.Serialization.DataMember(false)\r\n        private baseTime: Date = new Date();\r\n\r\n        /** Field will be serialized and when deserialised the value will be retained. */\r\n        @Accelatrix.Serialization.DataMember()\r\n        public get Time(): Date\r\n        {\r\n            return this.baseTime;\r\n        }\r\n        public set Time(value: Date)\r\n        {\r\n            this.baseTime = value;\r\n        }        \r\n    }\r\n\r\n    @Accelatrix.Serialization.KnownType\r\n    class SerializableClass extends BaseSerializableClass\r\n    {\r\n        /** Field will NOT be serialized. */\r\n        @Accelatrix.Serialization.DataMember(false)        \r\n        private name: string;\r\n\r\n        public constructor(name: string)\r\n        {\r\n            super();\r\n            this.name = name;\r\n        }\r\n\r\n        /** Property will be serialized. */\r\n        @Accelatrix.Serialization.DataMember()\r\n        public get NameProp(): string\r\n        {\r\n            return this.name;\r\n        }\r\n        public set NameProp(value: string)\r\n        {\r\n            this.name = value;\r\n        }\r\n\r\n        @Accelatrix.Serialization.OnSerializing()        \r\n        private OnSerializing()\r\n        {\r\n            console.log(\"About to serialize\");\r\n        }\r\n\r\n        @Accelatrix.Serialization.OnSerialized()\r\n        private OnSerialized()\r\n        {\r\n            console.log(\"Serialized complete.\");\r\n        }\r\n\r\n        @Accelatrix.Serialization.OnDeserializing()\r\n        private OnDeserializing()\r\n        {\r\n            console.log(\"About to deserialize\");\r\n        }\r\n\r\n        @Accelatrix.Serialization.OnDeserialized()\r\n        private OnDeserialized()\r\n        {\r\n            console.log(\"Deserialization complete.\");\r\n        }            \r\n    }\r\n}\r\n\r\n```\r\n\r\n##  Parallel execution with multithreading\r\n\u003e a Task system with Web Workers \r\n\r\nEver wanted to cater for parallel execution in the browser, but find the Web Workers specification too low-level\r\nand cumbersome to be of any use?! \r\n\r\nDo you appreciate the ellegance of C#'s Tasks and would like to have something similar in the browser?\r\nAlways type-centric?!\r\n\r\n\r\n```js\r\n// one-time init with the Scripts made available to the Workers (no DOM stuff)\r\n// Accelatrix already includes itself and you do not need to worry about it\r\nAccelatrix.Tasks.Config.Scripts.push( // ....... your scripts here\r\n\r\n// Example 1\r\nvar myTask = new Accelatrix.Tasks.Task(z =\u003e \"Hello \" + z.toString(), \"John Doe\");\r\nvar cancellablePromise = myTask.Start();\r\n\r\ncancellablePromise.Then(result =\u003e console.log(result))\r\n                  .Catch(ex =\u003e console.error(ex))\r\n                  .Finally(task =\u003e console.log(task));\r\n\r\n// Example 2\r\nvar myData = [ new Bio.Canine.Dog(), new Bio.Canine.Wolf(), new Bio.Feline(8, 9) ]\r\n\r\nAccelatrix.Tasks.Task.StartNew(data =\u003e data.Where(z =\u003e z.NumberOfLives == null).Distinct().ToList(), myData)\r\n                     .GetAwaiter()\r\n                     .Then(result =\u003e console.log(result))\r\n                     .Catch(ex =\u003e console.error(ex))\r\n                     .Finally(task =\u003e console.log(task));\r\n\r\n// Example 3: you can even pass enumerations and have them execute in the Web Worker\r\nvar myData = Accelatrix.Collections.Enumerable\r\n                                   .Range(0, 100000)\r\n                                   .Select(z =\u003e new Bio.Feline(z % 3 == 0 ? 8 : 6, 9));  // nothing executed\r\n\r\nAccelatrix.Tasks.Task.StartNew(data =\u003e data.Distinct().ToList(), myData)\r\n                     .GetAwaiter()\r\n                     .Then(result =\u003e console.log(result))\r\n                     .Catch(ex =\u003e console.error(ex))\r\n                     .Finally(task =\u003e console.log(task));\r\n\r\n\r\n// Example 4: Stress-load with 100 parallel requests\r\nAccelatrix.Collections.Enumerable\r\n                      .Range(0, 100)\r\n                      .ForEach(z =\u003e\r\n                      {\r\n                            Accelatrix.Tasks.Task.StartNew(data =\u003e data.Distinct().ToList(), myData)\r\n                                                 .GetAwaiter()\r\n                                                 .Finally(task =\u003e console.log(\"Task: \" + z.toString()));\r\n                      });\r\n\r\n\r\n// Example 5: Combine tasks into a single resultset\r\nAccelatrix.Tasks.CombinedTask.StartNew([\r\n                                            new Accelatrix.Tasks.Task((a, b) =\u003e Accelatrix.Collections.Enumerable.Range(a, b).ToList(), 0, 20),\r\n                                            new Accelatrix.Tasks.Task(() =\u003e Accelatrix.Collections.Enumerable.Range(20, 20).ToList()),\r\n                                            () =\u003e Accelatrix.Collections.Enumerable.Range(40, 20).ToList(),\r\n                                       ])\r\n                             .GetAwaiter()\r\n                             .Then(result =\u003e console.log(result))\r\n                             .Catch(ex =\u003e console.error(ex))\r\n                             .Finally(task =\u003e console.log(task));                   \r\n\r\n\r\n// Example 6: Share state between parallel activies (with a cost!)\r\n// This example will produce a single result from the task that runs first\r\nvar shared = new Accelatrix.Tasks.StatefulActivity\u003cnumber[]\u003e();\r\n\r\nAccelatrix.Tasks.CombinedTask.StartNew([\r\n\t\t\t\t\t   new Accelatrix.Tasks.ActivitySet([\r\n\t\t\t\t\t\t\t\t\t\tz =\u003e z.Take(1),\r\n\t\t\t\t\t\t\t\t\t\tshared.PushAndEvaluate(z =\u003e 1,\r\n                                                               (accumulated, mine) =\u003e accumulated.Where(z =\u003e z != null).Any()\r\n                                                                                      ? z =\u003e z.Take(0)\r\n                                                                                      : z =\u003e z ),\r\n\t\t\t\t\t\t\t\t\t\tz =\u003e z.ToList()\r\n\t\t\t\t\t\t\t\t\t  ],\r\n\t\t\t\t\t\t\t\t\t  [[0, 1, 2, 3, 4, 5]]),\r\n\t\t\t\t\t   new Accelatrix.Tasks.ActivitySet([\r\n\t\t\t\t\t\t\t\t\t\tz =\u003e z.Take(3),\r\n\t\t\t\t\t\t\t\t\t\tshared.PushAndEvaluate(z =\u003e 3,\r\n                                                               (accumulated, mine) =\u003e accumulated.Where(z =\u003e z != null).Any()\r\n                                                                                      ? z =\u003e z.Take(0)\r\n                                                                                      : z =\u003e z.Take(1) ),\r\n\t\t\t\t\t\t\t\t\t\tz =\u003e z.ToList()\r\n\t\t\t\t\t\t\t\t\t  ],\r\n\t\t\t\t\t\t\t\t\t  [[6, 7, 8, 9,10, 11]])\r\n\t\t\t\t\t])\r\n\t\t\t       .GetAwaiter()\r\n\t\t\t       .Then(z =\u003e console.log(z))\r\n\t\t\t       .Catch(ex =\u003e console.error(ex))\r\n\t\t\t       .Finally(t =\u003e shared.Dispose())\r\n```\r\n\r\n\r\n## Parallel Enumerations\r\n\r\nParallel execution of enumerations with a .AsParallel() that parallelises execution across different threads \r\nis possible with the .AsParallel() function, e.g.:\r\n\r\n```js\r\nAccelatrix.Collections.Enumerable\r\n                      .Range(0, 100)\r\n                      .AsParallel() // sends everything to threads                      \r\n                      .Select(z =\u003e \"Item \" + z.toString())\r\n                      .Skip(2)\r\n                      .Take(10)                      \r\n                      .ToList()\r\n                          .Catch(ex =\u003e console.error(ex))\r\n                          .Then(z =\u003e console.log(z))                          \r\n``` \r\nThe location of .AsParallel() in the chain gives you control at which point operations are moved to parallel execution as DOM operations need to remain in the UI thread.\r\nIt is also possible to await on the result of a Parallel enumeration, e.g.:\r\n\r\n```js\r\nawait [1, 2, 3, 4, 5, .....].AsParallel() // sends everything to threads                      \r\n                            .Select(z =\u003e z * -1)\r\n                            .Where(z =\u003e z % 2 == 0)\r\n                            .ToList()                     \r\n``` \r\n\r\n# Tell us about your experience\r\n\u003e Please take a minute to [tell us](https://ferreira-family.org/Accelatrix/Questionnaire) about your experience and help make Accelatrix even better.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccelatrix%2Faccelatrix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faccelatrix%2Faccelatrix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccelatrix%2Faccelatrix/lists"}