Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 66 additions & 66 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
{
"name": "@schematichq/schematic-typescript-node",
"version": "1.3.1",
"private": false,
"repository": {
"type": "git",
"url": "git+https://github.com/schematichq/schematic-node.git"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"format": "biome format --write --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"format:check": "biome format --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"lint": "biome lint --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"lint:fix": "biome lint --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"check": "biome check --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"check:fix": "biome check --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"build": "node build.js",
"prepack": "cp -rv dist/. .",
"test": "jest --config jest.config.mjs",
"test:unit": "jest --selectProjects unit",
"test:wire": "jest --selectProjects wire",
"build:legacy": "tsc"
},
"dependencies": {
"form-data": "^4.0.4",
"formdata-node": "^6.0.3",
"node-fetch": "^2.7.0",
"readable-stream": "^4.5.2"
},
"devDependencies": {
"@types/node-fetch": "^2.6.12",
"@types/readable-stream": "^4.0.18",
"webpack": "^5.97.1",
"ts-loader": "^9.5.1",
"jest": "^29.7.0",
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.14",
"ts-jest": "^29.3.4",
"jest-environment-jsdom": "^29.7.0",
"msw": "2.11.2",
"@types/node": "^18.19.70",
"typescript": "~5.7.2",
"@biomejs/biome": "2.3.1",
"esbuild": "^0.25.9"
},
"browser": {
"fs": false,
"os": false,
"path": false,
"stream": false,
"crypto": false,
"timers": false
},
"packageManager": "yarn@1.22.22",
"engines": {
"node": ">=18.0.0"
},
"sideEffects": false,
"license": "MIT",
"files": [
"dist/**/*.js",
"dist/**/*.d.ts",
"!dist/**/*.js.map",
"!dist/**/*.test.*",
"README.md"
]
"name": "@schematichq/schematic-typescript-node",
"version": "1.3.2",
"private": false,
"repository": {
"type": "git",
"url": "git+https://github.com/schematichq/schematic-node.git"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"format": "biome format --write --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"format:check": "biome format --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"lint": "biome lint --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"lint:fix": "biome lint --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"check": "biome check --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"check:fix": "biome check --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none",
"build": "node build.js",
"prepack": "cp -rv dist/. .",
"test": "jest --config jest.config.mjs",
"test:unit": "jest --selectProjects unit",
"test:wire": "jest --selectProjects wire",
"build:legacy": "tsc"
},
"dependencies": {
"form-data": "^4.0.4",
"formdata-node": "^6.0.3",
"node-fetch": "^2.7.0",
"readable-stream": "^4.5.2"
},
"devDependencies": {
"@types/node-fetch": "^2.6.12",
"@types/readable-stream": "^4.0.18",
"webpack": "^5.97.1",
"ts-loader": "^9.5.1",
"jest": "^29.7.0",
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.14",
"ts-jest": "^29.3.4",
"jest-environment-jsdom": "^29.7.0",
"msw": "2.11.2",
"@types/node": "^18.19.70",
"typescript": "~5.7.2",
"@biomejs/biome": "2.3.1",
"esbuild": "^0.25.9"
},
"browser": {
"fs": false,
"os": false,
"path": false,
"stream": false,
"crypto": false,
"timers": false
},
"packageManager": "yarn@1.22.22",
"engines": {
"node": ">=18.0.0"
},
"sideEffects": false,
"license": "MIT",
"files": [
"dist/**/*.js",
"dist/**/*.d.ts",
"!dist/**/*.js.map",
"!dist/**/*.test.*",
"README.md"
]
}
65 changes: 42 additions & 23 deletions src/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,35 +123,46 @@ export class SchematicClient extends BaseClient {
return getDefault();
}

try {
const cacheKey = JSON.stringify({ evalCtx, key });
for (const provider of this.flagCheckCacheProviders) {
const cacheKey = JSON.stringify({ evalCtx, key });

for (const provider of this.flagCheckCacheProviders) {
try {
const cachedValue = await provider.get(cacheKey);
if (cachedValue !== undefined) {
this.logger.debug(`${provider.constructor.name} cache hit for flag ${key}`);
return cachedValue;
}
} catch (err) {
this.logger.warn(`Cache read error for flag ${key} from ${provider.constructor.name}: ${err}`);
}
}

let value: boolean;
try {
const response = await this.features.checkFlag(key, evalCtx, {
timeoutInSeconds: options?.timeoutMs !== undefined ? options.timeoutMs / 1000 : undefined,
});
if (response.data.value === undefined) {
this.logger.debug(`No value returned from feature flag API for flag ${key}, falling back to default`);
return getDefault();
}

for (const provider of this.flagCheckCacheProviders) {
this.logger.debug(`Caching value for flag ${key} in ${provider.constructor.name}`);
await provider.set(cacheKey, response.data.value);
}

value = response.data.value;
this.logger.debug(`Feature flag API response for ${key}: ${JSON.stringify(response.data)}`);
return response.data.value;
} catch (err) {
this.logger.error(`Error checking flag ${key}: ${err}`);
return getDefault();
}

for (const provider of this.flagCheckCacheProviders) {
try {
this.logger.debug(`Caching value for flag ${key} in ${provider.constructor.name}`);
await provider.set(cacheKey, value);
} catch (err) {
this.logger.warn(`Cache write error for flag ${key} to ${provider.constructor.name}: ${err}`);
}
}

return value;
}

/**
Expand Down Expand Up @@ -193,16 +204,20 @@ export class SchematicClient extends BaseClient {
let foundInCache = false;

for (const provider of this.flagCheckCacheProviders) {
const cachedValue = await provider.get(cacheKey);
if (cachedValue !== undefined) {
this.logger.debug(`${provider.constructor.name} cache hit for flag ${key}`);
cachedResults.set(key, {
flag: key,
value: cachedValue,
reason: 'Retrieved from cache'
});
foundInCache = true;
break;
try {
const cachedValue = await provider.get(cacheKey);
if (cachedValue !== undefined) {
this.logger.debug(`${provider.constructor.name} cache hit for flag ${key}`);
cachedResults.set(key, {
flag: key,
value: cachedValue,
reason: 'Retrieved from cache'
});
foundInCache = true;
break;
}
} catch (err) {
this.logger.warn(`Cache read error for flag ${key} from ${provider.constructor.name}: ${err}`);
}
}

Expand Down Expand Up @@ -233,8 +248,12 @@ export class SchematicClient extends BaseClient {
// Cache the fresh result
const cacheKey = JSON.stringify({ evalCtx, key });
for (const provider of this.flagCheckCacheProviders) {
this.logger.debug(`Caching value for flag ${cacheKey} in ${provider.constructor.name}`);
await provider.set(cacheKey, apiResult.value);
try {
this.logger.debug(`Caching value for flag ${cacheKey} in ${provider.constructor.name}`);
await provider.set(cacheKey, apiResult.value);
} catch (err) {
this.logger.warn(`Cache write error for flag ${key} to ${provider.constructor.name}: ${err}`);
}
}
results.push(apiResult);
} else {
Expand All @@ -260,7 +279,7 @@ export class SchematicClient extends BaseClient {

} catch (err) {
this.logger.error(`Error checking flags ${keys ? keys.join(', ') : 'all'}: ${err}`);

// Return default values for all requested keys
if (keys && keys.length > 0) {
return keys.map(key => ({
Expand Down
2 changes: 1 addition & 1 deletion src/cache.test.ts → tests/cache.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint @typescript-eslint/no-explicit-any: 0 */

import { LocalCache } from "./cache";
import { LocalCache } from "../src/cache";

jest.useFakeTimers();

Expand Down
8 changes: 4 additions & 4 deletions src/events.test.ts → tests/events.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* eslint @typescript-eslint/no-explicit-any: 0 */

import { EventBuffer } from "./events";
import { EventsClient } from "./api/resources/events/client/Client";
import { CreateEventRequestBody } from "./api";
import { Logger } from "./logger";
import { EventBuffer } from "../src/events";
import { EventsClient } from "../src/api/resources/events/client/Client";
import { CreateEventRequestBody } from "../src/api";
import { Logger } from "../src/logger";

process.env.NODE_ENV = "test";

Expand Down
Loading
Loading