Compare commits
41 Commits
Author | SHA1 | Date | |
---|---|---|---|
6af4f6b9c0 | |||
1141681b60 | |||
2bf04ccb70 | |||
97232adbb0 | |||
dda83e35c0 | |||
8bf1af08d3 | |||
69b2aa7fb8 | |||
75140e9d70 | |||
e45c662658 | |||
d9b0ebb5ed | |||
f5075abafb | |||
e131b8c9ff | |||
244d229fa3 | |||
96080c5de0 | |||
a981c63f9b | |||
cd5e2f03f4 | |||
eb5c1f40ee | |||
ed1d66ee2a | |||
45122024fc | |||
fcaed1a3a0 | |||
0ce5eba798 | |||
9d6111a77f | |||
ac11045812 | |||
2266ee0c73 | |||
e4f0a60644 | |||
946e1cb7d3 | |||
6e5d17a793 | |||
3f7a3c2786 | |||
925921a9fe | |||
61ccf38d85 | |||
061a79b0fd | |||
2f4fb82918 | |||
266da3b476 | |||
074767b294 | |||
85abc4da3d | |||
716d805723 | |||
9feaa921bf | |||
6b57e8b1f3 | |||
f7b6df5ff7 | |||
6a4df84f4f | |||
17b59fd222 |
66
.gitea/workflows/default_nottags.yaml
Normal file
66
.gitea/workflows/default_nottags.yaml
Normal file
@@ -0,0 +1,66 @@
|
||||
name: Default (not tags)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
|
||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{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 @ship.zone/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
|
124
.gitea/workflows/default_tags.yaml
Normal file
124
.gitea/workflows/default_tags.yaml
Normal file
@@ -0,0 +1,124 @@
|
||||
name: Default (tags)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
env:
|
||||
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
|
||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{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 @ship.zone/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 @ship.zone/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 @ship.zone/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 @ship.zone/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
|
11
.gitignore
vendored
11
.gitignore
vendored
@@ -3,7 +3,6 @@
|
||||
# artifacts
|
||||
coverage/
|
||||
public/
|
||||
pages/
|
||||
|
||||
# installs
|
||||
node_modules/
|
||||
@@ -15,8 +14,10 @@ node_modules/
|
||||
|
||||
# builds
|
||||
dist/
|
||||
dist_web/
|
||||
dist_serve/
|
||||
dist_ts_web/
|
||||
dist_*/
|
||||
|
||||
# custom
|
||||
# AI
|
||||
.claude/
|
||||
.serena/
|
||||
|
||||
#------# custom
|
126
.gitlab-ci.yml
126
.gitlab-ci.yml
@@ -1,126 +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
|
||||
|
||||
snyk:
|
||||
image: registry.gitlab.com/hosttoday/ht-docker-node:snyk
|
||||
stage: security
|
||||
script:
|
||||
- npmci npm prepare
|
||||
- npmci command npm install --ignore-scripts
|
||||
- npmci command snyk test
|
||||
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
24
.vscode/launch.json
vendored
@@ -2,28 +2,10 @@
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "current file",
|
||||
"type": "node",
|
||||
"command": "npm test",
|
||||
"name": "Run npm test",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"${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"
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -15,7 +15,7 @@
|
||||
"properties": {
|
||||
"projectType": {
|
||||
"type": "string",
|
||||
"enum": ["website", "element", "service", "npm"]
|
||||
"enum": ["website", "element", "service", "npm", "wcc"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
110
changelog.md
Normal file
110
changelog.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-08-28 - 3.2.0 - feat(docs)
|
||||
Expand README with detailed usage/examples, update test runner and test script, and pin/bump dependencies
|
||||
|
||||
- Completely overhauled README: added highlights, Quick Start, advanced configuration, core operations, examples, storage tier explanations, performance tips, and API reference.
|
||||
- Updated tests to use @git.zone/tstest/tapbundle (test import changed) and adjusted package.json test script to run with --verbose --logfile --timeout 60.
|
||||
- Bumped/pinned dependencies: @push.rocks/smartcache -> ^1.0.18 and several packages now have explicit version ranges (e.g. @push.rocks/lik -> ^6.2.2).
|
||||
- Removed devDependency on @push.rocks/tapbundle.
|
||||
|
||||
## 2025-08-28 - 3.1.2 - fix(core)
|
||||
Update CI workflows and dependencies; apply small bugfixes and formatting improvements
|
||||
|
||||
- Update Gitea workflow image URL and computed repo URL to internal registry and simplified repo path
|
||||
- Switch npmci install target from @shipzone/npmci to @ship.zone/npmci in CI scripts
|
||||
- Bump devDependencies and dependencies to newer versions (tsbuild, tstest, tapbundle, lik, smartbucket, smartfile, smartpath, smartpromise, taskbuffer, tsclass, etc.)
|
||||
- Add package metadata: homepage anchor, packageManager, bugs URL and pnpm overrides block
|
||||
- Fix TypeScript formatting and signatures (consistent trailing commas, multiline parameter lists, path join argument formatting)
|
||||
- Fix file system and S3 manager calls to ensure consistent path handling and argument formatting (improved encoding/consistency in disk and S3 managers)
|
||||
- Correct test file syntax (object commas) to avoid runtime/parse issues
|
||||
- Update .gitignore to add AI tool folders and reorganize custom section
|
||||
- Add pnpm-workspace.yaml with onlyBuiltDependencies entry
|
||||
|
||||
## 2024-11-26 - 3.1.1 - fix(core)
|
||||
|
||||
Fix S3 cache manager methods for better path encoding consistency
|
||||
|
||||
- Corrected path parameter usage in S3 manager methods to ensure encoding and consistency.
|
||||
- Updated package.json Git dependencies for scoped packages.
|
||||
|
||||
## 2024-11-24 - 3.1.0 - feat(core)
|
||||
|
||||
Enhanced caching solution with optional configurations and improved documentation.
|
||||
|
||||
- Improved package description and keywords for better discoverability.
|
||||
- Updated dependencies to latest versions.
|
||||
- Added strict type checking in TypeScript configurations.
|
||||
- Enhanced README with detailed usage instructions and examples.
|
||||
|
||||
## 2024-05-29 to 2024-02-14 - 3.0.8
|
||||
|
||||
Minor configuration updates and documentation changes.
|
||||
|
||||
- Updated project description.
|
||||
- Modified tsconfig setup.
|
||||
- Adjustments to npmextra.json regarding githost.
|
||||
|
||||
## 2024-02-14 - 3.0.7
|
||||
|
||||
Core enhancements and bug fixes.
|
||||
|
||||
- Fixed updates in the core module to improve stability.
|
||||
|
||||
## 2024-02-14 - 3.0.6
|
||||
|
||||
Core maintenance and updates.
|
||||
|
||||
- Implemented minor fixes in the core module.
|
||||
|
||||
## 2023-07-21 - 3.0.5
|
||||
|
||||
Addressed core module adjustments.
|
||||
|
||||
- Patched core module to rectify issues.
|
||||
|
||||
## 2023-07-20 - 3.0.4
|
||||
|
||||
Further improvements to core functionality.
|
||||
|
||||
- Additional fixes applied to the core component.
|
||||
|
||||
## 2023-07-11 to 2023-07-10 - 3.0.3
|
||||
|
||||
Organizational and structural changes.
|
||||
|
||||
- Transitioned to a new organizational scheme.
|
||||
|
||||
## 2023-01-09 - 3.0.2
|
||||
|
||||
Core module corrections.
|
||||
|
||||
- Resolved various issues within the core module.
|
||||
|
||||
## 2022-06-09 - 3.0.1
|
||||
|
||||
Continuous enhancements in core functionality.
|
||||
|
||||
- Continued bug fixes for core module efficiency.
|
||||
|
||||
## 2022-04-04 to 2022-04-02 - 3.0.0
|
||||
|
||||
Major release with significant updates.
|
||||
|
||||
## 2022-03-22 - 2.0.0
|
||||
|
||||
Significant breaking changes in core tech stack.
|
||||
|
||||
- BREAKING CHANGE: Transitioned core module to ECMAScript Modules (ESM).
|
||||
|
||||
## 2021-05-10 - 1.0.9
|
||||
|
||||
Caching improvements and optimization.
|
||||
|
||||
- Enhanced caching by properly respecting TTL across all cache levels.
|
||||
|
||||
## 2020-02-15 to 2020-02-05 - 1.0.6 to 1.0.1
|
||||
|
||||
Initial series of core module fixes and updates.
|
||||
|
||||
- Persistent efforts to stabilize and improve core functionalities.
|
@@ -2,17 +2,34 @@
|
||||
"gitzone": {
|
||||
"projectType": "npm",
|
||||
"module": {
|
||||
"githost": "gitlab.com",
|
||||
"gitscope": "pushrocks",
|
||||
"githost": "code.foss.global",
|
||||
"gitscope": "push.rocks",
|
||||
"gitrepo": "levelcache",
|
||||
"shortDescription": "a cache that uses memory/disk/s3 as backup",
|
||||
"npmPackagename": "@pushrocks/levelcache",
|
||||
"description": "A versatile caching solution offering multi-level storage utilizing memory, disk, and Amazon S3 for efficient data management and backup.",
|
||||
"npmPackagename": "@push.rocks/levelcache",
|
||||
"license": "MIT",
|
||||
"projectDomain": "push.rocks"
|
||||
"projectDomain": "push.rocks",
|
||||
"keywords": [
|
||||
"caching",
|
||||
"data storage",
|
||||
"memory cache",
|
||||
"disk cache",
|
||||
"S3 storage",
|
||||
"data backup",
|
||||
"multi-level caching",
|
||||
"performance",
|
||||
"persistent storage",
|
||||
"data retrieval",
|
||||
"Node.js",
|
||||
"TypeScript"
|
||||
]
|
||||
}
|
||||
},
|
||||
"npmci": {
|
||||
"npmGlobalTools": [],
|
||||
"npmAccessLevel": "public"
|
||||
},
|
||||
"tsdoc": {
|
||||
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13188
package-lock.json
generated
13188
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
80
package.json
80
package.json
@@ -1,45 +1,79 @@
|
||||
{
|
||||
"name": "@pushrocks/levelcache",
|
||||
"version": "1.0.7",
|
||||
"name": "@push.rocks/levelcache",
|
||||
"version": "3.2.0",
|
||||
"private": false,
|
||||
"description": "a cache that uses memory/disk/s3 as backup",
|
||||
"description": "A versatile caching solution offering multi-level storage utilizing memory, disk, and Amazon S3 for efficient data management and backup.",
|
||||
"main": "dist_ts/index.js",
|
||||
"typings": "dist_ts/index.d.ts",
|
||||
"type": "module",
|
||||
"author": "Lossless GmbH",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "(tstest test/ --web)",
|
||||
"build": "(tsbuild --web)"
|
||||
"test": "(tstest test/ --verbose --logfile --timeout 60)",
|
||||
"build": "(tsbuild --web --allowimplicitany)",
|
||||
"buildDocs": "tsdoc",
|
||||
"localPublish": "gitzone commit && pnpm run build && pnpm publish && pnpm publish --access public --registry=\"https://registry.npmjs.org\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gitzone/tsbuild": "^2.1.25",
|
||||
"@gitzone/tstest": "^1.0.52",
|
||||
"@pushrocks/tapbundle": "^3.2.14",
|
||||
"@types/node": "^14.14.41",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-prettier": "^1.15.0"
|
||||
"@git.zone/tsbuild": "^2.6.7",
|
||||
"@git.zone/tsrun": "^1.2.44",
|
||||
"@git.zone/tstest": "^2.3.5",
|
||||
"@types/node": "^24.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pushrocks/lik": "^4.0.20",
|
||||
"@pushrocks/smartbucket": "^1.0.39",
|
||||
"@pushrocks/smartcache": "^1.0.13",
|
||||
"@pushrocks/smartexit": "^1.0.15",
|
||||
"@pushrocks/smartfile": "^8.0.9",
|
||||
"@pushrocks/smartjson": "^4.0.6",
|
||||
"@pushrocks/smartpromise": "^3.1.5",
|
||||
"@pushrocks/smartstring": "^3.0.24",
|
||||
"@pushrocks/smartunique": "^3.0.3",
|
||||
"@pushrocks/taskbuffer": "^2.1.13"
|
||||
"@push.rocks/lik": "^6.2.2",
|
||||
"@push.rocks/smartbucket": "^3.3.10",
|
||||
"@push.rocks/smartcache": "^1.0.18",
|
||||
"@push.rocks/smartenv": "^5.0.13",
|
||||
"@push.rocks/smartexit": "^1.0.23",
|
||||
"@push.rocks/smartfile": "^11.2.7",
|
||||
"@push.rocks/smartjson": "^5.0.20",
|
||||
"@push.rocks/smartpath": "^6.0.0",
|
||||
"@push.rocks/smartpromise": "^4.2.3",
|
||||
"@push.rocks/smartstring": "^4.0.15",
|
||||
"@push.rocks/smartunique": "^3.0.9",
|
||||
"@push.rocks/taskbuffer": "^3.1.10",
|
||||
"@tsclass/tsclass": "^9.2.0"
|
||||
},
|
||||
"files": [
|
||||
"ts/**/*",
|
||||
"ts_web/**/*",
|
||||
"dist/**/*",
|
||||
"dist_web/**/*",
|
||||
"dist_*/**/*",
|
||||
"dist_ts/**/*",
|
||||
"dist_ts_web/**/*",
|
||||
"assets/**/*",
|
||||
"cli.js",
|
||||
"npmextra.json",
|
||||
"readme.md"
|
||||
]
|
||||
],
|
||||
"browserslist": [
|
||||
"last 1 chrome versions"
|
||||
],
|
||||
"keywords": [
|
||||
"caching",
|
||||
"data storage",
|
||||
"memory cache",
|
||||
"disk cache",
|
||||
"S3 storage",
|
||||
"data backup",
|
||||
"multi-level caching",
|
||||
"performance",
|
||||
"persistent storage",
|
||||
"data retrieval",
|
||||
"Node.js",
|
||||
"TypeScript"
|
||||
],
|
||||
"homepage": "https://code.foss.global/push.rocks/levelcache#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://code.foss.global/push.rocks/levelcache.git"
|
||||
},
|
||||
"packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748",
|
||||
"bugs": {
|
||||
"url": "https://code.foss.global/push.rocks/levelcache/issues"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {}
|
||||
}
|
||||
}
|
||||
|
9657
pnpm-lock.yaml
generated
Normal file
9657
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
4
pnpm-workspace.yaml
Normal file
4
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
onlyBuiltDependencies:
|
||||
- esbuild
|
||||
- mongodb-memory-server
|
||||
- puppeteer
|
1
readme.hints.md
Normal file
1
readme.hints.md
Normal file
@@ -0,0 +1 @@
|
||||
|
402
readme.md
402
readme.md
@@ -1,35 +1,389 @@
|
||||
# @pushrocks/levelcache
|
||||
a cache that uses memory/disk/s3 as backup
|
||||
# @push.rocks/levelcache 🚀
|
||||
|
||||
## Availabililty and Links
|
||||
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/levelcache)
|
||||
* [gitlab.com (source)](https://gitlab.com/pushrocks/levelcache)
|
||||
* [github.com (source mirror)](https://github.com/pushrocks/levelcache)
|
||||
* [docs (typedoc)](https://pushrocks.gitlab.io/levelcache/)
|
||||
**Supercharged Multi-Level Caching for Modern Applications**
|
||||
|
||||
## Status for master
|
||||
[](https://gitlab.com/pushrocks/levelcache/commits/master)
|
||||
[](https://gitlab.com/pushrocks/levelcache/commits/master)
|
||||
[](https://www.npmjs.com/package/@pushrocks/levelcache)
|
||||
[](https://snyk.io/test/npm/@pushrocks/levelcache)
|
||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
||||
[](https://prettier.io/)
|
||||
A high-performance, tiered caching solution that intelligently leverages memory, disk, and S3 storage to deliver blazing-fast data access with reliable persistence and backup capabilities.
|
||||
|
||||
## Highlights
|
||||
|
||||
✨ **Intelligent Tiered Storage** - Automatically routes data between memory, disk, and S3 based on size and access patterns
|
||||
⚡ **Lightning Fast** - Memory-first architecture ensures microsecond access times for hot data
|
||||
💾 **Persistent & Durable** - Optional disk and S3 layers provide data durability across restarts
|
||||
🎯 **TTL Support** - Built-in time-to-live for automatic cache expiration
|
||||
🔧 **TypeScript First** - Full type safety and excellent IDE support
|
||||
☁️ **S3 Ready** - Seamless integration with Amazon S3 for massive scale caching
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
# Using npm
|
||||
npm install @push.rocks/levelcache --save
|
||||
|
||||
# Using yarn
|
||||
yarn add @push.rocks/levelcache
|
||||
|
||||
# Using pnpm (recommended)
|
||||
pnpm add @push.rocks/levelcache
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@pushrocks/levelcache implements an efficient way to cache larger amounts of data ind a multilevel approach.
|
||||
smaller and prioritized data is safed in memory.
|
||||
### Quick Start
|
||||
|
||||
Use TypeScript for best in class intellisense.
|
||||
Get up and running with just a few lines:
|
||||
|
||||
## Contribution
|
||||
```typescript
|
||||
import { LevelCache, CacheEntry } from '@push.rocks/levelcache';
|
||||
|
||||
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
||||
// Initialize cache with minimal config
|
||||
const cache = new LevelCache({
|
||||
cacheId: 'myAppCache'
|
||||
});
|
||||
|
||||
For further information read the linked docs at the top of this readme.
|
||||
// Wait for cache to be ready
|
||||
await cache.ready;
|
||||
|
||||
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
||||
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
|
||||
// Store data
|
||||
const entry = new CacheEntry({
|
||||
contents: Buffer.from('Hello Cache World! 🎉'),
|
||||
ttl: 60000 // 1 minute TTL
|
||||
});
|
||||
|
||||
[](https://maintainedby.lossless.com)
|
||||
await cache.storeCacheEntryByKey('greeting', entry);
|
||||
|
||||
// Retrieve data
|
||||
const retrieved = await cache.retrieveCacheEntryByKey('greeting');
|
||||
console.log(retrieved.contents.toString()); // "Hello Cache World! 🎉"
|
||||
```
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
`LevelCache` offers granular control over storage tiers and behavior:
|
||||
|
||||
```typescript
|
||||
const cache = new LevelCache({
|
||||
cacheId: 'productionCache',
|
||||
|
||||
// Storage Limits
|
||||
maxMemoryStorageInMB: 128, // 128MB RAM cache (default: 0.5)
|
||||
maxDiskStorageInMB: 1024, // 1GB disk cache (default: 10)
|
||||
maxS3StorageInMB: 10240, // 10GB S3 storage (optional)
|
||||
|
||||
// Disk Configuration
|
||||
diskStoragePath: './cache-data', // Custom disk location (default: '.nogit')
|
||||
|
||||
// S3 Configuration (optional)
|
||||
s3Config: {
|
||||
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||
region: 'us-east-1'
|
||||
},
|
||||
s3BucketName: 'my-cache-bucket',
|
||||
|
||||
// Behavior Options
|
||||
forceLevel: 'memory', // Force specific tier (optional)
|
||||
immutableCache: false, // Prevent cache mutations
|
||||
persistentCache: true // Persist cache on restarts
|
||||
});
|
||||
```
|
||||
|
||||
### Core Operations
|
||||
|
||||
#### Storing Data
|
||||
|
||||
```typescript
|
||||
// Store text data
|
||||
const textEntry = new CacheEntry({
|
||||
contents: Buffer.from('Important text data'),
|
||||
ttl: 3600000, // 1 hour
|
||||
typeInfo: 'text/plain' // Optional metadata
|
||||
});
|
||||
await cache.storeCacheEntryByKey('document:123', textEntry);
|
||||
|
||||
// Store JSON data
|
||||
const jsonData = { user: 'john', role: 'admin' };
|
||||
const jsonEntry = new CacheEntry({
|
||||
contents: Buffer.from(JSON.stringify(jsonData)),
|
||||
ttl: 7200000, // 2 hours
|
||||
typeInfo: 'application/json'
|
||||
});
|
||||
await cache.storeCacheEntryByKey('user:john', jsonEntry);
|
||||
|
||||
// Store binary data (images, files, etc.)
|
||||
const imageBuffer = await fs.readFile('./logo.png');
|
||||
const imageEntry = new CacheEntry({
|
||||
contents: imageBuffer,
|
||||
ttl: 86400000, // 24 hours
|
||||
typeInfo: 'image/png'
|
||||
});
|
||||
await cache.storeCacheEntryByKey('assets:logo', imageEntry);
|
||||
```
|
||||
|
||||
#### Retrieving Data
|
||||
|
||||
```typescript
|
||||
// Basic retrieval
|
||||
const entry = await cache.retrieveCacheEntryByKey('user:john');
|
||||
if (entry) {
|
||||
const userData = JSON.parse(entry.contents.toString());
|
||||
console.log(userData); // { user: 'john', role: 'admin' }
|
||||
} else {
|
||||
console.log('Cache miss or expired');
|
||||
}
|
||||
|
||||
// Check if key exists
|
||||
const exists = await cache.checkKeyPresence('user:john');
|
||||
console.log(`Key exists: ${exists}`);
|
||||
|
||||
// Handle cache misses gracefully
|
||||
async function getUser(userId: string) {
|
||||
const cacheKey = `user:${userId}`;
|
||||
let entry = await cache.retrieveCacheEntryByKey(cacheKey);
|
||||
|
||||
if (!entry) {
|
||||
// Cache miss - fetch from database
|
||||
const userData = await database.getUser(userId);
|
||||
|
||||
// Store in cache for next time
|
||||
entry = new CacheEntry({
|
||||
contents: Buffer.from(JSON.stringify(userData)),
|
||||
ttl: 600000 // 10 minutes
|
||||
});
|
||||
await cache.storeCacheEntryByKey(cacheKey, entry);
|
||||
}
|
||||
|
||||
return JSON.parse(entry.contents.toString());
|
||||
}
|
||||
```
|
||||
|
||||
#### Managing Cache
|
||||
|
||||
```typescript
|
||||
// Delete specific entry
|
||||
await cache.deleteCacheEntryByKey('user:john');
|
||||
|
||||
// Clean expired entries
|
||||
await cache.cleanOutdated();
|
||||
|
||||
// Clear entire cache
|
||||
await cache.cleanAll();
|
||||
```
|
||||
|
||||
### Storage Tiers Explained
|
||||
|
||||
`LevelCache` automatically determines the optimal storage tier based on data size and available capacity:
|
||||
|
||||
#### 1. **Memory Cache** 🧠
|
||||
- **Speed**: Microsecond access
|
||||
- **Best for**: Frequently accessed, small data
|
||||
- **Default limit**: 0.5MB (configurable)
|
||||
- First tier checked for all operations
|
||||
|
||||
#### 2. **Disk Cache** 💾
|
||||
- **Speed**: Millisecond access
|
||||
- **Best for**: Medium-sized data, persistent storage needed
|
||||
- **Default limit**: 10MB (configurable)
|
||||
- Data survives process restarts when `persistentCache: true`
|
||||
|
||||
#### 3. **S3 Cache** ☁️
|
||||
- **Speed**: Network latency (typically 50-200ms)
|
||||
- **Best for**: Large data, long-term storage, distributed caching
|
||||
- **Default limit**: 50MB (configurable)
|
||||
- Requires S3 configuration
|
||||
- Ideal for shared cache across multiple instances
|
||||
|
||||
### Real-World Use Cases
|
||||
|
||||
#### API Response Caching
|
||||
|
||||
```typescript
|
||||
class ApiCache {
|
||||
private cache: LevelCache;
|
||||
|
||||
constructor() {
|
||||
this.cache = new LevelCache({
|
||||
cacheId: 'apiResponses',
|
||||
maxMemoryStorageInMB: 256,
|
||||
maxDiskStorageInMB: 2048,
|
||||
persistentCache: true
|
||||
});
|
||||
}
|
||||
|
||||
async getCachedResponse(endpoint: string, params: any) {
|
||||
const cacheKey = `api:${endpoint}:${JSON.stringify(params)}`;
|
||||
|
||||
let cached = await this.cache.retrieveCacheEntryByKey(cacheKey);
|
||||
if (cached) {
|
||||
return JSON.parse(cached.contents.toString());
|
||||
}
|
||||
|
||||
// Fetch fresh data
|
||||
const response = await fetch(endpoint, { params });
|
||||
const data = await response.json();
|
||||
|
||||
// Cache for 5 minutes
|
||||
const entry = new CacheEntry({
|
||||
contents: Buffer.from(JSON.stringify(data)),
|
||||
ttl: 300000
|
||||
});
|
||||
await this.cache.storeCacheEntryByKey(cacheKey, entry);
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Session Storage
|
||||
|
||||
```typescript
|
||||
class SessionManager {
|
||||
private cache: LevelCache;
|
||||
|
||||
constructor() {
|
||||
this.cache = new LevelCache({
|
||||
cacheId: 'sessions',
|
||||
maxMemoryStorageInMB: 64,
|
||||
maxDiskStorageInMB: 512,
|
||||
immutableCache: false,
|
||||
persistentCache: true
|
||||
});
|
||||
}
|
||||
|
||||
async createSession(userId: string, sessionData: any) {
|
||||
const sessionId = generateSessionId();
|
||||
const entry = new CacheEntry({
|
||||
contents: Buffer.from(JSON.stringify({
|
||||
userId,
|
||||
...sessionData,
|
||||
createdAt: Date.now()
|
||||
})),
|
||||
ttl: 86400000 // 24 hour sessions
|
||||
});
|
||||
|
||||
await this.cache.storeCacheEntryByKey(`session:${sessionId}`, entry);
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
async getSession(sessionId: string) {
|
||||
const entry = await this.cache.retrieveCacheEntryByKey(`session:${sessionId}`);
|
||||
return entry ? JSON.parse(entry.contents.toString()) : null;
|
||||
}
|
||||
|
||||
async destroySession(sessionId: string) {
|
||||
await this.cache.deleteCacheEntryByKey(`session:${sessionId}`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Distributed Processing Cache
|
||||
|
||||
```typescript
|
||||
// Share computed results across multiple workers using S3
|
||||
const distributedCache = new LevelCache({
|
||||
cacheId: 'mlModelResults',
|
||||
maxMemoryStorageInMB: 512,
|
||||
maxDiskStorageInMB: 5120,
|
||||
maxS3StorageInMB: 102400, // 100GB for model outputs
|
||||
s3Config: {
|
||||
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||
region: 'us-west-2'
|
||||
},
|
||||
s3BucketName: 'ml-computation-cache',
|
||||
persistentCache: true
|
||||
});
|
||||
|
||||
// Worker process can store results
|
||||
async function storeComputationResult(jobId: string, result: Buffer) {
|
||||
const entry = new CacheEntry({
|
||||
contents: result,
|
||||
ttl: 604800000, // 7 days
|
||||
typeInfo: 'application/octet-stream'
|
||||
});
|
||||
await distributedCache.storeCacheEntryByKey(`job:${jobId}`, entry);
|
||||
}
|
||||
|
||||
// Other workers can retrieve results
|
||||
async function getComputationResult(jobId: string) {
|
||||
const entry = await distributedCache.retrieveCacheEntryByKey(`job:${jobId}`);
|
||||
return entry ? entry.contents : null;
|
||||
}
|
||||
```
|
||||
|
||||
### Performance Tips 🎯
|
||||
|
||||
1. **Size your tiers appropriately** - Set memory limits based on your hot data size
|
||||
2. **Use meaningful cache keys** - Include version/hash in keys for cache invalidation
|
||||
3. **Set realistic TTLs** - Balance freshness with performance
|
||||
4. **Monitor cache hit rates** - Track `checkKeyPresence()` to optimize tier sizes
|
||||
5. **Batch operations** - Group related cache operations when possible
|
||||
6. **Use compression** - Compress large values before caching to maximize tier utilization
|
||||
|
||||
### Migration & Compatibility
|
||||
|
||||
Coming from other caching solutions? Here's how LevelCache compares:
|
||||
|
||||
- **Redis** → LevelCache provides similar speed with added persistence and S3 backup
|
||||
- **Memcached** → LevelCache adds persistence and automatic tier management
|
||||
- **Local storage** → LevelCache adds memory tier and S3 backup capabilities
|
||||
- **S3 only** → LevelCache adds memory and disk tiers for dramatic speed improvements
|
||||
|
||||
## API Reference
|
||||
|
||||
### LevelCache Class
|
||||
|
||||
#### Constructor Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `cacheId` | string | required | Unique identifier for the cache instance |
|
||||
| `maxMemoryStorageInMB` | number | 0.5 | Maximum memory storage in megabytes |
|
||||
| `maxDiskStorageInMB` | number | 10 | Maximum disk storage in megabytes |
|
||||
| `maxS3StorageInMB` | number | 50 | Maximum S3 storage in megabytes |
|
||||
| `diskStoragePath` | string | '.nogit' | Path for disk cache storage |
|
||||
| `s3Config` | object | undefined | AWS S3 configuration object |
|
||||
| `s3BucketName` | string | undefined | S3 bucket name for cache storage |
|
||||
| `forceLevel` | string | undefined | Force storage to specific tier |
|
||||
| `immutableCache` | boolean | false | Prevent cache entry modifications |
|
||||
| `persistentCache` | boolean | false | Persist cache across restarts |
|
||||
|
||||
#### Methods
|
||||
|
||||
| Method | Returns | Description |
|
||||
|--------|---------|-------------|
|
||||
| `ready` | Promise<void> | Resolves when cache is initialized |
|
||||
| `storeCacheEntryByKey(key, entry)` | Promise<void> | Store a cache entry |
|
||||
| `retrieveCacheEntryByKey(key)` | Promise<CacheEntry\|null> | Retrieve a cache entry |
|
||||
| `checkKeyPresence(key)` | Promise<boolean> | Check if key exists |
|
||||
| `deleteCacheEntryByKey(key)` | Promise<void> | Delete a cache entry |
|
||||
| `cleanOutdated()` | Promise<void> | Remove expired entries |
|
||||
| `cleanAll()` | Promise<void> | Clear entire cache |
|
||||
|
||||
### CacheEntry Class
|
||||
|
||||
#### Constructor Options
|
||||
|
||||
| Option | Type | Required | Description |
|
||||
|--------|------|----------|-------------|
|
||||
| `contents` | Buffer | yes | The data to cache |
|
||||
| `ttl` | number | yes | Time-to-live in milliseconds |
|
||||
| `typeInfo` | string | no | Optional metadata about content type |
|
||||
|
||||
## License and Legal Information
|
||||
|
||||
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
||||
|
||||
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
||||
|
||||
### Trademarks
|
||||
|
||||
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
|
||||
|
||||
### Company Information
|
||||
|
||||
Task Venture Capital GmbH
|
||||
Registered at District court Bremen HRB 35230 HB, Germany
|
||||
|
||||
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
||||
|
||||
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
41
test/test.ts
41
test/test.ts
@@ -1,24 +1,43 @@
|
||||
import { expect, tap } from '@pushrocks/tapbundle';
|
||||
import * as levelcache from '../ts/index';
|
||||
import { CacheEntry } from '../ts/index';
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as levelcache from '../ts/index.js';
|
||||
import { CacheEntry } from '../ts/index.js';
|
||||
|
||||
let testLevelCache: levelcache.LevelCache;
|
||||
|
||||
tap.test('should create a new levelcache instance', async () => {
|
||||
testLevelCache = new levelcache.LevelCache({
|
||||
cacheId: 'myCache'
|
||||
cacheId: 'myCache',
|
||||
});
|
||||
expect(testLevelCache).to.be.instanceOf(levelcache.LevelCache);
|
||||
expect(testLevelCache).toBeInstanceOf(levelcache.LevelCache);
|
||||
});
|
||||
|
||||
tap.test('should cache a value', async () => {
|
||||
await testLevelCache.storeCacheEntryByKey('mykey', new CacheEntry({
|
||||
contents: Buffer.from('heythere'),
|
||||
ttl: 10000,
|
||||
typeInfo: 'string'
|
||||
}));
|
||||
await testLevelCache.storeCacheEntryByKey(
|
||||
'mykey',
|
||||
new CacheEntry({
|
||||
contents: Buffer.from('heythere'),
|
||||
ttl: 10000,
|
||||
typeInfo: 'string',
|
||||
}),
|
||||
);
|
||||
const result = await testLevelCache.retrieveCacheEntryByKey('mykey');
|
||||
console.log(result);
|
||||
expect(result.contents.toString()).toEqual('heythere');
|
||||
});
|
||||
|
||||
tap.test('should respect ttl', async (tools) => {
|
||||
await testLevelCache.storeCacheEntryByKey(
|
||||
'mykey',
|
||||
new CacheEntry({
|
||||
contents: Buffer.from('heythere'),
|
||||
ttl: 1000,
|
||||
typeInfo: 'string',
|
||||
}),
|
||||
);
|
||||
const result = await testLevelCache.retrieveCacheEntryByKey('mykey');
|
||||
expect(result.contents.toString()).toEqual('heythere');
|
||||
await tools!.delayFor(1100);
|
||||
const result2 = await testLevelCache.retrieveCacheEntryByKey('mykey');
|
||||
expect(result2).toBeNull();
|
||||
});
|
||||
|
||||
tap.start();
|
||||
|
8
ts/00_commitinfo_data.ts
Normal file
8
ts/00_commitinfo_data.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* autocreated commitinfo by @push.rocks/commitinfo
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/levelcache',
|
||||
version: '3.2.0',
|
||||
description: 'A versatile caching solution offering multi-level storage utilizing memory, disk, and Amazon S3 for efficient data management and backup.'
|
||||
}
|
@@ -1,3 +1,2 @@
|
||||
export * from './levelcache.classes.levelcache';
|
||||
export * from './levelcache.classes.cacheentry';
|
||||
|
||||
export * from './levelcache.classes.levelcache.js';
|
||||
export * from './levelcache.classes.cacheentry.js';
|
||||
|
@@ -1,25 +1,41 @@
|
||||
import { CacheEntry } from "./levelcache.classes.cacheentry";
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry.js';
|
||||
|
||||
export abstract class AbstractCache {
|
||||
public abstract ready: Promise<void>;
|
||||
public abstract status: 'active' | 'inactive';
|
||||
|
||||
// Blobs
|
||||
|
||||
// Cache Entries
|
||||
/**
|
||||
* store a Blob
|
||||
*/
|
||||
public abstract storeCacheEntryByKey(keyArg: string, valueArg: CacheEntry): Promise<void>;
|
||||
public abstract storeCacheEntryByKey(
|
||||
keyArg: string,
|
||||
valueArg: CacheEntry,
|
||||
): Promise<void>;
|
||||
|
||||
// Cache Entries
|
||||
/**
|
||||
* retrieve cache entry
|
||||
*/
|
||||
public abstract retrieveCacheEntryByKey(keyArg: string): Promise<CacheEntry>;
|
||||
|
||||
/**
|
||||
* checks for the presence of a key
|
||||
* @param keyArg
|
||||
*/
|
||||
public abstract checkKeyPresence(keyArg: string): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* cleans the cache
|
||||
* delete a key
|
||||
*/
|
||||
public abstract clean(): Promise<void>;
|
||||
}
|
||||
public abstract deleteCacheEntryByKey(keyArg: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* clean the cache
|
||||
*/
|
||||
public abstract cleanOutdated(): Promise<void>;
|
||||
|
||||
/**
|
||||
* cleans the complete cache
|
||||
*/
|
||||
public abstract cleanAll(): Promise<void>;
|
||||
}
|
||||
|
@@ -1,8 +1,11 @@
|
||||
import * as plugins from './levelcache.plugins';
|
||||
import * as paths from './levelcache.paths';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache';
|
||||
import { ILevelCacheConstructorOptions, LevelCache } from './levelcache.classes.levelcache';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry';
|
||||
import * as plugins from './levelcache.plugins.js';
|
||||
import * as paths from './levelcache.paths.js';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache.js';
|
||||
import {
|
||||
type ILevelCacheConstructorOptions,
|
||||
LevelCache,
|
||||
} from './levelcache.classes.levelcache.js';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry.js';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -10,9 +13,9 @@ import { CacheEntry } from './levelcache.classes.cacheentry';
|
||||
export class CacheDiskManager extends AbstractCache {
|
||||
private levelCacheRef: LevelCache;
|
||||
private readyDeferred = plugins.smartpromise.defer<void>();
|
||||
|
||||
|
||||
public ready = this.readyDeferred.promise;
|
||||
public status: 'active' | 'inactive';
|
||||
public status: 'active' | 'inactive';
|
||||
public fsPath: string;
|
||||
public maxCacheSizeInMb: number;
|
||||
|
||||
@@ -24,9 +27,15 @@ export class CacheDiskManager extends AbstractCache {
|
||||
|
||||
public async init() {
|
||||
if (this.levelCacheRef.options.diskStoragePath) {
|
||||
this.fsPath = plugins.path.join(this.levelCacheRef.options.diskStoragePath, this.levelCacheRef.options.cacheId);
|
||||
this.fsPath = plugins.path.join(
|
||||
this.levelCacheRef.options.diskStoragePath,
|
||||
this.levelCacheRef.options.cacheId,
|
||||
);
|
||||
} else {
|
||||
this.fsPath = plugins.path.join(paths.nogitDir, this.levelCacheRef.options.cacheId);
|
||||
this.fsPath = plugins.path.join(
|
||||
paths.nogitDir,
|
||||
this.levelCacheRef.options.cacheId,
|
||||
);
|
||||
}
|
||||
if (this.status === 'active') {
|
||||
plugins.smartfile.fs.ensureDirSync(this.fsPath);
|
||||
@@ -35,22 +44,34 @@ export class CacheDiskManager extends AbstractCache {
|
||||
}
|
||||
|
||||
public async retrieveCacheEntryByKey(keyArg: string): Promise<CacheEntry> {
|
||||
const fileString = await plugins.smartfile.fs.toStringSync(plugins.path.join(this.fsPath, encodeURIComponent(keyArg)));
|
||||
const fileString = await plugins.smartfile.fs.toStringSync(
|
||||
plugins.path.join(this.fsPath, encodeURIComponent(keyArg)),
|
||||
);
|
||||
return CacheEntry.fromStorageJsonString(fileString);
|
||||
}
|
||||
|
||||
public async storeCacheEntryByKey(keyArg: string, cacheEntryArg: CacheEntry) {
|
||||
await plugins.smartfile.memory.toFs(cacheEntryArg.foldToJson(), plugins.path.join(this.fsPath, encodeURIComponent(keyArg)));
|
||||
await plugins.smartfile.memory.toFs(
|
||||
cacheEntryArg.foldToJson(),
|
||||
plugins.path.join(this.fsPath, encodeURIComponent(keyArg)),
|
||||
);
|
||||
}
|
||||
|
||||
public async checkKeyPresence(keyArg): Promise<boolean> {
|
||||
return plugins.smartfile.fs.isFile(plugins.path.join(this.fsPath, encodeURIComponent(keyArg)));
|
||||
public async checkKeyPresence(keyArg: string): Promise<boolean> {
|
||||
return plugins.smartfile.fs.isFile(
|
||||
plugins.path.join(this.fsPath, encodeURIComponent(keyArg)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* cleans the DiskCache directory
|
||||
*/
|
||||
public async clean() {
|
||||
public async deleteCacheEntryByKey(keyArg: string) {
|
||||
await plugins.smartfile.fs.remove(
|
||||
plugins.path.join(this.fsPath, encodeURIComponent(keyArg)),
|
||||
);
|
||||
}
|
||||
|
||||
public async cleanOutdated() {}
|
||||
|
||||
public async cleanAll() {
|
||||
if (this.status === 'active') {
|
||||
if (plugins.smartfile.fs.isDirectory(this.fsPath)) {
|
||||
await plugins.smartfile.fs.ensureEmptyDir(this.fsPath);
|
||||
|
@@ -1,13 +1,16 @@
|
||||
import * as plugins from './levelcache.plugins';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry';
|
||||
import { ILevelCacheConstructorOptions, LevelCache } from './levelcache.classes.levelcache';
|
||||
import * as plugins from './levelcache.plugins.js';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache.js';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry.js';
|
||||
import {
|
||||
type ILevelCacheConstructorOptions,
|
||||
LevelCache,
|
||||
} from './levelcache.classes.levelcache.js';
|
||||
|
||||
export class CacheMemoryManager extends AbstractCache {
|
||||
private levelCacheRef: LevelCache;
|
||||
private fastMap = new plugins.lik.FastMap<CacheEntry>();
|
||||
private readyDeferred = plugins.smartpromise.defer<void>();
|
||||
|
||||
|
||||
public ready = this.readyDeferred.promise;
|
||||
public status: 'active' | 'inactive';
|
||||
|
||||
@@ -22,7 +25,10 @@ export class CacheMemoryManager extends AbstractCache {
|
||||
this.readyDeferred.resolve();
|
||||
}
|
||||
|
||||
public async storeCacheEntryByKey(keyArg: string, cacheEntryArg: CacheEntry): Promise<void> {
|
||||
public async storeCacheEntryByKey(
|
||||
keyArg: string,
|
||||
cacheEntryArg: CacheEntry,
|
||||
): Promise<void> {
|
||||
this.fastMap.addToMap(keyArg, cacheEntryArg, { force: true });
|
||||
}
|
||||
|
||||
@@ -38,8 +44,13 @@ export class CacheMemoryManager extends AbstractCache {
|
||||
}
|
||||
}
|
||||
|
||||
public async clean() {
|
||||
public async deleteCacheEntryByKey(keyArg: string) {
|
||||
this.fastMap.removeFromMap(keyArg);
|
||||
}
|
||||
|
||||
public async cleanOutdated() {}
|
||||
|
||||
public async cleanAll() {
|
||||
this.fastMap.clean();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import * as plugins from './levelcache.plugins';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache';
|
||||
import { LevelCache } from './levelcache.classes.levelcache';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry';
|
||||
import * as plugins from './levelcache.plugins.js';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache.js';
|
||||
import { LevelCache } from './levelcache.classes.levelcache.js';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry.js';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -24,15 +24,21 @@ export class CacheS3Manager extends AbstractCache {
|
||||
|
||||
public async init() {
|
||||
if (this.levelCacheRef.options.s3Config) {
|
||||
this.smartbucket = new plugins.smartbucket.SmartBucket(this.levelCacheRef.options.s3Config);
|
||||
this.s3CacheBucket = await this.smartbucket.getBucketByName('');
|
||||
this.s3CacheDir = await (await this.s3CacheBucket.getBaseDirectory()).getSubDirectoryByName(
|
||||
this.levelCacheRef.options.cacheId
|
||||
this.smartbucket = new plugins.smartbucket.SmartBucket(
|
||||
this.levelCacheRef.options.s3Config,
|
||||
);
|
||||
this.s3CacheBucket = await this.smartbucket.getBucketByName('');
|
||||
this.s3CacheDir = await (
|
||||
await this.s3CacheBucket.getBaseDirectory()
|
||||
).getSubDirectoryByName(this.levelCacheRef.options.cacheId);
|
||||
if (this.levelCacheRef.options.maxS3StorageInMB) {
|
||||
console.log(`cache level S3 activated with ${this.levelCacheRef.options.maxS3StorageInMB}`);
|
||||
console.log(
|
||||
`cache level S3 activated with ${this.levelCacheRef.options.maxS3StorageInMB}`,
|
||||
);
|
||||
} else {
|
||||
console.log(`s3 cache started without limit. Automatically applying timebox of 1 month`);
|
||||
console.log(
|
||||
`s3 cache started without limit. Automatically applying timebox of 1 month`,
|
||||
);
|
||||
}
|
||||
this.status = 'active';
|
||||
} else {
|
||||
@@ -42,13 +48,20 @@ export class CacheS3Manager extends AbstractCache {
|
||||
}
|
||||
|
||||
public async retrieveCacheEntryByKey(keyArg: string): Promise<CacheEntry> {
|
||||
const jsonFileString = (await this.s3CacheDir.fastGet(encodeURIComponent(keyArg))).toString();
|
||||
const jsonFileString = (
|
||||
await this.s3CacheDir.fastGet({
|
||||
path: encodeURIComponent(keyArg),
|
||||
})
|
||||
).toString();
|
||||
const cacheEntry = CacheEntry.fromStorageJsonString(jsonFileString);
|
||||
return cacheEntry;
|
||||
}
|
||||
|
||||
public async storeCacheEntryByKey(keyArg: string, cacheEntryArg: CacheEntry) {
|
||||
await this.s3CacheDir.fastStore(encodeURIComponent(keyArg), cacheEntryArg.toStorageJsonString());
|
||||
await this.s3CacheDir.fastPut({
|
||||
path: encodeURIComponent(keyArg),
|
||||
contents: cacheEntryArg.toStorageJsonString(),
|
||||
});
|
||||
}
|
||||
|
||||
public async checkKeyPresence(keyArg: string): Promise<boolean> {
|
||||
@@ -61,7 +74,22 @@ export class CacheS3Manager extends AbstractCache {
|
||||
return false;
|
||||
}
|
||||
|
||||
public async clean() {
|
||||
await this.s3CacheDir.deleteWithAllContents();
|
||||
public async deleteCacheEntryByKey(keyArg: string) {
|
||||
if (this.status === 'active') {
|
||||
await this.s3CacheDir.fastRemove({
|
||||
path: encodeURIComponent(keyArg),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clean outdated
|
||||
*/
|
||||
public async cleanOutdated() {}
|
||||
|
||||
public async cleanAll() {
|
||||
await this.s3CacheDir.delete({
|
||||
mode: 'permanent',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import * as plugins from './levelcache.plugins';
|
||||
import * as plugins from './levelcache.plugins.js';
|
||||
|
||||
export interface ICacheEntryConstructorOptions {
|
||||
key?: string;
|
||||
@@ -10,7 +10,10 @@ export interface ICacheEntryConstructorOptions {
|
||||
/**
|
||||
* a CacheEntry
|
||||
*/
|
||||
export class CacheEntry extends plugins.smartjson.Smartjson implements ICacheEntryConstructorOptions {
|
||||
export class CacheEntry
|
||||
extends plugins.smartjson.Smartjson
|
||||
implements ICacheEntryConstructorOptions
|
||||
{
|
||||
public static fromStorageJsonString(storageJsonString: string) {
|
||||
return new CacheEntry(plugins.smartjson.parse(storageJsonString));
|
||||
}
|
||||
@@ -21,9 +24,12 @@ export class CacheEntry extends plugins.smartjson.Smartjson implements ICacheEnt
|
||||
@plugins.smartjson.foldDec()
|
||||
public ttl: number;
|
||||
|
||||
@plugins.smartjson.foldDec()
|
||||
public createdAt: number;
|
||||
|
||||
@plugins.smartjson.foldDec()
|
||||
public typeInfo: string;
|
||||
|
||||
|
||||
@plugins.smartjson.foldDec()
|
||||
contents: Buffer;
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import * as plugins from './levelcache.plugins';
|
||||
import { LevelCache } from './levelcache.classes.levelcache';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry';
|
||||
import * as plugins from './levelcache.plugins.js';
|
||||
import { LevelCache } from './levelcache.classes.levelcache.js';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache.js';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry.js';
|
||||
|
||||
export class CacheRouter {
|
||||
public levelCacheRef: LevelCache;
|
||||
@@ -14,24 +14,37 @@ export class CacheRouter {
|
||||
/**
|
||||
* gets the relevant cache to perform a store action on
|
||||
*/
|
||||
async getCacheForStoreAction(keyArg: string, cacheEntry: CacheEntry): Promise<AbstractCache> {
|
||||
async getCacheForStoreAction(
|
||||
keyArg: string,
|
||||
cacheEntry: CacheEntry,
|
||||
): Promise<AbstractCache> {
|
||||
let returnCache: AbstractCache;
|
||||
const mbToBytesMultiplier = 1000 * 1000;
|
||||
const maxMemoryBytes =
|
||||
this.levelCacheRef.options.maxMemoryStorageInMB * mbToBytesMultiplier;
|
||||
const maxDiskBytes =
|
||||
this.levelCacheRef.options.maxDiskStorageInMB * mbToBytesMultiplier;
|
||||
const maxS3Bytes =
|
||||
this.levelCacheRef.options.maxS3StorageInMB * mbToBytesMultiplier;
|
||||
|
||||
switch (true) {
|
||||
case cacheEntry.contents.byteLength <= 500:
|
||||
case cacheEntry.contents.byteLength <= maxMemoryBytes &&
|
||||
this.levelCacheRef.cacheMemoryManager.status === 'active':
|
||||
returnCache = this.levelCacheRef.cacheMemoryManager;
|
||||
break;
|
||||
case this.levelCacheRef.cacheDiskManager.status === 'active' &&
|
||||
cacheEntry.contents.byteLength >= 500 &&
|
||||
(cacheEntry.contents.byteLength < 10000 ||
|
||||
this.levelCacheRef.cacheS3Manager.status === 'inactive'):
|
||||
cacheEntry.contents.byteLength > maxMemoryBytes &&
|
||||
cacheEntry.contents.byteLength <= maxDiskBytes &&
|
||||
this.levelCacheRef.cacheDiskManager.status === 'active':
|
||||
returnCache = this.levelCacheRef.cacheDiskManager;
|
||||
break;
|
||||
case cacheEntry.contents.byteLength >= 10000 &&
|
||||
case cacheEntry.contents.byteLength > maxDiskBytes &&
|
||||
cacheEntry.contents.byteLength < maxS3Bytes &&
|
||||
this.levelCacheRef.cacheS3Manager.status === 'active':
|
||||
returnCache = this.levelCacheRef.cacheS3Manager;
|
||||
break;
|
||||
default:
|
||||
returnCache = this.levelCacheRef.cacheMemoryManager;
|
||||
returnCache = null;
|
||||
}
|
||||
this.cacheKeyMap.addToMap(keyArg, returnCache);
|
||||
return returnCache;
|
||||
@@ -46,7 +59,7 @@ export class CacheRouter {
|
||||
if (!returnCache && this.levelCacheRef.options.persistentCache) {
|
||||
const checkCache = (cacheArg: AbstractCache) => {
|
||||
const resultPromise = cacheArg.checkKeyPresence(keyArg);
|
||||
resultPromise.then(hasKeyArg => {
|
||||
resultPromise.then((hasKeyArg) => {
|
||||
if (hasKeyArg) {
|
||||
done.resolve(cacheArg);
|
||||
}
|
||||
@@ -56,7 +69,7 @@ export class CacheRouter {
|
||||
Promise.all([
|
||||
checkCache(this.levelCacheRef.cacheMemoryManager),
|
||||
checkCache(this.levelCacheRef.cacheDiskManager),
|
||||
checkCache(this.levelCacheRef.cacheMemoryManager)
|
||||
checkCache(this.levelCacheRef.cacheMemoryManager),
|
||||
]).then(() => {
|
||||
done.resolve(returnCache);
|
||||
});
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import * as plugins from './levelcache.plugins';
|
||||
import { CacheDiskManager } from './levelcache.classes.cache.diskmanager';
|
||||
import { CacheMemoryManager } from './levelcache.classes.cache.memorymanager';
|
||||
import { CacheS3Manager } from './levelcache.classes.cache.s3manager';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry';
|
||||
import { CacheRouter } from './levelcache.classes.cacherouter';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache';
|
||||
import * as plugins from './levelcache.plugins.js';
|
||||
import { CacheDiskManager } from './levelcache.classes.cache.diskmanager.js';
|
||||
import { CacheMemoryManager } from './levelcache.classes.cache.memorymanager.js';
|
||||
import { CacheS3Manager } from './levelcache.classes.cache.s3manager.js';
|
||||
import { CacheEntry } from './levelcache.classes.cacheentry.js';
|
||||
import { CacheRouter } from './levelcache.classes.cacherouter.js';
|
||||
import { AbstractCache } from './levelcache.abstract.classes.cache.js';
|
||||
|
||||
export interface ILevelCacheConstructorOptions {
|
||||
/**
|
||||
@@ -15,7 +15,7 @@ export interface ILevelCacheConstructorOptions {
|
||||
maxDiskStorageInMB?: number;
|
||||
maxS3StorageInMB?: number;
|
||||
diskStoragePath?: string;
|
||||
s3Config?: plugins.smartbucket.ISmartBucketConfig;
|
||||
s3Config?: plugins.tsclass.storage.IS3Descriptor;
|
||||
s3BucketName?: string;
|
||||
forceLevel?: 'memory' | 'disk' | 's3';
|
||||
expirationInMs?: number;
|
||||
@@ -42,13 +42,18 @@ export class LevelCache extends AbstractCache {
|
||||
|
||||
constructor(optionsArg: ILevelCacheConstructorOptions) {
|
||||
super();
|
||||
this.options = optionsArg;
|
||||
this.options = {
|
||||
maxMemoryStorageInMB: 0.5,
|
||||
maxDiskStorageInMB: 10,
|
||||
maxS3StorageInMB: 50,
|
||||
...optionsArg,
|
||||
};
|
||||
this.init();
|
||||
}
|
||||
|
||||
public async init() {
|
||||
this.cacheDiskManager = new CacheDiskManager(this);
|
||||
this.cacheMemoryManager = new CacheMemoryManager(this);
|
||||
this.cacheDiskManager = new CacheDiskManager(this);
|
||||
this.cacheS3Manager = new CacheS3Manager(this);
|
||||
await Promise.all([
|
||||
this.cacheDiskManager.ready,
|
||||
@@ -59,9 +64,16 @@ export class LevelCache extends AbstractCache {
|
||||
}
|
||||
|
||||
// store things
|
||||
public async storeCacheEntryByKey(keyArg: string, cacheEntryArg: CacheEntry): Promise<void> {
|
||||
public async storeCacheEntryByKey(
|
||||
keyArg: string,
|
||||
cacheEntryArg: CacheEntry,
|
||||
): Promise<void> {
|
||||
cacheEntryArg.key = keyArg;
|
||||
const targetCache = await this.cacheRouter.getCacheForStoreAction(keyArg, cacheEntryArg);
|
||||
const targetCache = await this.cacheRouter.getCacheForStoreAction(
|
||||
keyArg,
|
||||
cacheEntryArg,
|
||||
);
|
||||
cacheEntryArg.createdAt = Date.now();
|
||||
await targetCache.storeCacheEntryByKey(keyArg, cacheEntryArg);
|
||||
}
|
||||
|
||||
@@ -70,33 +82,47 @@ export class LevelCache extends AbstractCache {
|
||||
* retrieve cache entry
|
||||
*/
|
||||
public async retrieveCacheEntryByKey(keyArg: string): Promise<CacheEntry> {
|
||||
const targetCache = await this.cacheRouter.getCacheForRetrieveAction(keyArg);
|
||||
const targetCache =
|
||||
await this.cacheRouter.getCacheForRetrieveAction(keyArg);
|
||||
if (targetCache) {
|
||||
const cacheEntry = await targetCache.retrieveCacheEntryByKey(keyArg);
|
||||
if (cacheEntry.createdAt + cacheEntry.ttl < Date.now()) {
|
||||
await this.deleteCacheEntryByKey(keyArg).catch();
|
||||
return null;
|
||||
}
|
||||
return cacheEntry;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async checkKeyPresence(keyArg: string): Promise<boolean> {
|
||||
return plugins.smartpromise.getFirstTrueOrFalse([
|
||||
this.cacheMemoryManager.checkKeyPresence(keyArg),
|
||||
this.cacheDiskManager.checkKeyPresence(keyArg),
|
||||
this.cacheS3Manager.checkKeyPresence(keyArg)
|
||||
this.cacheS3Manager.checkKeyPresence(keyArg),
|
||||
]);
|
||||
}
|
||||
|
||||
public async deleteCacheEntryByKey(keyArg) {
|
||||
await Promise.all([
|
||||
this.cacheMemoryManager.deleteCacheEntryByKey(keyArg),
|
||||
this.cacheDiskManager.deleteCacheEntryByKey(keyArg),
|
||||
this.cacheS3Manager.deleteCacheEntryByKey(keyArg),
|
||||
]);
|
||||
}
|
||||
|
||||
// cache maintenance
|
||||
public async cleanOutdated() {}
|
||||
|
||||
/**
|
||||
* cleans the cache
|
||||
* cleans the complete cache
|
||||
*/
|
||||
public async clean(): Promise<void> {
|
||||
public async cleanAll(): Promise<void> {
|
||||
await Promise.all([
|
||||
this.cacheDiskManager.clean(),
|
||||
this.cacheDiskManager.clean(),
|
||||
this.cacheS3Manager.clean(),
|
||||
this.cacheDiskManager.cleanAll(),
|
||||
this.cacheDiskManager.cleanAll(),
|
||||
this.cacheS3Manager.cleanAll(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,7 @@
|
||||
import * as plugins from './levelcache.plugins';
|
||||
import * as plugins from './levelcache.plugins.js';
|
||||
|
||||
export const packageDir = plugins.path.join(__dirname, '../');
|
||||
export const packageDir = plugins.path.join(
|
||||
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
||||
'../',
|
||||
);
|
||||
export const nogitDir = plugins.path.join(packageDir, '.nogit/');
|
||||
|
@@ -3,16 +3,17 @@ import * as path from 'path';
|
||||
|
||||
export { path };
|
||||
|
||||
// @pushrocks scope
|
||||
import * as lik from '@pushrocks/lik';
|
||||
import * as smartbucket from '@pushrocks/smartbucket';
|
||||
import * as smartcache from '@pushrocks/smartcache';
|
||||
import * as smartfile from '@pushrocks/smartfile';
|
||||
import * as smartjson from '@pushrocks/smartjson';
|
||||
import * as smartpromise from '@pushrocks/smartpromise';
|
||||
import * as smartstring from '@pushrocks/smartstring';
|
||||
import * as smartunique from '@pushrocks/smartunique';
|
||||
import * as taskbuffer from '@pushrocks/taskbuffer';
|
||||
// @push.rocks scope
|
||||
import * as lik from '@push.rocks/lik';
|
||||
import * as smartbucket from '@push.rocks/smartbucket';
|
||||
import * as smartcache from '@push.rocks/smartcache';
|
||||
import * as smartfile from '@push.rocks/smartfile';
|
||||
import * as smartjson from '@push.rocks/smartjson';
|
||||
import * as smartpath from '@push.rocks/smartpath';
|
||||
import * as smartpromise from '@push.rocks/smartpromise';
|
||||
import * as smartstring from '@push.rocks/smartstring';
|
||||
import * as smartunique from '@push.rocks/smartunique';
|
||||
import * as taskbuffer from '@push.rocks/taskbuffer';
|
||||
|
||||
export {
|
||||
lik,
|
||||
@@ -20,8 +21,14 @@ export {
|
||||
smartcache,
|
||||
smartfile,
|
||||
smartjson,
|
||||
smartpath,
|
||||
smartpromise,
|
||||
smartstring,
|
||||
smartunique,
|
||||
taskbuffer,
|
||||
};
|
||||
|
||||
// @tsclass scope
|
||||
import * as tsclass from '@tsclass/tsclass';
|
||||
|
||||
export { tsclass };
|
||||
|
@@ -1,7 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"target": "es2017",
|
||||
"module": "commonjs"
|
||||
}
|
||||
}
|
||||
"useDefineForClassFields": false,
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {}
|
||||
},
|
||||
"exclude": ["dist_*/**/*.d.ts"]
|
||||
}
|
||||
|
17
tslint.json
17
tslint.json
@@ -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"
|
||||
}
|
Reference in New Issue
Block a user