@reflag/node-sdk 1.0.0-alpha.1
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/LICENSE +21 -0
- package/README.md +835 -0
- package/dist/package.json +49 -0
- package/dist/src/batch-buffer.js +85 -0
- package/dist/src/batch-buffer.js.map +1 -0
- package/dist/src/cache.js +71 -0
- package/dist/src/cache.js.map +1 -0
- package/dist/src/client.js +1141 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/config.js +98 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/edgeClient.js +32 -0
- package/dist/src/edgeClient.js.map +1 -0
- package/dist/src/fetch-http-client.js +85 -0
- package/dist/src/fetch-http-client.js.map +1 -0
- package/dist/src/flusher.js +56 -0
- package/dist/src/flusher.js.map +1 -0
- package/dist/src/inRequestCache.js +72 -0
- package/dist/src/inRequestCache.js.map +1 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/periodicallyUpdatingCache.js +78 -0
- package/dist/src/periodicallyUpdatingCache.js.map +1 -0
- package/dist/src/rate-limiter.js +52 -0
- package/dist/src/rate-limiter.js.map +1 -0
- package/dist/src/types.js +6 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils.js +207 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/types/src/batch-buffer.d.ts +27 -0
- package/dist/types/src/batch-buffer.d.ts.map +1 -0
- package/dist/types/src/cache.d.ts +16 -0
- package/dist/types/src/cache.d.ts.map +1 -0
- package/dist/types/src/client.d.ts +410 -0
- package/dist/types/src/client.d.ts.map +1 -0
- package/dist/types/src/config.d.ts +20 -0
- package/dist/types/src/config.d.ts.map +1 -0
- package/dist/types/src/edgeClient.d.ts +25 -0
- package/dist/types/src/edgeClient.d.ts.map +1 -0
- package/dist/types/src/fetch-http-client.d.ts +20 -0
- package/dist/types/src/fetch-http-client.d.ts.map +1 -0
- package/dist/types/src/flusher.d.ts +4 -0
- package/dist/types/src/flusher.d.ts.map +1 -0
- package/dist/types/src/inRequestCache.d.ts +7 -0
- package/dist/types/src/inRequestCache.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/periodicallyUpdatingCache.d.ts +16 -0
- package/dist/types/src/periodicallyUpdatingCache.d.ts.map +1 -0
- package/dist/types/src/rate-limiter.d.ts +14 -0
- package/dist/types/src/rate-limiter.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +639 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/src/utils.d.ts +65 -0
- package/dist/types/src/utils.d.ts.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reflag/node-sdk",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/reflagcom/javascript.git"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "vite",
|
|
11
|
+
"start": "vite",
|
|
12
|
+
"build": "tsc --project tsconfig.build.json",
|
|
13
|
+
"test": "vitest -c vite.config.js",
|
|
14
|
+
"test:ci": "vitest run -c vite.config.js --reporter=default --reporter=junit --outputFile=junit.xml",
|
|
15
|
+
"coverage": "vitest run --coverage",
|
|
16
|
+
"lint": "eslint .",
|
|
17
|
+
"lint:ci": "eslint --output-file eslint-report.json --format json .",
|
|
18
|
+
"prettier": "prettier --check .",
|
|
19
|
+
"format": "yarn lint --fix && yarn prettier --write",
|
|
20
|
+
"preversion": "yarn lint && yarn prettier && yarn vitest run -c vite.config.js && yarn build"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"main": "./dist/src/index.js",
|
|
29
|
+
"types": "./dist/types/src/index.d.ts",
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@babel/core": "~7.24.7",
|
|
32
|
+
"@reflag/eslint-config": "~0.0.2",
|
|
33
|
+
"@reflag/tsconfig": "~0.0.2",
|
|
34
|
+
"@types/node": "^22.12.0",
|
|
35
|
+
"@vitest/coverage-v8": "~1.6.0",
|
|
36
|
+
"c8": "~10.1.0",
|
|
37
|
+
"eslint": "^9.21.0",
|
|
38
|
+
"flush-promises": "~1.0.2",
|
|
39
|
+
"prettier": "^3.5.2",
|
|
40
|
+
"ts-node": "~10.9.2",
|
|
41
|
+
"typescript": "^5.7.3",
|
|
42
|
+
"vite": "~5.4.18",
|
|
43
|
+
"vite-plugin-dts": "~3.9.1",
|
|
44
|
+
"vitest": "~1.6.0"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@reflag/flag-evaluation": "1.0.0"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const config_1 = require("./config");
|
|
13
|
+
const utils_1 = require("./utils");
|
|
14
|
+
/**
|
|
15
|
+
* A buffer that accumulates items and flushes them in batches.
|
|
16
|
+
* @typeparam T - The type of items to buffer.
|
|
17
|
+
*/
|
|
18
|
+
class BatchBuffer {
|
|
19
|
+
/**
|
|
20
|
+
* Creates a new `BatchBuffer` instance.
|
|
21
|
+
* @param options - The options to configure the buffer.
|
|
22
|
+
* @throws If the options are invalid.
|
|
23
|
+
*/
|
|
24
|
+
constructor(options) {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
this.buffer = [];
|
|
27
|
+
this.timer = null;
|
|
28
|
+
(0, utils_1.ok)((0, utils_1.isObject)(options), "options must be an object");
|
|
29
|
+
(0, utils_1.ok)(typeof options.flushHandler === "function", "flushHandler must be a function");
|
|
30
|
+
(0, utils_1.ok)((0, utils_1.isObject)(options.logger) || !options.logger, "logger must be an object");
|
|
31
|
+
(0, utils_1.ok)((typeof options.maxSize === "number" && options.maxSize > 0) ||
|
|
32
|
+
typeof options.maxSize !== "number", "maxSize must be greater than 0");
|
|
33
|
+
(0, utils_1.ok)((typeof options.intervalMs === "number" && options.intervalMs >= 0) ||
|
|
34
|
+
typeof options.intervalMs !== "number", "intervalMs must be greater than or equal to 0");
|
|
35
|
+
this.flushHandler = options.flushHandler;
|
|
36
|
+
this.logger = options.logger;
|
|
37
|
+
this.maxSize = (_a = options.maxSize) !== null && _a !== void 0 ? _a : config_1.BATCH_MAX_SIZE;
|
|
38
|
+
this.intervalMs = (_b = options.intervalMs) !== null && _b !== void 0 ? _b : config_1.BATCH_INTERVAL_MS;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Adds an item to the buffer.
|
|
42
|
+
*
|
|
43
|
+
* @param item - The item to add.
|
|
44
|
+
*/
|
|
45
|
+
add(item) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
this.buffer.push(item);
|
|
48
|
+
if (this.buffer.length >= this.maxSize) {
|
|
49
|
+
yield this.flush();
|
|
50
|
+
}
|
|
51
|
+
else if (!this.timer && this.intervalMs > 0) {
|
|
52
|
+
this.timer = setTimeout(() => this.flush(), this.intervalMs).unref();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
flush() {
|
|
57
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
var _a, _b, _c;
|
|
59
|
+
if (this.timer) {
|
|
60
|
+
clearTimeout(this.timer);
|
|
61
|
+
this.timer = null;
|
|
62
|
+
}
|
|
63
|
+
if (this.buffer.length === 0) {
|
|
64
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug("buffer is empty. nothing to flush");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const flushingBuffer = this.buffer;
|
|
68
|
+
this.buffer = [];
|
|
69
|
+
try {
|
|
70
|
+
yield this.flushHandler(flushingBuffer);
|
|
71
|
+
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.info("flushed buffered items", {
|
|
72
|
+
count: flushingBuffer.length,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
(_c = this.logger) === null || _c === void 0 ? void 0 : _c.error("flush of buffered items failed; discarding items", {
|
|
77
|
+
error,
|
|
78
|
+
count: flushingBuffer.length,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.default = BatchBuffer;
|
|
85
|
+
//# sourceMappingURL=batch-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-buffer.js","sourceRoot":"","sources":["../../src/batch-buffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.default = cache;
|
|
13
|
+
/**
|
|
14
|
+
* Create a cached function that updates the value asynchronously.
|
|
15
|
+
*
|
|
16
|
+
* The value is updated every `ttl` milliseconds.
|
|
17
|
+
* If the value is older than `staleTtl` milliseconds, a warning is logged.
|
|
18
|
+
*
|
|
19
|
+
* @typeParam T - The type of the value.
|
|
20
|
+
* @param ttl - The time-to-live in milliseconds.
|
|
21
|
+
* @param staleTtl - The time-to-live after which a warning is logged.
|
|
22
|
+
* @param logger - The logger to use.
|
|
23
|
+
* @param fn - The function to call to get the value.
|
|
24
|
+
* @returns The cache object.
|
|
25
|
+
**/
|
|
26
|
+
function cache(ttl, staleTtl, logger, fn) {
|
|
27
|
+
let cachedValue;
|
|
28
|
+
let lastUpdate;
|
|
29
|
+
let timeoutId;
|
|
30
|
+
let refreshPromise;
|
|
31
|
+
const update = () => __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
if (timeoutId) {
|
|
33
|
+
clearTimeout(timeoutId);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const newValue = yield fn();
|
|
37
|
+
if (newValue === undefined) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
cachedValue = newValue;
|
|
41
|
+
lastUpdate = Date.now();
|
|
42
|
+
logger === null || logger === void 0 ? void 0 : logger.debug("updated cached value", cachedValue);
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
logger === null || logger === void 0 ? void 0 : logger.error("failed to update cached value", e);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
refreshPromise = undefined;
|
|
49
|
+
timeoutId = setTimeout(update, ttl).unref();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const get = () => {
|
|
53
|
+
if (lastUpdate !== undefined) {
|
|
54
|
+
const age = Date.now() - lastUpdate;
|
|
55
|
+
if (age > staleTtl) {
|
|
56
|
+
logger === null || logger === void 0 ? void 0 : logger.warn("cached value is stale", { age, cachedValue });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return cachedValue;
|
|
60
|
+
};
|
|
61
|
+
const refresh = () => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
if (!refreshPromise) {
|
|
63
|
+
refreshPromise = update();
|
|
64
|
+
}
|
|
65
|
+
yield refreshPromise;
|
|
66
|
+
logger === null || logger === void 0 ? void 0 : logger.info("refreshed cached features");
|
|
67
|
+
return get();
|
|
68
|
+
});
|
|
69
|
+
return { get, refresh };
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":";;;;;;;;;;;AAeA,wBAuDC;AApED;;;;;;;;;;;;IAYI;AACJ,SAAwB,KAAK,CAC3B,GAAW,EACX,QAAgB,EAChB,MAA0B,EAC1B,EAAgC;IAEhC,IAAI,WAA0B,CAAC;IAC/B,IAAI,UAA8B,CAAC;IACnC,IAAI,SAAqC,CAAC;IAC1C,IAAI,cAAyC,CAAC;IAE9C,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,EAAE,EAAE,CAAC;YAC5B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,OAAO;YACT,CAAC;YACD,WAAW,GAAG,QAAQ,CAAC;YAEvB,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAExB,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAC,sBAAsB,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;gBAAS,CAAC;YACT,cAAc,GAAG,SAAS,CAAC;YAC3B,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC,CAAA,CAAC;IAEF,MAAM,GAAG,GAAG,GAAG,EAAE;QACf,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,UAAW,CAAC;YACrC,IAAI,GAAG,GAAG,QAAQ,EAAE,CAAC;gBACnB,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,uBAAuB,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,GAAG,MAAM,EAAE,CAAC;QAC5B,CAAC;QACD,MAAM,cAAc,CAAC;QACrB,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAC1C,OAAO,GAAG,EAAE,CAAC;IACf,CAAC,CAAA,CAAC;IAEF,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AAC1B,CAAC"}
|