@nestarc/feature-flag 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -7
- package/package.json +13 -6
- package/prisma/schema.prisma +3 -2
package/README.md
CHANGED
|
@@ -34,9 +34,13 @@ npm install @nestarc/feature-flag
|
|
|
34
34
|
### Peer dependencies
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
npm install @nestjs/common @nestjs/core @prisma/client class-transformer class-validator rxjs reflect-metadata
|
|
37
|
+
npm install @nestjs/common @nestjs/core @prisma/client @prisma/adapter-pg pg class-transformer class-validator rxjs reflect-metadata
|
|
38
|
+
npm install --save-dev prisma
|
|
38
39
|
```
|
|
39
40
|
|
|
41
|
+
Prisma 7 requires Node.js 20.19+, 22.12+, or 24+. This package follows the
|
|
42
|
+
same runtime requirement.
|
|
43
|
+
|
|
40
44
|
### Optional
|
|
41
45
|
|
|
42
46
|
```bash
|
|
@@ -76,6 +80,45 @@ When a flag is updated on any instance, all other instances are notified via Pub
|
|
|
76
80
|
|
|
77
81
|
## Prisma Schema
|
|
78
82
|
|
|
83
|
+
Prisma 7 keeps connection URLs in `prisma.config.ts` and requires a database
|
|
84
|
+
driver adapter at runtime. A minimal PostgreSQL setup is:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
// prisma.config.ts
|
|
88
|
+
import 'dotenv/config';
|
|
89
|
+
import { defineConfig, env } from 'prisma/config';
|
|
90
|
+
|
|
91
|
+
export default defineConfig({
|
|
92
|
+
schema: 'prisma/schema.prisma',
|
|
93
|
+
migrations: { path: 'prisma/migrations' },
|
|
94
|
+
datasource: { url: env('DATABASE_URL') },
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```prisma
|
|
99
|
+
generator client {
|
|
100
|
+
provider = "prisma-client"
|
|
101
|
+
output = "../src/generated/prisma"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
datasource db {
|
|
105
|
+
provider = "postgresql"
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Create the client with `@prisma/adapter-pg`, then pass that instance to
|
|
110
|
+
`FeatureFlagModule`:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { PrismaPg } from '@prisma/adapter-pg';
|
|
114
|
+
import { PrismaClient } from './generated/prisma/client';
|
|
115
|
+
|
|
116
|
+
const adapter = new PrismaPg({
|
|
117
|
+
connectionString: process.env.DATABASE_URL,
|
|
118
|
+
});
|
|
119
|
+
const prisma = new PrismaClient({ adapter });
|
|
120
|
+
```
|
|
121
|
+
|
|
79
122
|
Add the following models to your `schema.prisma`:
|
|
80
123
|
|
|
81
124
|
```prisma
|
|
@@ -764,16 +807,16 @@ export class AppModule {}
|
|
|
764
807
|
|
|
765
808
|
## Performance
|
|
766
809
|
|
|
767
|
-
Measured with PostgreSQL 16, Prisma
|
|
810
|
+
Measured with PostgreSQL 16, Prisma 7.9.1, 500 iterations on Apple Silicon:
|
|
768
811
|
|
|
769
812
|
| Scenario | Avg | P50 | P95 | P99 |
|
|
770
813
|
|----------|-----|-----|-----|-----|
|
|
771
|
-
| **isEnabled() — cache hit** | **0.04ms** | **0.
|
|
772
|
-
| isEnabled() — cache miss (DB lookup) | 1.
|
|
773
|
-
| isEnabled() — override cascade (cold) |
|
|
774
|
-
| **evaluateAll() — 50 flags (mixed)** | **0.19ms** | **0.04ms** | **1.
|
|
814
|
+
| **isEnabled() — cache hit** | **0.04ms** | **0.04ms** | **0.05ms** | **0.12ms** |
|
|
815
|
+
| isEnabled() — cache miss (DB lookup) | 1.17ms | 1.10ms | 1.62ms | 2.04ms |
|
|
816
|
+
| isEnabled() — override cascade (cold) | 0.95ms | 0.89ms | 1.36ms | 1.87ms |
|
|
817
|
+
| **evaluateAll() — 50 flags (mixed)** | **0.19ms** | **0.04ms** | **1.47ms** | **1.78ms** |
|
|
775
818
|
|
|
776
|
-
Cache speedup: **
|
|
819
|
+
Cache speedup: **29.2x** (hit vs miss). Keep the default 30s cache TTL for optimal performance.
|
|
777
820
|
|
|
778
821
|
> Reproduce: `docker compose up -d && dotenv -e .env.test -- npx ts-node benchmarks/evaluation-overhead.ts`
|
|
779
822
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestarc/feature-flag",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "DB-backed feature flags for NestJS + Prisma + PostgreSQL with tenant-aware overrides",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"build": "tsc -p tsconfig.build.json",
|
|
27
27
|
"test": "jest",
|
|
28
28
|
"test:cov": "jest --coverage",
|
|
29
|
+
"prebench": "npm run prisma:generate",
|
|
29
30
|
"bench": "dotenv -e .env.test -- npx ts-node benchmarks/evaluation-overhead.ts",
|
|
30
31
|
"lint": "eslint 'src/**/*.ts' 'test/**/*.ts'",
|
|
31
32
|
"format": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
"docker:down": "docker compose down",
|
|
35
36
|
"db:migrate": "dotenv -e .env.test -- npx prisma migrate deploy",
|
|
36
37
|
"db:reset": "dotenv -e .env.test -- npx prisma migrate reset --force",
|
|
37
|
-
"pretest:e2e": "npm run docker:up && npm run db:migrate",
|
|
38
|
+
"pretest:e2e": "npm run prisma:generate && npm run docker:up && npm run db:migrate",
|
|
38
39
|
"test:e2e": "dotenv -e .env.test -- jest --config jest.e2e.config.ts --runInBand"
|
|
39
40
|
},
|
|
40
41
|
"repository": {
|
|
@@ -56,11 +57,14 @@
|
|
|
56
57
|
],
|
|
57
58
|
"author": "nestarc",
|
|
58
59
|
"license": "MIT",
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
62
|
+
},
|
|
59
63
|
"peerDependencies": {
|
|
60
64
|
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
|
61
65
|
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
|
62
66
|
"@openfeature/server-sdk": "^1.0.0",
|
|
63
|
-
"@prisma/client": "^
|
|
67
|
+
"@prisma/client": "^7.0.0",
|
|
64
68
|
"class-transformer": "^0.5.1",
|
|
65
69
|
"class-validator": "^0.14.0 || ^0.15.0",
|
|
66
70
|
"ioredis": "^5.0.0",
|
|
@@ -92,20 +96,23 @@
|
|
|
92
96
|
"@nestjs/event-emitter": "^3.0.0",
|
|
93
97
|
"@nestjs/platform-express": "^11.0.0",
|
|
94
98
|
"@nestjs/testing": "^11.0.0",
|
|
95
|
-
"@prisma/
|
|
99
|
+
"@prisma/adapter-pg": "^7.9.1",
|
|
100
|
+
"@prisma/client": "^7.9.1",
|
|
96
101
|
"@types/express": "^5.0.0",
|
|
97
102
|
"@types/ioredis-mock": "^8.2.7",
|
|
98
103
|
"@types/jest": "^29.5.0",
|
|
99
104
|
"@types/supertest": "^7.2.0",
|
|
100
105
|
"class-transformer": "^0.5.1",
|
|
101
106
|
"class-validator": "^0.15.1",
|
|
107
|
+
"dotenv": "^17.2.3",
|
|
102
108
|
"dotenv-cli": "^11.0.0",
|
|
103
109
|
"eslint": "^9.0.0",
|
|
104
|
-
"ioredis": "^5.
|
|
110
|
+
"ioredis": "^5.11.1",
|
|
105
111
|
"ioredis-mock": "^8.13.1",
|
|
106
112
|
"jest": "^29.7.0",
|
|
113
|
+
"pg": "^8.22.0",
|
|
107
114
|
"prettier": "^3.0.0",
|
|
108
|
-
"prisma": "^
|
|
115
|
+
"prisma": "^7.9.1",
|
|
109
116
|
"reflect-metadata": "^0.2.0",
|
|
110
117
|
"rxjs": "^7.8.0",
|
|
111
118
|
"supertest": "^7.2.2",
|
package/prisma/schema.prisma
CHANGED