├── .nvmrc ├── javascript ├── .npmrc ├── dist │ ├── cjs │ │ └── src │ │ │ ├── index.es5.d.ts │ │ │ ├── types │ │ │ ├── mongo.js │ │ │ ├── mongo.js.map │ │ │ ├── change-event.js │ │ │ ├── change-event.js.map │ │ │ ├── mongo.d.ts │ │ │ ├── index.js.map │ │ │ ├── change-event.d.ts │ │ │ ├── index.js │ │ │ └── index.d.ts │ │ │ ├── truth-table-generator │ │ │ ├── types.js │ │ │ ├── types.js.map │ │ │ ├── util.d.ts │ │ │ ├── runner.node.d.ts │ │ │ ├── config.d.ts │ │ │ ├── types.d.ts │ │ │ ├── database │ │ │ │ ├── mingo.d.ts │ │ │ │ ├── index.js.map │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── mingo.js.map │ │ │ │ └── mingo.js │ │ │ ├── util.js.map │ │ │ ├── config.js.map │ │ │ ├── procedures.d.ts │ │ │ ├── fuzzing.d.ts │ │ │ ├── binary-state.d.ts │ │ │ ├── queries.d.ts │ │ │ ├── config.js │ │ │ ├── data-generator.d.ts │ │ │ ├── index.d.ts │ │ │ ├── calculate-bdd-quality.d.ts │ │ │ ├── util.js │ │ │ ├── binary-state.js.map │ │ │ ├── binary-state.js │ │ │ ├── fuzzing.js.map │ │ │ └── index.js.map │ │ │ ├── index.es5.js.map │ │ │ ├── bdd │ │ │ ├── bdd.template.d.ts │ │ │ ├── write-bdd-template.d.ts │ │ │ ├── bdd.template.js.map │ │ │ ├── bdd.generated.js.map │ │ │ ├── bdd.template.js │ │ │ ├── write-bdd-template.js.map │ │ │ ├── bdd.generated.js │ │ │ ├── bdd.generated.d.ts │ │ │ └── write-bdd-template.js │ │ │ ├── actions │ │ │ ├── index.d.ts │ │ │ ├── index.js.map │ │ │ ├── action-functions.d.ts │ │ │ └── index.js │ │ │ ├── states │ │ │ ├── index.d.ts │ │ │ ├── state-resolver.d.ts │ │ │ └── index.js.map │ │ │ ├── index.js.map │ │ │ ├── index.es5.js │ │ │ ├── index.d.ts │ │ │ ├── util.d.ts │ │ │ └── index.js │ └── esm │ │ └── src │ │ ├── index.es5.d.ts │ │ ├── package.json │ │ ├── types │ │ ├── mongo.js │ │ ├── change-event.js │ │ ├── index.js │ │ ├── mongo.js.map │ │ ├── change-event.js.map │ │ ├── mongo.d.ts │ │ ├── index.js.map │ │ ├── change-event.d.ts │ │ └── index.d.ts │ │ ├── truth-table-generator │ │ ├── types.js │ │ ├── types.js.map │ │ ├── util.d.ts │ │ ├── runner.node.d.ts │ │ ├── config.d.ts │ │ ├── types.d.ts │ │ ├── database │ │ │ ├── mingo.d.ts │ │ │ ├── index.js.map │ │ │ ├── index.js │ │ │ ├── index.d.ts │ │ │ ├── mingo.js.map │ │ │ └── mingo.js │ │ ├── util.js │ │ ├── config.js │ │ ├── util.js.map │ │ ├── procedures.d.ts │ │ ├── config.js.map │ │ ├── fuzzing.d.ts │ │ ├── binary-state.d.ts │ │ ├── queries.d.ts │ │ ├── data-generator.d.ts │ │ ├── index.d.ts │ │ ├── calculate-bdd-quality.d.ts │ │ ├── binary-state.js │ │ ├── binary-state.js.map │ │ ├── fuzzing.js.map │ │ ├── index.js.map │ │ └── fuzzing.js │ │ ├── index.es5.js │ │ ├── index.es5.js.map │ │ ├── bdd │ │ ├── bdd.template.d.ts │ │ ├── write-bdd-template.d.ts │ │ ├── bdd.template.js.map │ │ ├── bdd.generated.js.map │ │ ├── bdd.template.js │ │ ├── write-bdd-template.js.map │ │ ├── write-bdd-template.js │ │ ├── bdd.generated.js │ │ └── bdd.generated.d.ts │ │ ├── actions │ │ ├── index.d.ts │ │ ├── index.js.map │ │ ├── action-functions.d.ts │ │ └── index.js │ │ ├── states │ │ ├── index.d.ts │ │ ├── state-resolver.d.ts │ │ ├── index.js.map │ │ └── index.js │ │ ├── index.js.map │ │ ├── index.js │ │ ├── index.d.ts │ │ └── util.d.ts ├── src │ ├── index.es5.ts │ ├── types │ │ ├── mongo.ts │ │ ├── change-event.ts │ │ └── index.ts │ ├── truth-table-generator │ │ ├── types.ts │ │ ├── util.ts │ │ ├── config.ts │ │ ├── database │ │ │ ├── index.ts │ │ │ └── mingo.ts │ │ └── binary-state.ts │ ├── bdd │ │ ├── bdd.template.ts │ │ ├── bdd.generated.ts │ │ ├── write-bdd-template.ts │ │ └── bdd.optimize.state.json │ ├── actions │ │ └── index.ts │ ├── index.ts │ └── states │ │ └── index.ts ├── fuzzing-nohup.sh ├── .npmignore ├── optimize-nohup.sh ├── .gitignore ├── perf.md ├── test │ ├── unit │ │ ├── index.test.ts │ │ ├── fuzzing.test.ts │ │ ├── queries.test.ts │ │ ├── minimongo.test.ts │ │ ├── truth-table-generator.test.ts │ │ ├── binary-state.test.ts │ │ └── calculate-bdd-quality.test.ts │ └── helper │ │ └── input.ts ├── truth-table-generator │ └── package.json ├── tsconfig.json ├── DEVELOPER.md ├── tslint.json └── README.md ├── examples └── browser │ ├── .npmrc │ ├── .gitignore │ ├── README.md │ ├── tsconfig.json │ ├── webpack.js │ ├── src │ ├── types.ts │ ├── util.ts │ └── logs.ts │ ├── test │ └── e2e.test.ts │ ├── package.json │ ├── index.html │ └── tslint.json ├── .github ├── FUNDING.yml └── workflows │ └── main.yml ├── orga ├── event-reduce.png └── event-reduce.drawio ├── renovate.json ├── LICENSE └── docs ├── bundle.js.LICENSE.txt └── index.html /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.9.0 2 | -------------------------------------------------------------------------------- /javascript/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /examples/browser/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /examples/browser/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist -------------------------------------------------------------------------------- /javascript/dist/cjs/src/index.es5.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/index.es5.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/package.json: -------------------------------------------------------------------------------- 1 | { "type": "module", "sideEffects": false } 2 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/mongo.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=mongo.js.map -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: pubkey 4 | -------------------------------------------------------------------------------- /examples/browser/README.md: -------------------------------------------------------------------------------- 1 | # examples that run in the browser and are used in the test-page -------------------------------------------------------------------------------- /javascript/src/index.es5.ts: -------------------------------------------------------------------------------- 1 | import * as pkg from './index.js'; 2 | module.exports = pkg; 3 | -------------------------------------------------------------------------------- /javascript/fuzzing-nohup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | nohup npm run fuzzing-parallel & 5 | -------------------------------------------------------------------------------- /orga/event-reduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pubkey/event-reduce/HEAD/orga/event-reduce.png -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/types.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=types.js.map -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/change-event.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=change-event.js.map -------------------------------------------------------------------------------- /javascript/.npmignore: -------------------------------------------------------------------------------- 1 | /test 2 | perf.md 3 | tsconfig.json 4 | tslint.json 5 | dist/esm/test/ 6 | dist/cjs/test/ 7 | -------------------------------------------------------------------------------- /javascript/optimize-nohup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | nohup npm run optimize-parallel > optimize.nohup.out & 5 | -------------------------------------------------------------------------------- /javascript/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /src/logic-generator/logic-map-output/ 3 | *.out 4 | /dist/cjs/test/ 5 | /dist/esm/test/ 6 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/index.es5.js: -------------------------------------------------------------------------------- 1 | import * as pkg from './index.js'; 2 | module.exports = pkg; 3 | //# sourceMappingURL=index.es5.js.map -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/index.js: -------------------------------------------------------------------------------- 1 | export * from './change-event.js'; 2 | export * from './mongo.js'; 3 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/mongo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=mongo.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/mongo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"mongo.js","sourceRoot":"","sources":["../../../../src/types/mongo.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/mongo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"mongo.js","sourceRoot":"","sources":["../../../../src/types/mongo.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/types.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=types.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/change-event.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=change-event.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/change-event.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"change-event.js","sourceRoot":"","sources":["../../../../src/types/change-event.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/change-event.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"change-event.js","sourceRoot":"","sources":["../../../../src/types/change-event.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/mongo.d.ts: -------------------------------------------------------------------------------- 1 | export type MongoQuery = { 2 | selector: any; 3 | skip?: number; 4 | limit?: number; 5 | sort: string[]; 6 | }; 7 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/mongo.d.ts: -------------------------------------------------------------------------------- 1 | export type MongoQuery = { 2 | selector: any; 3 | skip?: number; 4 | limit?: number; 5 | sort: string[]; 6 | }; 7 | -------------------------------------------------------------------------------- /javascript/perf.md: -------------------------------------------------------------------------------- 1 | # find valid state sets 2 | 3 | BEFORE: 4 | 534 5 | 563 6 | 574 7 | 601 8 | 624 9 | 10 | 462 11 | 487 12 | 493 13 | 14 | # truth table: 15 | 16 | 230 states -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/types.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/types.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/util.d.ts: -------------------------------------------------------------------------------- 1 | export declare function readJsonFile(path: string): any; 2 | export declare function writeJsonFile(path: string, data: any): void; 3 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/types.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/types.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/util.d.ts: -------------------------------------------------------------------------------- 1 | export declare function readJsonFile(path: string): any; 2 | export declare function writeJsonFile(path: string, data: any): void; 3 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,oDAAkC;AAClC,6CAA2B"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/types/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/runner.node.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * sort object attributes 3 | * @link https://stackoverflow.com/a/39442287 4 | */ 5 | export declare function sortObject(obj: T): T; 6 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/runner.node.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * sort object attributes 3 | * @link https://stackoverflow.com/a/39442287 4 | */ 5 | export declare function sortObject(obj: T): T; 6 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/index.es5.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.es5.js","sourceRoot":"","sources":["../../../src/index.es5.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAkC;AAClC,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/index.es5.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.es5.js","sourceRoot":"","sources":["../../../src/index.es5.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAClC,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC"} -------------------------------------------------------------------------------- /javascript/src/types/mongo.ts: -------------------------------------------------------------------------------- 1 | export type MongoQuery = { 2 | selector: any; 3 | skip?: number; 4 | limit?: number; 5 | sort: string[] // sort is not optional because sorting must be predictable 6 | }; 7 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/config.d.ts: -------------------------------------------------------------------------------- 1 | export declare const OUTPUT_FOLDER_PATH: string; 2 | export declare const OUTPUT_TRUTH_TABLE_PATH: string; 3 | export declare const FUZZING_QUERIES_PATH: string; 4 | export declare const FUZZING_PROCEDURES_PATH: string; 5 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/config.d.ts: -------------------------------------------------------------------------------- 1 | export declare const OUTPUT_FOLDER_PATH: string; 2 | export declare const OUTPUT_TRUTH_TABLE_PATH: string; 3 | export declare const FUZZING_QUERIES_PATH: string; 4 | export declare const FUZZING_PROCEDURES_PATH: string; 5 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/types.d.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent, StateSet } from '../types/index.js'; 2 | export interface Human { 3 | _id: string; 4 | name: string; 5 | gender: 'm' | 'f'; 6 | age: number; 7 | } 8 | export type Procedure = ChangeEvent[]; 9 | export type StateActionIdMap = Map; 10 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/types.d.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent, StateSet } from '../types/index.js'; 2 | export interface Human { 3 | _id: string; 4 | name: string; 5 | gender: 'm' | 'f'; 6 | age: number; 7 | } 8 | export type Procedure = ChangeEvent[]; 9 | export type StateActionIdMap = Map; 10 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "statusCheckVerify": true, 6 | "ignoreDeps": [], 7 | "automerge": true, 8 | "major": { 9 | "automerge": true 10 | }, 11 | "ignorePaths": [], 12 | "rebaseStalePrs": true, 13 | "prHourlyLimit": 4, 14 | "dependencyDashboard": false 15 | } 16 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/database/mingo.d.ts: -------------------------------------------------------------------------------- 1 | import type { Collection } from '.'; 2 | import type { DeterministicSortComparator, MongoQuery } from '../../types'; 3 | export declare function mingoCollectionCreator(): Collection; 4 | export declare function getMingoSortComparator(query: MongoQuery): DeterministicSortComparator; 5 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/database/mingo.d.ts: -------------------------------------------------------------------------------- 1 | import type { Collection } from '.'; 2 | import type { DeterministicSortComparator, MongoQuery } from '../../types'; 3 | export declare function mingoCollectionCreator(): Collection; 4 | export declare function getMingoSortComparator(query: MongoQuery): DeterministicSortComparator; 5 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/bdd.template.d.ts: -------------------------------------------------------------------------------- 1 | import { SimpleBdd } from 'binary-decision-diagram'; 2 | import type { StateResolveFunctionInput } from '../types/index.js'; 3 | export declare const minimalBddString = "${minimalBddString}"; 4 | export declare function getSimpleBdd(): SimpleBdd; 5 | export declare const resolveInput: (input: StateResolveFunctionInput) => number; 6 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/bdd.template.d.ts: -------------------------------------------------------------------------------- 1 | import { SimpleBdd } from 'binary-decision-diagram'; 2 | import type { StateResolveFunctionInput } from '../types/index.js'; 3 | export declare const minimalBddString = "${minimalBddString}"; 4 | export declare function getSimpleBdd(): SimpleBdd; 5 | export declare const resolveInput: (input: StateResolveFunctionInput) => number; 6 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/util.js: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | export function readJsonFile(path) { 3 | const content = fs.readFileSync(path, 'utf-8'); 4 | return JSON.parse(content); 5 | } 6 | export function writeJsonFile(path, data) { 7 | fs.writeFileSync(path, JSON.stringify(data, null, 2), { encoding: 'utf8', flag: 'w' }); 8 | } 9 | //# sourceMappingURL=util.js.map -------------------------------------------------------------------------------- /javascript/src/truth-table-generator/types.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent, StateSet } from '../types/index.js'; 2 | 3 | export interface Human { 4 | _id: string; // primary 5 | name: string; 6 | gender: 'm' | 'f'; 7 | age: number; 8 | } 9 | 10 | // a procedure is a list of events used in tests 11 | export type Procedure = ChangeEvent[]; 12 | 13 | export type StateActionIdMap = Map; 14 | -------------------------------------------------------------------------------- /javascript/test/unit/index.test.ts: -------------------------------------------------------------------------------- 1 | console.log('### starting unit-tests ###'); 2 | import './minimongo.test.js'; 3 | import './actions.test.js'; 4 | import './states.test.js'; 5 | import './binary-state.test.js'; 6 | import './queries.test.js'; 7 | import './fuzzing.test.js'; 8 | import './calculate-bdd-quality.test.js'; 9 | import './truth-table-generator.test.js'; 10 | 11 | // should be last 12 | import './generated-stuff.test.js'; 13 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/write-bdd-template.d.ts: -------------------------------------------------------------------------------- 1 | import { PerformanceMeasurement } from '../truth-table-generator/calculate-bdd-quality.js'; 2 | export declare const BDD_TEMPLATE_LOCATION: string; 3 | export declare const BDD_OPTIMIZE_STATE_LOCATION: string; 4 | export declare const BDD_TEMPLATE_GOAL: string; 5 | export declare function writeBddTemplate(minimalBddString: string, performanceMeasurement: PerformanceMeasurement, quality: number): void; 6 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/write-bdd-template.d.ts: -------------------------------------------------------------------------------- 1 | import { PerformanceMeasurement } from '../truth-table-generator/calculate-bdd-quality.js'; 2 | export declare const BDD_TEMPLATE_LOCATION: string; 3 | export declare const BDD_OPTIMIZE_STATE_LOCATION: string; 4 | export declare const BDD_TEMPLATE_GOAL: string; 5 | export declare function writeBddTemplate(minimalBddString: string, performanceMeasurement: PerformanceMeasurement, quality: number): void; 6 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/actions/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ActionName, ActionFunction } from '../types/index.js'; 2 | export * from './action-functions.js'; 3 | /** 4 | * all actions ordered by performance-cost 5 | * cheapest first 6 | * TODO run tests on which is really the fastest 7 | */ 8 | export declare const orderedActionList: ActionName[]; 9 | export declare const actionFunctions: { 10 | [k in ActionName]: ActionFunction; 11 | }; 12 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/actions/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ActionName, ActionFunction } from '../types/index.js'; 2 | export * from './action-functions.js'; 3 | /** 4 | * all actions ordered by performance-cost 5 | * cheapest first 6 | * TODO run tests on which is really the fastest 7 | */ 8 | export declare const orderedActionList: ActionName[]; 9 | export declare const actionFunctions: { 10 | [k in ActionName]: ActionFunction; 11 | }; 12 | -------------------------------------------------------------------------------- /javascript/src/truth-table-generator/util.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | 3 | export function readJsonFile(path: string): any { 4 | const content = fs.readFileSync(path, 'utf-8'); 5 | return JSON.parse(content); 6 | } 7 | 8 | export function writeJsonFile( 9 | path: string, 10 | data: any 11 | ) { 12 | fs.writeFileSync( 13 | path, 14 | JSON.stringify(data, null, 2), 15 | { encoding: 'utf8', flag: 'w' } 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/config.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | export const OUTPUT_FOLDER_PATH = path.join(__dirname, 'output'); 3 | export const OUTPUT_TRUTH_TABLE_PATH = path.join(OUTPUT_FOLDER_PATH, 'truth-table.json').replace('dist/cjs/', ''); 4 | export const FUZZING_QUERIES_PATH = path.join(OUTPUT_FOLDER_PATH, 'queries.json').replace('dist/cjs/', ''); 5 | export const FUZZING_PROCEDURES_PATH = path.join(OUTPUT_FOLDER_PATH, 'procedures.json').replace('dist/cjs/', ''); 6 | //# sourceMappingURL=config.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/bdd.template.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"bdd.template.js","sourceRoot":"","sources":["../../../../src/bdd/bdd.template.ts"],"names":[],"mappings":";;;AAAA,qEAIiC;AAEjC,iDAAiE;AAEpD,QAAA,gBAAgB,GAAG,qBAAqB,CAAC;AAEtD,IAAI,SAAgC,CAAC;AACrC,SAAgB,YAAY;IACxB,IAAI,CAAC,SAAS,EAAE;QACZ,SAAS,GAAG,IAAA,kDAAwB,EAAC,wBAAgB,CAAC,CAAC;KAC1D;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AALD,oCAKC;AAEM,MAAM,YAAY,GAAG,CAAC,KAAqC,EAAE,EAAE;IAClE,OAAO,IAAA,8CAAoB,EACvB,YAAY,EAAE,EACd,sCAA2B,EAC3B,KAAK,CACR,CAAC;AACN,CAAC,CAAC;AANW,QAAA,YAAY,gBAMvB"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/bdd.generated.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"bdd.generated.js","sourceRoot":"","sources":["../../../../src/bdd/bdd.generated.ts"],"names":[],"mappings":";;;AAAA,qEAIiC;AAEjC,iDAAiE;AAEpD,QAAA,gBAAgB,GAAG,+pBAA+pB,CAAC;AAEhsB,IAAI,SAAgC,CAAC;AACrC,SAAgB,YAAY;IACxB,IAAI,CAAC,SAAS,EAAE;QACZ,SAAS,GAAG,IAAA,kDAAwB,EAAC,wBAAgB,CAAC,CAAC;KAC1D;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AALD,oCAKC;AAEM,MAAM,YAAY,GAAG,CAAC,KAAqC,EAAE,EAAE;IAClE,OAAO,IAAA,8CAAoB,EACvB,YAAY,EAAE,EACd,sCAA2B,EAC3B,KAAK,CACR,CAAC;AACN,CAAC,CAAC;AANW,QAAA,YAAY,gBAMvB"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/database/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/truth-table-generator/database/index.ts"],"names":[],"mappings":"AAEA,cAAc,YAAY,CAAC;AAkB3B,MAAM,UAAU,gBAAgB,CAC5B,UAAsB,EACtB,WAAiC;IAEjC,QAAQ,WAAW,CAAC,SAAS,EAAE;QAC3B,KAAK,QAAQ;YACT,UAAU,CAAC,MAAM,CACb,WAAW,CAAC,GAAU,CACzB,CAAC;YACF,MAAM;QACV,KAAK,QAAQ;YACT,UAAU,CAAC,MAAM,CACb,WAAW,CAAC,GAAU,CACzB,CAAC;YACF,MAAM;QACV,KAAK,QAAQ;YACT,UAAU,CAAC,MAAM,CACb,WAAW,CAAC,EAAE,CACjB,CAAC;YACF,MAAM;KACb;AACL,CAAC"} -------------------------------------------------------------------------------- /examples/browser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "strict": false, 6 | "moduleResolution": "node", 7 | "module": "es6", 8 | "target": "es5", 9 | "allowJs": true, 10 | "allowSyntheticDefaultImports": true, 11 | "esModuleInterop": true, 12 | "lib": [ 13 | "es2015", 14 | "dom" 15 | ] 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | ".git" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/database/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/truth-table-generator/database/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAEA,6CAA2B;AAkB3B,SAAgB,gBAAgB,CAC5B,UAAsB,EACtB,WAAiC;IAEjC,QAAQ,WAAW,CAAC,SAAS,EAAE;QAC3B,KAAK,QAAQ;YACT,UAAU,CAAC,MAAM,CACb,WAAW,CAAC,GAAU,CACzB,CAAC;YACF,MAAM;QACV,KAAK,QAAQ;YACT,UAAU,CAAC,MAAM,CACb,WAAW,CAAC,GAAU,CACzB,CAAC;YACF,MAAM;QACV,KAAK,QAAQ;YACT,UAAU,CAAC,MAAM,CACb,WAAW,CAAC,EAAE,CACjB,CAAC;YACF,MAAM;KACb;AACL,CAAC;AArBD,4CAqBC"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/database/index.js: -------------------------------------------------------------------------------- 1 | export * from './mingo.js'; 2 | export function applyChangeEvent(collection, changeEvent) { 3 | switch (changeEvent.operation) { 4 | case 'INSERT': 5 | collection.upsert(changeEvent.doc); 6 | break; 7 | case 'UPDATE': 8 | collection.upsert(changeEvent.doc); 9 | break; 10 | case 'DELETE': 11 | collection.remove(changeEvent.id); 12 | break; 13 | } 14 | } 15 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/util.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,MAAM,UAAU,YAAY,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,aAAa,CACzB,IAAY,EACZ,IAAS;IAET,EAAE,CAAC,aAAa,CACZ,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAC7B,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAClC,CAAC;AACN,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/util.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/util.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AAEzB,SAAgB,YAAY,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC;AAHD,oCAGC;AAED,SAAgB,aAAa,CACzB,IAAY,EACZ,IAAS;IAET,EAAE,CAAC,aAAa,CACZ,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAC7B,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAClC,CAAC;AACN,CAAC;AATD,sCASC"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/config.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/config.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAEX,QAAA,kBAAkB,GAAG,cAAI,CAAC,IAAI,CACvC,SAAS,EACT,QAAQ,CACX,CAAC;AAEW,QAAA,uBAAuB,GAAG,cAAI,CAAC,IAAI,CAC5C,0BAAkB,EAClB,kBAAkB,CACrB,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAEd,QAAA,oBAAoB,GAAG,cAAI,CAAC,IAAI,CACzC,0BAAkB,EAClB,cAAc,CACjB,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAEd,QAAA,uBAAuB,GAAG,cAAI,CAAC,IAAI,CAC5C,0BAAkB,EAClB,iBAAiB,CACpB,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/bdd.template.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"bdd.template.js","sourceRoot":"","sources":["../../../../src/bdd/bdd.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,wBAAwB,EACxB,oBAAoB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEjE,MAAM,CAAC,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAEtD,IAAI,SAAgC,CAAC;AACrC,MAAM,UAAU,YAAY;IACxB,IAAI,CAAC,SAAS,EAAE;QACZ,SAAS,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;KAC1D;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAqC,EAAE,EAAE;IAClE,OAAO,oBAAoB,CACvB,YAAY,EAAE,EACd,2BAA2B,EAC3B,KAAK,CACR,CAAC;AACN,CAAC,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/procedures.d.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent } from '../types/index.js'; 2 | import type { Human, Procedure } from './types.js'; 3 | export declare function insertChangeAndCleanup(): ChangeEvent[]; 4 | export declare function insertFiveSorted(): ChangeEvent[]; 5 | export declare function insertFiveSortedThenRemoveSorted(): ChangeEvent[]; 6 | export declare function oneThatWasCrashing(): ChangeEvent[]; 7 | export declare function sortParamChanged(): ChangeEvent[]; 8 | export declare function getTestProcedures(): Procedure[]; 9 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/bdd.generated.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"bdd.generated.js","sourceRoot":"","sources":["../../../../src/bdd/bdd.generated.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,wBAAwB,EACxB,oBAAoB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEjE,MAAM,CAAC,MAAM,gBAAgB,GAAG,+pBAA+pB,CAAC;AAEhsB,IAAI,SAAgC,CAAC;AACrC,MAAM,UAAU,YAAY;IACxB,IAAI,CAAC,SAAS,EAAE;QACZ,SAAS,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;KAC1D;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAqC,EAAE,EAAE;IAClE,OAAO,oBAAoB,CACvB,YAAY,EAAE,EACd,2BAA2B,EAC3B,KAAK,CACR,CAAC;AACN,CAAC,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/procedures.d.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent } from '../types/index.js'; 2 | import type { Human, Procedure } from './types.js'; 3 | export declare function insertChangeAndCleanup(): ChangeEvent[]; 4 | export declare function insertFiveSorted(): ChangeEvent[]; 5 | export declare function insertFiveSortedThenRemoveSorted(): ChangeEvent[]; 6 | export declare function oneThatWasCrashing(): ChangeEvent[]; 7 | export declare function sortParamChanged(): ChangeEvent[]; 8 | export declare function getTestProcedures(): Procedure[]; 9 | -------------------------------------------------------------------------------- /javascript/src/truth-table-generator/config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | export const OUTPUT_FOLDER_PATH = path.join( 4 | __dirname, 5 | 'output' 6 | ); 7 | 8 | export const OUTPUT_TRUTH_TABLE_PATH = path.join( 9 | OUTPUT_FOLDER_PATH, 10 | 'truth-table.json' 11 | ).replace('dist/cjs/', ''); 12 | 13 | export const FUZZING_QUERIES_PATH = path.join( 14 | OUTPUT_FOLDER_PATH, 15 | 'queries.json' 16 | ).replace('dist/cjs/', ''); 17 | 18 | export const FUZZING_PROCEDURES_PATH = path.join( 19 | OUTPUT_FOLDER_PATH, 20 | 'procedures.json' 21 | ).replace('dist/cjs/', ''); 22 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/bdd.template.js: -------------------------------------------------------------------------------- 1 | import { minimalStringToSimpleBdd, resolveWithSimpleBdd } from 'binary-decision-diagram'; 2 | import { stateResolveFunctionByIndex } from '../states/index.js'; 3 | export const minimalBddString = '${minimalBddString}'; 4 | let simpleBdd; 5 | export function getSimpleBdd() { 6 | if (!simpleBdd) { 7 | simpleBdd = minimalStringToSimpleBdd(minimalBddString); 8 | } 9 | return simpleBdd; 10 | } 11 | export const resolveInput = (input) => { 12 | return resolveWithSimpleBdd(getSimpleBdd(), stateResolveFunctionByIndex, input); 13 | }; 14 | //# sourceMappingURL=bdd.template.js.map -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/config.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CACvC,SAAS,EACT,QAAQ,CACX,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC,IAAI,CAC5C,kBAAkB,EAClB,kBAAkB,CACrB,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAE3B,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC,IAAI,CACzC,kBAAkB,EAClB,cAAc,CACjB,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAE3B,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC,IAAI,CAC5C,kBAAkB,EAClB,iBAAiB,CACpB,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/database/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent, MongoQuery, QueryParams } from '../../types'; 2 | export * from './mingo.js'; 3 | /** 4 | * Abstract the database so that 5 | * we can swap it out. 6 | */ 7 | export type CollectionCreator = () => Collection; 8 | export interface Collection { 9 | getQueryParams(query: MongoQuery): QueryParams; 10 | upsert(doc: any): void; 11 | remove(docId: string): void; 12 | query(query: MongoQuery): any[]; 13 | } 14 | export declare function applyChangeEvent(collection: Collection, changeEvent: ChangeEvent): void; 15 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/fuzzing.d.ts: -------------------------------------------------------------------------------- 1 | import type { MongoQuery } from '../types/index.js'; 2 | import type { Procedure, StateActionIdMap } from './types.js'; 3 | export type FuzzingReturn = { 4 | ok: boolean; 5 | query: MongoQuery; 6 | procedure: Procedure; 7 | amountOfHandled: number; 8 | amountOfOptimized: number; 9 | }; 10 | /** 11 | * randomly generates queries and events 12 | * and returns on the first broken one 13 | * 14 | * returns ok:true if no problem was found 15 | */ 16 | export declare function fuzzing(table: StateActionIdMap, queriesAmount?: number, eventsAmount?: number): FuzzingReturn; 17 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/database/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent, MongoQuery, QueryParams } from '../../types'; 2 | export * from './mingo.js'; 3 | /** 4 | * Abstract the database so that 5 | * we can swap it out. 6 | */ 7 | export type CollectionCreator = () => Collection; 8 | export interface Collection { 9 | getQueryParams(query: MongoQuery): QueryParams; 10 | upsert(doc: any): void; 11 | remove(docId: string): void; 12 | query(query: MongoQuery): any[]; 13 | } 14 | export declare function applyChangeEvent(collection: Collection, changeEvent: ChangeEvent): void; 15 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/fuzzing.d.ts: -------------------------------------------------------------------------------- 1 | import type { MongoQuery } from '../types/index.js'; 2 | import type { Procedure, StateActionIdMap } from './types.js'; 3 | export type FuzzingReturn = { 4 | ok: boolean; 5 | query: MongoQuery; 6 | procedure: Procedure; 7 | amountOfHandled: number; 8 | amountOfOptimized: number; 9 | }; 10 | /** 11 | * randomly generates queries and events 12 | * and returns on the first broken one 13 | * 14 | * returns ok:true if no problem was found 15 | */ 16 | export declare function fuzzing(table: StateActionIdMap, queriesAmount?: number, eventsAmount?: number): FuzzingReturn; 17 | -------------------------------------------------------------------------------- /javascript/truth-table-generator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "event-reduce-truth-table-generator", 3 | "sideEffects": false, 4 | "types": "../dist/esm/src/truth-table-generator/index.d.ts", 5 | "exports": { 6 | ".": { 7 | "default": { 8 | "types": "../dist/esm/src/truth-table-generator/index.d.ts", 9 | "import": "../dist/esm/src/truth-table-generator/index.js", 10 | "default": "../dist/cjs/src/truth-table-generator/index.js" 11 | } 12 | }, 13 | "./package.json": "./package.json" 14 | }, 15 | "main": ".../dist/cjs/src/truth-table-generator/index.js", 16 | "module": "../dist/esm/src/truth-table-generator/index.js" 17 | } 18 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/binary-state.d.ts: -------------------------------------------------------------------------------- 1 | import type { StateSet } from '../types/index.js'; 2 | export declare const STATE_SET_LENGTH: number; 3 | export declare const FIRST_STATE_SET: StateSet; 4 | export declare const LAST_STATE_SET: StateSet; 5 | export declare function getNextStateSet(stateSet?: StateSet): string; 6 | /** 7 | * @link https://stackoverflow.com/a/16155417 8 | */ 9 | export declare function decimalToPaddedBinary(decimal: number, padding?: number): string; 10 | export declare function binaryToDecimal(binary: string): number; 11 | export declare function maxBinaryWithLength(length: number): string; 12 | export declare function oppositeBinary(i: string): string; 13 | export declare function stateSetToObject(stateSet: StateSet): any; 14 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/binary-state.d.ts: -------------------------------------------------------------------------------- 1 | import type { StateSet } from '../types/index.js'; 2 | export declare const STATE_SET_LENGTH: number; 3 | export declare const FIRST_STATE_SET: StateSet; 4 | export declare const LAST_STATE_SET: StateSet; 5 | export declare function getNextStateSet(stateSet?: StateSet): string; 6 | /** 7 | * @link https://stackoverflow.com/a/16155417 8 | */ 9 | export declare function decimalToPaddedBinary(decimal: number, padding?: number): string; 10 | export declare function binaryToDecimal(binary: string): number; 11 | export declare function maxBinaryWithLength(length: number): string; 12 | export declare function oppositeBinary(i: string): string; 13 | export declare function stateSetToObject(stateSet: StateSet): any; 14 | -------------------------------------------------------------------------------- /javascript/src/bdd/bdd.template.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SimpleBdd, 3 | minimalStringToSimpleBdd, 4 | resolveWithSimpleBdd 5 | } from 'binary-decision-diagram'; 6 | import type { StateResolveFunctionInput } from '../types/index.js'; 7 | import { stateResolveFunctionByIndex } from '../states/index.js'; 8 | 9 | export const minimalBddString = '${minimalBddString}'; 10 | 11 | let simpleBdd: SimpleBdd | undefined; 12 | export function getSimpleBdd() { 13 | if (!simpleBdd) { 14 | simpleBdd = minimalStringToSimpleBdd(minimalBddString); 15 | } 16 | return simpleBdd; 17 | } 18 | 19 | export const resolveInput = (input: StateResolveFunctionInput) => { 20 | return resolveWithSimpleBdd( 21 | getSimpleBdd(), 22 | stateResolveFunctionByIndex, 23 | input 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/actions/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/actions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAKA,+DAiB+B;AAE/B,wDAAsC;AAEtC;;;;GAIG;AACU,QAAA,iBAAiB,GAAiB;IAC3C,WAAW;IACX,aAAa;IACb,YAAY;IACZ,iBAAiB;IACjB,gBAAgB;IAChB,uBAAuB;IACvB,uBAAuB;IACvB,wBAAwB;IACxB,sBAAsB;IACtB,gBAAgB;IAChB,iBAAiB;IACjB,aAAa;IACb,sBAAsB;IACtB,uCAAuC;IACvC,mBAAmB;IACnB,eAAe;CAClB,CAAC;AAGW,QAAA,eAAe,GAExB;IACA,SAAS,EAAT,+BAAS;IACT,WAAW,EAAX,iCAAW;IACX,UAAU,EAAV,gCAAU;IACV,eAAe,EAAf,qCAAe;IACf,cAAc,EAAd,oCAAc;IACd,qBAAqB,EAArB,2CAAqB;IACrB,qBAAqB,EAArB,2CAAqB;IACrB,sBAAsB,EAAtB,4CAAsB;IACtB,oBAAoB,EAApB,0CAAoB;IACpB,cAAc,EAAd,oCAAc;IACd,eAAe,EAAf,qCAAe;IACf,WAAW,EAAX,iCAAW;IACX,oBAAoB,EAApB,0CAAoB;IACpB,qCAAqC,EAArC,2DAAqC;IACrC,iBAAiB,EAAjB,uCAAiB;IACjB,aAAa,EAAb,mCAAa;CAChB,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/queries.d.ts: -------------------------------------------------------------------------------- 1 | import type { MongoQuery } from '../types/index.js'; 2 | export declare const DEFAULT_EXAMPLE_QUERY: MongoQuery; 3 | export declare const findAllQuery: MongoQuery; 4 | export declare const SELECTOR_VARIATIONS: Partial[]; 5 | export declare const SKIP_VARIATIONS: { 6 | skip: number | undefined; 7 | }[]; 8 | export declare const LIMIT_VARIATIONS: { 9 | limit: number | undefined; 10 | }[]; 11 | export declare const SORT_VARIATION: { 12 | sort: string[]; 13 | }[]; 14 | export declare const QUERIES_FROM_FUZZING: MongoQuery[]; 15 | export declare function getQueryVariations(): MongoQuery[]; 16 | export declare function randomOperation(): string; 17 | export declare function randomSelector(): any; 18 | export declare function randomQuery(): MongoQuery; 19 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/queries.d.ts: -------------------------------------------------------------------------------- 1 | import type { MongoQuery } from '../types/index.js'; 2 | export declare const DEFAULT_EXAMPLE_QUERY: MongoQuery; 3 | export declare const findAllQuery: MongoQuery; 4 | export declare const SELECTOR_VARIATIONS: Partial[]; 5 | export declare const SKIP_VARIATIONS: { 6 | skip: number | undefined; 7 | }[]; 8 | export declare const LIMIT_VARIATIONS: { 9 | limit: number | undefined; 10 | }[]; 11 | export declare const SORT_VARIATION: { 12 | sort: string[]; 13 | }[]; 14 | export declare const QUERIES_FROM_FUZZING: MongoQuery[]; 15 | export declare function getQueryVariations(): MongoQuery[]; 16 | export declare function randomOperation(): string; 17 | export declare function randomSelector(): any; 18 | export declare function randomQuery(): MongoQuery; 19 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/actions/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/actions/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,SAAS,EACT,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,qCAAqC,EACrC,iBAAiB,EACjB,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACvB,MAAM,uBAAuB,CAAC;AAE/B,cAAc,uBAAuB,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAiB;IAC3C,WAAW;IACX,aAAa;IACb,YAAY;IACZ,iBAAiB;IACjB,gBAAgB;IAChB,uBAAuB;IACvB,uBAAuB;IACvB,wBAAwB;IACxB,sBAAsB;IACtB,gBAAgB;IAChB,iBAAiB;IACjB,aAAa;IACb,sBAAsB;IACtB,uCAAuC;IACvC,mBAAmB;IACnB,eAAe;CAClB,CAAC;AAGF,MAAM,CAAC,MAAM,eAAe,GAExB;IACA,SAAS;IACT,WAAW;IACX,UAAU;IACV,eAAe;IACf,cAAc;IACd,qBAAqB;IACrB,qBAAqB;IACrB,sBAAsB;IACtB,oBAAoB;IACpB,cAAc;IACd,eAAe;IACf,WAAW;IACX,oBAAoB;IACpB,qCAAqC;IACrC,iBAAiB;IACjB,aAAa;CAChB,CAAC"} -------------------------------------------------------------------------------- /javascript/test/helper/input.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StateResolveFunctionInput, 3 | QueryParams 4 | } from '../../src/types/index.js'; 5 | import { Human } from '../../src/truth-table-generator/types.js'; 6 | import { randomChangeEvent } from '../../src/truth-table-generator/data-generator.js'; 7 | import { mingoCollectionCreator } from '../../src/truth-table-generator/database/mingo.js'; 8 | 9 | 10 | const pseudoCollection = mingoCollectionCreator(); 11 | 12 | export function getExampleStateResolveFunctionInput(): StateResolveFunctionInput { 13 | const queryParams: QueryParams = pseudoCollection.getQueryParams({ 14 | selector: {}, 15 | sort: ['_id'] 16 | }); 17 | return { 18 | previousResults: [], 19 | changeEvent: randomChangeEvent([], 'INSERT'), 20 | queryParams 21 | }; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /javascript/test/unit/fuzzing.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | 3 | import { fuzzing } from '../../src/truth-table-generator/fuzzing.js'; 4 | import { orderedActionList } from '../../src/actions/index.js'; 5 | import { StateActionIdMap } from '../../src/truth-table-generator/types.js'; 6 | 7 | describe('fuzzing.test.ts', () => { 8 | 9 | const indexOfRunAgain = orderedActionList.indexOf('runFullQueryAgain'); 10 | const indexOfDoNothing = orderedActionList.indexOf('doNothing'); 11 | 12 | it('should have no error on runFullQueryAgain', async () => { 13 | const map: StateActionIdMap = new Map(); 14 | map.get = () => indexOfRunAgain; 15 | const result = await fuzzing( 16 | map, 17 | 10, 18 | 10 19 | ); 20 | assert.strictEqual(result.ok, true); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/change-event.d.ts: -------------------------------------------------------------------------------- 1 | import type { WriteOperation } from './index.js'; 2 | export interface ChangeEventBase { 3 | operation: WriteOperation; 4 | /** 5 | * document id, 6 | * value of the primary key. 7 | */ 8 | id: string; 9 | } 10 | export interface ChangeEventInsert extends ChangeEventBase { 11 | operation: 'INSERT'; 12 | doc: DocType; 13 | previous: null; 14 | } 15 | export interface ChangeEventUpdate extends ChangeEventBase { 16 | operation: 'UPDATE'; 17 | doc: DocType; 18 | previous: DocType; 19 | } 20 | export interface ChangeEventDelete extends ChangeEventBase { 21 | operation: 'DELETE'; 22 | doc: null; 23 | previous: DocType; 24 | } 25 | export type ChangeEvent = ChangeEventInsert | ChangeEventUpdate | ChangeEventDelete; 26 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/change-event.d.ts: -------------------------------------------------------------------------------- 1 | import type { WriteOperation } from './index.js'; 2 | export interface ChangeEventBase { 3 | operation: WriteOperation; 4 | /** 5 | * document id, 6 | * value of the primary key. 7 | */ 8 | id: string; 9 | } 10 | export interface ChangeEventInsert extends ChangeEventBase { 11 | operation: 'INSERT'; 12 | doc: DocType; 13 | previous: null; 14 | } 15 | export interface ChangeEventUpdate extends ChangeEventBase { 16 | operation: 'UPDATE'; 17 | doc: DocType; 18 | previous: DocType; 19 | } 20 | export interface ChangeEventDelete extends ChangeEventBase { 21 | operation: 'DELETE'; 22 | doc: null; 23 | previous: DocType; 24 | } 25 | export type ChangeEvent = ChangeEventInsert | ChangeEventUpdate | ChangeEventDelete; 26 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/bdd.template.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.resolveInput = exports.getSimpleBdd = exports.minimalBddString = void 0; 4 | const binary_decision_diagram_1 = require("binary-decision-diagram"); 5 | const index_js_1 = require("../states/index.js"); 6 | exports.minimalBddString = '${minimalBddString}'; 7 | let simpleBdd; 8 | function getSimpleBdd() { 9 | if (!simpleBdd) { 10 | simpleBdd = (0, binary_decision_diagram_1.minimalStringToSimpleBdd)(exports.minimalBddString); 11 | } 12 | return simpleBdd; 13 | } 14 | exports.getSimpleBdd = getSimpleBdd; 15 | const resolveInput = (input) => { 16 | return (0, binary_decision_diagram_1.resolveWithSimpleBdd)(getSimpleBdd(), index_js_1.stateResolveFunctionByIndex, input); 17 | }; 18 | exports.resolveInput = resolveInput; 19 | //# sourceMappingURL=bdd.template.js.map -------------------------------------------------------------------------------- /javascript/src/types/change-event.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | WriteOperation 3 | } from './index.js'; 4 | 5 | export interface ChangeEventBase { 6 | operation: WriteOperation; 7 | /** 8 | * document id, 9 | * value of the primary key. 10 | */ 11 | id: string; 12 | } 13 | 14 | export interface ChangeEventInsert extends ChangeEventBase { 15 | operation: 'INSERT'; 16 | doc: DocType; 17 | previous: null; 18 | } 19 | 20 | export interface ChangeEventUpdate extends ChangeEventBase { 21 | operation: 'UPDATE'; 22 | doc: DocType; 23 | previous: DocType; 24 | } 25 | 26 | export interface ChangeEventDelete extends ChangeEventBase { 27 | operation: 'DELETE'; 28 | doc: null; 29 | previous: DocType; 30 | } 31 | 32 | export type ChangeEvent = ChangeEventInsert | ChangeEventUpdate | ChangeEventDelete; 33 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/states/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ResolverFunctions } from 'binary-decision-diagram'; 2 | import type { StateName, StateResolveFunction, StateSet, StateResolveFunctionInput } from '../types/index.js'; 3 | export * from './state-resolver.js'; 4 | /** 5 | * all states ordered by performance-cost 6 | * cheapest first 7 | * TODO run tests on which is really the fastest 8 | */ 9 | export declare const orderedStateList: StateName[]; 10 | export declare const stateResolveFunctions: { 11 | readonly [k in StateName]: StateResolveFunction; 12 | }; 13 | export declare const stateResolveFunctionByIndex: ResolverFunctions>; 14 | export declare function resolveState(stateName: StateName, input: StateResolveFunctionInput): boolean; 15 | export declare function getStateSet(input: StateResolveFunctionInput): StateSet; 16 | export declare function logStateSet(stateSet: StateSet): void; 17 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.FUZZING_PROCEDURES_PATH = exports.FUZZING_QUERIES_PATH = exports.OUTPUT_TRUTH_TABLE_PATH = exports.OUTPUT_FOLDER_PATH = void 0; 7 | const path_1 = __importDefault(require("path")); 8 | exports.OUTPUT_FOLDER_PATH = path_1.default.join(__dirname, 'output'); 9 | exports.OUTPUT_TRUTH_TABLE_PATH = path_1.default.join(exports.OUTPUT_FOLDER_PATH, 'truth-table.json').replace('dist/cjs/', ''); 10 | exports.FUZZING_QUERIES_PATH = path_1.default.join(exports.OUTPUT_FOLDER_PATH, 'queries.json').replace('dist/cjs/', ''); 11 | exports.FUZZING_PROCEDURES_PATH = path_1.default.join(exports.OUTPUT_FOLDER_PATH, 'procedures.json').replace('dist/cjs/', ''); 12 | //# sourceMappingURL=config.js.map -------------------------------------------------------------------------------- /javascript/dist/esm/src/states/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ResolverFunctions } from 'binary-decision-diagram'; 2 | import type { StateName, StateResolveFunction, StateSet, StateResolveFunctionInput } from '../types/index.js'; 3 | export * from './state-resolver.js'; 4 | /** 5 | * all states ordered by performance-cost 6 | * cheapest first 7 | * TODO run tests on which is really the fastest 8 | */ 9 | export declare const orderedStateList: StateName[]; 10 | export declare const stateResolveFunctions: { 11 | readonly [k in StateName]: StateResolveFunction; 12 | }; 13 | export declare const stateResolveFunctionByIndex: ResolverFunctions>; 14 | export declare function resolveState(stateName: StateName, input: StateResolveFunctionInput): boolean; 15 | export declare function getStateSet(input: StateResolveFunctionInput): StateSet; 16 | export declare function logStateSet(stateSet: StateSet): void; 17 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./change-event.js"), exports); 18 | __exportStar(require("./mongo.js"), exports); 19 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAUA,gDAAgD;AAChD,iDAAwE;AACxE,6DAAsD;AA6BtD,oDAAkC;AAClC,4CAA0B;AAC1B,qDAAmC;AAEnC,SAAgB,sBAAsB,CAClC,mBAAwC,EACxC,KAAyC;IAKzC,MAAM,QAAQ,GAAa,IAAA,sBAAW,EAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,EAAE;QACb,OAAO;YACH,MAAM,EAAE,mBAAmB;YAC3B,QAAQ;SACX,CAAC;KACL;SAAM;QACH,OAAO;YACH,MAAM,EAAE,UAAU;YAClB,QAAQ;SACX,CAAC;KACL;AACL,CAAC;AApBD,wDAoBC;AAED,SAAgB,mBAAmB,CAC/B,KAAyC;IAEzC,MAAM,gBAAgB,GAAG,IAAA,+BAAY,EACjC,KAAK,CACR,CAAC;IACF,OAAO,4BAAiB,CAAC,gBAAgB,CAAC,CAAC;AAC/C,CAAC;AAPD,kDAOC;AAED,SAAgB,uBAAuB,CACnC,KAAyC;IAEzC,MAAM,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,0BAAe,CAAC,UAAU,CAAC,CAAC;AACvC,CAAC;AALD,0DAKC;AAED;;;;GAIG;AACH,SAAgB,SAAS,CACrB,MAAkB,EAClB,WAAiC,EACjC,WAAiC,EACjC,eAA0B,EAC1B,cAA8C;IAE9C,MAAM,EAAE,GAA4B,0BAAe,CAAC,MAAM,CAAC,CAAC;IAC5D,EAAE,CAAC;QACC,WAAW;QACX,WAAW;QACX,eAAe;QACf,cAAc;KACjB,CAAC,CAAC;IACH,OAAO,eAAe,CAAC;AAC3B,CAAC;AAfD,8BAeC"} -------------------------------------------------------------------------------- /javascript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "target": "ES2022", 5 | "removeComments": false, 6 | "preserveConstEnums": true, 7 | "sourceMap": true, 8 | "strictNullChecks": true, 9 | "noImplicitAny": true, 10 | "strict": true, 11 | "noImplicitReturns": true, 12 | "noImplicitThis": true, 13 | "downlevelIteration": true, 14 | "esModuleInterop": true, 15 | "declaration": true, 16 | "resolveJsonModule": true, 17 | "outDir": "./dist/cjs", 18 | "lib": [ 19 | "es7", 20 | "dom" 21 | ] 22 | }, 23 | "formatCodeOptions": { 24 | "indentSize": 2, 25 | "tabSize": 2 26 | }, 27 | "include": [ 28 | "src", 29 | "test" 30 | ], 31 | "exclude": [ 32 | "node_modules", 33 | "**/node_modules/*", 34 | "dist", 35 | "src/truth-table-generator/output", 36 | "**.txt", 37 | "**.json" 38 | ], 39 | "compileOnSave": false 40 | } 41 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AA6BtD,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AAEnC,MAAM,UAAU,sBAAsB,CAClC,mBAAwC,EACxC,KAAyC;IAKzC,MAAM,QAAQ,GAAa,WAAW,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,EAAE;QACb,OAAO;YACH,MAAM,EAAE,mBAAmB;YAC3B,QAAQ;SACX,CAAC;KACL;SAAM;QACH,OAAO;YACH,MAAM,EAAE,UAAU;YAClB,QAAQ;SACX,CAAC;KACL;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CAC/B,KAAyC;IAEzC,MAAM,gBAAgB,GAAG,YAAY,CACjC,KAAK,CACR,CAAC;IACF,OAAO,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,uBAAuB,CACnC,KAAyC;IAEzC,MAAM,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,eAAe,CAAC,UAAU,CAAC,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACrB,MAAkB,EAClB,WAAiC,EACjC,WAAiC,EACjC,eAA0B,EAC1B,cAA8C;IAE9C,MAAM,EAAE,GAA4B,eAAe,CAAC,MAAM,CAAC,CAAC;IAC5D,EAAE,CAAC;QACC,WAAW;QACX,WAAW;QACX,eAAe;QACf,cAAc;KACjB,CAAC,CAAC;IACH,OAAO,eAAe,CAAC;AAC3B,CAAC"} -------------------------------------------------------------------------------- /javascript/test/unit/queries.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { 3 | getQueryVariations, 4 | SELECTOR_VARIATIONS, 5 | SKIP_VARIATIONS, 6 | LIMIT_VARIATIONS, 7 | SORT_VARIATION 8 | } from '../../src/truth-table-generator/queries.js'; 9 | 10 | describe('queries-state.test.ts', () => { 11 | it('should have all query variations', () => { 12 | const queries = getQueryVariations(); 13 | const amount = 14 | SELECTOR_VARIATIONS.length * 15 | SKIP_VARIATIONS.length * 16 | LIMIT_VARIATIONS.length * 17 | SORT_VARIATION.length; 18 | assert.ok(queries.length > amount); 19 | }); 20 | it('should have no duplicates', () => { 21 | const queries = getQueryVariations(); 22 | const set: Set = new Set(); 23 | queries.forEach(q => { 24 | const str = JSON.stringify(q); 25 | if (set.has(str)) { 26 | throw new Error('query is duplicate: ' + str); 27 | } else { 28 | set.add(str); 29 | } 30 | }); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Daniel Meyer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/data-generator.d.ts: -------------------------------------------------------------------------------- 1 | import type { Human, Procedure } from './types.js'; 2 | import type { ChangeEvent } from '../../src/types/index.js'; 3 | /** 4 | * Do not use a too height value 5 | * so that it more often triggers sort changes. 6 | */ 7 | export declare const HUMAN_MAX_AGE = 20; 8 | export declare function randomHuman(partial?: Partial): Human; 9 | export declare const STATIC_RANDOM_HUMAN: Human; 10 | export declare function randomHumans(amount?: number, partial?: Partial): Human[]; 11 | export declare const mutateFieldFunctions: { 12 | [k: string]: (i: Human) => void; 13 | }; 14 | export declare function randomChangeHuman(input: Human): Human; 15 | export declare function randomChangeEvent(allDocs: Human[], favor: 'INSERT' | 'DELETE'): ChangeEvent; 16 | export declare const randomEventsPrematureCalculation: { 17 | [amount: number]: Procedure; 18 | }; 19 | export declare function getRandomChangeEvents(amount?: number): Procedure; 20 | export declare function fillRandomEvents(amount: number): void; 21 | export declare function _getRandomChangeEvents(amount?: number): Procedure; 22 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/data-generator.d.ts: -------------------------------------------------------------------------------- 1 | import type { Human, Procedure } from './types.js'; 2 | import type { ChangeEvent } from '../../src/types/index.js'; 3 | /** 4 | * Do not use a too height value 5 | * so that it more often triggers sort changes. 6 | */ 7 | export declare const HUMAN_MAX_AGE = 20; 8 | export declare function randomHuman(partial?: Partial): Human; 9 | export declare const STATIC_RANDOM_HUMAN: Human; 10 | export declare function randomHumans(amount?: number, partial?: Partial): Human[]; 11 | export declare const mutateFieldFunctions: { 12 | [k: string]: (i: Human) => void; 13 | }; 14 | export declare function randomChangeHuman(input: Human): Human; 15 | export declare function randomChangeEvent(allDocs: Human[], favor: 'INSERT' | 'DELETE'): ChangeEvent; 16 | export declare const randomEventsPrematureCalculation: { 17 | [amount: number]: Procedure; 18 | }; 19 | export declare function getRandomChangeEvents(amount?: number): Procedure; 20 | export declare function fillRandomEvents(amount: number): void; 21 | export declare function _getRandomChangeEvents(amount?: number): Procedure; 22 | -------------------------------------------------------------------------------- /orga/event-reduce.drawio: -------------------------------------------------------------------------------- 1 | 3Zddk5owFIZ/DZc6QADlcnVd227babttvY4QIWMgbAiK++ubQFC+HIe2jNNyoeHNF3nOyTmJBpZRvmYwCT9RHxHN1P1cA4+aac5NXfxK4VQKwFVCwLBfSsZFeMFvSIlVswz7KG005JQSjpOm6NE4Rh5vaJAxemw221HSnDWBAeoILx4kXXWDfR5Wy5pd9HcIB2E1s+G4ZU0Eq8ZqJWkIfXqsSWClgSWjlJelKF8iItlVXDbvTxvyce+sP3xNX+GPxfP3zz8n5WBPQ7qcl8BQzH976Nzxn92HtZsna/YlPuxSboCJYZdjHyDJFDC1WH6qCIp1J7KIcjH5wqfZtqgxxAujWewjOYEu3o4h5uglgZ6sPgpvElrII6Ia7zAhS0ooK4YFT8Uj9JQzukd9NerbEOMob1nzBgrjbB/h14hGiLOT6HeseUDloGHN+hZQIlReF5z7XsiKgoI7ALTZ4Swd2dRfM1R8mWY6ROLdMlEKZImhNCM87ZhjEPO/TrAKC4qTCgpGxa0G2DB7AM/H4gs6fFcHucDr9Iz70QN6C5/Vg0/vweeMhW9AGPAYTdPBu10vnhGZmuZsareonpUaV8vu2fb2SFjd21j/JISODtWyWo5qdx3V6fFTYyw/rQb+f4jO7020m5lidBRJCEYSVbxN5d8/mqbsNu275ymjm6iuR9qMkdOCQW+P+G2Gzcx2za8Z5ZBjGgt54o7p6MB2p2DWoD+xhDTvGKCPv+3Op7OxorJhXTss6N+Qnwm+bYvw8uxbow0JDiRET/RDAvJCEsTi2vGgKiLs+7K73CD4DZZnZgk8oTjmxZLshWY/yrEyTtPy4jTqqcNs5sdznKnZwu2xhTl8L4jXy72oqKtdLsHqFw== -------------------------------------------------------------------------------- /javascript/src/truth-table-generator/database/index.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent, MongoQuery, QueryParams } from '../../types'; 2 | 3 | export * from './mingo.js'; 4 | 5 | /** 6 | * Abstract the database so that 7 | * we can swap it out. 8 | */ 9 | export type CollectionCreator = () => Collection; 10 | 11 | 12 | export interface Collection { 13 | getQueryParams(query: MongoQuery): QueryParams; 14 | upsert(doc: any): void; 15 | remove(docId: string): void; 16 | query(query: MongoQuery): any[]; 17 | } 18 | 19 | 20 | 21 | export function applyChangeEvent( 22 | collection: Collection, 23 | changeEvent: ChangeEvent 24 | ): void { 25 | switch (changeEvent.operation) { 26 | case 'INSERT': 27 | collection.upsert( 28 | changeEvent.doc as any 29 | ); 30 | break; 31 | case 'UPDATE': 32 | collection.upsert( 33 | changeEvent.doc as any 34 | ); 35 | break; 36 | case 'DELETE': 37 | collection.remove( 38 | changeEvent.id 39 | ); 40 | break; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/write-bdd-template.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"write-bdd-template.js","sourceRoot":"","sources":["../../../../src/bdd/write-bdd-template.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,gDAAwB;AAKX,QAAA,qBAAqB,GAAG,cAAI,CAAC,IAAI,CAC1C,SAAS,EACT,mBAAmB,CACtB,CAAC;AACW,QAAA,2BAA2B,GAAG,cAAI,CAAC,IAAI,CAChD,SAAS,EACT,2BAA2B,CAC9B,CAAC;AACW,QAAA,iBAAiB,GAAG,cAAI,CAAC,IAAI,CACtC,SAAS,EACT,oBAAoB,CACvB,CAAC;AAEF,SAAgB,gBAAgB,CAC5B,gBAAwB,EACxB,sBAA8C,EAC9C,OAAe;IAEf,IAAI,cAAc,GAAW,EAAE,CAAC,YAAY,CAAC,6BAAqB,EAAE,OAAO,CAAC,CAAC;IAC7E,MAAM,gBAAgB,GAAG;QACrB,gBAAgB,EAAE,IAAI,GAAG,gBAAgB,GAAG,IAAI;KACnD,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE;QACxD,MAAM,aAAa,GAAG,OAAiB,CAAC;QACxC,MAAM,WAAW,GAAG,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC;QACzC,cAAc,GAAG,cAAc,CAAC,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,aAAa,CACZ,mCAA2B,EAC3B,IAAI,CAAC,SAAS,CAAC;QACX,sBAAsB;QACtB,gBAAgB;QAChB,OAAO;KACV,EAAE,IAAI,EAAE,CAAC,CAAC,EACX,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAClC,CAAC;IAGF,EAAE,CAAC,aAAa,CACZ,yBAAiB,EACjB,cAAc,EACd,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAClC,CAAC;AACN,CAAC;AAhCD,4CAgCC"} -------------------------------------------------------------------------------- /examples/browser/webpack.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | 4 | module.exports = { 5 | entry: './src/index.ts', 6 | plugins: [ 7 | new webpack.ProvidePlugin({ 8 | process: 'process/browser', 9 | }), 10 | new webpack.ProvidePlugin({ 11 | Buffer: ['buffer', 'Buffer'], 12 | }) 13 | ], 14 | module: { 15 | rules: [{ 16 | test: /\.tsx?$/, 17 | use: 'ts-loader', 18 | exclude: /node_modules/ 19 | }, 20 | { 21 | test: /\.less$/, 22 | use: [ 23 | { 24 | loader: 'style-loader', 25 | }, 26 | { 27 | loader: 'css-loader', 28 | }, 29 | { 30 | loader: 'less-loader', 31 | options: { 32 | lessOptions: { 33 | strictMath: true, 34 | noIeCompat: true, 35 | }, 36 | }, 37 | }, 38 | ], 39 | }] 40 | }, 41 | resolve: { 42 | extensions: ['.ts', '.js'] 43 | }, 44 | optimization: { 45 | minimize: false 46 | }, 47 | output: { 48 | filename: 'bundle.js', 49 | path: path.resolve(__dirname, 'dist') 50 | }, 51 | mode: 'development' 52 | }; 53 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/write-bdd-template.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"write-bdd-template.js","sourceRoot":"","sources":["../../../../src/bdd/write-bdd-template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,IAAI,MAAM,MAAM,CAAC;AAKxB,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC,IAAI,CAC1C,SAAS,EACT,mBAAmB,CACtB,CAAC;AACF,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAC,IAAI,CAChD,SAAS,EACT,2BAA2B,CAC9B,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CACtC,SAAS,EACT,oBAAoB,CACvB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAC5B,gBAAwB,EACxB,sBAA8C,EAC9C,OAAe;IAEf,IAAI,cAAc,GAAW,EAAE,CAAC,YAAY,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;IAC7E,MAAM,gBAAgB,GAAG;QACrB,gBAAgB,EAAE,IAAI,GAAG,gBAAgB,GAAG,IAAI;KACnD,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE;QACxD,MAAM,aAAa,GAAG,OAAiB,CAAC;QACxC,MAAM,WAAW,GAAG,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC;QACzC,cAAc,GAAG,cAAc,CAAC,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,aAAa,CACZ,2BAA2B,EAC3B,IAAI,CAAC,SAAS,CAAC;QACX,sBAAsB;QACtB,gBAAgB;QAChB,OAAO;KACV,EAAE,IAAI,EAAE,CAAC,CAAC,EACX,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAClC,CAAC;IAGF,EAAE,CAAC,aAAa,CACZ,iBAAiB,EACjB,cAAc,EACd,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAClC,CAAC;AACN,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/write-bdd-template.js: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import path from 'path'; 3 | export const BDD_TEMPLATE_LOCATION = path.join(__dirname, './bdd.template.ts'); 4 | export const BDD_OPTIMIZE_STATE_LOCATION = path.join(__dirname, './bdd.optimize.state.json'); 5 | export const BDD_TEMPLATE_GOAL = path.join(__dirname, './bdd.generated.ts'); 6 | export function writeBddTemplate(minimalBddString, performanceMeasurement, quality) { 7 | let templateString = fs.readFileSync(BDD_TEMPLATE_LOCATION, 'utf-8'); 8 | const replaceVariables = { 9 | minimalBddString: '\'' + minimalBddString + '\'', 10 | }; 11 | Object.entries(replaceVariables).forEach(([key, content]) => { 12 | const contentString = content; 13 | const templateVar = '\'${' + key + '}\''; 14 | templateString = templateString.replace(templateVar, contentString); 15 | }); 16 | fs.writeFileSync(BDD_OPTIMIZE_STATE_LOCATION, JSON.stringify({ 17 | performanceMeasurement, 18 | minimalBddString, 19 | quality 20 | }, null, 4), { encoding: 'utf8', flag: 'w' }); 21 | fs.writeFileSync(BDD_TEMPLATE_GOAL, templateString, { encoding: 'utf8', flag: 'w' }); 22 | } 23 | //# sourceMappingURL=write-bdd-template.js.map -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/bdd.generated.js: -------------------------------------------------------------------------------- 1 | import { minimalStringToSimpleBdd, resolveWithSimpleBdd } from 'binary-decision-diagram'; 2 | import { stateResolveFunctionByIndex } from '../states/index.js'; 3 | export const minimalBddString = '14a1b,c+d2e5f0g/h.i4j*k-l)m(n6oeh6pnm6qen6ril6snh6tin6ubo9vce9wmh9xns9yne9zmi9{cm9|ad9}cp9~aq9ae9¡bf9¢bq9£cg9¤ck9¥cn9¦nd9§np9¨nq9©nf9ªng9«nm9¬nk9­mr9®ms9¯mt9°mj9±mk9²ml9³mn9´mc8µ³{8¶¯}8·°¤8¸³§8¹mn8º³«8»³m8¼m´4½z²4¾³w4¿zµ4À¯¶4Á°·4³º4ó¸4Äm¹4Åv¤7Æyn7ÇÀÁ7È~7É¥¤7ÊÃÄ7˨n7̺¹7Í­°7ήm7ϯ°7бm7ѳm7Ò¼m5ÓÄm5Ô¹m5Õ½°5Ö¾m5׿°5ØÇÏ5ÙÂm5ÚÊÑ5Û±m5ܺm5ÝÌÑ5ÞÕÍ2ß|2à¡u2á£Å2âÖÎ2ã¦Æ2ä©x2åªÆ2æ×Ø2ç|È2è¡¢2é£É2ꤥ2ëÙÚ2ì¦Ë2í©n2îªn2ïÛÐ2ðÜÝ2ñ¬n2òÒÓ/óan/ôbn/õcn/öÞâ/÷ßã/øàä/ùáå/úæë/ûçì/üèí/ýéî/þÍÎ/ÿÏÑ/ĀòÔ,ācn,Ăöï,ă¤ñ,Ąúð,ąêñ,ĆþÐ,ćÿÑ,Ĉac0ĉbc0Ċóõ0ċôā0Čßá0čà¤0Ďçé0ďèê0Đ÷ù0đøă0Ēûý0ēüą0ĔmÒ-ĕmĀ-ĖÞæ-ėČĎ-Ęčď-ęĂĄ-ĚĐĒ-ěđē-Ĝ²»-ĝÍÏ-ĞĆć-ğ²³-ĠĔĈ3ġĕĊ3ĢĖė3ģęĚ3ĤĢĝ(ĥĜğ(ĦģĞ(ħĠġ+Ĩĉċ+ĩĤĦ+ĪĘě+īħĨ1ĬĩĪ1ĭĬī*Įĥm*ĭĮ.'; 4 | let simpleBdd; 5 | export function getSimpleBdd() { 6 | if (!simpleBdd) { 7 | simpleBdd = minimalStringToSimpleBdd(minimalBddString); 8 | } 9 | return simpleBdd; 10 | } 11 | export const resolveInput = (input) => { 12 | return resolveWithSimpleBdd(getSimpleBdd(), stateResolveFunctionByIndex, input); 13 | }; 14 | //# sourceMappingURL=bdd.generated.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/actions/action-functions.d.ts: -------------------------------------------------------------------------------- 1 | import type { ActionFunction } from '../types/index.js'; 2 | export declare const doNothing: ActionFunction; 3 | export declare const insertFirst: ActionFunction; 4 | export declare const insertLast: ActionFunction; 5 | export declare const removeFirstItem: ActionFunction; 6 | export declare const removeLastItem: ActionFunction; 7 | export declare const removeFirstInsertLast: ActionFunction; 8 | export declare const removeLastInsertFirst: ActionFunction; 9 | export declare const removeFirstInsertFirst: ActionFunction; 10 | export declare const removeLastInsertLast: ActionFunction; 11 | export declare const removeExisting: ActionFunction; 12 | export declare const replaceExisting: ActionFunction; 13 | /** 14 | * this function always returns wrong results 15 | * it must be later optimised out 16 | * otherwise there is something broken 17 | */ 18 | export declare const alwaysWrong: ActionFunction; 19 | export declare const insertAtSortPosition: ActionFunction; 20 | export declare const removeExistingAndInsertAtSortPosition: ActionFunction; 21 | export declare const runFullQueryAgain: ActionFunction; 22 | export declare const unknownAction: ActionFunction; 23 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/actions/action-functions.d.ts: -------------------------------------------------------------------------------- 1 | import type { ActionFunction } from '../types/index.js'; 2 | export declare const doNothing: ActionFunction; 3 | export declare const insertFirst: ActionFunction; 4 | export declare const insertLast: ActionFunction; 5 | export declare const removeFirstItem: ActionFunction; 6 | export declare const removeLastItem: ActionFunction; 7 | export declare const removeFirstInsertLast: ActionFunction; 8 | export declare const removeLastInsertFirst: ActionFunction; 9 | export declare const removeFirstInsertFirst: ActionFunction; 10 | export declare const removeLastInsertLast: ActionFunction; 11 | export declare const removeExisting: ActionFunction; 12 | export declare const replaceExisting: ActionFunction; 13 | /** 14 | * this function always returns wrong results 15 | * it must be later optimised out 16 | * otherwise there is something broken 17 | */ 18 | export declare const alwaysWrong: ActionFunction; 19 | export declare const insertAtSortPosition: ActionFunction; 20 | export declare const removeExistingAndInsertAtSortPosition: ActionFunction; 21 | export declare const runFullQueryAgain: ActionFunction; 22 | export declare const unknownAction: ActionFunction; 23 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/states/state-resolver.d.ts: -------------------------------------------------------------------------------- 1 | import type { StateResolveFunction } from '../types/index.js'; 2 | export declare const hasLimit: StateResolveFunction; 3 | export declare const isFindOne: StateResolveFunction; 4 | export declare const hasSkip: StateResolveFunction; 5 | export declare const isDelete: StateResolveFunction; 6 | export declare const isInsert: StateResolveFunction; 7 | export declare const isUpdate: StateResolveFunction; 8 | export declare const wasLimitReached: StateResolveFunction; 9 | export declare const sortParamsChanged: StateResolveFunction; 10 | export declare const wasInResult: StateResolveFunction; 11 | export declare const wasFirst: StateResolveFunction; 12 | export declare const wasLast: StateResolveFunction; 13 | export declare const wasSortedBeforeFirst: StateResolveFunction; 14 | export declare const wasSortedAfterLast: StateResolveFunction; 15 | export declare const isSortedBeforeFirst: StateResolveFunction; 16 | export declare const isSortedAfterLast: StateResolveFunction; 17 | export declare const wasMatching: StateResolveFunction; 18 | export declare const doesMatchNow: StateResolveFunction; 19 | export declare const wasResultsEmpty: StateResolveFunction; 20 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/states/state-resolver.d.ts: -------------------------------------------------------------------------------- 1 | import type { StateResolveFunction } from '../types/index.js'; 2 | export declare const hasLimit: StateResolveFunction; 3 | export declare const isFindOne: StateResolveFunction; 4 | export declare const hasSkip: StateResolveFunction; 5 | export declare const isDelete: StateResolveFunction; 6 | export declare const isInsert: StateResolveFunction; 7 | export declare const isUpdate: StateResolveFunction; 8 | export declare const wasLimitReached: StateResolveFunction; 9 | export declare const sortParamsChanged: StateResolveFunction; 10 | export declare const wasInResult: StateResolveFunction; 11 | export declare const wasFirst: StateResolveFunction; 12 | export declare const wasLast: StateResolveFunction; 13 | export declare const wasSortedBeforeFirst: StateResolveFunction; 14 | export declare const wasSortedAfterLast: StateResolveFunction; 15 | export declare const isSortedBeforeFirst: StateResolveFunction; 16 | export declare const isSortedAfterLast: StateResolveFunction; 17 | export declare const wasMatching: StateResolveFunction; 18 | export declare const doesMatchNow: StateResolveFunction; 19 | export declare const wasResultsEmpty: StateResolveFunction; 20 | -------------------------------------------------------------------------------- /examples/browser/src/types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChangeEvent 3 | } from 'event-reduce-js'; 4 | import { QueryParams } from 'event-reduce-js'; 5 | 6 | export type Procedure = ChangeEvent[]; 7 | 8 | export interface Human { 9 | _id: string; // primary 10 | name: string; 11 | gender: 'm' | 'f'; 12 | age: number; 13 | } 14 | export type IdToDocumentMap = Map; 15 | 16 | export type MongoQuery = { 17 | selector: any; 18 | skip?: number; 19 | limit?: number; 20 | sort: any[] 21 | }; 22 | 23 | export type FirestoreQueryPart = { 24 | field: string; 25 | op: '==' | '>=' | '<=' | '<' | '>'; 26 | value: string | number; 27 | }; 28 | 29 | export type FirestoreQuery = FirestoreQueryPart[]; 30 | 31 | export type Query = MongoQuery | FirestoreQuery; 32 | 33 | export interface DatabaseImplementation { 34 | getName(): string; 35 | getStorageOptions(): string[]; 36 | 37 | init(storageOption: string): Promise; 38 | getExampleQueries(): QueryType[]; 39 | getQueryParams(query: QueryType): QueryParams; 40 | getRawResults(query: QueryType): Promise; 41 | getAll(): Promise; 42 | 43 | // returns the amount of time it took in ms 44 | handleEvent(changeEvent: ChangeEvent): Promise; 45 | } 46 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/index.es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const pkg = __importStar(require("./index.js")); 27 | module.exports = pkg; 28 | //# sourceMappingURL=index.es5.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { StateActionIdMap, Procedure, Human } from './types.js'; 2 | import type { ActionName, ActionFunctionInput, MongoQuery } from '../types/index.js'; 3 | export * from './binary-state.js'; 4 | export * from './calculate-bdd-quality.js'; 5 | export * from './data-generator.js'; 6 | export * from './fuzzing.js'; 7 | export * from './procedures.js'; 8 | export * from './queries.js'; 9 | export type * from './types.js'; 10 | export * from './database/index.js'; 11 | export interface GenerateTruthTableInput { 12 | queries: MongoQuery[]; 13 | procedures: Procedure[]; 14 | table?: StateActionIdMap; 15 | log?: boolean; 16 | } 17 | export declare function generateTruthTable({ queries, procedures, table, log }: GenerateTruthTableInput): StateActionIdMap; 18 | export declare function incrementTruthTableActions(table: Map | undefined, queries: MongoQuery[], procedure: Procedure, log?: boolean): number; 19 | export declare function getNextWorkingAction(input: ActionFunctionInput, resultAfter: Human[], lastWorkingActionId: number, log?: boolean): number; 20 | /** 21 | * returns true if the action calculates the same 22 | * results as given 23 | */ 24 | export declare function doesActionWork(input: ActionFunctionInput, resultAfter: Human[], actionName: ActionName, log?: boolean): boolean; 25 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { StateActionIdMap, Procedure, Human } from './types.js'; 2 | import type { ActionName, ActionFunctionInput, MongoQuery } from '../types/index.js'; 3 | export * from './binary-state.js'; 4 | export * from './calculate-bdd-quality.js'; 5 | export * from './data-generator.js'; 6 | export * from './fuzzing.js'; 7 | export * from './procedures.js'; 8 | export * from './queries.js'; 9 | export type * from './types.js'; 10 | export * from './database/index.js'; 11 | export interface GenerateTruthTableInput { 12 | queries: MongoQuery[]; 13 | procedures: Procedure[]; 14 | table?: StateActionIdMap; 15 | log?: boolean; 16 | } 17 | export declare function generateTruthTable({ queries, procedures, table, log }: GenerateTruthTableInput): StateActionIdMap; 18 | export declare function incrementTruthTableActions(table: Map | undefined, queries: MongoQuery[], procedure: Procedure, log?: boolean): number; 19 | export declare function getNextWorkingAction(input: ActionFunctionInput, resultAfter: Human[], lastWorkingActionId: number, log?: boolean): number; 20 | /** 21 | * returns true if the action calculates the same 22 | * results as given 23 | */ 24 | export declare function doesActionWork(input: ActionFunctionInput, resultAfter: Human[], actionName: ActionName, log?: boolean): boolean; 25 | -------------------------------------------------------------------------------- /javascript/src/bdd/bdd.generated.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SimpleBdd, 3 | minimalStringToSimpleBdd, 4 | resolveWithSimpleBdd 5 | } from 'binary-decision-diagram'; 6 | import type { StateResolveFunctionInput } from '../types/index.js'; 7 | import { stateResolveFunctionByIndex } from '../states/index.js'; 8 | 9 | export const minimalBddString = '14a1b,c+d2e5f0g/h.i4j*k-l)m(n6oeh6pnm6qen6ril6snh6tin6ubo9vce9wmh9xns9yne9zmi9{cm9|ad9}cp9~aq9ae9¡bf9¢bq9£cg9¤ck9¥cn9¦nd9§np9¨nq9©nf9ªng9«nm9¬nk9­mr9®ms9¯mt9°mj9±mk9²ml9³mn9´mc8µ³{8¶¯}8·°¤8¸³§8¹mn8º³«8»³m8¼m´4½z²4¾³w4¿zµ4À¯¶4Á°·4³º4ó¸4Äm¹4Åv¤7Æyn7ÇÀÁ7È~7É¥¤7ÊÃÄ7˨n7̺¹7Í­°7ήm7ϯ°7бm7ѳm7Ò¼m5ÓÄm5Ô¹m5Õ½°5Ö¾m5׿°5ØÇÏ5ÙÂm5ÚÊÑ5Û±m5ܺm5ÝÌÑ5ÞÕÍ2ß|2à¡u2á£Å2âÖÎ2ã¦Æ2ä©x2åªÆ2æ×Ø2ç|È2è¡¢2é£É2ꤥ2ëÙÚ2ì¦Ë2í©n2îªn2ïÛÐ2ðÜÝ2ñ¬n2òÒÓ/óan/ôbn/õcn/öÞâ/÷ßã/øàä/ùáå/úæë/ûçì/üèí/ýéî/þÍÎ/ÿÏÑ/ĀòÔ,ācn,Ăöï,ă¤ñ,Ąúð,ąêñ,ĆþÐ,ćÿÑ,Ĉac0ĉbc0Ċóõ0ċôā0Čßá0čà¤0Ďçé0ďèê0Đ÷ù0đøă0Ēûý0ēüą0ĔmÒ-ĕmĀ-ĖÞæ-ėČĎ-Ęčď-ęĂĄ-ĚĐĒ-ěđē-Ĝ²»-ĝÍÏ-ĞĆć-ğ²³-ĠĔĈ3ġĕĊ3ĢĖė3ģęĚ3ĤĢĝ(ĥĜğ(ĦģĞ(ħĠġ+Ĩĉċ+ĩĤĦ+ĪĘě+īħĨ1ĬĩĪ1ĭĬī*Įĥm*ĭĮ.'; 10 | 11 | let simpleBdd: SimpleBdd | undefined; 12 | export function getSimpleBdd() { 13 | if (!simpleBdd) { 14 | simpleBdd = minimalStringToSimpleBdd(minimalBddString); 15 | } 16 | return simpleBdd; 17 | } 18 | 19 | export const resolveInput = (input: StateResolveFunctionInput) => { 20 | return resolveWithSimpleBdd( 21 | getSimpleBdd(), 22 | stateResolveFunctionByIndex, 23 | input 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/database/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | exports.applyChangeEvent = void 0; 18 | __exportStar(require("./mingo.js"), exports); 19 | function applyChangeEvent(collection, changeEvent) { 20 | switch (changeEvent.operation) { 21 | case 'INSERT': 22 | collection.upsert(changeEvent.doc); 23 | break; 24 | case 'UPDATE': 25 | collection.upsert(changeEvent.doc); 26 | break; 27 | case 'DELETE': 28 | collection.remove(changeEvent.id); 29 | break; 30 | } 31 | } 32 | exports.applyChangeEvent = applyChangeEvent; 33 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/calculate-bdd-quality.d.ts: -------------------------------------------------------------------------------- 1 | import { RootNode } from 'binary-decision-diagram'; 2 | import type { MongoQuery, StateName } from '../types/index.js'; 3 | import type { Procedure } from './types.js'; 4 | export type PerformanceMeasurement = { 5 | [k in StateName]: number; 6 | }; 7 | /** 8 | * measure how much cpu each of the state functions needs 9 | */ 10 | export declare function measurePerformanceOfStateFunctions(rounds?: number): Promise; 11 | /** 12 | * Comparator used to find the best sort-order of the boolean functions. 13 | * In the past we just used the bdd with the least amount of nodes. 14 | * But not all state-functions need the same performance so we optimize 15 | * to use the least amount of cpu cycles 16 | * 17 | * @returns the better bdd 18 | */ 19 | export declare function getBetterBdd(a: RootNode, b: RootNode, perfMeasurement: PerformanceMeasurement, queries: MongoQuery[], procedures: Procedure[]): Promise; 20 | export type FunctionUsageCount = { 21 | [k in StateName]: number; 22 | }; 23 | export declare function countFunctionUsages(bdd: RootNode, queries: MongoQuery[], procedures: Procedure[]): FunctionUsageCount; 24 | /** 25 | * returns the quality of the BDD, 26 | * the higher the better 27 | */ 28 | export declare const QUALITY_BY_BDD_CACHE: WeakMap; 29 | export declare function getQualityOfBdd(bdd: RootNode, perfMeasurement: PerformanceMeasurement, queries: MongoQuery[], procedures: Procedure[]): number; 30 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/calculate-bdd-quality.d.ts: -------------------------------------------------------------------------------- 1 | import { RootNode } from 'binary-decision-diagram'; 2 | import type { MongoQuery, StateName } from '../types/index.js'; 3 | import type { Procedure } from './types.js'; 4 | export type PerformanceMeasurement = { 5 | [k in StateName]: number; 6 | }; 7 | /** 8 | * measure how much cpu each of the state functions needs 9 | */ 10 | export declare function measurePerformanceOfStateFunctions(rounds?: number): Promise; 11 | /** 12 | * Comparator used to find the best sort-order of the boolean functions. 13 | * In the past we just used the bdd with the least amount of nodes. 14 | * But not all state-functions need the same performance so we optimize 15 | * to use the least amount of cpu cycles 16 | * 17 | * @returns the better bdd 18 | */ 19 | export declare function getBetterBdd(a: RootNode, b: RootNode, perfMeasurement: PerformanceMeasurement, queries: MongoQuery[], procedures: Procedure[]): Promise; 20 | export type FunctionUsageCount = { 21 | [k in StateName]: number; 22 | }; 23 | export declare function countFunctionUsages(bdd: RootNode, queries: MongoQuery[], procedures: Procedure[]): FunctionUsageCount; 24 | /** 25 | * returns the quality of the BDD, 26 | * the higher the better 27 | */ 28 | export declare const QUALITY_BY_BDD_CACHE: WeakMap; 29 | export declare function getQualityOfBdd(bdd: RootNode, perfMeasurement: PerformanceMeasurement, queries: MongoQuery[], procedures: Procedure[]): number; 30 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/bdd.generated.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.resolveInput = exports.getSimpleBdd = exports.minimalBddString = void 0; 4 | const binary_decision_diagram_1 = require("binary-decision-diagram"); 5 | const index_js_1 = require("../states/index.js"); 6 | exports.minimalBddString = '14a1b,c+d2e5f0g/h.i4j*k-l)m(n6oeh6pnm6qen6ril6snh6tin6ubo9vce9wmh9xns9yne9zmi9{cm9|ad9}cp9~aq9ae9¡bf9¢bq9£cg9¤ck9¥cn9¦nd9§np9¨nq9©nf9ªng9«nm9¬nk9­mr9®ms9¯mt9°mj9±mk9²ml9³mn9´mc8µ³{8¶¯}8·°¤8¸³§8¹mn8º³«8»³m8¼m´4½z²4¾³w4¿zµ4À¯¶4Á°·4³º4ó¸4Äm¹4Åv¤7Æyn7ÇÀÁ7È~7É¥¤7ÊÃÄ7˨n7̺¹7Í­°7ήm7ϯ°7бm7ѳm7Ò¼m5ÓÄm5Ô¹m5Õ½°5Ö¾m5׿°5ØÇÏ5ÙÂm5ÚÊÑ5Û±m5ܺm5ÝÌÑ5ÞÕÍ2ß|2à¡u2á£Å2âÖÎ2ã¦Æ2ä©x2åªÆ2æ×Ø2ç|È2è¡¢2é£É2ꤥ2ëÙÚ2ì¦Ë2í©n2îªn2ïÛÐ2ðÜÝ2ñ¬n2òÒÓ/óan/ôbn/õcn/öÞâ/÷ßã/øàä/ùáå/úæë/ûçì/üèí/ýéî/þÍÎ/ÿÏÑ/ĀòÔ,ācn,Ăöï,ă¤ñ,Ąúð,ąêñ,ĆþÐ,ćÿÑ,Ĉac0ĉbc0Ċóõ0ċôā0Čßá0čà¤0Ďçé0ďèê0Đ÷ù0đøă0Ēûý0ēüą0ĔmÒ-ĕmĀ-ĖÞæ-ėČĎ-Ęčď-ęĂĄ-ĚĐĒ-ěđē-Ĝ²»-ĝÍÏ-ĞĆć-ğ²³-ĠĔĈ3ġĕĊ3ĢĖė3ģęĚ3ĤĢĝ(ĥĜğ(ĦģĞ(ħĠġ+Ĩĉċ+ĩĤĦ+ĪĘě+īħĨ1ĬĩĪ1ĭĬī*Įĥm*ĭĮ.'; 7 | let simpleBdd; 8 | function getSimpleBdd() { 9 | if (!simpleBdd) { 10 | simpleBdd = (0, binary_decision_diagram_1.minimalStringToSimpleBdd)(exports.minimalBddString); 11 | } 12 | return simpleBdd; 13 | } 14 | exports.getSimpleBdd = getSimpleBdd; 15 | const resolveInput = (input) => { 16 | return (0, binary_decision_diagram_1.resolveWithSimpleBdd)(getSimpleBdd(), index_js_1.stateResolveFunctionByIndex, input); 17 | }; 18 | exports.resolveInput = resolveInput; 19 | //# sourceMappingURL=bdd.generated.js.map -------------------------------------------------------------------------------- /javascript/dist/esm/src/index.js: -------------------------------------------------------------------------------- 1 | import { getStateSet } from './states/index.js'; 2 | import { actionFunctions, orderedActionList } from './actions/index.js'; 3 | import { resolveInput } from './bdd/bdd.generated.js'; 4 | export * from './states/index.js'; 5 | export * from './util.js'; 6 | export * from './actions/index.js'; 7 | export function calculateActionFromMap(stateSetToActionMap, input) { 8 | const stateSet = getStateSet(input); 9 | const actionName = stateSetToActionMap.get(stateSet); 10 | if (!actionName) { 11 | return { 12 | action: 'runFullQueryAgain', 13 | stateSet 14 | }; 15 | } 16 | else { 17 | return { 18 | action: actionName, 19 | stateSet 20 | }; 21 | } 22 | } 23 | export function calculateActionName(input) { 24 | const resolvedActionId = resolveInput(input); 25 | return orderedActionList[resolvedActionId]; 26 | } 27 | export function calculateActionFunction(input) { 28 | const actionName = calculateActionName(input); 29 | return actionFunctions[actionName]; 30 | } 31 | /** 32 | * for performance reasons, 33 | * @mutates the input 34 | * @returns the new results 35 | */ 36 | export function runAction(action, queryParams, changeEvent, previousResults, keyDocumentMap) { 37 | const fn = actionFunctions[action]; 38 | fn({ 39 | queryParams, 40 | changeEvent, 41 | previousResults, 42 | keyDocumentMap 43 | }); 44 | return previousResults; 45 | } 46 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/DEVELOPER.md: -------------------------------------------------------------------------------- 1 | # Developer stuff 2 | 3 | ## npm run test 4 | Run all tests in nodejs 5 | 6 | 7 | ## Going from Scratch to a finished build 8 | 9 | We have to perform several steps to create a fully optimized and tested bdd: 10 | 11 | ### Generate initial truth table 12 | 13 | `npm run generate-truth-table` 14 | 15 | Calculate the initial truth table from the defined events and queries. 16 | It takes about 5 minutes and will write the result into `src/truth-table-generator/ouput/`. 17 | 18 | ### npm run iterative-fuzzing 19 | 20 | Randomly generate write events and check if their optimized result matches a full query over the database. 21 | If not, it adapts the truth table to ensure that the errored query now works. 22 | 23 | Run this until it no longer logs that it has found errors. I had let this run about one month. 24 | 25 | To let it run on a server, use this command so you can exit the terminal and it still runs: 26 | `nohup npm run iterative-fuzzing &> iterative-fuzzing.out &` 27 | 28 | ### optimize bdd 29 | 30 | `npm run optimize-bdd` 31 | 32 | Optimize the binary decision diagramm to get the one which has the best performance. 33 | Because there are 2^13 permutations or the bdd order, we just generate a random order and test it. 34 | As soon as we find a better bdd, it is written to the generated files. 35 | Run this until it no longer finds a better bdd. I had let this run about one week. 36 | 37 | To let it run on a server, use this command so you can exit the terminal and it still runs: 38 | `nohup npm run optimize-bdd &> optimize-bdd.out &` 39 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/actions/index.js: -------------------------------------------------------------------------------- 1 | import { doNothing, insertFirst, insertLast, removeFirstItem, removeLastItem, removeFirstInsertLast, removeLastInsertFirst, removeExisting, replaceExisting, alwaysWrong, insertAtSortPosition, removeExistingAndInsertAtSortPosition, runFullQueryAgain, unknownAction, removeFirstInsertFirst, removeLastInsertLast } from './action-functions.js'; 2 | export * from './action-functions.js'; 3 | /** 4 | * all actions ordered by performance-cost 5 | * cheapest first 6 | * TODO run tests on which is really the fastest 7 | */ 8 | export const orderedActionList = [ 9 | 'doNothing', 10 | 'insertFirst', 11 | 'insertLast', 12 | 'removeFirstItem', 13 | 'removeLastItem', 14 | 'removeFirstInsertLast', 15 | 'removeLastInsertFirst', 16 | 'removeFirstInsertFirst', 17 | 'removeLastInsertLast', 18 | 'removeExisting', 19 | 'replaceExisting', 20 | 'alwaysWrong', 21 | 'insertAtSortPosition', 22 | 'removeExistingAndInsertAtSortPosition', 23 | 'runFullQueryAgain', 24 | 'unknownAction' 25 | ]; 26 | export const actionFunctions = { 27 | doNothing, 28 | insertFirst, 29 | insertLast, 30 | removeFirstItem, 31 | removeLastItem, 32 | removeFirstInsertLast, 33 | removeLastInsertFirst, 34 | removeFirstInsertFirst, 35 | removeLastInsertLast, 36 | removeExisting, 37 | replaceExisting, 38 | alwaysWrong, 39 | insertAtSortPosition, 40 | removeExistingAndInsertAtSortPosition, 41 | runFullQueryAgain, 42 | unknownAction 43 | }; 44 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/test/unit/minimongo.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | 3 | import { 4 | randomHuman, 5 | randomHumans 6 | } from '../../src/truth-table-generator/data-generator.js'; 7 | 8 | import { clone } from 'async-test-util'; 9 | import { MongoQuery } from '../../src/index.js'; 10 | import { mingoCollectionCreator } from '../../src/truth-table-generator/database/mingo.js'; 11 | 12 | /** 13 | * sometimes we think stuff is wrong with minimongo 14 | * so we add tests to pin the correct behavior 15 | */ 16 | describe('minimongo.test.ts', () => { 17 | it('upsert does not affect sort order', async () => { 18 | const collection = mingoCollectionCreator(); 19 | 20 | const addHumans = new Array(5).fill(0) 21 | .map(() => randomHuman()); 22 | await Promise.all( 23 | addHumans.map(human => collection.upsert( 24 | human 25 | )) 26 | ); 27 | const query: MongoQuery = { 28 | selector: {}, 29 | limit: 5, 30 | sort: ['age'] 31 | }; 32 | const results = await collection.query( 33 | query 34 | ); 35 | assert.ok(results[0].age <= results[1].age); 36 | 37 | // change one 38 | const changeHuman = clone(results[2]); 39 | changeHuman.age = 0; 40 | await collection.upsert( 41 | changeHuman 42 | ); 43 | 44 | const results2 = await collection.query( 45 | query 46 | ); 47 | assert.strictEqual(results2[0].age, 0); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent, ActionName, ResultKeyDocumentMap, QueryParams, StateSetToActionMap, StateSet, ActionFunction, StateResolveFunctionInput } from './types/index.js'; 2 | /** 3 | * Export as type to ensure we do not 4 | * end with an import statement in the build output 5 | * which would increase the build size. 6 | */ 7 | export type { ActionFunction, ActionFunctionInput, ActionName, ChangeEvent, ChangeEventBase, ChangeEventDelete, ChangeEventInsert, ChangeEventUpdate, MongoQuery, QueryMatcher, QueryParams, ResultKeyDocumentMap, DeterministicSortComparator, StateName, StateResolveFunction, StateResolveFunctionInput, StateSet, StateSetToActionMap, WriteOperation } from './types/index.js'; 8 | export * from './states/index.js'; 9 | export * from './util.js'; 10 | export * from './actions/index.js'; 11 | export declare function calculateActionFromMap(stateSetToActionMap: StateSetToActionMap, input: StateResolveFunctionInput): { 12 | action: ActionName; 13 | stateSet: StateSet; 14 | }; 15 | export declare function calculateActionName(input: StateResolveFunctionInput): ActionName; 16 | export declare function calculateActionFunction(input: StateResolveFunctionInput): ActionFunction; 17 | /** 18 | * for performance reasons, 19 | * @mutates the input 20 | * @returns the new results 21 | */ 22 | export declare function runAction(action: ActionName, queryParams: QueryParams, changeEvent: ChangeEvent, previousResults: DocType[], keyDocumentMap?: ResultKeyDocumentMap): DocType[]; 23 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ChangeEvent, ActionName, ResultKeyDocumentMap, QueryParams, StateSetToActionMap, StateSet, ActionFunction, StateResolveFunctionInput } from './types/index.js'; 2 | /** 3 | * Export as type to ensure we do not 4 | * end with an import statement in the build output 5 | * which would increase the build size. 6 | */ 7 | export type { ActionFunction, ActionFunctionInput, ActionName, ChangeEvent, ChangeEventBase, ChangeEventDelete, ChangeEventInsert, ChangeEventUpdate, MongoQuery, QueryMatcher, QueryParams, ResultKeyDocumentMap, DeterministicSortComparator, StateName, StateResolveFunction, StateResolveFunctionInput, StateSet, StateSetToActionMap, WriteOperation } from './types/index.js'; 8 | export * from './states/index.js'; 9 | export * from './util.js'; 10 | export * from './actions/index.js'; 11 | export declare function calculateActionFromMap(stateSetToActionMap: StateSetToActionMap, input: StateResolveFunctionInput): { 12 | action: ActionName; 13 | stateSet: StateSet; 14 | }; 15 | export declare function calculateActionName(input: StateResolveFunctionInput): ActionName; 16 | export declare function calculateActionFunction(input: StateResolveFunctionInput): ActionFunction; 17 | /** 18 | * for performance reasons, 19 | * @mutates the input 20 | * @returns the new results 21 | */ 22 | export declare function runAction(action: ActionName, queryParams: QueryParams, changeEvent: ChangeEvent, previousResults: DocType[], keyDocumentMap?: ResultKeyDocumentMap): DocType[]; 23 | -------------------------------------------------------------------------------- /javascript/src/bdd/write-bdd-template.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import path from 'path'; 3 | import { 4 | PerformanceMeasurement 5 | } from '../truth-table-generator/calculate-bdd-quality.js'; 6 | 7 | export const BDD_TEMPLATE_LOCATION = path.join( 8 | __dirname, 9 | './bdd.template.ts' 10 | ); 11 | export const BDD_OPTIMIZE_STATE_LOCATION = path.join( 12 | __dirname, 13 | './bdd.optimize.state.json' 14 | ); 15 | export const BDD_TEMPLATE_GOAL = path.join( 16 | __dirname, 17 | './bdd.generated.ts' 18 | ); 19 | 20 | export function writeBddTemplate( 21 | minimalBddString: string, 22 | performanceMeasurement: PerformanceMeasurement, 23 | quality: number 24 | ) { 25 | let templateString: string = fs.readFileSync(BDD_TEMPLATE_LOCATION, 'utf-8'); 26 | const replaceVariables = { 27 | minimalBddString: '\'' + minimalBddString + '\'', 28 | }; 29 | 30 | Object.entries(replaceVariables).forEach(([key, content]) => { 31 | const contentString = content as string; 32 | const templateVar = '\'${' + key + '}\''; 33 | templateString = templateString.replace(templateVar, contentString); 34 | }); 35 | 36 | fs.writeFileSync( 37 | BDD_OPTIMIZE_STATE_LOCATION, 38 | JSON.stringify({ 39 | performanceMeasurement, 40 | minimalBddString, 41 | quality 42 | }, null, 4), 43 | { encoding: 'utf8', flag: 'w' } 44 | ); 45 | 46 | 47 | fs.writeFileSync( 48 | BDD_TEMPLATE_GOAL, 49 | templateString, 50 | { encoding: 'utf8', flag: 'w' } 51 | ); 52 | } 53 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/binary-state.js: -------------------------------------------------------------------------------- 1 | import { orderedStateList } from '../states/index.js'; 2 | export const STATE_SET_LENGTH = orderedStateList.length; 3 | export const FIRST_STATE_SET = new Array(STATE_SET_LENGTH).fill(0).map(() => '0').join(''); 4 | export const LAST_STATE_SET = new Array(STATE_SET_LENGTH).fill(0).map(() => '1').join(''); 5 | export function getNextStateSet(stateSet) { 6 | if (!stateSet) { 7 | return FIRST_STATE_SET; 8 | } 9 | const decimal = binaryToDecimal(stateSet); 10 | const increase = decimal + 1; 11 | const binary = decimalToPaddedBinary(increase); 12 | return binary; 13 | } 14 | /** 15 | * @link https://stackoverflow.com/a/16155417 16 | */ 17 | export function decimalToPaddedBinary(decimal, padding = STATE_SET_LENGTH) { 18 | const binary = (decimal >>> 0).toString(2); 19 | const padded = binary.padStart(padding, '0'); 20 | return padded; 21 | } 22 | export function binaryToDecimal(binary) { 23 | return parseInt(binary, 2); 24 | } 25 | export function maxBinaryWithLength(length) { 26 | return new Array(length).fill(0).map(() => '1').join(''); 27 | } 28 | export function oppositeBinary(i) { 29 | if (i === '1') { 30 | return '0'; 31 | } 32 | else if (i === '0') { 33 | return '1'; 34 | } 35 | else { 36 | throw new Error('non-binary given'); 37 | } 38 | } 39 | export function stateSetToObject(stateSet) { 40 | const ret = {}; 41 | let i = 0; 42 | orderedStateList.forEach(s => { 43 | ret[s] = stateSet[i]; 44 | i++; 45 | }); 46 | return ret; 47 | } 48 | //# sourceMappingURL=binary-state.js.map -------------------------------------------------------------------------------- /examples/browser/test/e2e.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Selector 3 | } from 'testcafe'; 4 | import { wait, waitUntil } from 'async-test-util'; 5 | import { DEFAULT_LOADING_STATE, getImplementations } from '../src/util'; 6 | 7 | console.log('open page'); 8 | 9 | const implementations = getImplementations(); 10 | 11 | const techs: string[] = []; 12 | implementations.forEach(imp => { 13 | const name = imp.getName(); 14 | imp.getStorageOptions().forEach(option => { 15 | const tech = name + ':' + option; 16 | techs.push(tech); 17 | }); 18 | }); 19 | 20 | /* tslint:disable-next-line */ 21 | fixture `A fixture`; 22 | 23 | const rootUrl = 'http://0.0.0.0:8888/'; 24 | // const rootUrl = 'https://pubkey.github.io/event-reduce/'; 25 | 26 | for (const tech of techs) { 27 | test.page(rootUrl + '?tech=' + tech) 28 | ('run in both modes (' + tech + ')', async t => { 29 | 30 | async function getLoadingState() { 31 | const loadingState = await Selector('#loading-state').innerText; 32 | return loadingState; 33 | } 34 | 35 | await t.click('#test100EventsButton'); 36 | await wait(100); 37 | 38 | await waitUntil(async () => { 39 | const state = await getLoadingState(); 40 | return state === DEFAULT_LOADING_STATE; 41 | }); 42 | 43 | await t.click('#test100EventsEventReduceButton'); 44 | await wait(100); 45 | 46 | await waitUntil(async () => { 47 | const state = await getLoadingState(); 48 | return state === DEFAULT_LOADING_STATE; 49 | }); 50 | }); 51 | } 52 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/util.d.ts: -------------------------------------------------------------------------------- 1 | import type { MongoQuery, DeepReadonlyObject } from './types/index.js'; 2 | export declare function lastOfArray(ar: T[]): T; 3 | /** 4 | * @link https://stackoverflow.com/a/5915122 5 | */ 6 | export declare function randomOfArray(items: T[]): T; 7 | export declare function shuffleArray(arr: T[]): T[]; 8 | /** 9 | * normalizes sort-field 10 | * in: '-age' 11 | * out: 'age' 12 | */ 13 | export declare function normalizeSortField(field: string): string; 14 | export declare function getSortFieldsOfQuery(query: MongoQuery): string[]; 15 | /** 16 | * @link https://stackoverflow.com/a/1431113 17 | */ 18 | export declare function replaceCharAt(str: string, index: number, replacement: string): string; 19 | export declare function mapToObject(map: Map): { 20 | [k: string]: V; 21 | }; 22 | export declare function objectToMap(object: { 23 | [k: string]: V; 24 | }): Map; 25 | export declare function cloneMap(map: Map): Map; 26 | /** 27 | * does a flat copy on the objects, 28 | * is about 3 times faster then using deepClone 29 | * @link https://jsperf.com/object-rest-spread-vs-clone/2 30 | */ 31 | export declare function flatClone(obj: T | DeepReadonlyObject): T; 32 | export declare function ensureNotFalsy(obj: T | false | undefined | null): T; 33 | export declare function mergeSets(sets: Set[]): Set; 34 | /** 35 | * @link https://stackoverflow.com/a/12830454/3443137 36 | */ 37 | export declare function roundToTwoDecimals(num: number): number; 38 | export declare function isObject(value: null): boolean; 39 | export declare function getProperty(object: any, path: string | string[], value?: any): any; 40 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/util.d.ts: -------------------------------------------------------------------------------- 1 | import type { MongoQuery, DeepReadonlyObject } from './types/index.js'; 2 | export declare function lastOfArray(ar: T[]): T; 3 | /** 4 | * @link https://stackoverflow.com/a/5915122 5 | */ 6 | export declare function randomOfArray(items: T[]): T; 7 | export declare function shuffleArray(arr: T[]): T[]; 8 | /** 9 | * normalizes sort-field 10 | * in: '-age' 11 | * out: 'age' 12 | */ 13 | export declare function normalizeSortField(field: string): string; 14 | export declare function getSortFieldsOfQuery(query: MongoQuery): string[]; 15 | /** 16 | * @link https://stackoverflow.com/a/1431113 17 | */ 18 | export declare function replaceCharAt(str: string, index: number, replacement: string): string; 19 | export declare function mapToObject(map: Map): { 20 | [k: string]: V; 21 | }; 22 | export declare function objectToMap(object: { 23 | [k: string]: V; 24 | }): Map; 25 | export declare function cloneMap(map: Map): Map; 26 | /** 27 | * does a flat copy on the objects, 28 | * is about 3 times faster then using deepClone 29 | * @link https://jsperf.com/object-rest-spread-vs-clone/2 30 | */ 31 | export declare function flatClone(obj: T | DeepReadonlyObject): T; 32 | export declare function ensureNotFalsy(obj: T | false | undefined | null): T; 33 | export declare function mergeSets(sets: Set[]): Set; 34 | /** 35 | * @link https://stackoverflow.com/a/12830454/3443137 36 | */ 37 | export declare function roundToTwoDecimals(num: number): number; 38 | export declare function isObject(value: null): boolean; 39 | export declare function getProperty(object: any, path: string | string[], value?: any): any; 40 | -------------------------------------------------------------------------------- /javascript/src/bdd/bdd.optimize.state.json: -------------------------------------------------------------------------------- 1 | { 2 | "performanceMeasurement": { 3 | "isInsert": 0.0005134089980274439, 4 | "isUpdate": 0.0005059200078248977, 5 | "isDelete": 0.0005452740341424942, 6 | "hasLimit": 0.0004327639751136303, 7 | "isFindOne": 0.00046740003488957883, 8 | "hasSkip": 0.0004786954801529646, 9 | "wasResultsEmpty": 0.00046854151226580145, 10 | "wasLimitReached": 0.0005687805358320474, 11 | "wasFirst": 0.0006331859696656466, 12 | "wasLast": 0.000993298990651965, 13 | "sortParamsChanged": 0.0021037884596735237, 14 | "wasInResult": 0.001067824000492692, 15 | "wasSortedBeforeFirst": 0.005706427520141006, 16 | "wasSortedAfterLast": 0.0063148145023733376, 17 | "isSortedBeforeFirst": 0.005680875465273857, 18 | "isSortedAfterLast": 0.006254887519404292, 19 | "wasMatching": 0.02021647496894002, 20 | "doesMatchNow": 0.016383298518136143 21 | }, 22 | "minimalBddString": "14a1b,c+d2e5f0g/h.i4j*k-l)m(n6oeh6pnm6qen6ril6snh6tin6ubo9vce9wmh9xns9yne9zmi9{cm9|ad9}cp9~aq9ae9¡bf9¢bq9£cg9¤ck9¥cn9¦nd9§np9¨nq9©nf9ªng9«nm9¬nk9­mr9®ms9¯mt9°mj9±mk9²ml9³mn9´mc8µ³{8¶¯}8·°¤8¸³§8¹mn8º³«8»³m8¼m´4½z²4¾³w4¿zµ4À¯¶4Á°·4³º4ó¸4Äm¹4Åv¤7Æyn7ÇÀÁ7È~7É¥¤7ÊÃÄ7˨n7̺¹7Í­°7ήm7ϯ°7бm7ѳm7Ò¼m5ÓÄm5Ô¹m5Õ½°5Ö¾m5׿°5ØÇÏ5ÙÂm5ÚÊÑ5Û±m5ܺm5ÝÌÑ5ÞÕÍ2ß|2à¡u2á£Å2âÖÎ2ã¦Æ2ä©x2åªÆ2æ×Ø2ç|È2è¡¢2é£É2ꤥ2ëÙÚ2ì¦Ë2í©n2îªn2ïÛÐ2ðÜÝ2ñ¬n2òÒÓ/óan/ôbn/õcn/öÞâ/÷ßã/øàä/ùáå/úæë/ûçì/üèí/ýéî/þÍÎ/ÿÏÑ/ĀòÔ,ācn,Ăöï,ă¤ñ,Ąúð,ąêñ,ĆþÐ,ćÿÑ,Ĉac0ĉbc0Ċóõ0ċôā0Čßá0čà¤0Ďçé0ďèê0Đ÷ù0đøă0Ēûý0ēüą0ĔmÒ-ĕmĀ-ĖÞæ-ėČĎ-Ęčď-ęĂĄ-ĚĐĒ-ěđē-Ĝ²»-ĝÍÏ-ĞĆć-ğ²³-ĠĔĈ3ġĕĊ3ĢĖė3ģęĚ3ĤĢĝ(ĥĜğ(ĦģĞ(ħĠġ+Ĩĉċ+ĩĤĦ+ĪĘě+īħĨ1ĬĩĪ1ĭĬī*Įĥm*ĭĮ.", 23 | "quality": 608.2791532363426 24 | } -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | push: 9 | branches: [master] 10 | pull_request: 11 | branches: [master] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | test: 19 | runs-on: ubuntu-22.04 20 | env: 21 | TAG: "${{github.sha}}" 22 | COMPOSE_DOCKER_CLI_BUILD: 1 23 | DOCKER_BUILDKIT: 1 24 | NODE_OPTIONS: "--max-old-space-size=4096" 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | - name: Set node version 29 | uses: actions/setup-node@v4 30 | with: 31 | node-version-file: ".nvmrc" 32 | 33 | - name: javascript implementation install & build 34 | working-directory: ./javascript 35 | run: | 36 | npm install 37 | npm run build 38 | 39 | - name: javascript tests 40 | uses: GabrielBB/xvfb-action@v1.6 41 | with: 42 | working-directory: ./javascript 43 | run: npm run test 44 | 45 | - name: build examples 46 | working-directory: ./examples/browser 47 | run: | 48 | npm install 49 | npm run lint 50 | npm run build 51 | 52 | - name: test examples 53 | uses: GabrielBB/xvfb-action@v1.6 54 | with: 55 | working-directory: ./examples/browser 56 | run: npm run test 57 | 58 | - run: npm run lint 59 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/util.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | exports.writeJsonFile = exports.readJsonFile = void 0; 27 | const fs = __importStar(require("fs")); 28 | function readJsonFile(path) { 29 | const content = fs.readFileSync(path, 'utf-8'); 30 | return JSON.parse(content); 31 | } 32 | exports.readJsonFile = readJsonFile; 33 | function writeJsonFile(path, data) { 34 | fs.writeFileSync(path, JSON.stringify(data, null, 2), { encoding: 'utf8', flag: 'w' }); 35 | } 36 | exports.writeJsonFile = writeJsonFile; 37 | //# sourceMappingURL=util.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/binary-state.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"binary-state.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/binary-state.ts"],"names":[],"mappings":";;;AACA,iDAAsD;AAEzC,QAAA,gBAAgB,GAAG,2BAAgB,CAAC,MAAM,CAAC;AAC3C,QAAA,eAAe,GAAa,IAAI,KAAK,CAAC,wBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxF,QAAA,cAAc,GAAa,IAAI,KAAK,CAAC,wBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAEpG,SAAgB,eAAe,CAC3B,QAAmB;IAEnB,IAAI,CAAC,QAAQ,EAAE;QACX,OAAO,uBAAe,CAAC;KAC1B;IACD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC;AAClB,CAAC;AAVD,0CAUC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CACjC,OAAe,EACf,UAAkB,wBAAgB;IAElC,MAAM,MAAM,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAClB,CAAC;AAPD,sDAOC;AAED,SAAgB,eAAe,CAAC,MAAc;IAC1C,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAFD,0CAEC;AAED,SAAgB,mBAAmB,CAAC,MAAc;IAC9C,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC;AAFD,kDAEC;AAED,SAAgB,cAAc,CAAC,CAAS;IACpC,IAAI,CAAC,KAAK,GAAG,EAAE;QACX,OAAO,GAAG,CAAC;KACd;SAAM,IAAI,CAAC,KAAK,GAAG,EAAE;QAClB,OAAO,GAAG,CAAC;KACd;SAAM;QACH,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;KACvC;AACL,CAAC;AARD,wCAQC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IAC/C,MAAM,GAAG,GAAQ,EAAE,CAAC;IACpB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,2BAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACzB,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC,EAAE,CAAC;IACR,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACf,CAAC;AARD,4CAQC"} -------------------------------------------------------------------------------- /examples/browser/src/util.ts: -------------------------------------------------------------------------------- 1 | import { MiniMongoImplementation } from './minimongo'; 2 | import { NeDbImplementation } from './nedb'; 3 | import { PouchDbImplementation } from './pouchdb'; 4 | import { 5 | DatabaseImplementation, 6 | Human, 7 | IdToDocumentMap 8 | } from './types'; 9 | 10 | 11 | /** 12 | * @link https://stackoverflow.com/a/5915122 13 | */ 14 | export function randomOfArray(items: T[]): T { 15 | return items[Math.floor(Math.random() * items.length)]; 16 | } 17 | 18 | export function idToDocMapFromList(docs: Human[]): IdToDocumentMap { 19 | const map: IdToDocumentMap = new Map(); 20 | docs.forEach(doc => map.set(doc._id, doc)); 21 | return map; 22 | } 23 | 24 | 25 | /** 26 | * @link https://stackoverflow.com/a/3364546 27 | */ 28 | export function removeOptions(selectbox) { 29 | let i; 30 | for (i = selectbox.options.length - 1; i >= 0; i--) { 31 | selectbox.remove(i); 32 | } 33 | } 34 | 35 | 36 | // @link https://stackoverflow.com/a/901144/3443137 37 | export function getParameterByName(name, url?) { 38 | if (!url) url = window.location.href; 39 | name = name.replace(/[\[\]]/g, '\\$&'); 40 | const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'); 41 | const results = regex.exec(url); 42 | if (!results) return null; 43 | if (!results[2]) return ''; 44 | return decodeURIComponent(results[2].replace(/\+/g, ' ')); 45 | } 46 | 47 | export const DEFAULT_LOADING_STATE = 'Waiting for action trigger'; 48 | 49 | export function getImplementations() { 50 | const implementations: DatabaseImplementation[] = [ 51 | new MiniMongoImplementation(), 52 | new PouchDbImplementation(), 53 | new NeDbImplementation() 54 | ]; 55 | return implementations; 56 | } 57 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/binary-state.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"binary-state.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/binary-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,MAAM,CAAC;AACxD,MAAM,CAAC,MAAM,eAAe,GAAa,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrG,MAAM,CAAC,MAAM,cAAc,GAAa,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAEpG,MAAM,UAAU,eAAe,CAC3B,QAAmB;IAEnB,IAAI,CAAC,QAAQ,EAAE;QACX,OAAO,eAAe,CAAC;KAC1B;IACD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACjC,OAAe,EACf,UAAkB,gBAAgB;IAElC,MAAM,MAAM,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAc;IAC1C,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAC9C,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAS;IACpC,IAAI,CAAC,KAAK,GAAG,EAAE;QACX,OAAO,GAAG,CAAC;KACd;SAAM,IAAI,CAAC,KAAK,GAAG,EAAE;QAClB,OAAO,GAAG,CAAC;KACd;SAAM;QACH,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;KACvC;AACL,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IAC/C,MAAM,GAAG,GAAQ,EAAE,CAAC;IACpB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACzB,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC,EAAE,CAAC;IACR,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACf,CAAC"} -------------------------------------------------------------------------------- /javascript/src/truth-table-generator/binary-state.ts: -------------------------------------------------------------------------------- 1 | import type { StateSet } from '../types/index.js'; 2 | import { orderedStateList } from '../states/index.js'; 3 | 4 | export const STATE_SET_LENGTH = orderedStateList.length; 5 | export const FIRST_STATE_SET: StateSet = new Array(STATE_SET_LENGTH).fill(0).map(() => '0').join(''); 6 | export const LAST_STATE_SET: StateSet = new Array(STATE_SET_LENGTH).fill(0).map(() => '1').join(''); 7 | 8 | export function getNextStateSet( 9 | stateSet?: StateSet 10 | ) { 11 | if (!stateSet) { 12 | return FIRST_STATE_SET; 13 | } 14 | const decimal = binaryToDecimal(stateSet); 15 | const increase = decimal + 1; 16 | const binary = decimalToPaddedBinary(increase); 17 | return binary; 18 | } 19 | 20 | /** 21 | * @link https://stackoverflow.com/a/16155417 22 | */ 23 | export function decimalToPaddedBinary( 24 | decimal: number, 25 | padding: number = STATE_SET_LENGTH 26 | ) { 27 | const binary = (decimal >>> 0).toString(2); 28 | const padded = binary.padStart(padding, '0'); 29 | return padded; 30 | } 31 | 32 | export function binaryToDecimal(binary: string): number { 33 | return parseInt(binary, 2); 34 | } 35 | 36 | export function maxBinaryWithLength(length: number): string { 37 | return new Array(length).fill(0).map(() => '1').join(''); 38 | } 39 | 40 | export function oppositeBinary(i: string): string { 41 | if (i === '1') { 42 | return '0'; 43 | } else if (i === '0') { 44 | return '1'; 45 | } else { 46 | throw new Error('non-binary given'); 47 | } 48 | } 49 | 50 | export function stateSetToObject(stateSet: StateSet): any { 51 | const ret: any = {}; 52 | let i = 0; 53 | orderedStateList.forEach(s => { 54 | ret[s] = stateSet[i]; 55 | i++; 56 | }); 57 | return ret; 58 | } 59 | -------------------------------------------------------------------------------- /javascript/src/actions/index.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ActionName, 3 | ActionFunction 4 | } from '../types/index.js'; 5 | 6 | import { 7 | doNothing, 8 | insertFirst, 9 | insertLast, 10 | removeFirstItem, 11 | removeLastItem, 12 | removeFirstInsertLast, 13 | removeLastInsertFirst, 14 | removeExisting, 15 | replaceExisting, 16 | alwaysWrong, 17 | insertAtSortPosition, 18 | removeExistingAndInsertAtSortPosition, 19 | runFullQueryAgain, 20 | unknownAction, 21 | removeFirstInsertFirst, 22 | removeLastInsertLast 23 | } from './action-functions.js'; 24 | 25 | export * from './action-functions.js'; 26 | 27 | /** 28 | * all actions ordered by performance-cost 29 | * cheapest first 30 | * TODO run tests on which is really the fastest 31 | */ 32 | export const orderedActionList: ActionName[] = [ 33 | 'doNothing', 34 | 'insertFirst', 35 | 'insertLast', 36 | 'removeFirstItem', 37 | 'removeLastItem', 38 | 'removeFirstInsertLast', 39 | 'removeLastInsertFirst', 40 | 'removeFirstInsertFirst', 41 | 'removeLastInsertLast', 42 | 'removeExisting', 43 | 'replaceExisting', 44 | 'alwaysWrong', 45 | 'insertAtSortPosition', 46 | 'removeExistingAndInsertAtSortPosition', 47 | 'runFullQueryAgain', 48 | 'unknownAction' 49 | ]; 50 | 51 | 52 | export const actionFunctions: { 53 | [k in ActionName]: ActionFunction 54 | } = { 55 | doNothing, 56 | insertFirst, 57 | insertLast, 58 | removeFirstItem, 59 | removeLastItem, 60 | removeFirstInsertLast, 61 | removeLastInsertFirst, 62 | removeFirstInsertFirst, 63 | removeLastInsertLast, 64 | removeExisting, 65 | replaceExisting, 66 | alwaysWrong, 67 | insertAtSortPosition, 68 | removeExistingAndInsertAtSortPosition, 69 | runFullQueryAgain, 70 | unknownAction 71 | }; 72 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/states/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/states/index.ts"],"names":[],"mappings":"AASA,OAAO,EACH,QAAQ,EACR,SAAS,EACT,OAAO,EACP,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,OAAO,EACP,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACf,MAAM,qBAAqB,CAAC;AAE7B,cAAc,qBAAqB,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAgB;IACzC,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,WAAW;IACX,SAAS;IACT,iBAAiB;IACjB,iBAAiB;IACjB,UAAU;IACV,SAAS;IACT,mBAAmB;IACnB,aAAa;IACb,sBAAsB;IACtB,oBAAoB;IACpB,qBAAqB;IACrB,mBAAmB;IACnB,aAAa;IACb,cAAc;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAE9B;IACA,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,eAAe;IACf,eAAe;IACf,QAAQ;IACR,OAAO;IACP,iBAAiB;IACjB,WAAW;IACX,oBAAoB;IACpB,kBAAkB;IAClB,mBAAmB;IACnB,iBAAiB;IACjB,WAAW;IACX,YAAY;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAEpC;IACA,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,SAAS;IACZ,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,eAAe;IAClB,CAAC,EAAE,eAAe;IAClB,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,OAAO;IACV,EAAE,EAAE,iBAAiB;IACrB,EAAE,EAAE,WAAW;IACf,EAAE,EAAE,oBAAoB;IACxB,EAAE,EAAE,kBAAkB;IACtB,EAAE,EAAE,mBAAmB;IACvB,EAAE,EAAE,iBAAiB;IACrB,EAAE,EAAE,WAAW;IACf,EAAE,EAAE,YAAY;CACnB,CAAC;AAEF,MAAM,UAAU,YAAY,CACxB,SAAoB,EACpB,KAAyC;IAEzC,MAAM,EAAE,GAAkC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC3E,IAAI,CAAC,EAAE,EAAE;QACL,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,SAAS,CAAC,CAAC;KACtE;IACD,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,WAAW,CACvB,KAAyC;IAEzC,IAAI,GAAG,GAAa,EAAE,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC9C,MAAM,IAAI,GAAc,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9B,GAAG,IAAI,GAAG,CAAC;KACd;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAkB;IAC1C,gBAAgB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACtC,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/states/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/states/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AASA,2DAmB6B;AAE7B,sDAAoC;AAEpC;;;;GAIG;AACU,QAAA,gBAAgB,GAAgB;IACzC,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,WAAW;IACX,SAAS;IACT,iBAAiB;IACjB,iBAAiB;IACjB,UAAU;IACV,SAAS;IACT,mBAAmB;IACnB,aAAa;IACb,sBAAsB;IACtB,oBAAoB;IACpB,qBAAqB;IACrB,mBAAmB;IACnB,aAAa;IACb,cAAc;CACjB,CAAC;AAEW,QAAA,qBAAqB,GAE9B;IACA,QAAQ,EAAR,4BAAQ;IACR,QAAQ,EAAR,4BAAQ;IACR,QAAQ,EAAR,4BAAQ;IACR,QAAQ,EAAR,4BAAQ;IACR,SAAS,EAAT,6BAAS;IACT,OAAO,EAAP,2BAAO;IACP,eAAe,EAAf,mCAAe;IACf,eAAe,EAAf,mCAAe;IACf,QAAQ,EAAR,4BAAQ;IACR,OAAO,EAAP,2BAAO;IACP,iBAAiB,EAAjB,qCAAiB;IACjB,WAAW,EAAX,+BAAW;IACX,oBAAoB,EAApB,wCAAoB;IACpB,kBAAkB,EAAlB,sCAAkB;IAClB,mBAAmB,EAAnB,uCAAmB;IACnB,iBAAiB,EAAjB,qCAAiB;IACjB,WAAW,EAAX,+BAAW;IACX,YAAY,EAAZ,gCAAY;CACf,CAAC;AAEW,QAAA,2BAA2B,GAEpC;IACA,CAAC,EAAE,4BAAQ;IACX,CAAC,EAAE,4BAAQ;IACX,CAAC,EAAE,4BAAQ;IACX,CAAC,EAAE,4BAAQ;IACX,CAAC,EAAE,6BAAS;IACZ,CAAC,EAAE,2BAAO;IACV,CAAC,EAAE,mCAAe;IAClB,CAAC,EAAE,mCAAe;IAClB,CAAC,EAAE,4BAAQ;IACX,CAAC,EAAE,2BAAO;IACV,EAAE,EAAE,qCAAiB;IACrB,EAAE,EAAE,+BAAW;IACf,EAAE,EAAE,wCAAoB;IACxB,EAAE,EAAE,sCAAkB;IACtB,EAAE,EAAE,uCAAmB;IACvB,EAAE,EAAE,qCAAiB;IACrB,EAAE,EAAE,+BAAW;IACf,EAAE,EAAE,gCAAY;CACnB,CAAC;AAEF,SAAgB,YAAY,CACxB,SAAoB,EACpB,KAAyC;IAEzC,MAAM,EAAE,GAAkC,6BAAqB,CAAC,SAAS,CAAC,CAAC;IAC3E,IAAI,CAAC,EAAE,EAAE;QACL,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,SAAS,CAAC,CAAC;KACtE;IACD,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC;AATD,oCASC;AAED,SAAgB,WAAW,CACvB,KAAyC;IAEzC,IAAI,GAAG,GAAa,EAAE,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,wBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC9C,MAAM,IAAI,GAAc,wBAAgB,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9B,GAAG,IAAI,GAAG,CAAC;KACd;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAXD,kCAWC;AAED,SAAgB,WAAW,CAAC,QAAkB;IAC1C,wBAAgB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACtC,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC;AAJD,kCAIC"} -------------------------------------------------------------------------------- /examples/browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "event-reduce-examples-browser", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "lint": "tslint --project .", 6 | "start": "webpack-dev-server --config webpack.dev.js", 7 | "test:e2e": "testcafe chrome -e test/ --hostname localhost", 8 | "test": "concurrently \"npm run serve\" \"sleep 4 && npm run test:e2e\" --kill-others --success first", 9 | "mongo": "bash mongodb.bash", 10 | "serve": "ws -p 8888 -d dist/", 11 | "build": "webpack --config webpack.js && cp ./index.html ./dist/index.html" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/pubkey/event-reduce.git" 16 | }, 17 | "author": "pubkey", 18 | "bugs": { 19 | "url": "https://github.com/pubkey/event-reduce/issues" 20 | }, 21 | "homepage": "https://github.com/pubkey/event-reduce#readme", 22 | "dependencies": { 23 | "@types/nedb": "1.8.16", 24 | "@types/pouchdb-core": "7.0.14", 25 | "async-test-util": "2.2.1", 26 | "event-reduce-js": "file:../../javascript/", 27 | "faker": "5.5.3", 28 | "json-pretty-html": "1.1.6", 29 | "minimongo": "6.16.0", 30 | "nedb": "1.8.0", 31 | "pouchdb-adapter-idb": "8.0.1", 32 | "pouchdb-adapter-indexeddb": "8.0.1", 33 | "pouchdb-adapter-memory": "8.0.1", 34 | "pouchdb-core": "8.0.1", 35 | "pouchdb-find": "8.0.1", 36 | "rxjs": "7.8.1", 37 | "stream": "0.0.2", 38 | "webpack": "5.89.0", 39 | "webpack-cli": "5.1.4" 40 | }, 41 | "devDependencies": { 42 | "@babel/polyfill": "7.12.1", 43 | "@types/faker": "5.5.9", 44 | "assert": "2.1.0", 45 | "concurrently": "8.2.2", 46 | "css-loader": "6.8.1", 47 | "less": "4.2.0", 48 | "less-loader": "11.1.3", 49 | "local-web-server": "5.3.0", 50 | "path": "0.12.7", 51 | "style-loader": "3.3.3", 52 | "testcafe": "3.4.0", 53 | "ts-loader": "9.5.1", 54 | "tslint": "6.1.3", 55 | "typescript": "5.3.2", 56 | "util": "0.12.5", 57 | "webpack-dev-server": "4.15.1" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/binary-state.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.stateSetToObject = exports.oppositeBinary = exports.maxBinaryWithLength = exports.binaryToDecimal = exports.decimalToPaddedBinary = exports.getNextStateSet = exports.LAST_STATE_SET = exports.FIRST_STATE_SET = exports.STATE_SET_LENGTH = void 0; 4 | const index_js_1 = require("../states/index.js"); 5 | exports.STATE_SET_LENGTH = index_js_1.orderedStateList.length; 6 | exports.FIRST_STATE_SET = new Array(exports.STATE_SET_LENGTH).fill(0).map(() => '0').join(''); 7 | exports.LAST_STATE_SET = new Array(exports.STATE_SET_LENGTH).fill(0).map(() => '1').join(''); 8 | function getNextStateSet(stateSet) { 9 | if (!stateSet) { 10 | return exports.FIRST_STATE_SET; 11 | } 12 | const decimal = binaryToDecimal(stateSet); 13 | const increase = decimal + 1; 14 | const binary = decimalToPaddedBinary(increase); 15 | return binary; 16 | } 17 | exports.getNextStateSet = getNextStateSet; 18 | /** 19 | * @link https://stackoverflow.com/a/16155417 20 | */ 21 | function decimalToPaddedBinary(decimal, padding = exports.STATE_SET_LENGTH) { 22 | const binary = (decimal >>> 0).toString(2); 23 | const padded = binary.padStart(padding, '0'); 24 | return padded; 25 | } 26 | exports.decimalToPaddedBinary = decimalToPaddedBinary; 27 | function binaryToDecimal(binary) { 28 | return parseInt(binary, 2); 29 | } 30 | exports.binaryToDecimal = binaryToDecimal; 31 | function maxBinaryWithLength(length) { 32 | return new Array(length).fill(0).map(() => '1').join(''); 33 | } 34 | exports.maxBinaryWithLength = maxBinaryWithLength; 35 | function oppositeBinary(i) { 36 | if (i === '1') { 37 | return '0'; 38 | } 39 | else if (i === '0') { 40 | return '1'; 41 | } 42 | else { 43 | throw new Error('non-binary given'); 44 | } 45 | } 46 | exports.oppositeBinary = oppositeBinary; 47 | function stateSetToObject(stateSet) { 48 | const ret = {}; 49 | let i = 0; 50 | index_js_1.orderedStateList.forEach(s => { 51 | ret[s] = stateSet[i]; 52 | i++; 53 | }); 54 | return ret; 55 | } 56 | exports.stateSetToObject = stateSetToObject; 57 | //# sourceMappingURL=binary-state.js.map -------------------------------------------------------------------------------- /javascript/test/unit/truth-table-generator.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | 3 | import { Human } from '../../src/truth-table-generator/types.js'; 4 | import { oneThatWasCrashing } from '../../src/truth-table-generator/procedures.js'; 5 | import { generateTruthTable } from '../../src/truth-table-generator/index.js'; 6 | import { StateResolveFunctionInput, MongoQuery } from '../../src/types/index.js'; 7 | import { calculateActionFromMap } from '../../src/index.js'; 8 | import { mingoCollectionCreator } from '../../src/truth-table-generator/database/mingo.js'; 9 | import { applyChangeEvent } from '../../src/truth-table-generator/database/index.js'; 10 | 11 | /** 12 | * sometimes we think stuff is wrong with minimongo 13 | * so we add tests to pin the correct behavior 14 | */ 15 | describe('truth-table-generator.test.ts', () => { 16 | describe('.generateTruthTable()', () => { 17 | it('should contain all itterated states', async () => { 18 | const query: MongoQuery = { 19 | selector: { gender: 'm' }, 20 | sort: ['age', '_id'] 21 | }; 22 | const procedures = [oneThatWasCrashing()]; 23 | const table = await generateTruthTable({ 24 | queries: [query], 25 | procedures, 26 | log: false 27 | }); 28 | 29 | const collection = mingoCollectionCreator(); 30 | for (const changeEvent of procedures[0]) { 31 | const resultsBefore: Human[] = await collection.query(query); 32 | const keyDocumentMap = new Map(); 33 | resultsBefore.forEach(d => keyDocumentMap.set(d._id, d)); 34 | applyChangeEvent( 35 | collection, 36 | changeEvent 37 | ); 38 | 39 | const input: StateResolveFunctionInput = { 40 | previousResults: resultsBefore, 41 | queryParams: collection.getQueryParams(query), 42 | keyDocumentMap, 43 | changeEvent 44 | }; 45 | 46 | const resultFromMap = calculateActionFromMap( 47 | table as any, 48 | input 49 | ); 50 | assert.ok(table.has(resultFromMap.stateSet)); 51 | } 52 | }); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/fuzzing.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"fuzzing.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/fuzzing.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /docs/bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * [js-sha1]{@link https://github.com/emn178/js-sha1} 3 | * 4 | * @version 0.6.0 5 | * @author Chen, Yi-Cyuan [emn178@gmail.com] 6 | * @copyright Chen, Yi-Cyuan 2014-2017 7 | * @license MIT 8 | */ 9 | 10 | /*! 11 | localForage -- Offline Storage, Improved 12 | Version 1.10.0 13 | https://localforage.github.io/localForage 14 | (c) 2013-2017 Mozilla, Apache License 2.0 15 | */ 16 | 17 | /*! 18 | * Bowser - a browser detector 19 | * https://github.com/ded/bowser 20 | * MIT License | (c) Dustin Diaz 2014 21 | */ 22 | 23 | /*! 24 | * prr 25 | * (c) 2013 Rod Vagg 26 | * https://github.com/rvagg/prr 27 | * License: MIT 28 | */ 29 | 30 | /*! 31 | * The buffer module from node.js, for the browser. 32 | * 33 | * @author Feross Aboukhadijeh 34 | * @license MIT 35 | */ 36 | 37 | /*! 38 | * The buffer module from node.js, for the browser. 39 | * 40 | * @author Feross Aboukhadijeh 41 | * @license MIT 42 | */ 43 | 44 | /*! 45 | * async 46 | * https://github.com/caolan/async 47 | * 48 | * Copyright 2010-2014 Caolan McMahon 49 | * Released under the MIT license 50 | */ 51 | 52 | /*! 53 | * jQuery JavaScript Library v3.7.1 54 | * https://jquery.com/ 55 | * 56 | * Copyright OpenJS Foundation and other contributors 57 | * Released under the MIT license 58 | * https://jquery.org/license 59 | * 60 | * Date: 2023-08-28T13:37Z 61 | */ 62 | 63 | /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ 64 | 65 | /*! safe-buffer. MIT License. Feross Aboukhadijeh */ 66 | 67 | /** 68 | * splaytree v3.1.0 69 | * Fast Splay tree for Node and browser 70 | * 71 | * @author Alexander Milevski 72 | * @license MIT 73 | * @preserve 74 | */ 75 | 76 | /** 77 | * @license 78 | * lodash 3.10.1 (Custom Build) 79 | * Build: `lodash modern -d -o ./index.js` 80 | * Copyright 2012-2015 The Dojo Foundation 81 | * Based on Underscore.js 1.8.3 82 | * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 83 | * Available under MIT license 84 | */ 85 | 86 | /** 87 | * @license IDBWrapper - A cross-browser wrapper for IndexedDB 88 | * Version 1.7.2 89 | * Copyright (c) 2011 - 2017 Jens Arps 90 | * http://jensarps.de/ 91 | * 92 | * Licensed under the MIT license 93 | */ 94 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/fuzzing.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"fuzzing.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/fuzzing.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/bdd.generated.d.ts: -------------------------------------------------------------------------------- 1 | import { SimpleBdd } from 'binary-decision-diagram'; 2 | import type { StateResolveFunctionInput } from '../types/index.js'; 3 | export declare const minimalBddString = "14a1b,c+d2e5f0g/h.i4j*k-l)m(n6oeh6pnm6qen6ril6snh6tin6ubo9vce9wmh9xns9yne9zmi9{cm9|ad9}cp9~aq9ae9\u00A1bf9\u00A2bq9\u00A3cg9\u00A4ck9\u00A5cn9\u00A6nd9\u00A7np9\u00A8nq9\u00A9nf9\u00AAng9\u00ABnm9\u00ACnk9\u00ADmr9\u00AEms9\u00AFmt9\u00B0mj9\u00B1mk9\u00B2ml9\u00B3mn9\u00B4mc8\u00B5\u00B3{8\u00B6\u00AF}8\u00B7\u00B0\u00A48\u00B8\u00B3\u00A78\u00B9mn8\u00BA\u00B3\u00AB8\u00BB\u00B3m8\u00BCm\u00B44\u00BDz\u00B24\u00BE\u00B3w4\u00BFz\u00B54\u00C0\u00AF\u00B64\u00C1\u00B0\u00B74\u00C2\u00B3\u00BA4\u00C3\u00B3\u00B84\u00C4m\u00B94\u00C5v\u00A47\u00C6yn7\u00C7\u00C0\u00C17\u00C8~7\u00C9\u00A5\u00A47\u00CA\u00C3\u00C47\u00CB\u00A8n7\u00CC\u00BA\u00B97\u00CD\u00AD\u00B07\u00CE\u00AEm7\u00CF\u00AF\u00B07\u00D0\u00B1m7\u00D1\u00B3m7\u00D2\u00BCm5\u00D3\u00C4m5\u00D4\u00B9m5\u00D5\u00BD\u00B05\u00D6\u00BEm5\u00D7\u00BF\u00B05\u00D8\u00C7\u00CF5\u00D9\u00C2m5\u00DA\u00CA\u00D15\u00DB\u00B1m5\u00DC\u00BAm5\u00DD\u00CC\u00D15\u00DE\u00D5\u00CD2\u00DF|2\u00E0\u00A1u2\u00E1\u00A3\u00C52\u00E2\u00D6\u00CE2\u00E3\u00A6\u00C62\u00E4\u00A9x2\u00E5\u00AA\u00C62\u00E6\u00D7\u00D82\u00E7|\u00C82\u00E8\u00A1\u00A22\u00E9\u00A3\u00C92\u00EA\u00A4\u00A52\u00EB\u00D9\u00DA2\u00EC\u00A6\u00CB2\u00ED\u00A9n2\u00EE\u00AAn2\u00EF\u00DB\u00D02\u00F0\u00DC\u00DD2\u00F1\u00ACn2\u00F2\u00D2\u00D3/\u00F3an/\u00F4bn/\u00F5cn/\u00F6\u00DE\u00E2/\u00F7\u00DF\u00E3/\u00F8\u00E0\u00E4/\u00F9\u00E1\u00E5/\u00FA\u00E6\u00EB/\u00FB\u00E7\u00EC/\u00FC\u00E8\u00ED/\u00FD\u00E9\u00EE/\u00FE\u00CD\u00CE/\u00FF\u00CF\u00D1/\u0100\u00F2\u00D4,\u0101cn,\u0102\u00F6\u00EF,\u0103\u00A4\u00F1,\u0104\u00FA\u00F0,\u0105\u00EA\u00F1,\u0106\u00FE\u00D0,\u0107\u00FF\u00D1,\u0108ac0\u0109bc0\u010A\u00F3\u00F50\u010B\u00F4\u01010\u010C\u00DF\u00E10\u010D\u00E0\u00A40\u010E\u00E7\u00E90\u010F\u00E8\u00EA0\u0110\u00F7\u00F90\u0111\u00F8\u01030\u0112\u00FB\u00FD0\u0113\u00FC\u01050\u0114m\u00D2-\u0115m\u0100-\u0116\u00DE\u00E6-\u0117\u010C\u010E-\u0118\u010D\u010F-\u0119\u0102\u0104-\u011A\u0110\u0112-\u011B\u0111\u0113-\u011C\u00B2\u00BB-\u011D\u00CD\u00CF-\u011E\u0106\u0107-\u011F\u00B2\u00B3-\u0120\u0114\u01083\u0121\u0115\u010A3\u0122\u0116\u01173\u0123\u0119\u011A3\u0124\u0122\u011D(\u0125\u011C\u011F(\u0126\u0123\u011E(\u0127\u0120\u0121+\u0128\u0109\u010B+\u0129\u0124\u0126+\u012A\u0118\u011B+\u012B\u0127\u01281\u012C\u0129\u012A1\u012D\u012C\u012B*\u012E\u0125m*\u012D\u012E."; 4 | export declare function getSimpleBdd(): SimpleBdd; 5 | export declare const resolveInput: (input: StateResolveFunctionInput) => number; 6 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/bdd/bdd.generated.d.ts: -------------------------------------------------------------------------------- 1 | import { SimpleBdd } from 'binary-decision-diagram'; 2 | import type { StateResolveFunctionInput } from '../types/index.js'; 3 | export declare const minimalBddString = "14a1b,c+d2e5f0g/h.i4j*k-l)m(n6oeh6pnm6qen6ril6snh6tin6ubo9vce9wmh9xns9yne9zmi9{cm9|ad9}cp9~aq9ae9\u00A1bf9\u00A2bq9\u00A3cg9\u00A4ck9\u00A5cn9\u00A6nd9\u00A7np9\u00A8nq9\u00A9nf9\u00AAng9\u00ABnm9\u00ACnk9\u00ADmr9\u00AEms9\u00AFmt9\u00B0mj9\u00B1mk9\u00B2ml9\u00B3mn9\u00B4mc8\u00B5\u00B3{8\u00B6\u00AF}8\u00B7\u00B0\u00A48\u00B8\u00B3\u00A78\u00B9mn8\u00BA\u00B3\u00AB8\u00BB\u00B3m8\u00BCm\u00B44\u00BDz\u00B24\u00BE\u00B3w4\u00BFz\u00B54\u00C0\u00AF\u00B64\u00C1\u00B0\u00B74\u00C2\u00B3\u00BA4\u00C3\u00B3\u00B84\u00C4m\u00B94\u00C5v\u00A47\u00C6yn7\u00C7\u00C0\u00C17\u00C8~7\u00C9\u00A5\u00A47\u00CA\u00C3\u00C47\u00CB\u00A8n7\u00CC\u00BA\u00B97\u00CD\u00AD\u00B07\u00CE\u00AEm7\u00CF\u00AF\u00B07\u00D0\u00B1m7\u00D1\u00B3m7\u00D2\u00BCm5\u00D3\u00C4m5\u00D4\u00B9m5\u00D5\u00BD\u00B05\u00D6\u00BEm5\u00D7\u00BF\u00B05\u00D8\u00C7\u00CF5\u00D9\u00C2m5\u00DA\u00CA\u00D15\u00DB\u00B1m5\u00DC\u00BAm5\u00DD\u00CC\u00D15\u00DE\u00D5\u00CD2\u00DF|2\u00E0\u00A1u2\u00E1\u00A3\u00C52\u00E2\u00D6\u00CE2\u00E3\u00A6\u00C62\u00E4\u00A9x2\u00E5\u00AA\u00C62\u00E6\u00D7\u00D82\u00E7|\u00C82\u00E8\u00A1\u00A22\u00E9\u00A3\u00C92\u00EA\u00A4\u00A52\u00EB\u00D9\u00DA2\u00EC\u00A6\u00CB2\u00ED\u00A9n2\u00EE\u00AAn2\u00EF\u00DB\u00D02\u00F0\u00DC\u00DD2\u00F1\u00ACn2\u00F2\u00D2\u00D3/\u00F3an/\u00F4bn/\u00F5cn/\u00F6\u00DE\u00E2/\u00F7\u00DF\u00E3/\u00F8\u00E0\u00E4/\u00F9\u00E1\u00E5/\u00FA\u00E6\u00EB/\u00FB\u00E7\u00EC/\u00FC\u00E8\u00ED/\u00FD\u00E9\u00EE/\u00FE\u00CD\u00CE/\u00FF\u00CF\u00D1/\u0100\u00F2\u00D4,\u0101cn,\u0102\u00F6\u00EF,\u0103\u00A4\u00F1,\u0104\u00FA\u00F0,\u0105\u00EA\u00F1,\u0106\u00FE\u00D0,\u0107\u00FF\u00D1,\u0108ac0\u0109bc0\u010A\u00F3\u00F50\u010B\u00F4\u01010\u010C\u00DF\u00E10\u010D\u00E0\u00A40\u010E\u00E7\u00E90\u010F\u00E8\u00EA0\u0110\u00F7\u00F90\u0111\u00F8\u01030\u0112\u00FB\u00FD0\u0113\u00FC\u01050\u0114m\u00D2-\u0115m\u0100-\u0116\u00DE\u00E6-\u0117\u010C\u010E-\u0118\u010D\u010F-\u0119\u0102\u0104-\u011A\u0110\u0112-\u011B\u0111\u0113-\u011C\u00B2\u00BB-\u011D\u00CD\u00CF-\u011E\u0106\u0107-\u011F\u00B2\u00B3-\u0120\u0114\u01083\u0121\u0115\u010A3\u0122\u0116\u01173\u0123\u0119\u011A3\u0124\u0122\u011D(\u0125\u011C\u011F(\u0126\u0123\u011E(\u0127\u0120\u0121+\u0128\u0109\u010B+\u0129\u0124\u0126+\u012A\u0118\u011B+\u012B\u0127\u01281\u012C\u0129\u012A1\u012D\u012C\u012B*\u012E\u0125m*\u012D\u012E."; 4 | export declare function getSimpleBdd(): SimpleBdd; 5 | export declare const resolveInput: (input: StateResolveFunctionInput) => number; 6 | -------------------------------------------------------------------------------- /javascript/test/unit/binary-state.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { 3 | FIRST_STATE_SET, 4 | getNextStateSet, 5 | decimalToPaddedBinary, 6 | binaryToDecimal, 7 | LAST_STATE_SET 8 | } from '../../src/truth-table-generator/binary-state.js'; 9 | import { 10 | orderedStateList 11 | } from '../../src/states/index.js'; 12 | import { StateSet } from '../../src/types/index.js'; 13 | 14 | 15 | describe('binary-state.test.ts', () => { 16 | describe('FIRST_STATE_SET', () => { 17 | it('have the correct initial stateSet', () => { 18 | assert.strictEqual( 19 | orderedStateList.length, 20 | FIRST_STATE_SET.length 21 | ); 22 | const nonZero = FIRST_STATE_SET.split('').find(c => c !== '0'); 23 | assert.ok(!nonZero); 24 | }); 25 | }); 26 | describe('LAST_STATE_SET', () => { 27 | it('have the correct last stateSet', () => { 28 | assert.strictEqual( 29 | orderedStateList.length, 30 | LAST_STATE_SET.length 31 | ); 32 | const nonOne = LAST_STATE_SET.split('').find(c => c !== '1'); 33 | assert.ok(!nonOne); 34 | }); 35 | }); 36 | describe('decimalToPaddedBinary()', () => { 37 | it('should be zero', () => { 38 | assert.ok( 39 | decimalToPaddedBinary(0).endsWith('0') 40 | ); 41 | }); 42 | it('should be seven', () => { 43 | assert.ok( 44 | decimalToPaddedBinary(7).endsWith('0111') 45 | ); 46 | }); 47 | }); 48 | describe('getNextState()', () => { 49 | it('should get the initial state', () => { 50 | assert.strictEqual( 51 | FIRST_STATE_SET, 52 | getNextStateSet() 53 | ); 54 | }); 55 | it('should get one', () => { 56 | assert.strictEqual( 57 | binaryToDecimal(getNextStateSet(FIRST_STATE_SET)), 58 | 1 59 | ); 60 | }); 61 | it('all stateSets should have the correct length', () => { 62 | let lastSet = FIRST_STATE_SET; 63 | const sets: StateSet[] = new Array(10).fill(0) 64 | .map(() => { 65 | lastSet = getNextStateSet(lastSet); 66 | return lastSet; 67 | }); 68 | sets.forEach(set => { 69 | assert.strictEqual( 70 | set.length, 71 | orderedStateList.length 72 | ); 73 | assert.ok(set.startsWith('0')); 74 | }); 75 | }); 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/states/index.js: -------------------------------------------------------------------------------- 1 | import { hasLimit, isFindOne, hasSkip, wasResultsEmpty, isDelete, isInsert, isUpdate, wasLimitReached, sortParamsChanged, wasInResult, wasFirst, wasLast, wasSortedBeforeFirst, wasSortedAfterLast, isSortedBeforeFirst, isSortedAfterLast, wasMatching, doesMatchNow } from './state-resolver.js'; 2 | export * from './state-resolver.js'; 3 | /** 4 | * all states ordered by performance-cost 5 | * cheapest first 6 | * TODO run tests on which is really the fastest 7 | */ 8 | export const orderedStateList = [ 9 | 'isInsert', 10 | 'isUpdate', 11 | 'isDelete', 12 | 'hasLimit', 13 | 'isFindOne', 14 | 'hasSkip', 15 | 'wasResultsEmpty', 16 | 'wasLimitReached', 17 | 'wasFirst', 18 | 'wasLast', 19 | 'sortParamsChanged', 20 | 'wasInResult', 21 | 'wasSortedBeforeFirst', 22 | 'wasSortedAfterLast', 23 | 'isSortedBeforeFirst', 24 | 'isSortedAfterLast', 25 | 'wasMatching', 26 | 'doesMatchNow' 27 | ]; 28 | export const stateResolveFunctions = { 29 | isInsert, 30 | isUpdate, 31 | isDelete, 32 | hasLimit, 33 | isFindOne, 34 | hasSkip, 35 | wasResultsEmpty, 36 | wasLimitReached, 37 | wasFirst, 38 | wasLast, 39 | sortParamsChanged, 40 | wasInResult, 41 | wasSortedBeforeFirst, 42 | wasSortedAfterLast, 43 | isSortedBeforeFirst, 44 | isSortedAfterLast, 45 | wasMatching, 46 | doesMatchNow 47 | }; 48 | export const stateResolveFunctionByIndex = { 49 | 0: isInsert, 50 | 1: isUpdate, 51 | 2: isDelete, 52 | 3: hasLimit, 53 | 4: isFindOne, 54 | 5: hasSkip, 55 | 6: wasResultsEmpty, 56 | 7: wasLimitReached, 57 | 8: wasFirst, 58 | 9: wasLast, 59 | 10: sortParamsChanged, 60 | 11: wasInResult, 61 | 12: wasSortedBeforeFirst, 62 | 13: wasSortedAfterLast, 63 | 14: isSortedBeforeFirst, 64 | 15: isSortedAfterLast, 65 | 16: wasMatching, 66 | 17: doesMatchNow 67 | }; 68 | export function resolveState(stateName, input) { 69 | const fn = stateResolveFunctions[stateName]; 70 | if (!fn) { 71 | throw new Error('resolveState() has no function for ' + stateName); 72 | } 73 | return fn(input); 74 | } 75 | export function getStateSet(input) { 76 | let set = ''; 77 | for (let i = 0; i < orderedStateList.length; i++) { 78 | const name = orderedStateList[i]; 79 | const value = resolveState(name, input); 80 | const add = value ? '1' : '0'; 81 | set += add; 82 | } 83 | return set; 84 | } 85 | export function logStateSet(stateSet) { 86 | orderedStateList.forEach((state, index) => { 87 | console.log('state: ' + state + ' : ' + stateSet[index]); 88 | }); 89 | } 90 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/database/mingo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"mingo.js","sourceRoot":"","sources":["../../../../../src/truth-table-generator/database/mingo.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /javascript/dist/cjs/src/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | exports.runAction = exports.calculateActionFunction = exports.calculateActionName = exports.calculateActionFromMap = void 0; 18 | const index_js_1 = require("./states/index.js"); 19 | const index_js_2 = require("./actions/index.js"); 20 | const bdd_generated_js_1 = require("./bdd/bdd.generated.js"); 21 | __exportStar(require("./states/index.js"), exports); 22 | __exportStar(require("./util.js"), exports); 23 | __exportStar(require("./actions/index.js"), exports); 24 | function calculateActionFromMap(stateSetToActionMap, input) { 25 | const stateSet = (0, index_js_1.getStateSet)(input); 26 | const actionName = stateSetToActionMap.get(stateSet); 27 | if (!actionName) { 28 | return { 29 | action: 'runFullQueryAgain', 30 | stateSet 31 | }; 32 | } 33 | else { 34 | return { 35 | action: actionName, 36 | stateSet 37 | }; 38 | } 39 | } 40 | exports.calculateActionFromMap = calculateActionFromMap; 41 | function calculateActionName(input) { 42 | const resolvedActionId = (0, bdd_generated_js_1.resolveInput)(input); 43 | return index_js_2.orderedActionList[resolvedActionId]; 44 | } 45 | exports.calculateActionName = calculateActionName; 46 | function calculateActionFunction(input) { 47 | const actionName = calculateActionName(input); 48 | return index_js_2.actionFunctions[actionName]; 49 | } 50 | exports.calculateActionFunction = calculateActionFunction; 51 | /** 52 | * for performance reasons, 53 | * @mutates the input 54 | * @returns the new results 55 | */ 56 | function runAction(action, queryParams, changeEvent, previousResults, keyDocumentMap) { 57 | const fn = index_js_2.actionFunctions[action]; 58 | fn({ 59 | queryParams, 60 | changeEvent, 61 | previousResults, 62 | keyDocumentMap 63 | }); 64 | return previousResults; 65 | } 66 | exports.runAction = runAction; 67 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/actions/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | exports.actionFunctions = exports.orderedActionList = void 0; 18 | const action_functions_js_1 = require("./action-functions.js"); 19 | __exportStar(require("./action-functions.js"), exports); 20 | /** 21 | * all actions ordered by performance-cost 22 | * cheapest first 23 | * TODO run tests on which is really the fastest 24 | */ 25 | exports.orderedActionList = [ 26 | 'doNothing', 27 | 'insertFirst', 28 | 'insertLast', 29 | 'removeFirstItem', 30 | 'removeLastItem', 31 | 'removeFirstInsertLast', 32 | 'removeLastInsertFirst', 33 | 'removeFirstInsertFirst', 34 | 'removeLastInsertLast', 35 | 'removeExisting', 36 | 'replaceExisting', 37 | 'alwaysWrong', 38 | 'insertAtSortPosition', 39 | 'removeExistingAndInsertAtSortPosition', 40 | 'runFullQueryAgain', 41 | 'unknownAction' 42 | ]; 43 | exports.actionFunctions = { 44 | doNothing: action_functions_js_1.doNothing, 45 | insertFirst: action_functions_js_1.insertFirst, 46 | insertLast: action_functions_js_1.insertLast, 47 | removeFirstItem: action_functions_js_1.removeFirstItem, 48 | removeLastItem: action_functions_js_1.removeLastItem, 49 | removeFirstInsertLast: action_functions_js_1.removeFirstInsertLast, 50 | removeLastInsertFirst: action_functions_js_1.removeLastInsertFirst, 51 | removeFirstInsertFirst: action_functions_js_1.removeFirstInsertFirst, 52 | removeLastInsertLast: action_functions_js_1.removeLastInsertLast, 53 | removeExisting: action_functions_js_1.removeExisting, 54 | replaceExisting: action_functions_js_1.replaceExisting, 55 | alwaysWrong: action_functions_js_1.alwaysWrong, 56 | insertAtSortPosition: action_functions_js_1.insertAtSortPosition, 57 | removeExistingAndInsertAtSortPosition: action_functions_js_1.removeExistingAndInsertAtSortPosition, 58 | runFullQueryAgain: action_functions_js_1.runFullQueryAgain, 59 | unknownAction: action_functions_js_1.unknownAction 60 | }; 61 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /javascript/dist/cjs/src/bdd/write-bdd-template.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | exports.writeBddTemplate = exports.BDD_TEMPLATE_GOAL = exports.BDD_OPTIMIZE_STATE_LOCATION = exports.BDD_TEMPLATE_LOCATION = void 0; 30 | const fs = __importStar(require("fs")); 31 | const path_1 = __importDefault(require("path")); 32 | exports.BDD_TEMPLATE_LOCATION = path_1.default.join(__dirname, './bdd.template.ts'); 33 | exports.BDD_OPTIMIZE_STATE_LOCATION = path_1.default.join(__dirname, './bdd.optimize.state.json'); 34 | exports.BDD_TEMPLATE_GOAL = path_1.default.join(__dirname, './bdd.generated.ts'); 35 | function writeBddTemplate(minimalBddString, performanceMeasurement, quality) { 36 | let templateString = fs.readFileSync(exports.BDD_TEMPLATE_LOCATION, 'utf-8'); 37 | const replaceVariables = { 38 | minimalBddString: '\'' + minimalBddString + '\'', 39 | }; 40 | Object.entries(replaceVariables).forEach(([key, content]) => { 41 | const contentString = content; 42 | const templateVar = '\'${' + key + '}\''; 43 | templateString = templateString.replace(templateVar, contentString); 44 | }); 45 | fs.writeFileSync(exports.BDD_OPTIMIZE_STATE_LOCATION, JSON.stringify({ 46 | performanceMeasurement, 47 | minimalBddString, 48 | quality 49 | }, null, 4), { encoding: 'utf8', flag: 'w' }); 50 | fs.writeFileSync(exports.BDD_TEMPLATE_GOAL, templateString, { encoding: 'utf8', flag: 'w' }); 51 | } 52 | exports.writeBddTemplate = writeBddTemplate; 53 | //# sourceMappingURL=write-bdd-template.js.map -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/database/mingo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"mingo.js","sourceRoot":"","sources":["../../../../../src/truth-table-generator/database/mingo.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/database/mingo.js: -------------------------------------------------------------------------------- 1 | import { getSortFieldsOfQuery } from '../../util.js'; 2 | import { Query } from 'mingo'; 3 | import { compare as mingoSortComparator } from 'mingo/util'; 4 | import { getProperty } from '../../util.js'; 5 | export function mingoCollectionCreator() { 6 | const data = []; 7 | const collection = { 8 | upsert(docData) { 9 | this.remove(docData._id); 10 | data.push(docData); 11 | }, 12 | remove(docId) { 13 | for (let i = 0; i < data.length; i++) { 14 | const item = data[i]; 15 | if (item._id === docId) { 16 | data.splice(i, 1); 17 | break; 18 | } 19 | } 20 | }, 21 | getQueryParams(query) { 22 | const queryInstance = new Query(query.selector); 23 | return { 24 | primaryKey: '_id', 25 | skip: query.skip ? query.skip : undefined, 26 | limit: query.limit ? query.limit : undefined, 27 | queryMatcher: d => queryInstance.test(d), 28 | sortFields: getSortFieldsOfQuery(query), 29 | sortComparator: getMingoSortComparator(query) 30 | }; 31 | }, 32 | query(query) { 33 | const queryInstance = new Query(query.selector); 34 | const queryParams = this.getQueryParams(query); 35 | const skip = query.skip ? query.skip : 0; 36 | const limit = query.limit ? query.limit : Infinity; 37 | const skipPlusLimit = skip + limit; 38 | let rows = data 39 | .filter(d => queryInstance.test(d)) 40 | .sort(queryParams.sortComparator); 41 | rows = rows.slice(skip, skipPlusLimit); 42 | return rows; 43 | } 44 | }; 45 | return collection; 46 | } 47 | export function getMingoSortComparator(query) { 48 | if (!query.sort) { 49 | throw new Error('no sort given'); 50 | } 51 | const sortParts = []; 52 | query.sort.forEach((key) => { 53 | const direction = key.startsWith('-') ? 'desc' : 'asc'; 54 | sortParts.push({ 55 | key, 56 | direction: direction, 57 | getValueFn: (obj) => getProperty(obj, key) 58 | }); 59 | }); 60 | const fun = (a, b) => { 61 | for (let i = 0; i < sortParts.length; ++i) { 62 | const sortPart = sortParts[i]; 63 | const valueA = sortPart.getValueFn(a); 64 | const valueB = sortPart.getValueFn(b); 65 | if (valueA !== valueB) { 66 | const ret = sortPart.direction === 'asc' ? mingoSortComparator(valueA, valueB) : mingoSortComparator(valueB, valueA); 67 | return ret; 68 | } 69 | } 70 | }; 71 | return fun; 72 | } 73 | //# sourceMappingURL=mingo.js.map -------------------------------------------------------------------------------- /javascript/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ChangeEvent, 3 | ActionName, 4 | ResultKeyDocumentMap, 5 | QueryParams, 6 | StateSetToActionMap, 7 | StateSet, 8 | ActionFunction, 9 | StateResolveFunctionInput 10 | } from './types/index.js'; 11 | import { getStateSet } from './states/index.js'; 12 | import { actionFunctions, orderedActionList } from './actions/index.js'; 13 | import { resolveInput } from './bdd/bdd.generated.js'; 14 | 15 | /** 16 | * Export as type to ensure we do not 17 | * end with an import statement in the build output 18 | * which would increase the build size. 19 | */ 20 | export type { 21 | ActionFunction, 22 | ActionFunctionInput, 23 | ActionName, 24 | ChangeEvent, 25 | ChangeEventBase, 26 | ChangeEventDelete, 27 | ChangeEventInsert, 28 | ChangeEventUpdate, 29 | MongoQuery, 30 | QueryMatcher, 31 | QueryParams, 32 | ResultKeyDocumentMap, 33 | DeterministicSortComparator, 34 | StateName, 35 | StateResolveFunction, 36 | StateResolveFunctionInput, 37 | StateSet, 38 | StateSetToActionMap, 39 | WriteOperation 40 | } from './types/index.js'; 41 | 42 | export * from './states/index.js'; 43 | export * from './util.js'; 44 | export * from './actions/index.js'; 45 | 46 | export function calculateActionFromMap( 47 | stateSetToActionMap: StateSetToActionMap, 48 | input: StateResolveFunctionInput 49 | ): { 50 | action: ActionName, 51 | stateSet: StateSet 52 | } { 53 | const stateSet: StateSet = getStateSet(input); 54 | const actionName = stateSetToActionMap.get(stateSet); 55 | if (!actionName) { 56 | return { 57 | action: 'runFullQueryAgain', 58 | stateSet 59 | }; 60 | } else { 61 | return { 62 | action: actionName, 63 | stateSet 64 | }; 65 | } 66 | } 67 | 68 | export function calculateActionName( 69 | input: StateResolveFunctionInput 70 | ): ActionName { 71 | const resolvedActionId = resolveInput( 72 | input 73 | ); 74 | return orderedActionList[resolvedActionId]; 75 | } 76 | 77 | export function calculateActionFunction( 78 | input: StateResolveFunctionInput 79 | ): ActionFunction { 80 | const actionName = calculateActionName(input); 81 | return actionFunctions[actionName]; 82 | } 83 | 84 | /** 85 | * for performance reasons, 86 | * @mutates the input 87 | * @returns the new results 88 | */ 89 | export function runAction( 90 | action: ActionName, 91 | queryParams: QueryParams, 92 | changeEvent: ChangeEvent, 93 | previousResults: DocType[], 94 | keyDocumentMap?: ResultKeyDocumentMap 95 | ): DocType[] { 96 | const fn: ActionFunction = actionFunctions[action]; 97 | fn({ 98 | queryParams, 99 | changeEvent, 100 | previousResults, 101 | keyDocumentMap 102 | }); 103 | return previousResults; 104 | } 105 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ChangeEvent } from './change-event.js'; 2 | export * from './change-event.js'; 3 | export * from './mongo.js'; 4 | export type WriteOperation = 'INSERT' | 'UPDATE' | 'DELETE'; 5 | export type ResultKeyDocumentMap = Map; 6 | export type ActionName = 'doNothing' | 'insertFirst' | 'insertLast' | 'removeFirstItem' | 'removeLastItem' | 'removeFirstInsertLast' | 'removeLastInsertFirst' | 'removeFirstInsertFirst' | 'removeLastInsertLast' | 'removeExisting' | 'replaceExisting' | 'alwaysWrong' | // this should be optimised out by later steps 7 | 'insertAtSortPosition' | 'removeExistingAndInsertAtSortPosition' | 'runFullQueryAgain' | 'unknownAction'; 8 | export type StateName = 'hasLimit' | 'isFindOne' | 'hasSkip' | 'isDelete' | 'isInsert' | 'isUpdate' | 'wasResultsEmpty' | 'wasLimitReached' | 'sortParamsChanged' | 'wasInResult' | 'wasFirst' | 'wasLast' | 'wasSortedBeforeFirst' | 'wasSortedAfterLast' | 'isSortedAfterLast' | 'isSortedBeforeFirst' | 'wasMatching' | 'doesMatchNow'; 9 | export interface QueryParams { 10 | primaryKey: string; 11 | sortFields: string[]; 12 | skip?: number; 13 | limit?: number; 14 | queryMatcher: QueryMatcher; 15 | sortComparator: DeterministicSortComparator; 16 | } 17 | export type QueryMatcher = (doc: DocType) => boolean; 18 | /** 19 | * To have a deterministic sorting, we cannot return 0, 20 | * we only return 1 or -1. 21 | * This ensures that we always end with the same output array, no mather of the 22 | * pre-sorting of the input array. 23 | */ 24 | export type DeterministicSortComparator = (a: DocType, b: DocType) => 1 | -1; 25 | /** 26 | * A map contains a stateSet as key and an ActionName as value 27 | * State-sets that are not in the Map have 'runFullQueryAgain' as value 28 | * 29 | * The key is a binary-representation of the ordered state-list 30 | * like '010110110111...' 31 | * where the first '0' means that the first state (hasLimit) is false 32 | */ 33 | export type StateSet = string; 34 | export type StateSetToActionMap = Map; 35 | export interface StateResolveFunctionInput { 36 | queryParams: QueryParams; 37 | changeEvent: ChangeEvent; 38 | previousResults: DocType[]; 39 | keyDocumentMap?: ResultKeyDocumentMap; 40 | } 41 | export type StateResolveFunction = (input: StateResolveFunctionInput) => boolean; 42 | export type ActionFunctionInput = StateResolveFunctionInput; 43 | /** 44 | * for performance-reasons, 45 | * action-function mutate the input 46 | */ 47 | export type ActionFunction = (input: ActionFunctionInput) => void; 48 | /** 49 | * @link https://stackoverflow.com/a/49670389/3443137 50 | */ 51 | type DeepReadonly = T extends (infer R)[] ? DeepReadonlyArray : T extends Function ? T : T extends object ? DeepReadonlyObject : T; 52 | interface DeepReadonlyArray extends ReadonlyArray> { 53 | } 54 | export type DeepReadonlyObject = { 55 | readonly [P in keyof T]: DeepReadonly; 56 | }; 57 | -------------------------------------------------------------------------------- /javascript/dist/esm/src/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ChangeEvent } from './change-event.js'; 2 | export * from './change-event.js'; 3 | export * from './mongo.js'; 4 | export type WriteOperation = 'INSERT' | 'UPDATE' | 'DELETE'; 5 | export type ResultKeyDocumentMap = Map; 6 | export type ActionName = 'doNothing' | 'insertFirst' | 'insertLast' | 'removeFirstItem' | 'removeLastItem' | 'removeFirstInsertLast' | 'removeLastInsertFirst' | 'removeFirstInsertFirst' | 'removeLastInsertLast' | 'removeExisting' | 'replaceExisting' | 'alwaysWrong' | // this should be optimised out by later steps 7 | 'insertAtSortPosition' | 'removeExistingAndInsertAtSortPosition' | 'runFullQueryAgain' | 'unknownAction'; 8 | export type StateName = 'hasLimit' | 'isFindOne' | 'hasSkip' | 'isDelete' | 'isInsert' | 'isUpdate' | 'wasResultsEmpty' | 'wasLimitReached' | 'sortParamsChanged' | 'wasInResult' | 'wasFirst' | 'wasLast' | 'wasSortedBeforeFirst' | 'wasSortedAfterLast' | 'isSortedAfterLast' | 'isSortedBeforeFirst' | 'wasMatching' | 'doesMatchNow'; 9 | export interface QueryParams { 10 | primaryKey: string; 11 | sortFields: string[]; 12 | skip?: number; 13 | limit?: number; 14 | queryMatcher: QueryMatcher; 15 | sortComparator: DeterministicSortComparator; 16 | } 17 | export type QueryMatcher = (doc: DocType) => boolean; 18 | /** 19 | * To have a deterministic sorting, we cannot return 0, 20 | * we only return 1 or -1. 21 | * This ensures that we always end with the same output array, no mather of the 22 | * pre-sorting of the input array. 23 | */ 24 | export type DeterministicSortComparator = (a: DocType, b: DocType) => 1 | -1; 25 | /** 26 | * A map contains a stateSet as key and an ActionName as value 27 | * State-sets that are not in the Map have 'runFullQueryAgain' as value 28 | * 29 | * The key is a binary-representation of the ordered state-list 30 | * like '010110110111...' 31 | * where the first '0' means that the first state (hasLimit) is false 32 | */ 33 | export type StateSet = string; 34 | export type StateSetToActionMap = Map; 35 | export interface StateResolveFunctionInput { 36 | queryParams: QueryParams; 37 | changeEvent: ChangeEvent; 38 | previousResults: DocType[]; 39 | keyDocumentMap?: ResultKeyDocumentMap; 40 | } 41 | export type StateResolveFunction = (input: StateResolveFunctionInput) => boolean; 42 | export type ActionFunctionInput = StateResolveFunctionInput; 43 | /** 44 | * for performance-reasons, 45 | * action-function mutate the input 46 | */ 47 | export type ActionFunction = (input: ActionFunctionInput) => void; 48 | /** 49 | * @link https://stackoverflow.com/a/49670389/3443137 50 | */ 51 | type DeepReadonly = T extends (infer R)[] ? DeepReadonlyArray : T extends Function ? T : T extends object ? DeepReadonlyObject : T; 52 | interface DeepReadonlyArray extends ReadonlyArray> { 53 | } 54 | export type DeepReadonlyObject = { 55 | readonly [P in keyof T]: DeepReadonly; 56 | }; 57 | -------------------------------------------------------------------------------- /javascript/test/unit/calculate-bdd-quality.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { 3 | createBddFromTruthTable, 4 | fillTruthTable 5 | } from 'binary-decision-diagram'; 6 | 7 | import { 8 | measurePerformanceOfStateFunctions, 9 | countFunctionUsages, 10 | getQualityOfBdd 11 | } from '../../src/truth-table-generator/calculate-bdd-quality.js'; 12 | import { 13 | orderedStateList 14 | } from '../../src/states/index.js'; 15 | import { StateActionIdMap } from '../../src/truth-table-generator/types.js'; 16 | import { OUTPUT_TRUTH_TABLE_PATH } from '../../src/truth-table-generator/config.js'; 17 | import { readJsonFile } from '../../src/truth-table-generator/util.js'; 18 | import { objectToMap } from '../../src/index.js'; 19 | import { orderedActionList } from '../../src/actions/index.js'; 20 | import { 21 | DEFAULT_EXAMPLE_QUERY 22 | } from '../../src/truth-table-generator/queries.js'; 23 | import { 24 | insertFiveSorted 25 | } from '../../src/truth-table-generator/procedures.js'; 26 | 27 | describe('calculate-bdd-quality.test.ts', () => { 28 | const unknownValueActionId: number = 42; 29 | const truthTable: StateActionIdMap = objectToMap( 30 | readJsonFile(OUTPUT_TRUTH_TABLE_PATH) 31 | ); 32 | const truthTableWithActionName = new Map(); 33 | for (const [key, value] of truthTable.entries()) { 34 | const actionName = orderedActionList[value]; 35 | truthTableWithActionName.set(key, actionName); 36 | } 37 | fillTruthTable( 38 | truthTable, 39 | truthTable.keys().next().value.length, 40 | unknownValueActionId 41 | ); 42 | 43 | describe('.measurePerformanceOfStateFunctions()', () => { 44 | it('should give valid results', async () => { 45 | const res = await measurePerformanceOfStateFunctions(10); 46 | orderedStateList.forEach(k => { 47 | assert.ok(res[k]); 48 | assert.ok(res[k] > 0); 49 | }); 50 | }); 51 | }); 52 | describe('.countFunctionUsages()', () => { 53 | it('should have counted at least one', async () => { 54 | const bdd = createBddFromTruthTable(truthTable); 55 | const usages = await countFunctionUsages( 56 | bdd, 57 | [DEFAULT_EXAMPLE_QUERY], 58 | [insertFiveSorted()] 59 | ); 60 | const moreThenOne = Object.values(usages).find(n => n > 0); 61 | assert.ok(moreThenOne); 62 | }); 63 | }); 64 | describe('.getQualityOfBdd()', () => { 65 | it('should get a number', async () => { 66 | const bdd = createBddFromTruthTable(truthTable); 67 | const perfMeasurement = await measurePerformanceOfStateFunctions(100); 68 | const quality = await getQualityOfBdd( 69 | bdd, 70 | perfMeasurement, 71 | [DEFAULT_EXAMPLE_QUERY], 72 | [insertFiveSorted()] 73 | ); 74 | assert.strictEqual(typeof quality, 'number'); 75 | assert.ok(quality > 0); 76 | }); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/database/mingo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.getMingoSortComparator = exports.mingoCollectionCreator = void 0; 4 | const util_js_1 = require("../../util.js"); 5 | const mingo_1 = require("mingo"); 6 | const util_1 = require("mingo/util"); 7 | const util_js_2 = require("../../util.js"); 8 | function mingoCollectionCreator() { 9 | const data = []; 10 | const collection = { 11 | upsert(docData) { 12 | this.remove(docData._id); 13 | data.push(docData); 14 | }, 15 | remove(docId) { 16 | for (let i = 0; i < data.length; i++) { 17 | const item = data[i]; 18 | if (item._id === docId) { 19 | data.splice(i, 1); 20 | break; 21 | } 22 | } 23 | }, 24 | getQueryParams(query) { 25 | const queryInstance = new mingo_1.Query(query.selector); 26 | return { 27 | primaryKey: '_id', 28 | skip: query.skip ? query.skip : undefined, 29 | limit: query.limit ? query.limit : undefined, 30 | queryMatcher: d => queryInstance.test(d), 31 | sortFields: (0, util_js_1.getSortFieldsOfQuery)(query), 32 | sortComparator: getMingoSortComparator(query) 33 | }; 34 | }, 35 | query(query) { 36 | const queryInstance = new mingo_1.Query(query.selector); 37 | const queryParams = this.getQueryParams(query); 38 | const skip = query.skip ? query.skip : 0; 39 | const limit = query.limit ? query.limit : Infinity; 40 | const skipPlusLimit = skip + limit; 41 | let rows = data 42 | .filter(d => queryInstance.test(d)) 43 | .sort(queryParams.sortComparator); 44 | rows = rows.slice(skip, skipPlusLimit); 45 | return rows; 46 | } 47 | }; 48 | return collection; 49 | } 50 | exports.mingoCollectionCreator = mingoCollectionCreator; 51 | function getMingoSortComparator(query) { 52 | if (!query.sort) { 53 | throw new Error('no sort given'); 54 | } 55 | const sortParts = []; 56 | query.sort.forEach((key) => { 57 | const direction = key.startsWith('-') ? 'desc' : 'asc'; 58 | sortParts.push({ 59 | key, 60 | direction: direction, 61 | getValueFn: (obj) => (0, util_js_2.getProperty)(obj, key) 62 | }); 63 | }); 64 | const fun = (a, b) => { 65 | for (let i = 0; i < sortParts.length; ++i) { 66 | const sortPart = sortParts[i]; 67 | const valueA = sortPart.getValueFn(a); 68 | const valueB = sortPart.getValueFn(b); 69 | if (valueA !== valueB) { 70 | const ret = sortPart.direction === 'asc' ? (0, util_1.compare)(valueA, valueB) : (0, util_1.compare)(valueB, valueA); 71 | return ret; 72 | } 73 | } 74 | }; 75 | return fun; 76 | } 77 | exports.getMingoSortComparator = getMingoSortComparator; 78 | //# sourceMappingURL=mingo.js.map -------------------------------------------------------------------------------- /javascript/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [], 3 | "rules": { 4 | "arrow-return-shorthand": true, 5 | "callable-types": true, 6 | "class-name": true, 7 | "comment-format": [ 8 | true, 9 | "check-space" 10 | ], 11 | "curly": false, 12 | "eofline": true, 13 | "forin": false, 14 | "import-blacklist": [ 15 | true, 16 | "rxjs/Rx" 17 | ], 18 | "import-spacing": true, 19 | "indent": [ 20 | true, 21 | "spaces", 22 | 4 23 | ], 24 | "interface-over-type-literal": false, 25 | "label-position": true, 26 | "max-line-length": [ 27 | true, 28 | 160 29 | ], 30 | "member-access": false, 31 | "member-ordering": [ 32 | true, 33 | { 34 | "order": [ 35 | "static-field", 36 | "instance-field", 37 | "static-method", 38 | "instance-method" 39 | ] 40 | } 41 | ], 42 | "no-arg": true, 43 | "no-bitwise": false, 44 | "no-console": [ 45 | true, 46 | "debug", 47 | "info", 48 | "time", 49 | "timeEnd", 50 | "trace" 51 | ], 52 | "no-construct": true, 53 | "no-debugger": true, 54 | "no-duplicate-super": true, 55 | "no-empty": false, 56 | "no-empty-interface": true, 57 | "no-eval": true, 58 | "no-misused-new": true, 59 | "no-non-null-assertion": true, 60 | "no-redundant-jsdoc": true, 61 | "no-string-literal": false, 62 | "no-string-throw": true, 63 | "no-switch-case-fall-through": true, 64 | "no-trailing-whitespace": true, 65 | "no-unused-expression": true, 66 | "no-var-keyword": true, 67 | "object-literal-sort-keys": false, 68 | "one-line": [ 69 | true, 70 | "check-open-brace", 71 | "check-catch", 72 | "check-else", 73 | "check-whitespace" 74 | ], 75 | "prefer-const": true, 76 | "quotemark": [ 77 | true, 78 | "single" 79 | ], 80 | "radix": true, 81 | "semicolon": [ 82 | true, 83 | "always" 84 | ], 85 | "triple-equals": [ 86 | true, 87 | "allow-null-check" 88 | ], 89 | "typedef-whitespace": [ 90 | true, 91 | { 92 | "call-signature": "nospace", 93 | "index-signature": "nospace", 94 | "parameter": "nospace", 95 | "property-declaration": "nospace", 96 | "variable-declaration": "nospace" 97 | } 98 | ], 99 | "unified-signatures": true, 100 | "variable-name": false, 101 | "whitespace": [ 102 | true, 103 | "check-branch", 104 | "check-decl", 105 | "check-operator", 106 | "check-separator", 107 | "check-type" 108 | ] 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /javascript/dist/cjs/src/truth-table-generator/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/index.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /javascript/src/truth-table-generator/database/mingo.ts: -------------------------------------------------------------------------------- 1 | import type { Collection } from '.'; 2 | import type { DeterministicSortComparator, MongoQuery } from '../../types'; 3 | import { getSortFieldsOfQuery } from '../../util.js'; 4 | import type { Human } from '../types'; 5 | import { Query } from 'mingo'; 6 | import { 7 | compare as mingoSortComparator 8 | } from 'mingo/util'; 9 | import { 10 | getProperty 11 | } from '../../util.js'; 12 | 13 | export function mingoCollectionCreator(): Collection { 14 | const data: Human[] = []; 15 | const collection: Collection = { 16 | upsert(docData) { 17 | this.remove(docData._id); 18 | data.push(docData); 19 | }, 20 | remove(docId: string) { 21 | for (let i = 0; i < data.length; i++) { 22 | const item = data[i]; 23 | if (item._id === docId) { 24 | data.splice(i, 1); 25 | break; 26 | } 27 | } 28 | }, 29 | getQueryParams(query) { 30 | const queryInstance = new Query(query.selector); 31 | return { 32 | primaryKey: '_id', 33 | skip: query.skip ? query.skip : undefined, 34 | limit: query.limit ? query.limit : undefined, 35 | queryMatcher: d => queryInstance.test(d), 36 | sortFields: getSortFieldsOfQuery(query), 37 | sortComparator: getMingoSortComparator(query) 38 | }; 39 | }, 40 | query(query) { 41 | const queryInstance = new Query(query.selector); 42 | const queryParams = this.getQueryParams(query); 43 | const skip = query.skip ? query.skip : 0; 44 | const limit = query.limit ? query.limit : Infinity; 45 | const skipPlusLimit = skip + limit; 46 | 47 | let rows = data 48 | .filter(d => queryInstance.test(d)) 49 | .sort(queryParams.sortComparator); 50 | 51 | rows = rows.slice(skip, skipPlusLimit); 52 | return rows; 53 | } 54 | 55 | }; 56 | return collection; 57 | } 58 | 59 | 60 | export function getMingoSortComparator( 61 | query: MongoQuery 62 | ): DeterministicSortComparator { 63 | if (!query.sort) { 64 | throw new Error('no sort given'); 65 | } 66 | const sortParts: { 67 | key: string; 68 | direction: 'asc' | 'desc'; 69 | getValueFn: (obj: any) => any 70 | }[] = []; 71 | query.sort.forEach((key: string) => { 72 | const direction = key.startsWith('-') ? 'desc' : 'asc'; 73 | sortParts.push({ 74 | key, 75 | direction: direction, 76 | getValueFn: (obj: DocType) => getProperty(obj, key) 77 | }); 78 | }); 79 | const fun: DeterministicSortComparator = (a: DocType, b: DocType) => { 80 | for (let i = 0; i < sortParts.length; ++i) { 81 | const sortPart = sortParts[i]; 82 | const valueA = sortPart.getValueFn(a); 83 | const valueB = sortPart.getValueFn(b); 84 | if (valueA !== valueB) { 85 | const ret = sortPart.direction === 'asc' ? mingoSortComparator(valueA, valueB) : mingoSortComparator(valueB, valueA); 86 | return ret as any; 87 | } 88 | } 89 | }; 90 | 91 | return fun; 92 | } 93 | -------------------------------------------------------------------------------- /examples/browser/src/logs.ts: -------------------------------------------------------------------------------- 1 | 2 | export function formatMilliseconds(value: any) { 3 | return Math.ceil(value) + ' ms'; 4 | } 5 | 6 | export const logKeyExplanation: { 7 | [k: string]: { 8 | title: string; 9 | description: string; 10 | format: (value: any) => string 11 | } 12 | } = { 13 | totalTimeInMs: { 14 | title: 'Total Time', 15 | description: 'The total amount of time that was spend saving the events ' + 16 | 'and calculating the new results', 17 | format: formatMilliseconds 18 | }, 19 | totalWriteTime: { 20 | title: 'Time spend Writing', 21 | description: 'The amount of time that was spend writing the changes to the database', 22 | format: formatMilliseconds 23 | }, 24 | queryTime: { 25 | title: 'Query Time', 26 | description: 'The amount of time spend waiting for queries to be processed ' + 27 | 'by the database', 28 | format: formatMilliseconds 29 | }, 30 | optimizedEventsCount: { 31 | title: 'Optimized Events', 32 | description: 'Percent of events that have been optimized by EventReduce ' + 33 | 'and so did not require a query over the database to get the new results', 34 | format: (i: any) => i + ' %' 35 | 36 | } 37 | }; 38 | 39 | 40 | export function appendToLog(title: string, data?: any) { 41 | const logPlaceholder = document.getElementById('logs-placeholder'); 42 | if (logPlaceholder) { 43 | logPlaceholder.remove(); 44 | } 45 | 46 | const logDiv = document.getElementById('log') as any; 47 | const newLog = document.createElement('div'); 48 | newLog.classList.add('single-log'); 49 | 50 | const titleDiv = document.createElement('h4'); 51 | titleDiv.innerHTML = title; 52 | newLog.appendChild(titleDiv); 53 | 54 | const dateDiv = document.createElement('h5'); 55 | dateDiv.innerHTML = new Date().toLocaleTimeString(); 56 | newLog.appendChild(dateDiv); 57 | 58 | 59 | if (data) { 60 | const contentDiv = document.createElement('div'); 61 | contentDiv.classList.add('content'); 62 | 63 | Object.entries(data).forEach(([key, value], index) => { 64 | const explanation = logKeyExplanation[key]; 65 | if (index > 0) { 66 | const hrDiv = document.createElement('hr'); 67 | contentDiv.appendChild(hrDiv); 68 | } 69 | 70 | const entryDiv = document.createElement('div'); 71 | entryDiv.classList.add('list-item'); 72 | 73 | const keyDiv = document.createElement('div'); 74 | keyDiv.classList.add('key'); 75 | keyDiv.innerHTML = explanation.title; 76 | entryDiv.appendChild(keyDiv); 77 | 78 | const descriptionDiv = document.createElement('span'); 79 | descriptionDiv.classList.add('info-icon'); 80 | descriptionDiv.innerHTML = ' ⓘ'; 81 | descriptionDiv.title = explanation.description; 82 | keyDiv.appendChild(descriptionDiv); 83 | 84 | const valueDiv = document.createElement('div'); 85 | valueDiv.classList.add('value'); 86 | valueDiv.innerHTML = explanation.format(value); 87 | entryDiv.appendChild(valueDiv); 88 | 89 | contentDiv.appendChild(entryDiv); 90 | }); 91 | newLog.appendChild(contentDiv); 92 | } 93 | 94 | logDiv.prepend(newLog); 95 | } 96 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EventReduce Browser Demo 7 | 8 | 9 | 10 | 64 | 65 | 91 | 92 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /examples/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EventReduce Browser Demo 7 | 8 | 9 | 10 | 64 | 65 | 91 | 92 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /examples/browser/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [], 3 | "rules": { 4 | "arrow-return-shorthand": true, 5 | "callable-types": true, 6 | "class-name": true, 7 | "comment-format": [ 8 | true, 9 | "check-space" 10 | ], 11 | "curly": false, 12 | "deprecation": { 13 | "severity": "warn" 14 | }, 15 | "eofline": true, 16 | "forin": false, 17 | "import-blacklist": [ 18 | true, 19 | "rxjs/Rx" 20 | ], 21 | "import-spacing": true, 22 | "indent": [ 23 | true, 24 | "spaces", 25 | 4 26 | ], 27 | "interface-over-type-literal": false, 28 | "label-position": true, 29 | "max-line-length": [ 30 | true, 31 | 160 32 | ], 33 | "member-access": false, 34 | "member-ordering": [ 35 | true, 36 | { 37 | "order": [ 38 | "static-field", 39 | "instance-field", 40 | "static-method", 41 | "instance-method" 42 | ] 43 | } 44 | ], 45 | "no-arg": true, 46 | "no-bitwise": false, 47 | "no-console": [ 48 | true, 49 | "debug", 50 | "info", 51 | "time", 52 | "timeEnd", 53 | "trace" 54 | ], 55 | "no-construct": true, 56 | "no-debugger": true, 57 | "no-duplicate-super": true, 58 | "no-empty": false, 59 | "no-empty-interface": true, 60 | "no-eval": true, 61 | "no-misused-new": true, 62 | "no-non-null-assertion": true, 63 | "no-redundant-jsdoc": true, 64 | "no-shadowed-variable": true, 65 | "no-string-literal": false, 66 | "no-string-throw": true, 67 | "no-switch-case-fall-through": true, 68 | "no-trailing-whitespace": true, 69 | "no-unnecessary-initializer": true, 70 | "no-unused-expression": true, 71 | "no-use-before-declare": true, 72 | "no-var-keyword": true, 73 | "object-literal-sort-keys": false, 74 | "one-line": [ 75 | true, 76 | "check-open-brace", 77 | "check-catch", 78 | "check-else", 79 | "check-whitespace" 80 | ], 81 | "prefer-const": true, 82 | "quotemark": [ 83 | true, 84 | "single" 85 | ], 86 | "radix": true, 87 | "semicolon": [ 88 | true, 89 | "always" 90 | ], 91 | "triple-equals": [ 92 | true, 93 | "allow-null-check" 94 | ], 95 | "typedef-whitespace": [ 96 | true, 97 | { 98 | "call-signature": "nospace", 99 | "index-signature": "nospace", 100 | "parameter": "nospace", 101 | "property-declaration": "nospace", 102 | "variable-declaration": "nospace" 103 | } 104 | ], 105 | "unified-signatures": true, 106 | "variable-name": false, 107 | "whitespace": [ 108 | true, 109 | "check-branch", 110 | "check-decl", 111 | "check-operator", 112 | "check-separator", 113 | "check-type" 114 | ] 115 | } 116 | } -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/truth-table-generator/index.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /javascript/dist/esm/src/truth-table-generator/fuzzing.js: -------------------------------------------------------------------------------- 1 | import { randomQuery } from './queries.js'; 2 | import { getRandomChangeEvents } from './data-generator.js'; 3 | import { getStateSet } from '../states/index.js'; 4 | import { orderedActionList } from '../actions/index.js'; 5 | import { doesActionWork } from './index.js'; 6 | import { mingoCollectionCreator } from './database/mingo.js'; 7 | import { applyChangeEvent } from './database/index.js'; 8 | /** 9 | * randomly generates queries and events 10 | * and returns on the first broken one 11 | * 12 | * returns ok:true if no problem was found 13 | */ 14 | export function fuzzing(table, queriesAmount = 30, eventsAmount = 100) { 15 | let amountOfHandled = 0; 16 | let amountOfOptimized = 0; 17 | const queries = new Array(queriesAmount) 18 | .fill(0) 19 | .map(() => randomQuery()); 20 | const procedure = getRandomChangeEvents(eventsAmount); 21 | const queryParamsByQuery = new Map(); 22 | const collection = mingoCollectionCreator(); 23 | queries.forEach(query => { 24 | queryParamsByQuery.set(query, collection.getQueryParams(query)); 25 | }); 26 | const usedChangeEvents = []; 27 | for (const changeEvent of procedure) { 28 | usedChangeEvents.push(changeEvent); 29 | // get previous results 30 | const resultsBefore = new Map(); 31 | queries.forEach(query => { 32 | const res = collection.query(query); 33 | resultsBefore.set(query, res); 34 | }); 35 | applyChangeEvent(collection, changeEvent); 36 | // get results after event 37 | const resultsAfter = new Map(); 38 | queries.forEach(query => { 39 | const res = collection.query(query); 40 | resultsAfter.set(query, res); 41 | }); 42 | // find action to generate after results 43 | for (const query of queries) { 44 | const params = queryParamsByQuery.get(query); 45 | const previousResults = resultsBefore.get(query); 46 | const after = resultsAfter.get(query); 47 | const input = { 48 | changeEvent, 49 | previousResults, 50 | queryParams: params 51 | }; 52 | const state = getStateSet(input); 53 | const actionId = table.get(state); 54 | if (typeof actionId !== 'number') { 55 | return { 56 | ok: false, 57 | query, 58 | procedure: usedChangeEvents, 59 | amountOfHandled, 60 | amountOfOptimized 61 | }; 62 | } 63 | else { 64 | const currentActionId = actionId; 65 | const action = orderedActionList[currentActionId]; 66 | amountOfHandled++; 67 | if (action !== 'runFullQueryAgain') { 68 | amountOfOptimized++; 69 | } 70 | const ok = doesActionWork(input, after, action); 71 | if (!ok) { 72 | return { 73 | ok: false, 74 | query, 75 | procedure: usedChangeEvents, 76 | amountOfHandled, 77 | amountOfOptimized 78 | }; 79 | } 80 | } 81 | } 82 | } 83 | return { 84 | ok: true, 85 | query: queries[0], 86 | procedure, 87 | amountOfHandled, 88 | amountOfOptimized 89 | }; 90 | } 91 | //# sourceMappingURL=fuzzing.js.map -------------------------------------------------------------------------------- /javascript/src/states/index.ts: -------------------------------------------------------------------------------- 1 | import { ResolverFunctions } from 'binary-decision-diagram'; 2 | 3 | import type { 4 | StateName, 5 | StateResolveFunction, 6 | StateSet, 7 | StateResolveFunctionInput 8 | } from '../types/index.js'; 9 | 10 | import { 11 | hasLimit, 12 | isFindOne, 13 | hasSkip, 14 | wasResultsEmpty, 15 | isDelete, 16 | isInsert, 17 | isUpdate, 18 | wasLimitReached, 19 | sortParamsChanged, 20 | wasInResult, 21 | wasFirst, 22 | wasLast, 23 | wasSortedBeforeFirst, 24 | wasSortedAfterLast, 25 | isSortedBeforeFirst, 26 | isSortedAfterLast, 27 | wasMatching, 28 | doesMatchNow 29 | } from './state-resolver.js'; 30 | 31 | export * from './state-resolver.js'; 32 | 33 | /** 34 | * all states ordered by performance-cost 35 | * cheapest first 36 | * TODO run tests on which is really the fastest 37 | */ 38 | export const orderedStateList: StateName[] = [ 39 | 'isInsert', 40 | 'isUpdate', 41 | 'isDelete', 42 | 'hasLimit', 43 | 'isFindOne', 44 | 'hasSkip', 45 | 'wasResultsEmpty', 46 | 'wasLimitReached', 47 | 'wasFirst', 48 | 'wasLast', 49 | 'sortParamsChanged', 50 | 'wasInResult', 51 | 'wasSortedBeforeFirst', 52 | 'wasSortedAfterLast', 53 | 'isSortedBeforeFirst', 54 | 'isSortedAfterLast', 55 | 'wasMatching', 56 | 'doesMatchNow' 57 | ]; 58 | 59 | export const stateResolveFunctions: { 60 | readonly [k in StateName]: StateResolveFunction 61 | } = { 62 | isInsert, 63 | isUpdate, 64 | isDelete, 65 | hasLimit, 66 | isFindOne, 67 | hasSkip, 68 | wasResultsEmpty, 69 | wasLimitReached, 70 | wasFirst, 71 | wasLast, 72 | sortParamsChanged, 73 | wasInResult, 74 | wasSortedBeforeFirst, 75 | wasSortedAfterLast, 76 | isSortedBeforeFirst, 77 | isSortedAfterLast, 78 | wasMatching, 79 | doesMatchNow 80 | }; 81 | 82 | export const stateResolveFunctionByIndex: ResolverFunctions< 83 | StateResolveFunctionInput 84 | > = { 85 | 0: isInsert, 86 | 1: isUpdate, 87 | 2: isDelete, 88 | 3: hasLimit, 89 | 4: isFindOne, 90 | 5: hasSkip, 91 | 6: wasResultsEmpty, 92 | 7: wasLimitReached, 93 | 8: wasFirst, 94 | 9: wasLast, 95 | 10: sortParamsChanged, 96 | 11: wasInResult, 97 | 12: wasSortedBeforeFirst, 98 | 13: wasSortedAfterLast, 99 | 14: isSortedBeforeFirst, 100 | 15: isSortedAfterLast, 101 | 16: wasMatching, 102 | 17: doesMatchNow 103 | }; 104 | 105 | export function resolveState( 106 | stateName: StateName, 107 | input: StateResolveFunctionInput 108 | ): boolean { 109 | const fn: StateResolveFunction = stateResolveFunctions[stateName]; 110 | if (!fn) { 111 | throw new Error('resolveState() has no function for ' + stateName); 112 | } 113 | return fn(input); 114 | } 115 | 116 | export function getStateSet( 117 | input: StateResolveFunctionInput 118 | ): StateSet { 119 | let set: StateSet = ''; 120 | for (let i = 0; i < orderedStateList.length; i++) { 121 | const name: StateName = orderedStateList[i]; 122 | const value = resolveState(name, input); 123 | const add = value ? '1' : '0'; 124 | set += add; 125 | } 126 | return set; 127 | } 128 | 129 | export function logStateSet(stateSet: StateSet) { 130 | orderedStateList.forEach((state, index) => { 131 | console.log('state: ' + state + ' : ' + stateSet[index]); 132 | }); 133 | } 134 | -------------------------------------------------------------------------------- /javascript/src/types/index.ts: -------------------------------------------------------------------------------- 1 | import { ChangeEvent } from './change-event.js'; 2 | export * from './change-event.js'; 3 | export * from './mongo.js'; 4 | 5 | export type WriteOperation = 'INSERT' | 'UPDATE' | 'DELETE'; 6 | 7 | export type ResultKeyDocumentMap = Map; 8 | 9 | export type ActionName = 10 | 'doNothing' | 11 | 'insertFirst' | 12 | 'insertLast' | 13 | 'removeFirstItem' | 14 | 'removeLastItem' | 15 | 'removeFirstInsertLast' | 16 | 'removeLastInsertFirst' | 17 | 'removeFirstInsertFirst' | 18 | 'removeLastInsertLast' | 19 | 'removeExisting' | 20 | 'replaceExisting' | 21 | 'alwaysWrong' | // this should be optimised out by later steps 22 | 'insertAtSortPosition' | 23 | 'removeExistingAndInsertAtSortPosition' | 24 | 'runFullQueryAgain' | 25 | 'unknownAction' // if a state was never reached, we do not know the correct action 26 | ; 27 | export type StateName = 28 | 'hasLimit' | 29 | 'isFindOne' | 30 | 'hasSkip' | 31 | 'isDelete' | 32 | 'isInsert' | 33 | 'isUpdate' | 34 | 'wasResultsEmpty' | 35 | 'wasLimitReached' | 36 | 'sortParamsChanged' | 37 | 'wasInResult' | 38 | 'wasFirst' | 39 | 'wasLast' | 40 | 'wasSortedBeforeFirst' | 41 | 'wasSortedAfterLast' | 42 | 'isSortedAfterLast' | 43 | 'isSortedBeforeFirst' | 44 | 'wasMatching' | 45 | 'doesMatchNow'; 46 | 47 | export interface QueryParams { 48 | primaryKey: string; 49 | sortFields: string[]; 50 | skip?: number; 51 | limit?: number; 52 | queryMatcher: QueryMatcher; 53 | sortComparator: DeterministicSortComparator; 54 | } 55 | 56 | export type QueryMatcher = (doc: DocType) => boolean; 57 | 58 | /** 59 | * To have a deterministic sorting, we cannot return 0, 60 | * we only return 1 or -1. 61 | * This ensures that we always end with the same output array, no mather of the 62 | * pre-sorting of the input array. 63 | */ 64 | export type DeterministicSortComparator = (a: DocType, b: DocType) => 1 | -1; 65 | 66 | /** 67 | * A map contains a stateSet as key and an ActionName as value 68 | * State-sets that are not in the Map have 'runFullQueryAgain' as value 69 | * 70 | * The key is a binary-representation of the ordered state-list 71 | * like '010110110111...' 72 | * where the first '0' means that the first state (hasLimit) is false 73 | */ 74 | export type StateSet = string; 75 | export type StateSetToActionMap = Map; 76 | 77 | export interface StateResolveFunctionInput { 78 | queryParams: QueryParams; 79 | changeEvent: ChangeEvent; 80 | previousResults: DocType[]; 81 | keyDocumentMap?: ResultKeyDocumentMap; 82 | } 83 | 84 | export type StateResolveFunction = ( 85 | input: StateResolveFunctionInput 86 | ) => boolean; 87 | 88 | export type ActionFunctionInput = StateResolveFunctionInput; 89 | 90 | /** 91 | * for performance-reasons, 92 | * action-function mutate the input 93 | */ 94 | export type ActionFunction = ( 95 | input: ActionFunctionInput 96 | ) => void; 97 | 98 | 99 | /** 100 | * @link https://stackoverflow.com/a/49670389/3443137 101 | */ 102 | type DeepReadonly = 103 | T extends (infer R)[] ? DeepReadonlyArray : 104 | T extends Function ? T : 105 | T extends object ? DeepReadonlyObject : 106 | T; 107 | interface DeepReadonlyArray extends ReadonlyArray> { } 108 | export type DeepReadonlyObject = { 109 | readonly [P in keyof T]: DeepReadonly; 110 | }; 111 | -------------------------------------------------------------------------------- /javascript/README.md: -------------------------------------------------------------------------------- 1 | # EventReduce JavaScript Implementation 2 | 3 | This is the javascript version of the [EventReduce algorithm](https://github.com/pubkey/event-reduce). 4 | 5 | 6 | ## Installation 7 | 8 | `npm run install event-reduce-js --save` 9 | 10 | ## Usage 11 | 12 | In the following we will use EventReduce together with minimongo as an example. You can apply the code to any other database. 13 | 14 | 1. First you need some `QueryParams` that can be used by EventReduce to analyze result-event combinations. 15 | 16 | ```typescript 17 | import { 18 | getSortFieldsOfQuery, 19 | ChangeEvent, 20 | calculateActionName, 21 | StateResolveFunctionInput, 22 | runAction 23 | } from 'event-reduce-js'; 24 | 25 | // some stuff must not be coded by hand but is already in the minimongo library 26 | import { 27 | compileDocumentSelector, 28 | compileSort 29 | } from 'minimongo/src/selector'; 30 | 31 | // create this helper function that can be used for all queries 32 | export function getQueryParamsByMongoQuery(query: MongoQuery): QueryParams { 33 | const sort = query.sort ? query.sort : ['_id']; 34 | return { 35 | // primary key of the documents 36 | primaryKey: '_id', 37 | // a string[] with all fields that are used in the sorting 38 | sortFields: getSortFieldsOfQuery(query), 39 | skip: query.skip ? query.skip : undefined, 40 | limit: query.limit ? query.limit : undefined, 41 | // a function that returns true if the given document matches the query's selector 42 | queryMatcher: compileDocumentSelector(query.selector), 43 | // a function that can be used as comparator in Array.sort() (returns 1 or -1) 44 | sortComparator: compileSort(sort) 45 | }; 46 | } 47 | 48 | const exampleQuery: MongoQuery = { 49 | selector: { 50 | age: { 51 | $gt: 18 52 | }, 53 | gender: 'm' 54 | }, 55 | limit: 10, 56 | sort: ['name', '_id'] 57 | }; 58 | 59 | const queryParams = getQueryParamsByMongoQuery(exampleQuery); 60 | 61 | ``` 62 | 63 | 64 | 2. Now lets say you have an `changeEvent` from whatever changestream or observable your database provides. You also have the `currentResults` of the query. 65 | 66 | ```typescript 67 | 68 | // build the input 69 | const input: StateResolveFunctionInput = { 70 | // the changeEvent 71 | changeEvent, 72 | // queryParams from above 73 | queryParams, 74 | // array with previous results documents 75 | previousResults: currentResults, 76 | // key->document map with previous results indexed by primary key 77 | // (optional) improves performance 78 | keyDocumentMap: currentDocMap 79 | }; 80 | 81 | // calculate the correct action name 82 | const action = calculateActionName(input); 83 | 84 | if (action === 'runFullQueryAgain') { 85 | /** 86 | * when EventReduce could not optimize the input, 87 | * we get the actionName 'runFullQueryAgain' 88 | * and run the query over the database again 89 | */ 90 | currentResults = await implementation.getRawResults(query); 91 | // also refresh the key-document map 92 | currentDocMap.clear(); 93 | currentResults.forEach(doc => currentDocMap.set(doc._id, doc)); 94 | } else { 95 | // event-reduce could optimize the event, run the action function 96 | runAction( 97 | action, 98 | queryParams, 99 | changeEvent, 100 | currentResults, 101 | currentDocMap 102 | ); 103 | } 104 | 105 | // show new results 106 | // notice that for performance resons, 107 | // the functions of event-reduce will mutate the input variables 108 | console.dir(currentResults); 109 | ``` 110 | --------------------------------------------------------------------------------