From 22fa5fd091ac9160929640b265761393607dad2c Mon Sep 17 00:00:00 2001 From: Rolando Santamaria Maso Date: Sat, 24 Oct 2026 17:08:59 +0200 Subject: [PATCH] chore: switch to Bun fmt/check/build and update dependencies - Replace Rome with `bun fmt` (style preserved via bunfig.toml) - Replace tsc JS emit with `bun build`; tsc now only emits declarations - Type check with `bun check`; modernize tsconfig - Update all dependencies to latest (ioredis 6, @msgpack/msgpack 3, TypeScript 7) - Adapt zrange calls to ioredis 6 typings - Drop rome.json and package-lock.json; bump CI actions Co-Authored-By: Claude Opus 5.5 --- .github/ISSUE_TEMPLATE/bug_report.md | 22 ++- .github/ISSUE_TEMPLATE/custom.md | 3 - .github/ISSUE_TEMPLATE/feature_request.md | 2 +- .github/workflows/tests.yaml | 7 +- README.md | 22 ++- bun.lock | 89 +++++---- bunfig.toml | 5 + libs/sorted-repository.ts | 14 +- package-lock.json | 227 ---------------------- package.json | 33 ++-- rome.json | 24 --- tsconfig.build.json | 11 ++ tsconfig.json | 110 +---------- 13 files changed, 135 insertions(+), 434 deletions(-) create mode 100644 bunfig.toml delete mode 100644 package-lock.json delete mode 100644 rome.json create mode 100644 tsconfig.build.json 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 + [![NPM version](https://badgen.net/npm/v/item-store-redis)](https://www.npmjs.com/package/item-store-redis) [![NPM Total Downloads](https://badgen.net/npm/dt/item-store-redis)](https://www.npmjs.com/package/item-store-redis) [![License](https://badgen.net/npm/license/item-store-redis)](https://www.npmjs.com/package/item-store-redis) [![TypeScript support](https://badgen.net/npm/types/item-store-redis)](https://www.npmjs.com/package/item-store-redis) [![Github stars](https://badgen.net/github/stars/BackendStack21/item-store-redis?icon=github)](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"] }