diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 9c3c2b2..05e54fd 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -4,7 +4,6 @@ about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
-
---
**Describe the bug**
@@ -12,6 +11,7 @@ A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
+
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
@@ -23,16 +23,18 @@ A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
-**Desktop (please complete the following information):**
- - OS: [e.g. iOS]
- - Browser [e.g. chrome, safari]
- - Version [e.g. 22]
+**Desktop (please complete the following information):**
+
+- OS: [e.g. iOS]
+- Browser [e.g. chrome, safari]
+- Version [e.g. 22]
+
+**Smartphone (please complete the following information):**
-**Smartphone (please complete the following information):**
- - Device: [e.g. iPhone6]
- - OS: [e.g. iOS8.1]
- - Browser [e.g. stock browser, safari]
- - Version [e.g. 22]
+- Device: [e.g. iPhone6]
+- OS: [e.g. iOS8.1]
+- Browser [e.g. stock browser, safari]
+- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md
index 48d5f81..96a4735 100644
--- a/.github/ISSUE_TEMPLATE/custom.md
+++ b/.github/ISSUE_TEMPLATE/custom.md
@@ -4,7 +4,4 @@ about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''
-
---
-
-
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index efeb419..1434383 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -4,10 +4,10 @@ about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
-
---
**Have you contributed with at least a little donation to support the development of this project?**
+
- Paypal: https://www.paypal.me/kyberneees
**Is your feature request related to a problem? Please describe.**
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index e3ec3b0..6a51e45 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -7,14 +7,14 @@ jobs:
redis:
image: redis
ports:
- - 6379:6379
+ - 6379:6379
options: --entrypoint redis-server
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v4
- name: Setup Environment (Bun latest)
- uses: oven-sh/setup-bun@v1
+ uses: oven-sh/setup-bun@v2
with:
bun-version: latest
@@ -26,4 +26,3 @@ jobs:
- name: Run tests
run: bun run test
-
\ No newline at end of file
diff --git a/README.md b/README.md
index bc06bb7..322d7c9 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,18 @@
# Introduction
+
[](https://www.npmjs.com/package/item-store-redis)
[](https://www.npmjs.com/package/item-store-redis)
[](https://www.npmjs.com/package/item-store-redis)
[](https://www.npmjs.com/package/item-store-redis)
[](https://github.com/BackendStack21/item-store-redis.git)
-
+
> Explanatory article: https://medium.com/@kyberneees/introducing-item-store-redis-a-high-performance-redis-based-item-store-for-efficient-data-4510d4e9fcf9
This module provides classes that implement repositories for storing and retrieving data in a Redis database:
-- `ItemRepository`: The class provides basic functionality for storing and retrieving individual items, as well as querying all items or a subset of items in a paginated manner. The items are stored in Redis using a key-value data model with expiration support.
+- `ItemRepository`: The class provides basic functionality for storing and retrieving individual items, as well as querying all items or a subset of items in a paginated manner. The items are stored in Redis using a key-value data model with expiration support.
- `SortedItemRepository`: The class provides a more advanced functionality for storing and retrieving items in a sorted manner. The items are sorted based on a numeric score, and can be queried in a paginated manner as well. The items are stored in Redis using a sorted set data model, making it more performant and efficient at scale (see `demos/benchmark.ts`). Per-item expiration is not supported, but size and age based retention is available through `maxItems`, `trimToSize` and `deleteByScore`.
```ts
@@ -21,6 +22,7 @@ import { ItemRepository, SortedItemRepository, IItem } from 'item-store-redis'
## Class ItemRepository
### Constructor
+
```ts
constructor (name: string, redis?: Redis | Cluster, options?: IRepositoryOptions)
@@ -30,6 +32,7 @@ interface IRepositoryOptions {
```
### Usage
+
```ts
import { ItemRepository, IItem } from 'item-store-redis'
import Redis from 'ioredis'
@@ -38,7 +41,10 @@ const redis = new Redis({ host: 'localhost', port: 6379 })
const repository = new ItemRepository('my-unsorted-repo', redis)
await repository.set({ id: 'a', data }, 60) // expires in 60 seconds
-await repository.setMany([{ id: 'b', data }, { id: 'c', data }])
+await repository.setMany([
+ { id: 'b', data },
+ { id: 'c', data }
+])
const [a, missing] = await repository.getByIds(['a', 'missing']) // missing === null
for await (const item of repository.iterate({ batchSize: 500 })) {
@@ -47,6 +53,7 @@ for await (const item of repository.iterate({ batchSize: 500 })) {
```
### Interface
+
```ts
interface IItemRepository {
name: string
@@ -74,6 +81,7 @@ Keys are discovered with `SCAN` (never `KEYS`), on every master node when using
## Class SortedItemRepository
### Constructor
+
```ts
constructor (name: string, redis?: Redis | Cluster, options?: ISortedRepositoryOptions)
@@ -85,6 +93,7 @@ interface ISortedRepositoryOptions {
```
### Usage
+
```ts
import { SortedItemRepository, IItem } from 'item-store-redis'
import Redis from 'ioredis'
@@ -102,6 +111,7 @@ await repository.deleteByScore('-inf', (Date.now() - 86_400_000) * 1000) // rete
```
### Interface
+
```ts
interface ISortedItemRepository {
name: string
@@ -142,12 +152,15 @@ interface IScoreRangeOptions {
See `libs/model.ts` for the documented interfaces.
## Validation
+
Pages start at `1`; `page`, `pageSize`, expirations and `n` arguments must be integers in range, otherwise a `RangeError` is thrown (previously, values like `pageSize = 0` or `n = 0` silently selected the whole repository). Item ids must be non-empty strings.
## Redis Cluster
+
Both repositories support `Cluster` connections. `SortedItemRepository` stores its index and data under two keys. On standalone Redis, writes and deletes touching both keys run as a `MULTI` transaction. On Redis Cluster those keys live in different slots, so the commands run in a safe order instead (data before index on writes, index before data on deletes) and readers never observe indexed items without data. Set `hashTag: true` to keep both keys in the same slot and get atomic transactions on Cluster as well. Note that this changes the key layout (`items:{name}:`), so existing data stored without the option is not visible with it.
## Custom serialization
+
```ts
const repository = new ItemRepository('json-repo', redis, {
serializer: {
@@ -157,7 +170,6 @@ const repository = new ItemRepository('json-repo', redis, {
})
```
-
# License
```
@@ -183,4 +195,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-```
\ No newline at end of file
+```
diff --git a/bun.lock b/bun.lock
index 7b45414..5fd22c3 100644
--- a/bun.lock
+++ b/bun.lock
@@ -5,73 +5,94 @@
"": {
"name": "item-store-redis",
"dependencies": {
- "@msgpack/msgpack": "^2.8.0",
- "ioredis": "^5.3.1",
+ "@msgpack/msgpack": "^3.1.3",
+ "ioredis": "^6.0.0",
},
"devDependencies": {
- "@types/msgpack-lite": "^0.1.8",
- "bun-types": "^0.5.6",
- "msgpack-lite": "^0.1.26",
- "rome": "^11.0.0",
- "typescript": "^4.9.5",
+ "@types/msgpack-lite": "^0.1.12",
+ "bun-types": "^1.4.4",
+ "msgpack-lite": "^0.2.2",
+ "typescript": "^7.0.2",
},
},
},
"packages": {
- "@ioredis/commands": ["@ioredis/commands@1.2.0", "", {}, ""],
+ "@ioredis/commands": ["@ioredis/commands@2.0.0", "", {}, "sha512-vrx0AE/T0h7cRZwfo1M39Cr+ZhZrkf0V8mQN75wucKCxCLD9l/VX6no3gFvrLqD1IlG/1LtzWovqEw3t0Vr9zg=="],
- "@msgpack/msgpack": ["@msgpack/msgpack@2.8.0", "", {}, ""],
+ "@msgpack/msgpack": ["@msgpack/msgpack@3.1.3", "", {}, "sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA=="],
- "@rometools/cli-darwin-arm64": ["@rometools/cli-darwin-arm64@11.0.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-F3vkdY+s3FLIEnAjSbyHTuIPB88cLpccimW4ecid5I7S6GzGG3iUJI4xT00JhH73K4P/qW20/9r+kH1T9Du8Xg=="],
+ "@types/msgpack-lite": ["@types/msgpack-lite@0.1.12", "", { "dependencies": { "@types/node": "*" } }, "sha512-DzYHfFOxK1UCm3pErFyGCQzsNYjcy1chCtO5bLdvL0IbD6L0l0IZzYMHvFAmEDLJ+k6XJosY0WKKmjkOBu9gKQ=="],
- "@rometools/cli-darwin-x64": ["@rometools/cli-darwin-x64@11.0.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-X6jhtS6Iml4GOzgNtnLwIp/KXXhSdqeVyfv69m/AHnIzx3gQAjPZ7BPnJLvTCbhe4SKHL+uTZYFSCJpkUUKE6w=="],
+ "@types/node": ["@types/node@18.15.0", "", {}, ""],
- "@rometools/cli-linux-arm64": ["@rometools/cli-linux-arm64@11.0.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-dktTJJlTpmycBZ2TwhJBcAO8ztK8DdevdyZnFFxdYRvtmJgTjIsC2UFayf/SbKew8B8q1IhI0it+D6ihAeIpeg=="],
+ "@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ=="],
- "@rometools/cli-linux-x64": ["@rometools/cli-linux-x64@11.0.0", "", { "os": "linux", "cpu": "x64" }, "sha512-WVcnXPNdWGUWo0p4NU8YzuthjYR7q+b4vRcjdxtP1DlpphZmSsoC/RSE85nEqRAz8hChcKUansVzOPM8BSsuGA=="],
+ "@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA=="],
- "@rometools/cli-win32-arm64": ["@rometools/cli-win32-arm64@11.0.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-tPj6RThQzS7Q45jqQll7NlTYvNcsg/BEP3LYiiazqSh9FAFnMkrV6ewUcMPKWyAfiyLs7jlz4rRvdNRUSygzfQ=="],
+ "@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA=="],
- "@rometools/cli-win32-x64": ["@rometools/cli-win32-x64@11.0.0", "", { "os": "win32", "cpu": "x64" }, "sha512-bmBai8WHxYjsGk1+je7ZTfCUCWq30WJI3pQM8pzTA674lfGTZ9ymJoZwTaIMSO4rL5V9mlO6uLunsBKso9VqOg=="],
+ "@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ=="],
- "@types/msgpack-lite": ["@types/msgpack-lite@0.1.8", "", { "dependencies": { "@types/node": "*" } }, ""],
+ "@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw=="],
- "@types/node": ["@types/node@18.15.0", "", {}, ""],
+ "@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ=="],
- "bun-types": ["bun-types@0.5.6", "", {}, ""],
+ "@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ=="],
- "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, ""],
+ "@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ=="],
- "debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, ""],
+ "@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA=="],
- "denque": ["denque@2.1.0", "", {}, ""],
+ "@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA=="],
- "event-lite": ["event-lite@0.1.3", "", {}, ""],
+ "@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ=="],
- "ieee754": ["ieee754@1.2.1", "", {}, ""],
+ "@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw=="],
- "int64-buffer": ["int64-buffer@0.1.10", "", {}, ""],
+ "@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A=="],
- "ioredis": ["ioredis@5.3.1", "", { "dependencies": { "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, ""],
+ "@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA=="],
- "isarray": ["isarray@1.0.0", "", {}, ""],
+ "@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.2", "", { "os": "none", "cpu": "x64" }, "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA=="],
- "lodash.defaults": ["lodash.defaults@4.2.0", "", {}, ""],
+ "@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ=="],
- "lodash.isarguments": ["lodash.isarguments@3.1.0", "", {}, ""],
+ "@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg=="],
- "ms": ["ms@2.1.2", "", {}, ""],
+ "@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g=="],
- "msgpack-lite": ["msgpack-lite@0.1.26", "", { "dependencies": { "event-lite": "^0.1.1", "ieee754": "^1.1.8", "int64-buffer": "^0.1.9", "isarray": "^1.0.0" }, "bin": { "msgpack": "bin/msgpack" } }, ""],
+ "@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ=="],
- "redis-errors": ["redis-errors@1.2.0", "", {}, ""],
+ "@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g=="],
- "redis-parser": ["redis-parser@3.0.0", "", { "dependencies": { "redis-errors": "^1.0.0" } }, ""],
+ "bun-types": ["bun-types@1.4.4", "", { "dependencies": { "@types/node": "*", "undici-types": "*" } }, "sha512-yjrJh5oGX7mMPKGd19YXyIjmEuj4G4zNC30bs7PM9Az7NQ3ndF3j6hbeRdvJTRQEhJ/FYQwW0a2moweEi2hMxQ=="],
- "rome": ["rome@11.0.0", "", { "optionalDependencies": { "@rometools/cli-darwin-arm64": "11.0.0", "@rometools/cli-darwin-x64": "11.0.0", "@rometools/cli-linux-arm64": "11.0.0", "@rometools/cli-linux-x64": "11.0.0", "@rometools/cli-win32-arm64": "11.0.0", "@rometools/cli-win32-x64": "11.0.0" }, "bin": { "rome": "bin/rome" } }, "sha512-rRo6JOwpMLc3OkeTDRXkrmrDqnxDvZ75GS4f0jLDBNmRgDXWbu0F8eVnJoRn+VbK2AE7vWvhVOMBjnWowcopkQ=="],
+ "cluster-key-slot": ["cluster-key-slot@1.1.1", "", {}, "sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw=="],
+
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "denque": ["denque@2.1.0", "", {}, ""],
+
+ "event-lite": ["event-lite@1.0.1", "", {}, "sha512-h8y5birRx5g/R2scKNnkJ0HX1sJi2hwIH5t/vt+1hWDF+kaGODTYjXMTi3+0ApcNjr/xGbS2DduC8LQ7vnSV1Q=="],
+
+ "ieee754": ["ieee754@1.2.1", "", {}, ""],
+
+ "int64-buffer": ["int64-buffer@1.1.2", "", {}, "sha512-ZBb2qDtapL5lWiwgXIoNaCRb/OBPrQ6bK6J4p1AcPXzH/JA/eZmoTVCGGCOIQWIsWwOExGsPu5n8+aBG6itMzA=="],
+
+ "ioredis": ["ioredis@6.0.0", "", { "dependencies": { "@ioredis/commands": "2.0.0", "cluster-key-slot": "1.1.1", "debug": "4.4.3", "denque": "2.1.0", "redis-errors": "1.2.0", "standard-as-callback": "2.1.0" } }, "sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w=="],
+
+ "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
+
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+
+ "msgpack-lite": ["msgpack-lite@0.2.2", "", { "dependencies": { "event-lite": "^1.0.0", "ieee754": "^1.2.1", "int64-buffer": "^1.1.1", "isarray": "^2.0.5" }, "bin": { "msgpack": "bin/msgpack" } }, "sha512-FX9cfvURw4ehu3Dnsp9HJpA1uMUCFtSZruFgHUPrRszlok3tbObwm+zLEXdZ8TwbWwtVLqxLaYAVDhKzp2iCjQ=="],
+
+ "redis-errors": ["redis-errors@1.2.0", "", {}, ""],
"standard-as-callback": ["standard-as-callback@2.1.0", "", {}, ""],
- "typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, ""],
+ "typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="],
+
+ "undici-types": ["undici-types@8.12.3", "", {}, "sha512-EXE4ydL3S76dFb27UFjNVZHTyv/TLdATj/KUe29ptdcg6qXL48J2tZ3126E5kICj5jn781OR+XlVH1N6Mz8jbA=="],
}
}
diff --git a/bunfig.toml b/bunfig.toml
new file mode 100644
index 0000000..210694a
--- /dev/null
+++ b/bunfig.toml
@@ -0,0 +1,5 @@
+[fmt]
+printWidth = 120
+semi = false
+singleQuote = true
+trailingComma = "none"
diff --git a/libs/sorted-repository.ts b/libs/sorted-repository.ts
index f5ae924..227808e 100644
--- a/libs/sorted-repository.ts
+++ b/libs/sorted-repository.ts
@@ -92,7 +92,7 @@ export class SortedItemRepository implements ISortedItemRepository {
}
async getAll(): Promise[]> {
- const ids = await this.redis.zrange(this.keyPrefix, 0, -1)
+ const ids = await this.redis.zrange(this.keyPrefix, 0, '-1')
return this.fetch(ids)
}
@@ -127,7 +127,7 @@ export class SortedItemRepository implements ISortedItemRepository {
if (order === 'desc') {
tx.zrevrange(this.keyPrefix, start, end)
} else {
- tx.zrange(this.keyPrefix, start, end)
+ tx.zrange(this.keyPrefix, start, String(end))
}
const [count, ids] = (await this.exec(tx)) as [number, string[]]
@@ -146,7 +146,7 @@ export class SortedItemRepository implements ISortedItemRepository {
const ids =
order === 'desc'
? await this.redis.zrevrange(this.keyPrefix, start, end)
- : await this.redis.zrange(this.keyPrefix, start, end)
+ : await this.redis.zrange(this.keyPrefix, start, String(end))
for (const item of await this.fetch(ids)) {
yield item
}
@@ -156,7 +156,7 @@ export class SortedItemRepository implements ISortedItemRepository {
async deletePage(page: number, pageSize: number): Promise {
const [start, end] = pageBounds(page, pageSize)
- const ids = await this.redis.zrange(this.keyPrefix, start, end)
+ const ids = await this.redis.zrange(this.keyPrefix, start, String(end))
await this.deleteByIds(ids)
}
@@ -188,7 +188,7 @@ export class SortedItemRepository implements ISortedItemRepository {
async trimToSize(maxItems: number): Promise {
assertNonNegativeInteger(maxItems, 'maxItems')
- const ids = await this.redis.zrange(this.keyPrefix, 0, -(maxItems + 1))
+ const ids = await this.redis.zrange(this.keyPrefix, 0, String(-(maxItems + 1)))
return this.deleteByIds(ids)
}
@@ -209,7 +209,7 @@ export class SortedItemRepository implements ISortedItemRepository {
async getFirstNItems(n: number): Promise[]> {
assertNonNegativeInteger(n, 'n')
if (n === 0) return []
- const ids = await this.redis.zrange(this.keyPrefix, 0, n - 1)
+ const ids = await this.redis.zrange(this.keyPrefix, 0, String(n - 1))
return this.fetch(ids)
}
@@ -225,7 +225,7 @@ export class SortedItemRepository implements ISortedItemRepository {
async getItemsInRange(start: number, end: number): Promise[]> {
assertInteger(start, 'start')
assertInteger(end, 'end')
- const ids = await this.redis.zrange(this.keyPrefix, start, end)
+ const ids = await this.redis.zrange(this.keyPrefix, start, String(end))
return this.fetch(ids)
}
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index f4747d9..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,227 +0,0 @@
-{
- "name": "item-store-redis",
- "version": "0.4.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "item-store-redis",
- "version": "0.4.0",
- "license": "MIT",
- "dependencies": {
- "@msgpack/msgpack": "^2.8.0",
- "ioredis": "^5.3.1"
- },
- "devDependencies": {
- "@types/msgpack-lite": "^0.1.8",
- "bun-types": "^0.5.6",
- "msgpack-lite": "^0.1.26",
- "rome": "^11.0.0",
- "typescript": "^4.9.5"
- }
- },
- "node_modules/@ioredis/commands": {
- "version": "1.2.0",
- "license": "MIT"
- },
- "node_modules/@msgpack/msgpack": {
- "version": "2.8.0",
- "license": "ISC",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@rometools/cli-darwin-arm64": {
- "version": "11.0.0",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@types/msgpack-lite": {
- "version": "0.1.8",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/node": {
- "version": "18.15.0",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/bun-types": {
- "version": "0.5.6",
- "dev": true
- },
- "node_modules/cluster-key-slot": {
- "version": "1.1.2",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/debug": {
- "version": "4.3.4",
- "license": "MIT",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/denque": {
- "version": "2.1.0",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/event-lite": {
- "version": "0.1.3",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/ieee754": {
- "version": "1.2.1",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/int64-buffer": {
- "version": "0.1.10",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/ioredis": {
- "version": "5.3.1",
- "license": "MIT",
- "dependencies": {
- "@ioredis/commands": "^1.1.1",
- "cluster-key-slot": "^1.1.0",
- "debug": "^4.3.4",
- "denque": "^2.1.0",
- "lodash.defaults": "^4.2.0",
- "lodash.isarguments": "^3.1.0",
- "redis-errors": "^1.2.0",
- "redis-parser": "^3.0.0",
- "standard-as-callback": "^2.1.0"
- },
- "engines": {
- "node": ">=12.22.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/ioredis"
- }
- },
- "node_modules/isarray": {
- "version": "1.0.0",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.defaults": {
- "version": "4.2.0",
- "license": "MIT"
- },
- "node_modules/lodash.isarguments": {
- "version": "3.1.0",
- "license": "MIT"
- },
- "node_modules/ms": {
- "version": "2.1.2",
- "license": "MIT"
- },
- "node_modules/msgpack-lite": {
- "version": "0.1.26",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "event-lite": "^0.1.1",
- "ieee754": "^1.1.8",
- "int64-buffer": "^0.1.9",
- "isarray": "^1.0.0"
- },
- "bin": {
- "msgpack": "bin/msgpack"
- }
- },
- "node_modules/redis-errors": {
- "version": "1.2.0",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/redis-parser": {
- "version": "3.0.0",
- "license": "MIT",
- "dependencies": {
- "redis-errors": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/rome": {
- "version": "11.0.0",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "rome": "bin/rome"
- },
- "engines": {
- "node": ">=14.*"
- },
- "optionalDependencies": {
- "@rometools/cli-darwin-arm64": "11.0.0",
- "@rometools/cli-darwin-x64": "11.0.0",
- "@rometools/cli-linux-arm64": "11.0.0",
- "@rometools/cli-linux-x64": "11.0.0",
- "@rometools/cli-win32-arm64": "11.0.0",
- "@rometools/cli-win32-x64": "11.0.0"
- }
- },
- "node_modules/standard-as-callback": {
- "version": "2.1.0",
- "license": "MIT"
- },
- "node_modules/typescript": {
- "version": "4.9.5",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- }
- }
-}
diff --git a/package.json b/package.json
index a2af7d8..d961679 100644
--- a/package.json
+++ b/package.json
@@ -2,13 +2,14 @@
"name": "item-store-redis",
"version": "0.4.0",
"description": "This module provides classes that implement repositories for storing and retrieving data in a Redis database",
- "main": "dist/libs/index.js",
- "types": "dist/libs/index.d.ts",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
"scripts": {
- "build": "rm -rf dist/ && tsc",
- "lint": "bun x rome ci .",
- "format": "bun x rome format . --write",
- "test": "bun test test/*.test.ts"
+ "build": "rm -rf dist/ && bun build libs/index.ts --outdir dist --target node --format cjs --packages external && tsc -p tsconfig.build.json",
+ "lint": "bun check && bun fmt --check",
+ "format": "bun fmt",
+ "test": "bun test test/*.test.ts",
+ "prepublishOnly": "bun run lint && bun run build"
},
"repository": {
"type": "git",
@@ -18,7 +19,7 @@
"LICENSE",
"README.md",
"libs/",
- "dist/libs"
+ "dist/"
],
"keywords": [
"redis",
@@ -34,19 +35,13 @@
},
"homepage": "https://github.com/BackendStack21/item-store-redis#readme",
"dependencies": {
- "@msgpack/msgpack": "^2.8.0",
- "ioredis": "^5.3.1"
+ "@msgpack/msgpack": "^3.1.3",
+ "ioredis": "^6.0.0"
},
"devDependencies": {
- "msgpack-lite": "^0.1.26",
- "@types/msgpack-lite": "^0.1.8",
- "bun-types": "^0.5.6",
- "rome": "^11.0.0",
- "typescript": "^4.9.5"
- },
- "ts-standard": {
- "ignore": [
- "dist"
- ]
+ "@types/msgpack-lite": "^0.1.12",
+ "bun-types": "^1.4.4",
+ "msgpack-lite": "^0.2.2",
+ "typescript": "^7.0.2"
}
}
diff --git a/rome.json b/rome.json
deleted file mode 100644
index 69a5776..0000000
--- a/rome.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "formatter": {
- "enabled": true,
- "indentStyle": "space",
- "indentSize": 2,
- "lineWidth": 120,
- "ignore": [
- "dist"
- ]
- },
- "javascript": {
- "formatter": {
- "semicolons": "asNeeded",
- "quoteStyle": "single",
- "trailingComma": "none"
- }
- },
- "linter": {
- "enabled": true,
- "ignore": [
- "dist"
- ]
- }
-}
\ No newline at end of file
diff --git a/tsconfig.build.json b/tsconfig.build.json
new file mode 100644
index 0000000..58845e3
--- /dev/null
+++ b/tsconfig.build.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "noEmit": false,
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "rootDir": "libs",
+ "outDir": "dist"
+ },
+ "include": ["libs"]
+}
diff --git a/tsconfig.json b/tsconfig.json
index 12878b3..771e597 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,104 +1,14 @@
{
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
-
- /* Modules */
- "module": "CommonJS", /* Specify what module code is generated. */
- // "rootDir": "./", /* Specify the root folder within your source files. */
- "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- "types": ["bun-types"], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- // "resolveJsonModule": true, /* Enable importing .json files. */
- // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
- /* Emit */
- "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- // "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- "outDir": "./dist", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ "target": "ES2022",
+ "module": "Preserve",
+ "moduleResolution": "bundler",
+ "types": ["bun-types"],
+ "strict": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "skipLibCheck": true,
+ "noEmit": true
},
- "include": ["./libs/*", "./test/*", "./demos/*"]
+ "include": ["libs", "test", "demos"]
}