Compare commits

..

80 Commits

Author SHA1 Message Date
66658dc877 6.0.10 2023-11-13 16:43:07 +01:00
be78d74124 fix(core): update 2023-11-13 16:43:06 +01:00
bde0404777 6.0.9 2023-11-13 16:27:05 +01:00
dfe973f5d8 fix(core): update 2023-11-13 16:27:04 +01:00
326030456f 6.0.8 2023-11-13 14:59:04 +01:00
184dc98127 fix(core): update 2023-11-13 14:59:03 +01:00
702ce00288 6.0.7 2023-11-13 14:40:02 +01:00
ff0d745170 fix(core): update 2023-11-13 14:40:01 +01:00
8fc0438c75 6.0.6 2023-11-09 21:17:14 +01:00
355c2d132e fix(core): update 2023-11-09 21:17:13 +01:00
c083a47f07 6.0.5 2023-08-14 19:31:21 +02:00
9eb9403bea fix(core): update 2023-08-14 19:31:21 +02:00
029f2a6872 6.0.4 2023-08-14 19:27:29 +02:00
66676d89a5 fix(core): update 2023-08-14 19:27:28 +02:00
775a307056 6.0.3 2023-07-12 10:07:36 +02:00
4aa7621401 fix(core): update 2023-07-12 10:07:35 +02:00
b7ac5cb864 switch to new org scheme 2023-07-11 00:00:55 +02:00
f580281ccd switch to new org scheme 2023-07-10 02:41:33 +02:00
cc66f81c7e 6.0.2 2023-01-18 17:45:20 +01:00
6f1e32284d fix(core): update 2023-01-18 17:45:19 +01:00
47b511f1f0 6.0.1 2023-01-18 12:18:48 +01:00
24f82fe570 fix(core): update 2023-01-18 12:18:47 +01:00
60a0fab9db 6.0.0 2022-05-27 17:58:02 +02:00
61e287fbe4 BREAKING CHANGE(core): switch to esm 2022-05-27 17:58:02 +02:00
984297c9c3 5.0.6 2022-05-27 17:57:14 +02:00
55e4edc785 fix(core): update 2022-05-27 17:57:14 +02:00
0fdc891326 5.0.5 2022-05-27 17:53:02 +02:00
69ab47ed41 fix(core): update 2022-05-27 17:53:02 +02:00
b1bd8132de 5.0.4 2022-01-24 21:54:16 +01:00
4e672b13f4 fix(core): update 2022-01-24 21:54:16 +01:00
75c2f23d02 5.0.3 2022-01-24 07:45:40 +01:00
da0c459d74 fix(core): update 2022-01-24 07:45:38 +01:00
079b093e2c 5.0.2 2022-01-24 07:16:28 +01:00
55a3caec44 fix(core): update 2022-01-24 07:16:27 +01:00
28b3666aad 5.0.1 2022-01-24 05:22:51 +01:00
b17dd2ed64 fix(core): update 2022-01-24 05:22:49 +01:00
e551a68237 5.0.0 2021-09-21 16:34:12 +02:00
f402e55ff3 BREAKING CHANGE(objectmap): switch to async behaviours 2021-09-21 16:34:12 +02:00
15b8fe406a 4.0.22 2021-09-12 16:08:20 +02:00
c7557163cd fix(core): update 2021-09-12 16:08:20 +02:00
f84822dd5d 4.0.21 2021-09-12 15:39:47 +02:00
21d6e19a22 fix(core): update 2021-09-12 15:39:47 +02:00
8947738dc1 4.0.20 2020-11-24 19:11:43 +00:00
14bc5dcd25 fix(core): update 2020-11-24 19:11:42 +00:00
c2f366de7f 4.0.19 2020-11-24 18:53:28 +00:00
ae47276569 fix(core): update 2020-11-24 18:53:28 +00:00
42b59c109d 4.0.18 2020-11-24 18:47:46 +00:00
8f18faaf1c fix(core): update 2020-11-24 18:47:45 +00:00
ccd5b80d67 4.0.17 2020-07-14 10:55:49 +00:00
298904e17e fix(core): update 2020-07-14 10:55:48 +00:00
fa91e67aef 4.0.16 2020-07-14 08:58:30 +00:00
5e99066bee fix(core): update 2020-07-14 08:58:30 +00:00
a838f7eb80 4.0.15 2020-07-14 01:11:49 +00:00
979e93be27 fix(core): update 2020-07-14 01:11:48 +00:00
60587f052c 4.0.14 2020-07-12 00:44:51 +00:00
da5bd43a42 fix(core): update 2020-07-12 00:44:50 +00:00
24559d1582 4.0.13 2020-05-27 23:50:08 +00:00
d92657b130 fix(core): update 2020-05-27 23:50:07 +00:00
f8f34bf8a3 4.0.12 2020-05-27 20:22:46 +00:00
861d2c04b3 fix(core): update 2020-05-27 20:22:45 +00:00
5845d74160 4.0.11 2020-05-27 20:07:28 +00:00
9dd952e6b7 fix(core): update 2020-05-27 20:07:28 +00:00
742a711359 4.0.10 2020-05-27 18:54:07 +00:00
8878a0ef8b fix(core): update 2020-05-27 18:54:07 +00:00
6a52e81cdd 4.0.9 2020-05-27 18:41:22 +00:00
757e709f3f fix(core): update 2020-05-27 18:41:22 +00:00
e0d9c3a3e0 4.0.8 2020-05-27 18:22:40 +00:00
150953adaf fix(core): update 2020-05-27 18:22:40 +00:00
e0eba5d206 4.0.7 2020-05-27 18:15:14 +00:00
d9eb836f98 fix(core): update 2020-05-27 18:15:14 +00:00
6d29798660 4.0.6 2020-05-26 00:06:34 +00:00
f80a84086c fix(core): update 2020-05-26 00:06:34 +00:00
929a6eff07 4.0.5 2020-05-25 22:18:42 +00:00
87243881bb fix(core): update 2020-05-25 22:18:41 +00:00
5d51c14bd6 4.0.4 2020-05-25 22:04:22 +00:00
453c6d6ae8 fix(core): update 2020-05-25 22:04:21 +00:00
2e9fe308df 4.0.3 2020-05-25 18:10:10 +00:00
96a71638a0 fix(core): update 2020-05-25 18:10:10 +00:00
1c7582d328 4.0.2 2020-05-25 15:38:58 +00:00
ccff9b39be fix(core): update 2020-05-25 15:38:57 +00:00
37 changed files with 6592 additions and 2221 deletions

View File

@ -0,0 +1,66 @@
name: Default (not tags)
on:
push:
tags-ignore:
- '**'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Install pnpm and npmci
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
- name: Run npm prepare
run: npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build

View File

@ -0,0 +1,124 @@
name: Default (tags)
on:
push:
tags:
- '*'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build
release:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Release
run: |
npmci node install stable
npmci npm publish
metadata:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
continue-on-error: true
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Code quality
run: |
npmci command npm install -g typescript
npmci npm install
- name: Trigger
run: npmci trigger
- name: Build docs and upload artifacts
run: |
npmci node install stable
npmci npm install
pnpm install -g @git.zone/tsdoc
npmci command tsdoc
continue-on-error: true

View File

@ -1,127 +0,0 @@
# gitzone ci_default
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: '$CI_BUILD_STAGE'
stages:
- security
- test
- release
- metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- lossless
- docker
- notpriv
audit:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high
tags:
- lossless
- docker
- notpriv
# ====================
# test stage
# ====================
testStable:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- lossless
- docker
- priv
testBuild:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- lossless
- docker
- notpriv
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
only:
- tags
tags:
- lossless
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
allow_failure: true
script:
- npmci command npm install -g tslint typescript
- npmci npm prepare
- npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags:
- lossless
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- lossless
- docker
- notpriv
pages:
stage: metadata
script:
- npmci node install lts
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install
- npmci command tsdoc
tags:
- lossless
- docker
- notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true

24
.vscode/launch.json vendored
View File

@ -2,28 +2,10 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "current file", "command": "npm test",
"type": "node", "name": "Run npm test",
"request": "launch", "request": "launch",
"args": [ "type": "node-terminal"
"${relativeFile}"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "test.ts",
"type": "node",
"request": "launch",
"args": [
"test/test.ts"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
} }
] ]
} }

View File

@ -15,7 +15,7 @@
"properties": { "properties": {
"projectType": { "projectType": {
"type": "string", "type": "string",
"enum": ["website", "element", "service", "npm"] "enum": ["website", "element", "service", "npm", "wcc"]
} }
} }
} }

View File

@ -7,10 +7,10 @@
"projectType": "npm", "projectType": "npm",
"module": { "module": {
"githost": "gitlab.com", "githost": "gitlab.com",
"gitscope": "pushrocks", "gitscope": "push.rocks",
"gitrepo": "lik", "gitrepo": "lik",
"shortDescription": "light little helpers for node", "description": "light little helpers for node",
"npmPackagename": "@pushrocks/lik", "npmPackagename": "@push.rocks/lik",
"license": "MIT" "license": "MIT"
} }
} }

1850
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,15 @@
{ {
"name": "@pushrocks/lik", "name": "@push.rocks/lik",
"version": "4.0.1", "version": "6.0.10",
"private": false, "private": false,
"description": "light little helpers for node", "description": "light little helpers for node",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts", "typings": "dist_ts/index.d.ts",
"type": "module",
"scripts": { "scripts": {
"test": "(tstest test/)", "test": "(tstest test/)",
"build": "(tsbuild)" "build": "(tsbuild --web --allowimplicitany && tsbundle npm)",
"buildDocs": "tsdoc"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -20,22 +22,21 @@
}, },
"homepage": "https://gitlab.com/pushrocks/lik#README", "homepage": "https://gitlab.com/pushrocks/lik#README",
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.24", "@git.zone/tsbuild": "^2.1.66",
"@gitzone/tsrun": "^1.2.8", "@git.zone/tsbundle": "^2.0.8",
"@gitzone/tstest": "^1.0.28", "@git.zone/tsrun": "^1.2.44",
"@pushrocks/tapbundle": "^3.2.1", "@git.zone/tstest": "^1.0.77",
"@types/node": "^14.0.5", "@pushrocks/tapbundle": "^5.0.8",
"tslint": "^6.1.2", "@types/node": "^20.9.0"
"tslint-config-prettier": "^1.18.0"
}, },
"dependencies": { "dependencies": {
"@pushrocks/smartdelay": "^2.0.6", "@push.rocks/smartdelay": "^3.0.5",
"@pushrocks/smartpromise": "^3.0.6", "@push.rocks/smartmatch": "^2.0.0",
"@pushrocks/smartrx": "^2.0.5", "@push.rocks/smartpromise": "^4.0.3",
"@pushrocks/smarttime": "^3.0.12", "@push.rocks/smartrx": "^3.0.7",
"@pushrocks/smartunique": "^3.0.3", "@push.rocks/smarttime": "^4.0.6",
"@types/minimatch": "^3.0.3", "@types/minimatch": "^5.1.2",
"minimatch": "^3.0.4", "@types/symbol-tree": "^3.2.5",
"symbol-tree": "^3.2.4" "symbol-tree": "^3.2.4"
}, },
"files": [ "files": [
@ -49,5 +50,8 @@
"cli.js", "cli.js",
"npmextra.json", "npmextra.json",
"readme.md" "readme.md"
],
"browserslist": [
"last 1 chrome versions"
] ]
} }

5879
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,26 @@
# @pushrocks/lik # @push.rocks/lik
light little helpers for node light little helpers for node
## Availabililty and Links ## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/lik) * [npmjs.org (npm package)](https://www.npmjs.com/package/@push.rocks/lik)
* [gitlab.com (source)](https://gitlab.com/pushrocks/lik) * [gitlab.com (source)](https://gitlab.com/push.rocks/lik)
* [github.com (source mirror)](https://github.com/pushrocks/lik) * [github.com (source mirror)](https://github.com/push.rocks/lik)
* [docs (typedoc)](https://pushrocks.gitlab.io/lik/) * [docs (typedoc)](https://push.rocks.gitlab.io/lik/)
## Status for master ## Status for master
[![pipeline status](https://gitlab.com/pushrocks/lik/badges/master/pipeline.svg)](https://gitlab.com/pushrocks/lik/commits/master)
[![coverage report](https://gitlab.com/pushrocks/lik/badges/master/coverage.svg)](https://gitlab.com/pushrocks/lik/commits/master) Status Category | Status Badge
[![npm downloads per month](https://img.shields.io/npm/dm/@pushrocks/lik.svg)](https://www.npmjs.com/package/@pushrocks/lik) -- | --
[![Known Vulnerabilities](https://snyk.io/test/npm/@pushrocks/lik/badge.svg)](https://snyk.io/test/npm/@pushrocks/lik) GitLab Pipelines | [![pipeline status](https://gitlab.com/push.rocks/lik/badges/master/pipeline.svg)](https://lossless.cloud)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/) GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/push.rocks/lik/badges/master/coverage.svg)](https://lossless.cloud)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/) npm | [![npm downloads per month](https://badgen.net/npm/dy/@push.rocks/lik)](https://lossless.cloud)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/) Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/push.rocks/lik)](https://lossless.cloud)
TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud)
node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud)
PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@push.rocks/lik)](https://lossless.cloud)
PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@push.rocks/lik)](https://lossless.cloud)
BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@push.rocks/lik)](https://lossless.cloud)
## Usage ## Usage
@ -41,7 +47,6 @@ We are always happy for code contributions. If you are not the code contributing
For further information read the linked docs at the top of this readme. For further information read the linked docs at the top of this readme.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) ## Legal
> MIT licensed | **©** [Task Venture Capital GmbH](https://task.vc)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy) | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)

View File

@ -0,0 +1,29 @@
import { tap, expect } from '@pushrocks/tapbundle';
import * as lik from '../ts/index.js';
let testAsyncExecutionStack: lik.AsyncExecutionStack;
tap.test('should create a valid instance of AsyncExectionStack', async () => {
testAsyncExecutionStack = new lik.AsyncExecutionStack();
expect(testAsyncExecutionStack).toBeInstanceOf(lik.AsyncExecutionStack);
});
tap.test('should run in parallel', async (toolsArg) => {
await testAsyncExecutionStack.getExclusiveExecutionSlot(async () => {
await toolsArg.delayFor(2000);
console.log('should run first');
}, 2500);
testAsyncExecutionStack.getNonExclusiveExecutionSlot(async () => {
await toolsArg.delayFor(2000);
console.log('should run third');
}, 2500);
testAsyncExecutionStack.getNonExclusiveExecutionSlot(async () => {
await toolsArg.delayFor(1000);
console.log('should run second');
}, 2500);
await testAsyncExecutionStack.getExclusiveExecutionSlot(async () => {
console.log('should run fourth');
}, 0);
});
await tap.start();

30
test/test.fastmap.both.ts Normal file
View File

@ -0,0 +1,30 @@
import { tap, expect } from '@pushrocks/tapbundle';
import * as lik from '../ts/index.js';
tap.test('should create a valid fastmap', async () => {
const fastmap = new lik.FastMap();
expect(fastmap).toBeInstanceOf(lik.FastMap);
});
tap.test('should find an entry', async () => {
const fastmap = new lik.FastMap<{
value1: string;
value2: string;
}>();
fastmap.addToMap('heythere', {
value1: 'heyho',
value2: 'heyho2',
});
fastmap.addToMap('heythere2', {
value1: 'heyho3',
value2: 'heyho4',
});
const result = await fastmap.find(async (itemArg) => {
return itemArg.value2 === 'heyho4';
});
expect(result.value1).toEqual('heyho3');
});
await tap.start();

View File

@ -1,10 +1,10 @@
import { tap, expect } from '@pushrocks/tapbundle'; import { tap, expect } from '@pushrocks/tapbundle';
import * as lik from '../ts/index'; import * as lik from '../ts/index.js';
let testInterestmap: lik.InterestMap<number, number>; let testInterestmap: lik.InterestMap<number, number>;
tap.test('should create an interestmap', async () => { tap.test('should create an interestmap', async () => {
testInterestmap = new lik.InterestMap(numberArg => { testInterestmap = new lik.InterestMap((numberArg) => {
return numberArg.toString(); return numberArg.toString();
}); });
}); });
@ -22,4 +22,4 @@ tap.test('should be able to inform about a lost interest', async () => {
testInterestmap.informLostInterest(3); testInterestmap.informLostInterest(3);
}); });
tap.start(); await tap.start();

View File

@ -1,17 +1,17 @@
import { tap, expect } from '@pushrocks/tapbundle'; import { tap, expect } from '@pushrocks/tapbundle';
import { LimitedArray } from '../ts/index'; import { LimitedArray } from '../ts/index.js';
let testLimitedArray: LimitedArray<string>; let testLimitedArray: LimitedArray<string>;
tap.test('should create a LimitedArray', async () => { tap.test('should create a LimitedArray', async () => {
testLimitedArray = new LimitedArray(6); testLimitedArray = new LimitedArray(6);
expect(testLimitedArray).to.be.instanceof(LimitedArray); expect(testLimitedArray).toBeInstanceOf(LimitedArray);
}); });
tap.test('should never be longer than the set length', async () => { tap.test('should never be longer than the set length', async () => {
testLimitedArray.addMany(['hi', 'this', 'is', 'quite', 'a', 'long', 'string', ':)']); testLimitedArray.addMany(['hi', 'this', 'is', 'quite', 'a', 'long', 'string', ':)']);
expect(testLimitedArray.array.length).to.be.lessThan(7); expect(testLimitedArray.array.length < 7).toBeTrue();
}); });
tap.start(); await tap.start();

View File

@ -0,0 +1,24 @@
// import test framework
import { expect, tap } from '@pushrocks/tapbundle';
// import the module
import * as lik from '../ts/index.js';
let object1 = {};
let object2 = {};
let myLoopTracker: lik.LoopTracker<any>;
// tests
tap.test('should create a valid looptracker instance', async () => {
myLoopTracker = new lik.LoopTracker();
expect(myLoopTracker).toBeInstanceOf(lik.LoopTracker);
});
tap.test('should add objects once and return true', async () => {
expect(myLoopTracker.checkAndTrack(object1)).toBeTrue();
expect(myLoopTracker.checkAndTrack(object1)).toBeFalse();
expect(myLoopTracker.checkAndTrack(object2)).toBeTrue();
expect(myLoopTracker.checkAndTrack(object2)).toBeFalse();
});
await tap.start();

View File

@ -1,26 +0,0 @@
// import test framework
import { expect, tap } from '@pushrocks/tapbundle';
import * as events from 'events';
import * as smartpromise from '@pushrocks/smartpromise';
// import the module
import * as lik from '../ts/index';
let object1 = {};
let object2 = {};
let myLoopTracker: lik.LoopTracker<any>;
// tests
tap.test('should create a valid looptracker instance', async () => {
myLoopTracker = new lik.LoopTracker();
expect(myLoopTracker).to.be.instanceof(lik.LoopTracker);
});
tap.test('should add objects once and return true', async () => {
expect(myLoopTracker.checkAndTrack(object1)).to.be.true;
expect(myLoopTracker.checkAndTrack(object1)).to.be.false;
expect(myLoopTracker.checkAndTrack(object2)).to.be.true;
expect(myLoopTracker.checkAndTrack(object2)).to.be.false;
});
tap.start();

View File

@ -1,10 +1,8 @@
// import test framework // import test framework
import { expect, tap } from '@pushrocks/tapbundle'; import { expect, tap } from '@pushrocks/tapbundle';
import * as events from 'events';
import * as smartpromise from '@pushrocks/smartpromise';
// import the module // import the module
import * as lik from '../ts/index'; import * as lik from '../ts/index.js';
// Objectmap // Objectmap
interface ITestObject { interface ITestObject {
@ -14,65 +12,65 @@ interface ITestObject {
let testObjectmap: lik.ObjectMap<ITestObject>; let testObjectmap: lik.ObjectMap<ITestObject>;
let testObject1: ITestObject = { let testObject1: ITestObject = {
propOne: 'hello', propOne: 'hello',
propTwo: 'hello2' propTwo: 'hello2',
}; };
let testObject2: ITestObject = { let testObject2: ITestObject = {
propOne: 'hello', propOne: 'hello',
propTwo: 'hello2' propTwo: 'hello2',
}; };
tap.test('new lik.Objectmap() -> should correctly instantiate an Objectmap', async () => { tap.test('new lik.Objectmap() -> should correctly instantiate an Objectmap', async () => {
testObjectmap = new lik.ObjectMap<ITestObject>(); testObjectmap = new lik.ObjectMap<ITestObject>();
expect(testObjectmap).be.instanceof(lik.ObjectMap); expect(testObjectmap).toBeInstanceOf(lik.ObjectMap);
}); });
tap.test('lik.Objectmap.add() -> should correctly add an object to Objectmap', async () => { tap.test('lik.Objectmap.add() -> should correctly add an object to Objectmap', async () => {
testObjectmap.add(testObject1); testObjectmap.add(testObject1);
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testObjectmap.checkForObject(testObject1)).be.true; expect(testObjectmap.checkForObject(testObject1)).toBeTrue();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testObjectmap.checkForObject(testObject2)).be.false; expect(testObjectmap.checkForObject(testObject2)).toBeFalse();
}); });
tap.test('lik.Objectmap.remove() -> should correctly remove an object to Objectmap', async () => { tap.test('lik.Objectmap.remove() -> should correctly remove an object to Objectmap', async () => {
testObjectmap.add(testObject2); testObjectmap.add(testObject2);
testObjectmap.remove(testObject1); testObjectmap.remove(testObject1);
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testObjectmap.checkForObject(testObject1)).be.false; expect(testObjectmap.checkForObject(testObject1)).toBeFalse();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testObjectmap.checkForObject(testObject2)).be.true; expect(testObjectmap.checkForObject(testObject2)).toBeTrue();
}); });
tap.test('Objectmap.forEach -> should correctly run a function forEach map object', async () => { tap.test('Objectmap.forEach -> should correctly run a function forEach map object', async () => {
testObjectmap.forEach(itemArg => { testObjectmap.forEach((itemArg) => {
expect(itemArg).to.have.property('propOne'); expect(itemArg).toHaveProperty('propOne');
}); });
}); });
tap.test('lik.Objectmap.find() -> should correctly find an object', async () => { tap.test('lik.Objectmap.find() -> should correctly find an object', async () => {
let myObject = { propOne: 'helloThere', propTwo: 'helloAnyway' }; let myObject = { propOne: 'helloThere', propTwo: 'helloAnyway' };
testObjectmap.add(myObject); testObjectmap.add(myObject);
let referenceObject = testObjectmap.find(itemArg => { let referenceObject = await testObjectmap.find(async (itemArg) => {
return itemArg.propOne === 'helloThere'; return itemArg.propOne === 'helloThere';
}); });
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(myObject === referenceObject).be.true; expect(myObject === referenceObject).toBeTrue();
}); });
tap.test('lik.Objectmap.getArray() -> should return a cloned array', async () => { tap.test('lik.Objectmap.getArray() -> should return a cloned array', async () => {
let myObject = { propOne: 'test1', propTwo: 'wow, how awesome' }; let myObject = { propOne: 'test1', propTwo: 'wow, how awesome' };
testObjectmap.add(myObject); testObjectmap.add(myObject);
let clonedArray = testObjectmap.getArray(); let clonedArray = testObjectmap.getArray();
expect(clonedArray[clonedArray.length - 1]).to.eql(myObject); expect(clonedArray[clonedArray.length - 1]).toEqual(myObject);
}); });
tap.test('should get one object and then remove it', async () => { tap.test('should get one object and then remove it', async () => {
let originalLength = testObjectmap.getArray().length; let originalLength = testObjectmap.getArray().length;
let oneObject = testObjectmap.getOneAndRemove(); let oneObject = testObjectmap.getOneAndRemove();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(oneObject).not.be.null; expect(oneObject).not.toBeNull();
expect(testObjectmap.getArray().length).equal(originalLength - 1); expect(testObjectmap.getArray().length).toEqual(originalLength - 1);
expect(testObjectmap.getArray()).to.not.contain(oneObject); expect(testObjectmap.getArray()).not.toContain(oneObject);
}); });
tap.start(); await tap.start();

View File

@ -1,10 +1,8 @@
// import test framework // import test framework
import { expect, tap } from '@pushrocks/tapbundle'; import { expect, tap } from '@pushrocks/tapbundle';
import * as events from 'events';
import * as smartpromise from '@pushrocks/smartpromise';
// import the module // import the module
import * as lik from '../ts/index'; import * as lik from '../ts/index.js';
// testData // testData
let testStringmap: lik.Stringmap; let testStringmap: lik.Stringmap;
@ -18,14 +16,14 @@ let testString6 = 'testString6';
// tests // tests
tap.test('new lik.Objectmap() -> should create an instance of Stringmap', async () => { tap.test('new lik.Objectmap() -> should create an instance of Stringmap', async () => {
testStringmap = new lik.Stringmap(); testStringmap = new lik.Stringmap();
expect(testStringmap).be.instanceof(lik.Stringmap); expect(testStringmap).toBeInstanceOf(lik.Stringmap);
}); });
tap.test( tap.test(
'lik.Stringmap.checkString -> should return false for an string not in Stringmap', 'lik.Stringmap.checkString -> should return false for an string not in Stringmap',
async () => { async () => {
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkString(testString1)).be.false; expect(testStringmap.checkString(testString1)).toBeFalse();
} }
); );
@ -34,37 +32,37 @@ tap.test('lik.Stringmap.addString -> should add an string to Stringmap', async (
testStringmap.addString(testString2); testStringmap.addString(testString2);
testStringmap.addString(testString3); testStringmap.addString(testString3);
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkString(testString1)).be.true; expect(testStringmap.checkString(testString1)).toBeTrue();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkString(testString2)).be.true; expect(testStringmap.checkString(testString2)).toBeTrue();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkString(testString3)).be.true; expect(testStringmap.checkString(testString3)).toBeTrue();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkMinimatch('*String1')).be.true; expect(testStringmap.checkMinimatch('*String1')).toBeTrue();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkMinimatch('*String2')).be.true; expect(testStringmap.checkMinimatch('*String2')).toBeTrue();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkMinimatch('*String4')).be.false; expect(testStringmap.checkMinimatch('*String4')).toBeFalse();
}); });
tap.test('lik.Stringmap.addStringArray -> should add an array of strings', async () => { tap.test('lik.Stringmap.addStringArray -> should add an array of strings', async () => {
testStringmap.addStringArray([testString4, testString5, testString6]); testStringmap.addStringArray([testString4, testString5, testString6]);
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkMinimatch('*String4')).be.true; expect(testStringmap.checkMinimatch('*String4')).toBeTrue();
}); });
tap.test('lik.Stringmap.removeString -> should remove a string from Stringmap', async () => { tap.test('lik.Stringmap.removeString -> should remove a string from Stringmap', async () => {
testStringmap.removeString(testString2); testStringmap.removeString(testString2);
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(testStringmap.checkString(testString2)).be.false; expect(testStringmap.checkString(testString2)).toBeFalse();
}); });
tap.test('lik.Stringmap.getStringArray() -> should return a copy of stringArray', async () => { tap.test('lik.Stringmap.getStringArray() -> should return a copy of stringArray', async () => {
let clonedArray = testStringmap.getStringArray(); let clonedArray = testStringmap.getStringArray();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(clonedArray[0] === 'testString1').be.true; expect(clonedArray[0] === 'testString1').toBeTrue();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(clonedArray[0] === testString1).be.true; expect(clonedArray[0] === testString1).toBeTrue();
}); });
tap.test( tap.test(
@ -85,4 +83,4 @@ tap.test('lik.Stringmap.empty() -> should remove wipe and then notify', async ()
testStringmap.wipe(); testStringmap.wipe();
}); });
tap.start(); await tap.start();

View File

@ -1,19 +1,17 @@
// import test framework // import test framework
import { expect, tap } from '@pushrocks/tapbundle'; import { expect, tap } from '@pushrocks/tapbundle';
import * as events from 'events';
import * as smartpromise from '@pushrocks/smartpromise';
// import the module // import the module
import * as lik from '../ts/index'; import * as lik from '../ts/index.js';
let testTimedAggregator: lik.TimedAggregtor<string>; let testTimedAggregator: lik.TimedAggregtor<string>;
tap.test('should create a timed aggregaotor', async tools => { tap.test('should create a timed aggregaotor', async (tools) => {
testTimedAggregator = new lik.TimedAggregtor<string>({ testTimedAggregator = new lik.TimedAggregtor<string>({
aggregationIntervalInMillis: 1000, aggregationIntervalInMillis: 1000,
functionForAggregation: aggregation => { functionForAggregation: (aggregation) => {
console.log(aggregation); console.log(aggregation);
} },
}); });
testTimedAggregator.add('This'); testTimedAggregator.add('This');
testTimedAggregator.add('is a whole sentence.'); testTimedAggregator.add('is a whole sentence.');
@ -22,4 +20,4 @@ tap.test('should create a timed aggregaotor', async tools => {
await tools.delayFor(2000); await tools.delayFor(2000);
}); });
tap.start(); await tap.start();

View File

@ -1,5 +1,5 @@
import { tap, expect } from '@pushrocks/tapbundle'; import { tap, expect } from '@pushrocks/tapbundle';
import * as lik from '../ts/index'; import * as lik from '../ts/index.js';
class TestClass { class TestClass {
constructor(public hey: string) { constructor(public hey: string) {
@ -18,13 +18,13 @@ let testInstance6 = new TestClass('sixth');
tap.test('create a valid tree instance', async () => { tap.test('create a valid tree instance', async () => {
testTree = new lik.Tree(); testTree = new lik.Tree();
expect(testTree).to.be.instanceOf(lik.Tree); expect(testTree).toBeInstanceOf(lik.Tree);
}); });
tap.test('should insert an object', async () => { tap.test('should insert an object', async () => {
testTree.initialize(testInstance); testTree.initialize(testInstance);
let resultArray = testTree.treeToArray(testInstance, {}); let resultArray = testTree.treeToArray(testInstance, {});
expect(resultArray).to.contain(testInstance); expect(resultArray).toContain(testInstance);
}); });
tap.test('should add other objects in a hierachy', async () => { tap.test('should add other objects in a hierachy', async () => {
@ -37,4 +37,4 @@ tap.test("should create a JSON object that reflects a tree's hierachy", async ()
const jsonTreet = testTree.toJsonWithHierachy(testInstance); const jsonTreet = testTree.toJsonWithHierachy(testInstance);
}); });
tap.start(); await tap.start();

View File

@ -1 +0,0 @@
import './test.objectmap';

8
ts/00_commitinfo_data.ts Normal file
View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/lik',
version: '6.0.10',
description: 'light little helpers for node'
}

46
ts/backpressuredarray.ts Normal file
View File

@ -0,0 +1,46 @@
import * as plugins from './lik.plugins.js';
export class BackpressuredArray<T> {
public data: T[];
private highWaterMark: number;
public hasSpace = new plugins.smartrx.rxjs.Subject<'hasSpace'>();
constructor(highWaterMark: number = 16) {
this.data = [];
this.highWaterMark = highWaterMark;
}
push(item: T): boolean {
this.data.push(item);
const spaceAvailable = this.checkSpaceAvailable();
if (spaceAvailable) {
this.hasSpace.next('hasSpace');
}
return spaceAvailable
}
shift(): T | undefined {
const item = this.data.shift();
if (this.checkSpaceAvailable()) {
this.hasSpace.next('hasSpace');
}
return item;
}
checkSpaceAvailable(): boolean {
return this.data.length < this.highWaterMark;
}
waitForSpace(): Promise<void> {
return new Promise<void>((resolve) => {
if (this.checkSpaceAvailable()) {
resolve();
} else {
const subscription = this.hasSpace.subscribe(() => {
subscription.unsubscribe();
resolve();
});
}
});
}
}

View File

@ -1,8 +1,11 @@
export * from './lik.fastmap'; export * from './lik.asyncexecutionstack.js';
export * from './lik.interestmap'; export * from './backpressuredarray.js';
export * from './lik.limitedarray'; export * from './lik.fastmap.js';
export * from './lik.looptracker'; export * from './lik.interestmap.js';
export * from './lik.objectmap'; export * from './lik.interestmap.interest.js';
export * from './lik.stringmap'; export * from './lik.limitedarray.js';
export * from './lik.timedaggregator'; export * from './lik.looptracker.js';
export * from './lik.tree'; export * from './lik.objectmap.js';
export * from './lik.stringmap.js';
export * from './lik.timedaggregator.js';
export * from './lik.tree.js';

View File

@ -0,0 +1,110 @@
import * as plugins from './lik.plugins.js';
interface IExecutionSlot<T> {
executionDeferred: plugins.smartpromise.Deferred<T>;
funcToExecute: () => Promise<T>;
timeout?: number;
mode: 'exclusive' | 'nonexclusive';
}
export class AsyncExecutionStack {
private executionSlots: IExecutionSlot<any>[] = [];
private isProcessing = false;
public async getExclusiveExecutionSlot<T = any>(
funcArg: () => Promise<T>,
timeoutArg?: number
): Promise<T> {
const executionDeferred = plugins.smartpromise.defer<T>();
const executionSlot: IExecutionSlot<T> = {
funcToExecute: funcArg,
executionDeferred,
timeout: timeoutArg,
mode: 'exclusive',
};
this.executionSlots.push(executionSlot);
this.processExecutionSlots();
return executionDeferred.promise;
}
public async getNonExclusiveExecutionSlot<T = any>(
funcArg: () => Promise<T>,
timeoutArg?: number
): Promise<T> {
const executionDeferred = plugins.smartpromise.defer<T>();
const executionSlot: IExecutionSlot<T> = {
funcToExecute: funcArg,
executionDeferred,
timeout: timeoutArg,
mode: 'nonexclusive',
};
this.executionSlots.push(executionSlot);
this.processExecutionSlots();
return executionDeferred.promise;
}
private async processExecutionSlots() {
if (this.isProcessing) {
return;
}
this.isProcessing = true;
while (this.executionSlots.length > 0) {
const currentSlot = this.executionSlots[0];
if (currentSlot.mode === 'exclusive') {
await this.executeExclusiveSlot(currentSlot);
this.executionSlots.shift();
} else {
// Gather all non-exclusive slots at the front of the queue
const nonExclusiveSlots: IExecutionSlot<any>[] = [];
while (this.executionSlots.length > 0 && this.executionSlots[0].mode === 'nonexclusive') {
nonExclusiveSlots.push(this.executionSlots.shift()!);
}
await this.executeNonExclusiveSlots(nonExclusiveSlots);
}
}
this.isProcessing = false;
}
private async executeExclusiveSlot(slot: IExecutionSlot<any>) {
try {
if (slot.timeout) {
const result = await Promise.race([
slot.funcToExecute(),
plugins.smartdelay.delayFor(slot.timeout).then(() => {
throw new Error('Timeout reached');
}),
]);
slot.executionDeferred.resolve(result);
} else {
const result = await slot.funcToExecute();
slot.executionDeferred.resolve(result);
}
} catch (error) {
slot.executionDeferred.reject(error);
}
}
private async executeNonExclusiveSlots(slots: IExecutionSlot<any>[]) {
const promises = slots.map(async (slot) => {
try {
if (slot.timeout) {
const result = await Promise.race([
slot.funcToExecute(),
plugins.smartdelay.delayFor(slot.timeout).then(() => {
throw new Error('Timeout reached');
}),
]);
slot.executionDeferred.resolve(result);
} else {
const result = await slot.funcToExecute();
slot.executionDeferred.resolve(result);
}
} catch (error) {
slot.executionDeferred.reject(error);
}
});
await Promise.all(promises);
}
}

View File

@ -1,4 +1,9 @@
import * as plugins from './lik.plugins'; /* ============
The FastMap has the goal of creating the fastes to use map possible in JS
============ */
import * as plugins from './lik.plugins.js';
/** /**
* fast map allows for very quick lookups of objects with a unique key * fast map allows for very quick lookups of objects with a unique key
@ -29,7 +34,7 @@ export class FastMap<T> {
return this.mapObject[keyArg]; return this.mapObject[keyArg];
} }
public removeFromMap(keyArg): T { public removeFromMap(keyArg: string): T {
const removedItem = this.getByKey(keyArg); const removedItem = this.getByKey(keyArg);
delete this.mapObject[keyArg]; delete this.mapObject[keyArg];
return removedItem; return removedItem;
@ -50,7 +55,7 @@ export class FastMap<T> {
} }
/** /**
* returns a new Objectmap that includes * returns a new Fastmap that includes all values from this and all from the fastmap in the argument
*/ */
public concat(fastMapArg: FastMap<T>) { public concat(fastMapArg: FastMap<T>) {
const concatedFastmap = new FastMap<T>(); const concatedFastmap = new FastMap<T>();
@ -60,7 +65,7 @@ export class FastMap<T> {
for (const key of fastMapArg.getKeys()) { for (const key of fastMapArg.getKeys()) {
concatedFastmap.addToMap(key, fastMapArg.getByKey(key), { concatedFastmap.addToMap(key, fastMapArg.getByKey(key), {
force: true force: true,
}); });
} }
@ -68,15 +73,25 @@ export class FastMap<T> {
} }
/** /**
* tries to merge another Objectmap * tries to merge another Fastmap
* Note: uniqueKeyCollisions will cause overwrite * Note: uniqueKeyCollisions will cause overwrite
* @param objectMapArg * @param fastMapArg
*/ */
public addAllFromOther(fastMapArg: FastMap<T>) { public addAllFromOther(fastMapArg: FastMap<T>) {
for (const key of fastMapArg.getKeys()) { for (const key of fastMapArg.getKeys()) {
this.addToMap(key, fastMapArg.getByKey(key), { this.addToMap(key, fastMapArg.getByKey(key), {
force: true force: true,
}); });
} }
} }
public async find(findFunctionArg: (mapItemArg: T) => Promise<boolean>) {
for (const key of this.getKeys()) {
const item = this.getByKey(key);
const findFunctionResult = await findFunctionArg(item);
if (findFunctionResult) {
return item;
}
}
}
} }

View File

@ -1,8 +1,15 @@
import * as plugins from './lik.plugins'; import * as plugins from './lik.plugins.js';
import { InterestMap, IInterestComparisonFunc } from './lik.interestmap'; import { InterestMap, type IInterestComparisonFunc } from './lik.interestmap.js';
export interface IInterestOptions<DTInterestFullfillment> {
markLostAfterDefault: number;
defaultFullfillment?: DTInterestFullfillment;
}
export class Interest<DTInterestId, DTInterestFullfillment> { export class Interest<DTInterestId, DTInterestFullfillment> {
public options: IInterestOptions<DTInterestFullfillment>;
private interestMapRef: InterestMap<DTInterestId, DTInterestFullfillment>; private interestMapRef: InterestMap<DTInterestId, DTInterestFullfillment>;
public originalInterest: DTInterestId; public originalInterest: DTInterestId;
public comparisonFunc: IInterestComparisonFunc<DTInterestId>; public comparisonFunc: IInterestComparisonFunc<DTInterestId>;
@ -21,9 +28,8 @@ export class Interest<DTInterestId, DTInterestFullfillment> {
return this.comparisonFunc(this.originalInterest); return this.comparisonFunc(this.originalInterest);
} }
private interestDeferred: plugins.smartpromise.Deferred< private interestDeferred: plugins.smartpromise.Deferred<DTInterestFullfillment> =
DTInterestFullfillment new plugins.smartpromise.Deferred();
> = new plugins.smartpromise.Deferred();
public interestFullfilled = this.interestDeferred.promise; public interestFullfilled = this.interestDeferred.promise;
/** /**
@ -41,14 +47,20 @@ export class Interest<DTInterestId, DTInterestFullfillment> {
constructor( constructor(
interestMapArg: InterestMap<DTInterestId, DTInterestFullfillment>, interestMapArg: InterestMap<DTInterestId, DTInterestFullfillment>,
interestArg: DTInterestId, interestArg: DTInterestId,
comparisonFuncArg: IInterestComparisonFunc<DTInterestId> comparisonFuncArg: IInterestComparisonFunc<DTInterestId>,
optionsArg?: IInterestOptions<DTInterestFullfillment>
) { ) {
this.interestMapRef = interestMapArg;
this.originalInterest = interestArg; this.originalInterest = interestArg;
this.comparisonFunc = comparisonFuncArg; this.comparisonFunc = comparisonFuncArg;
this.interestMapRef = interestMapArg; this.options = optionsArg;
this.destructionTimer.completed.then(() => { this.destructionTimer.completed.then(() => {
this.destroy(); this.destroy();
}); });
if (this.options?.markLostAfterDefault) {
plugins.smartdelay.delayFor(this.options.markLostAfterDefault).then(this.markLost);
}
} }
// =============================== // ===============================
@ -60,6 +72,9 @@ export class Interest<DTInterestId, DTInterestFullfillment> {
*/ */
public destroy() { public destroy() {
this.interestMapRef.removeInterest(this); this.interestMapRef.removeInterest(this);
if (!this.isFullfilled && this.options.defaultFullfillment) {
this.fullfillInterest(this.options.defaultFullfillment);
}
} }
/** /**

View File

@ -1,13 +1,26 @@
import * as plugins from './lik.plugins'; /* ===========
import { ObjectMap } from './lik.objectmap'; The InterestMap is an mechanism that collects interests into something
An interest is expressed by an object, string or number.
A comparison func can be specified to make interests comparable
import { Observable } from 'rxjs'; For every unique interestId an interest is created.
Subssequent interests will be mapped to the same interest
which is then is only fullfilled once.
=========== */
import { Interest } from './lik.interestmap.interest'; import * as plugins from './lik.plugins.js';
import { ObjectMap } from './lik.objectmap.js';
import { Interest } from './lik.interestmap.interest.js';
export type IInterestComparisonFunc<T> = (objectArg: T) => string; export type IInterestComparisonFunc<T> = (objectArg: T) => string;
export interface IInterestMapOptions {
markLostAfterDefault?: number;
}
export class InterestMap<DTInterestId, DTInterestFullfillment> { export class InterestMap<DTInterestId, DTInterestFullfillment> {
public options: IInterestMapOptions;
/** /**
* stores interests that are currently fullfilled by the cache * stores interests that are currently fullfilled by the cache
*/ */
@ -18,26 +31,35 @@ export class InterestMap<DTInterestId, DTInterestFullfillment> {
*/ */
private comparisonFunc: IInterestComparisonFunc<DTInterestId>; private comparisonFunc: IInterestComparisonFunc<DTInterestId>;
constructor(comparisonFuncArg: IInterestComparisonFunc<DTInterestId>) { constructor(
comparisonFuncArg: IInterestComparisonFunc<DTInterestId>,
optionsArg: IInterestMapOptions = {}
) {
this.comparisonFunc = comparisonFuncArg; this.comparisonFunc = comparisonFuncArg;
this.options = optionsArg;
} }
/** /**
* adds an interest to the InterestMap * adds an interest to the InterestMap
* @param objectArg * @param interestId
*/ */
public async addInterest( public async addInterest(
objectArg: DTInterestId interestId: DTInterestId,
defaultFullfillmentArg?: DTInterestFullfillment
): Promise<Interest<DTInterestId, DTInterestFullfillment>> { ): Promise<Interest<DTInterestId, DTInterestFullfillment>> {
const comparisonString = this.comparisonFunc(objectArg); const comparisonString = this.comparisonFunc(interestId);
let returnInterest: Interest<DTInterestId, DTInterestFullfillment>; let returnInterest: Interest<DTInterestId, DTInterestFullfillment>;
const newInterest = new Interest<DTInterestId, DTInterestFullfillment>( const newInterest = new Interest<DTInterestId, DTInterestFullfillment>(
this, this,
objectArg, interestId,
this.comparisonFunc this.comparisonFunc,
{
markLostAfterDefault: this.options.markLostAfterDefault,
defaultFullfillment: defaultFullfillmentArg,
}
); );
let interestExists = false; let interestExists = false;
await this.interestObjectMap.forEach(interestArg => { await this.interestObjectMap.forEach((interestArg) => {
if (!interestExists && interestArg.comparisonString === newInterest.comparisonString) { if (!interestExists && interestArg.comparisonString === newInterest.comparisonString) {
console.log('info', `interest already exists for ${newInterest.comparisonString}`); console.log('info', `interest already exists for ${newInterest.comparisonString}`);
interestExists = true; interestExists = true;
@ -53,15 +75,13 @@ export class InterestMap<DTInterestId, DTInterestFullfillment> {
return returnInterest; return returnInterest;
} }
// tslint:disable-next-line:member-ordering
public interestObservable = new plugins.smartrx.ObservableIntake<Interest<DTInterestId, any>>(); public interestObservable = new plugins.smartrx.ObservableIntake<Interest<DTInterestId, any>>();
/** /**
* removes an interest from the interest map * removes an interest from the interest map
* @param objectArg removes an interest from the InterestMap
*/ */
public removeInterest(interestArg: Interest<DTInterestId, DTInterestFullfillment>) { public removeInterest(interestArg: Interest<DTInterestId, DTInterestFullfillment>) {
const interestToRemove = this.interestObjectMap.findOneAndRemove(interestArg2 => { const interestToRemove = this.interestObjectMap.findOneAndRemoveSync((interestArg2) => {
return interestArg.comparisonString === interestArg2.comparisonString; return interestArg.comparisonString === interestArg2.comparisonString;
}); });
} }
@ -79,7 +99,7 @@ export class InterestMap<DTInterestId, DTInterestFullfillment> {
* @param comparisonStringArg * @param comparisonStringArg
*/ */
public checkInterestByString(comparisonStringArg: string): boolean { public checkInterestByString(comparisonStringArg: string): boolean {
const foundInterest = this.interestObjectMap.find(interest => { const foundInterest = this.interestObjectMap.findSync((interest) => {
return interest.comparisonString === comparisonStringArg; return interest.comparisonString === comparisonStringArg;
}); });
if (foundInterest) { if (foundInterest) {
@ -102,11 +122,11 @@ export class InterestMap<DTInterestId, DTInterestFullfillment> {
/** /**
* finds an interest * finds an interest
* @param objectArg * @param interestId
*/ */
public findInterest(objectArg: DTInterestId): Interest<DTInterestId, DTInterestFullfillment> { public findInterest(interestId: DTInterestId): Interest<DTInterestId, DTInterestFullfillment> {
const comparableString = this.comparisonFunc(objectArg); const comparableString = this.comparisonFunc(interestId);
const interest = this.interestObjectMap.find(interestArg => { const interest = this.interestObjectMap.findSync((interestArg) => {
return interestArg.comparisonString === comparableString; return interestArg.comparisonString === comparableString;
}); });
return interest; // if an interest is found, the interest is returned, otherwise interest is null return interest; // if an interest is found, the interest is returned, otherwise interest is null

View File

@ -1,4 +1,4 @@
import * as plugins from './lik.plugins'; import * as plugins from './lik.plugins.js';
export class LimitedArray<T> { export class LimitedArray<T> {
array: T[] = []; array: T[] = [];

View File

@ -1,6 +1,6 @@
import * as plugins from './lik.plugins'; import * as plugins from './lik.plugins.js';
import { ObjectMap } from './lik.objectmap'; import { ObjectMap } from './lik.objectmap.js';
export class LoopTracker<T> { export class LoopTracker<T> {
referenceObjectMap = new ObjectMap<any>(); referenceObjectMap = new ObjectMap<any>();

View File

@ -1,14 +1,31 @@
import * as plugins from './lik.plugins'; import * as plugins from './lik.plugins.js';
import { FastMap } from './lik.fastmap'; import { FastMap } from './lik.fastmap.js';
export const uni = (prefix: string = 'uni') => {
return `${prefix}xxxxxxxxxxx`.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
};
export interface IObjectmapForEachFunction<T> { export interface IObjectmapForEachFunction<T> {
(itemArg: T): void; (itemArg: T): void;
} }
export interface IObjectmapFindFunction<T> { export interface IObjectmapFindFunctionSync<T> {
(itemArg: T): boolean; (itemArg: T): boolean;
} }
export interface IObjectmapFindFunction<T> {
(itemArg: T): Promise<boolean>;
}
export interface IObjectMapEventData<T> {
operation: 'add' | 'remove';
payload: T;
}
/** /**
* allows keeping track of objects * allows keeping track of objects
*/ */
@ -16,7 +33,7 @@ export class ObjectMap<T> {
private fastMap = new FastMap<T>(); private fastMap = new FastMap<T>();
// events // events
public eventSubject = new plugins.smartrx.rxjs.Subject<any>(); public eventSubject = new plugins.smartrx.rxjs.Subject<IObjectMapEventData<T>>();
/** /**
* returns a new instance * returns a new instance
@ -64,8 +81,12 @@ export class ObjectMap<T> {
} }
// otherwise lets create it // otherwise lets create it
const uniqueKey = plugins.smartunique.shortId(); const uniqueKey = uni('key');
this.addMappedUnique(uniqueKey, objectArg); this.addMappedUnique(uniqueKey, objectArg);
this.eventSubject.next({
operation: 'add',
payload: objectArg,
});
return uniqueKey; return uniqueKey;
} }
@ -104,7 +125,11 @@ export class ObjectMap<T> {
/** /**
* find object * find object
*/ */
public find(findFunction: IObjectmapFindFunction<T>): T { public async find(findFunction: IObjectmapFindFunction<T>): Promise<T> {
return this.fastMap.find(findFunction);
}
public findSync(findFunction: IObjectmapFindFunctionSync<T>): T {
for (const keyArg of this.fastMap.getKeys()) { for (const keyArg of this.fastMap.getKeys()) {
if (findFunction(this.fastMap.getByKey(keyArg))) { if (findFunction(this.fastMap.getByKey(keyArg))) {
return this.getMappedUnique(keyArg); return this.getMappedUnique(keyArg);
@ -115,8 +140,15 @@ export class ObjectMap<T> {
/** /**
* finds a specific element and then removes it * finds a specific element and then removes it
*/ */
public findOneAndRemove(findFunction: IObjectmapFindFunction<T>): T { public async findOneAndRemove(findFunction: IObjectmapFindFunction<T>): Promise<T> {
const foundElement = this.find(findFunction); const foundElement = await this.find(findFunction);
if (foundElement) {
this.remove(foundElement);
}
return foundElement;
}
public findOneAndRemoveSync(findFunction: IObjectmapFindFunctionSync<T>): T {
const foundElement = this.findSync(findFunction);
if (foundElement) { if (foundElement) {
this.remove(foundElement); this.remove(foundElement);
} }
@ -142,7 +174,10 @@ export class ObjectMap<T> {
} else { } else {
const keyToUse = keys[0]; const keyToUse = keys[0];
const removedItem = this.fastMap.removeFromMap(keyToUse); const removedItem = this.fastMap.removeFromMap(keyToUse);
this.eventSubject.next('remove'); this.eventSubject.next({
operation: 'remove',
payload: removedItem,
});
return removedItem; return removedItem;
} }
} }
@ -172,7 +207,10 @@ export class ObjectMap<T> {
if (this.checkForObject(objectArg)) { if (this.checkForObject(objectArg)) {
const keyArg = this.getKeyForObject(objectArg); const keyArg = this.getKeyForObject(objectArg);
const removedObject = this.fastMap.removeFromMap(keyArg); const removedObject = this.fastMap.removeFromMap(keyArg);
this.eventSubject.next('remove'); this.eventSubject.next({
operation: 'remove',
payload: removedObject,
});
return removedObject; return removedObject;
} }
return null; return null;

View File

@ -1,26 +1,17 @@
// ==============
// native
// ==============
import * as events from 'events';
export { events };
// ============== // ==============
// @pushrocks // @pushrocks
// ============== // ==============
import * as smartdelay from '@pushrocks/smartdelay'; import * as smartdelay from '@push.rocks/smartdelay';
import * as smartpromise from '@pushrocks/smartpromise'; import * as smartmatch from '@push.rocks/smartmatch';
import * as smartrx from '@pushrocks/smartrx'; import * as smartpromise from '@push.rocks/smartpromise';
import * as smarttime from '@pushrocks/smarttime'; import * as smartrx from '@push.rocks/smartrx';
import * as smartunique from '@pushrocks/smartunique'; import * as smarttime from '@push.rocks/smarttime';
export { smartdelay, smartpromise, smartrx, smarttime, smartunique }; export { smartdelay, smartmatch, smartpromise, smartrx, smarttime };
// ============== // ==============
// third party // third party
// ============== // ==============
import minimatch from 'minimatch'; import symbolTree from 'symbol-tree';
const symbolTree = require('symbol-tree');
export { minimatch, symbolTree }; export { symbolTree };

View File

@ -1,16 +1,14 @@
import * as plugins from './lik.plugins'; import * as plugins from './lik.plugins.js';
/** /**
* allows you to easily keep track of a bunch of strings * allows you to easily keep track of a bunch of strings
*/ */
export interface ITriggerFunction { export type TTriggerFunction = (stringArray?: string[]) => boolean;
(): boolean;
}
export class Stringmap { export class Stringmap {
private _stringArray: string[] = []; private _stringArray: string[] = [];
private _triggerUntilTrueFunctionArray: ITriggerFunction[] = []; private _triggerUntilTrueFunctionArray: TTriggerFunction[] = [];
constructor() {} constructor() {}
/** /**
* add a string to the Stringmap * add a string to the Stringmap
@ -60,9 +58,10 @@ export class Stringmap {
* checks stringPresence with minimatch * checks stringPresence with minimatch
*/ */
public checkMinimatch(miniMatchStringArg: string): boolean { public checkMinimatch(miniMatchStringArg: string): boolean {
const smartMatchInstance = new plugins.smartmatch.SmartMatch(miniMatchStringArg);
let foundMatch: boolean = false; let foundMatch: boolean = false;
for (const stringItem of this._stringArray) { for (const stringItem of this._stringArray) {
if (plugins.minimatch(stringItem, miniMatchStringArg)) { if (smartMatchInstance.match(stringItem)) {
foundMatch = true; foundMatch = true;
} }
} }
@ -92,10 +91,10 @@ export class Stringmap {
/** /**
* register a new trigger * register a new trigger
*/ */
public registerUntilTrue(functionArg: ITriggerFunction, callbackArg?: () => any) { public registerUntilTrue(functionArg: TTriggerFunction, callbackArg?: () => any) {
const trueDeferred = plugins.smartpromise.defer(); const trueDeferred = plugins.smartpromise.defer();
this._triggerUntilTrueFunctionArray.push(() => { this._triggerUntilTrueFunctionArray.push(() => {
const result = functionArg(); const result = functionArg(this.getStringArray());
if (result === true) { if (result === true) {
if (callbackArg) { if (callbackArg) {
callbackArg(); callbackArg();
@ -112,7 +111,7 @@ export class Stringmap {
* notifies triggers * notifies triggers
*/ */
private notifyTrigger() { private notifyTrigger() {
const filteredArray = this._triggerUntilTrueFunctionArray.filter(functionArg => { const filteredArray = this._triggerUntilTrueFunctionArray.filter((functionArg) => {
return !functionArg(); return !functionArg();
}); });
this._triggerUntilTrueFunctionArray = filteredArray; this._triggerUntilTrueFunctionArray = filteredArray;

View File

@ -1,4 +1,4 @@
import * as plugins from './lik.plugins'; import * as plugins from './lik.plugins.js';
export interface ITimedAggregatorOptions<T> { export interface ITimedAggregatorOptions<T> {
aggregationIntervalInMillis: number; aggregationIntervalInMillis: number;

View File

@ -1,4 +1,4 @@
import * as plugins from './lik.plugins'; import * as plugins from './lik.plugins.js';
export class Tree<T> { export class Tree<T> {
symbolTree: any; symbolTree: any;
@ -62,15 +62,15 @@ export class Tree<T> {
return this.symbolTree.ancestorsToArray(objectArg, optionsArg); return this.symbolTree.ancestorsToArray(objectArg, optionsArg);
} }
treeToArray(rootArg, optionsArg: any): T[] { treeToArray(rootArg: T, optionsArg: any): T[] {
return this.symbolTree.treeToArray(rootArg, optionsArg); return this.symbolTree.treeToArray(rootArg, optionsArg);
} }
childrenIterator(parentArg: T, optionsArg): T { childrenIterator(parentArg: T, optionsArg: any): T {
return this.symbolTree.childrenIterator(parentArg, optionsArg); return this.symbolTree.childrenIterator(parentArg, optionsArg);
} }
previousSiblingsIterator(objectArg): T { previousSiblingsIterator(objectArg: T): T {
return this.symbolTree.previousSiblingsIterator(objectArg); return this.symbolTree.previousSiblingsIterator(objectArg);
} }
@ -78,11 +78,11 @@ export class Tree<T> {
return this.symbolTree.nextSiblingsIterator(); return this.symbolTree.nextSiblingsIterator();
} }
ancestorsIterator(objectArg) { ancestorsIterator(objectArg: T) {
this.symbolTree.ancestorsIterator(); this.symbolTree.ancestorsIterator();
} }
treeIterator(rootArg: T, optionsArg): Iterable<T> { treeIterator(rootArg: T, optionsArg: any): Iterable<T> {
return this.symbolTree.treeIterator(rootArg); return this.symbolTree.treeIterator(rootArg);
} }
@ -114,7 +114,7 @@ export class Tree<T> {
return this.symbolTree.prependChild(referenceObjectArg, newObjectArg); return this.symbolTree.prependChild(referenceObjectArg, newObjectArg);
} }
appendChild(referenceObjectArg, newObjectArg) { appendChild(referenceObjectArg: T, newObjectArg: T) {
return this.symbolTree.appendChild(referenceObjectArg, newObjectArg); return this.symbolTree.appendChild(referenceObjectArg, newObjectArg);
} }
@ -126,7 +126,7 @@ export class Tree<T> {
* returns a branch of the tree as JSON * returns a branch of the tree as JSON
* can be user * can be user
*/ */
toJsonWithHierachy(rootElement) { toJsonWithHierachy(rootElement: T) {
const treeIterable = this.treeIterator(rootElement, {}); const treeIterable = this.treeIterator(rootElement, {});
for (const treeItem of treeIterable) { for (const treeItem of treeIterable) {
console.log(treeItem); console.log(treeItem);
@ -137,5 +137,5 @@ export class Tree<T> {
* builds a tree from a JSON with hierachy * builds a tree from a JSON with hierachy
* @param rootElement * @param rootElement
*/ */
fromJsonWithHierachy(rootElement) {} fromJsonWithHierachy(rootElement: T) {}
} }

10
tsconfig.json Normal file
View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "nodenext",
"esModuleInterop": true
}
}

View File

@ -1,17 +0,0 @@
{
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
}