@plyaz/core 1.0.3 → 1.0.4
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 +33 -21
- package/dist/base/cache/index.d.ts.map +1 -1
- package/dist/base/cache/strategies/redis.d.ts.map +1 -1
- package/dist/domain/featureFlags/provider.d.ts.map +1 -1
- package/dist/index.cjs +10 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +11 -21
- package/dist/index.mjs.map +1 -1
- package/dist/utils/common/hash.d.ts.map +1 -1
- package/dist/utils/common/values.d.ts.map +1 -1
- package/dist/utils/featureFlags/context.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
The `@plyaz/core` package serves as the orchestration layer that combines functionality from specialized packages to provide core business logic, domain models, and SDK foundations.
|
|
6
6
|
|
|
7
|
+
📚 **Full Documentation**:
|
|
8
|
+
- [Core Package Overview](https://plyaz.atlassian.net/wiki/spaces/SD/pages/37257227/Core+Package)
|
|
9
|
+
- [Feature Flag System](https://plyaz.atlassian.net/wiki/spaces/SD/pages/44859395)
|
|
10
|
+
- [Cache System](https://plyaz.atlassian.net/wiki/spaces/SD/pages/44892180)
|
|
11
|
+
|
|
7
12
|
## 🎯 Key Objectives
|
|
8
13
|
|
|
9
14
|
- **Business Logic Orchestration**: Centralize core business logic that coordinates between specialized packages
|
|
@@ -52,27 +57,34 @@ import { createLogger } from '@plyaz/logger';
|
|
|
52
57
|
│ └── contracts/ # External service contracts
|
|
53
58
|
```
|
|
54
59
|
|
|
55
|
-
## 🚀 Currently
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
- **
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- **
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
- **
|
|
60
|
+
## 🚀 Currently Implemented Features
|
|
61
|
+
|
|
62
|
+
> **Note**: The @plyaz/core package currently has two main features implemented. Additional providers and backend integrations are in development.
|
|
63
|
+
|
|
64
|
+
### ✅ Feature Flag System (Most Complete)
|
|
65
|
+
- **Implemented Providers**:
|
|
66
|
+
- ✅ Memory Provider - Fully functional with FEATURES constant
|
|
67
|
+
- ✅ File Provider - JSON/YAML support with hot reload capability
|
|
68
|
+
- ⏳ Redis Provider - Stub only (pending implementation)
|
|
69
|
+
- ⏳ API Provider - Stub only (pending implementation)
|
|
70
|
+
- ⏳ Database Provider - Stub only (pending implementation)
|
|
71
|
+
- **Frontend Support**: React hooks and context providers (working)
|
|
72
|
+
- **Backend Support**: NestJS module structure (partial - not fully integrated)
|
|
73
|
+
- **Engine**: Complete rule-based evaluation with targeting and rollouts
|
|
74
|
+
- **Testing**: Full override capabilities for test scenarios
|
|
75
|
+
|
|
76
|
+
### ✅ Cache System (Partially Complete)
|
|
77
|
+
- **Implemented Strategies**:
|
|
78
|
+
- ✅ Memory Strategy - LRU eviction with TTL management
|
|
79
|
+
- ⏳ Redis Strategy - Stub only (pending implementation)
|
|
80
|
+
- **Features**: Statistics tracking, automatic cleanup, TTL management
|
|
81
|
+
- **Integration**: Currently used by feature flag system
|
|
82
|
+
|
|
83
|
+
### 🚧 Pending Implementation
|
|
84
|
+
- **Backend Integration**: Full NestJS module integration
|
|
85
|
+
- **Additional Engines**: Calculation, Incentive, Validation, Insights
|
|
86
|
+
- **SDK Layer**: B2B partner SDK foundation
|
|
87
|
+
- **External Providers**: Redis, API, and Database connections
|
|
76
88
|
|
|
77
89
|
### File Provider Configuration
|
|
78
90
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/base/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/base/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAiB,WAAW,EAAc,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE9F;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,YAAY;IAQX,OAAO,CAAC,MAAM;IAP1B,OAAO,CAAC,QAAQ,CAAgB;IAEhC;;;;OAIG;gBACiB,MAAM,EAAE,WAAW;IAIvC;;;;;;;;OAQG;IACG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAahE;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAe5C;;;;;OAKG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;;;;OAKG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAexC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAI5C;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IActB;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../../../src/base/cache/strategies/redis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../../../src/base/cache/strategies/redis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAG5F;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IAgB1C,OAAO,CAAC,MAAM;IAf1B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAKX;IACF,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC;;;;OAIG;gBACiB,MAAM,EAAE,gBAAgB;IAO5C;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9D;;;;;OAKG;IACG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAuBxD;;;;;OAKG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxC;;;;;OAKG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;IAqBrC;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;;;;OAKG;YACW,eAAe;IAc7B;;;;;OAKG;YACW,mBAAmB;IA4BjC;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;CAGtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/domain/featureFlags/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,mBAAmB,IAAI,oBAAoB,EAC3C,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/domain/featureFlags/provider.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -51,8 +51,6 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
51
51
|
};
|
|
52
52
|
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
53
53
|
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
|
|
54
|
-
|
|
55
|
-
// src/utils/common/hash.ts
|
|
56
54
|
function hashString(str) {
|
|
57
55
|
const HASH_SHIFT = 5;
|
|
58
56
|
let hash = 0;
|
|
@@ -65,10 +63,10 @@ function hashString(str) {
|
|
|
65
63
|
}
|
|
66
64
|
__name(hashString, "hashString");
|
|
67
65
|
function isInRollout(identifier, percentage) {
|
|
68
|
-
if (percentage >=
|
|
66
|
+
if (percentage >= config.MATH_CONSTANTS.PERCENTAGE_MAX) return true;
|
|
69
67
|
if (percentage <= 0) return false;
|
|
70
68
|
const hash = hashString(identifier);
|
|
71
|
-
return hash %
|
|
69
|
+
return hash % config.MATH_CONSTANTS.PERCENTAGE_MAX < percentage;
|
|
72
70
|
}
|
|
73
71
|
__name(isInRollout, "isInRollout");
|
|
74
72
|
function createRolloutIdentifier(featureKey, userId) {
|
|
@@ -97,7 +95,7 @@ var HashUtils = {
|
|
|
97
95
|
* @param totalBuckets - Total number of buckets (default: 100)
|
|
98
96
|
* @returns true if identifier is in the bucket range
|
|
99
97
|
*/
|
|
100
|
-
isInBucketRange: /* @__PURE__ */ __name((identifier, startBucket, endBucket, totalBuckets =
|
|
98
|
+
isInBucketRange: /* @__PURE__ */ __name((identifier, startBucket, endBucket, totalBuckets = config.MATH_CONSTANTS.PERCENTAGE_MAX) => {
|
|
101
99
|
const bucket = hashString(identifier) % totalBuckets;
|
|
102
100
|
return bucket >= startBucket && bucket <= endBucket;
|
|
103
101
|
}, "isInBucketRange"),
|
|
@@ -112,8 +110,6 @@ var HashUtils = {
|
|
|
112
110
|
return hashString(str) % SAFE_INT;
|
|
113
111
|
}, "createSeed")
|
|
114
112
|
};
|
|
115
|
-
|
|
116
|
-
// src/utils/common/values.ts
|
|
117
113
|
function isStringFalsy(value) {
|
|
118
114
|
if (value === "") return true;
|
|
119
115
|
const lower = value.toLowerCase().trim();
|
|
@@ -179,7 +175,7 @@ var ValueUtils = {
|
|
|
179
175
|
*/
|
|
180
176
|
isValidPercentage: /* @__PURE__ */ __name((value) => {
|
|
181
177
|
if (typeof value !== "number") return false;
|
|
182
|
-
return !isNaN(value) && isFinite(value) && value >= 0 && value <=
|
|
178
|
+
return !isNaN(value) && isFinite(value) && value >= 0 && value <= config.MATH_CONSTANTS.PERCENTAGE_MAX;
|
|
183
179
|
}, "isValidPercentage"),
|
|
184
180
|
/**
|
|
185
181
|
* Clamps a number to a specific range.
|
|
@@ -225,8 +221,6 @@ var ValueUtils = {
|
|
|
225
221
|
return current;
|
|
226
222
|
}, "getNestedProperty")
|
|
227
223
|
};
|
|
228
|
-
|
|
229
|
-
// src/utils/featureFlags/context.ts
|
|
230
224
|
var FeatureFlagContextBuilder = class _FeatureFlagContextBuilder {
|
|
231
225
|
static {
|
|
232
226
|
__name(this, "FeatureFlagContextBuilder");
|
|
@@ -422,7 +416,7 @@ var ContextUtils = {
|
|
|
422
416
|
if (context.platform && !["web", "mobile", "desktop"].includes(context.platform)) {
|
|
423
417
|
errors.push("Platform must be web, mobile, or desktop");
|
|
424
418
|
}
|
|
425
|
-
if (context.country && context.country.length !==
|
|
419
|
+
if (context.country && context.country.length !== config.ISO_STANDARDS.ISO_COUNTRY_CODE_LENGTH) {
|
|
426
420
|
errors.push("Country must be a 2-letter ISO country code");
|
|
427
421
|
}
|
|
428
422
|
return {
|
|
@@ -1189,8 +1183,6 @@ var MemoryCacheStrategy = class {
|
|
|
1189
1183
|
}
|
|
1190
1184
|
}
|
|
1191
1185
|
};
|
|
1192
|
-
|
|
1193
|
-
// src/base/cache/strategies/redis.ts
|
|
1194
1186
|
var RedisCacheStrategy = class {
|
|
1195
1187
|
/**
|
|
1196
1188
|
* Creates a new Redis cache strategy.
|
|
@@ -1228,7 +1220,7 @@ var RedisCacheStrategy = class {
|
|
|
1228
1220
|
const redisKey = this.buildRedisKey(key);
|
|
1229
1221
|
const serializedEntry = JSON.stringify(entry);
|
|
1230
1222
|
const ttlMs = entry.expiresAt - Date.now();
|
|
1231
|
-
const ttlSeconds = Math.max(1, Math.ceil(ttlMs /
|
|
1223
|
+
const ttlSeconds = Math.max(1, Math.ceil(ttlMs / config.TIME_CONSTANTS.MILLISECONDS_PER_SECOND));
|
|
1232
1224
|
await this.client.set(redisKey, serializedEntry, "EX", ttlSeconds);
|
|
1233
1225
|
this.stats.setCount++;
|
|
1234
1226
|
}
|
|
@@ -1399,7 +1391,7 @@ var CacheManager = class {
|
|
|
1399
1391
|
const finalTtl = ttl ?? this.config.ttl;
|
|
1400
1392
|
const entry = {
|
|
1401
1393
|
data: value,
|
|
1402
|
-
expiresAt: Date.now() + finalTtl *
|
|
1394
|
+
expiresAt: Date.now() + finalTtl * config.TIME_CONSTANTS.MILLISECONDS_PER_SECOND,
|
|
1403
1395
|
createdAt: Date.now()
|
|
1404
1396
|
};
|
|
1405
1397
|
await this.strategy.set(key, entry);
|
|
@@ -1492,8 +1484,6 @@ var CacheManager = class {
|
|
|
1492
1484
|
await this.strategy.dispose?.();
|
|
1493
1485
|
}
|
|
1494
1486
|
};
|
|
1495
|
-
|
|
1496
|
-
// src/domain/featureFlags/provider.ts
|
|
1497
1487
|
var FeatureFlagProvider = class {
|
|
1498
1488
|
/**
|
|
1499
1489
|
* Creates a new feature flag provider.
|
|
@@ -1728,7 +1718,7 @@ var FeatureFlagProvider = class {
|
|
|
1728
1718
|
void this.refresh().catch((error) => {
|
|
1729
1719
|
this.log("Auto-refresh failed:", error);
|
|
1730
1720
|
});
|
|
1731
|
-
}, this.config.refreshInterval *
|
|
1721
|
+
}, this.config.refreshInterval * config.TIME_CONSTANTS.MILLISECONDS_PER_SECOND);
|
|
1732
1722
|
}
|
|
1733
1723
|
}
|
|
1734
1724
|
/**
|
|
@@ -2372,7 +2362,7 @@ var FileFeatureFlagProvider = class extends FeatureFlagProvider {
|
|
|
2372
2362
|
};
|
|
2373
2363
|
let content;
|
|
2374
2364
|
if (format === "json") {
|
|
2375
|
-
content = JSON.stringify(defaultData, null,
|
|
2365
|
+
content = JSON.stringify(defaultData, null, config.FORMAT_CONSTANTS.JSON_INDENT_SPACES);
|
|
2376
2366
|
} else {
|
|
2377
2367
|
content = yaml__namespace.stringify(defaultData);
|
|
2378
2368
|
}
|
|
@@ -2480,7 +2470,7 @@ var FileFeatureFlagProvider = class extends FeatureFlagProvider {
|
|
|
2480
2470
|
try {
|
|
2481
2471
|
let content;
|
|
2482
2472
|
if (format === "json") {
|
|
2483
|
-
content = JSON.stringify(fileData, null,
|
|
2473
|
+
content = JSON.stringify(fileData, null, config.FORMAT_CONSTANTS.JSON_INDENT_SPACES);
|
|
2484
2474
|
} else {
|
|
2485
2475
|
content = yaml__namespace.stringify(fileData);
|
|
2486
2476
|
}
|