@quonfig/node 0.0.2 → 0.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/dist/index.d.cts CHANGED
@@ -102,6 +102,8 @@ interface QuonfigOptions {
102
102
  initTimeout?: number;
103
103
  datadir?: string;
104
104
  datafile?: string | object;
105
+ /** Environment name to use in datadir mode. Supersedes the QUONFIG_ENVIRONMENT env var. */
106
+ environment?: string;
105
107
  }
106
108
  interface EvalMatch {
107
109
  isMatch: boolean;
@@ -202,6 +204,7 @@ declare class BoundQuonfig {
202
204
  defaultLevel?: string;
203
205
  contexts?: Contexts;
204
206
  }): boolean;
207
+ flush(): Promise<void>;
205
208
  keys(): string[];
206
209
  inContext(contexts: Contexts): BoundQuonfig;
207
210
  }
@@ -228,6 +231,7 @@ declare class Quonfig {
228
231
  private readonly initTimeout;
229
232
  private readonly datadir?;
230
233
  private readonly datafile?;
234
+ private readonly requestedEnvironment;
231
235
  private store;
232
236
  private evaluator;
233
237
  private resolver;
@@ -303,6 +307,18 @@ declare class Quonfig {
303
307
  * Create a BoundQuonfig with the given context baked in.
304
308
  */
305
309
  inContext(contexts: Contexts): BoundQuonfig;
310
+ /**
311
+ * Flush pending telemetry data immediately. Useful in serverless environments
312
+ * (Vercel, Lambda) where the process may be frozen before the background
313
+ * timer fires.
314
+ *
315
+ * ```typescript
316
+ * const value = quonfig.get("my-flag", contexts);
317
+ * await quonfig.flush();
318
+ * return NextResponse.json({ value });
319
+ * ```
320
+ */
321
+ flush(): Promise<void>;
306
322
  /**
307
323
  * Close the SDK. Stops SSE, polling, and telemetry.
308
324
  */
@@ -674,7 +690,7 @@ declare class TelemetryReporter {
674
690
  */
675
691
  stop(): void;
676
692
  private scheduleNext;
677
- private sync;
693
+ sync(): Promise<void>;
678
694
  }
679
695
 
680
696
  /**
package/dist/index.d.ts CHANGED
@@ -102,6 +102,8 @@ interface QuonfigOptions {
102
102
  initTimeout?: number;
103
103
  datadir?: string;
104
104
  datafile?: string | object;
105
+ /** Environment name to use in datadir mode. Supersedes the QUONFIG_ENVIRONMENT env var. */
106
+ environment?: string;
105
107
  }
106
108
  interface EvalMatch {
107
109
  isMatch: boolean;
@@ -202,6 +204,7 @@ declare class BoundQuonfig {
202
204
  defaultLevel?: string;
203
205
  contexts?: Contexts;
204
206
  }): boolean;
207
+ flush(): Promise<void>;
205
208
  keys(): string[];
206
209
  inContext(contexts: Contexts): BoundQuonfig;
207
210
  }
@@ -228,6 +231,7 @@ declare class Quonfig {
228
231
  private readonly initTimeout;
229
232
  private readonly datadir?;
230
233
  private readonly datafile?;
234
+ private readonly requestedEnvironment;
231
235
  private store;
232
236
  private evaluator;
233
237
  private resolver;
@@ -303,6 +307,18 @@ declare class Quonfig {
303
307
  * Create a BoundQuonfig with the given context baked in.
304
308
  */
305
309
  inContext(contexts: Contexts): BoundQuonfig;
310
+ /**
311
+ * Flush pending telemetry data immediately. Useful in serverless environments
312
+ * (Vercel, Lambda) where the process may be frozen before the background
313
+ * timer fires.
314
+ *
315
+ * ```typescript
316
+ * const value = quonfig.get("my-flag", contexts);
317
+ * await quonfig.flush();
318
+ * return NextResponse.json({ value });
319
+ * ```
320
+ */
321
+ flush(): Promise<void>;
306
322
  /**
307
323
  * Close the SDK. Stops SSE, polling, and telemetry.
308
324
  */
@@ -674,7 +690,7 @@ declare class TelemetryReporter {
674
690
  */
675
691
  stop(): void;
676
692
  private scheduleNext;
677
- private sync;
693
+ sync(): Promise<void>;
678
694
  }
679
695
 
680
696
  /**
package/dist/index.js CHANGED
@@ -1022,7 +1022,10 @@ function shouldLog(args) {
1022
1022
  while (loggerNameWithPrefix.includes(".")) {
1023
1023
  const resolvedLevel = getConfig(loggerNameWithPrefix);
1024
1024
  if (resolvedLevel !== void 0) {
1025
- return Number(resolvedLevel) <= desiredLevel;
1025
+ const resolvedLevelNum = parseLevel(resolvedLevel);
1026
+ if (resolvedLevelNum !== void 0) {
1027
+ return resolvedLevelNum <= desiredLevel;
1028
+ }
1026
1029
  }
1027
1030
  loggerNameWithPrefix = loggerNameWithPrefix.slice(
1028
1031
  0,
@@ -1036,8 +1039,8 @@ function shouldLog(args) {
1036
1039
  import { existsSync, readdirSync, readFileSync } from "fs";
1037
1040
  import { join } from "path";
1038
1041
  var CONFIG_SUBDIRS = ["configs", "feature-flags", "segments", "schemas", "log-levels"];
1039
- function loadEnvelopeFromDatadir(datadir) {
1040
- const environmentId = loadEnvironmentId(join(datadir, "environments.json"));
1042
+ function loadEnvelopeFromDatadir(datadir, environment) {
1043
+ const environmentId = resolveEnvironment(join(datadir, "environments.json"), environment);
1041
1044
  const configs = [];
1042
1045
  for (const subdir of CONFIG_SUBDIRS) {
1043
1046
  const dir = join(datadir, subdir);
@@ -1058,7 +1061,12 @@ function loadEnvelopeFromDatadir(datadir) {
1058
1061
  }
1059
1062
  };
1060
1063
  }
1061
- function loadEnvironmentId(environmentsPath) {
1064
+ function resolveEnvironment(environmentsPath, environment) {
1065
+ if (!environment) {
1066
+ throw new Error(
1067
+ "[quonfig] Environment required for datadir mode; set the `environment` option or QUONFIG_ENVIRONMENT env var"
1068
+ );
1069
+ }
1062
1070
  if (!existsSync(environmentsPath)) {
1063
1071
  throw new Error(`[quonfig] Datadir is missing environments.json: ${environmentsPath}`);
1064
1072
  }
@@ -1066,10 +1074,12 @@ function loadEnvironmentId(environmentsPath) {
1066
1074
  const candidates = normalizeEnvironmentCandidates(
1067
1075
  isWrappedEnvironmentList(environments) ? environments.environments : environments
1068
1076
  );
1069
- if (candidates.length === 0) {
1070
- return "";
1077
+ if (candidates.length > 0 && !candidates.includes(environment)) {
1078
+ throw new Error(
1079
+ `[quonfig] Environment "${environment}" not found in workspace; available environments: ${candidates.join(", ")}`
1080
+ );
1071
1081
  }
1072
- return candidates[0];
1082
+ return environment;
1073
1083
  }
1074
1084
  function isWrappedEnvironmentList(value) {
1075
1085
  return Boolean(
@@ -1426,6 +1436,9 @@ var BoundQuonfig = class _BoundQuonfig {
1426
1436
  contexts: mergeContexts(this.boundContexts, args.contexts)
1427
1437
  });
1428
1438
  }
1439
+ async flush() {
1440
+ return this.client.flush();
1441
+ }
1429
1442
  keys() {
1430
1443
  return this.client.keys();
1431
1444
  }
@@ -1446,6 +1459,7 @@ var Quonfig = class {
1446
1459
  initTimeout;
1447
1460
  datadir;
1448
1461
  datafile;
1462
+ requestedEnvironment;
1449
1463
  store;
1450
1464
  evaluator;
1451
1465
  resolver;
@@ -1476,6 +1490,7 @@ var Quonfig = class {
1476
1490
  this.initTimeout = options.initTimeout ?? DEFAULT_INIT_TIMEOUT;
1477
1491
  this.datadir = options.datadir;
1478
1492
  this.datafile = options.datafile;
1493
+ this.requestedEnvironment = options.environment || process.env.QUONFIG_ENVIRONMENT || "";
1479
1494
  this.instanceHash = randomUUID();
1480
1495
  this.store = new ConfigStore();
1481
1496
  this.evaluator = new Evaluator(this.store);
@@ -1664,6 +1679,22 @@ var Quonfig = class {
1664
1679
  inContext(contexts) {
1665
1680
  return new BoundQuonfig(this, mergeContexts(this.globalContext, contexts));
1666
1681
  }
1682
+ /**
1683
+ * Flush pending telemetry data immediately. Useful in serverless environments
1684
+ * (Vercel, Lambda) where the process may be frozen before the background
1685
+ * timer fires.
1686
+ *
1687
+ * ```typescript
1688
+ * const value = quonfig.get("my-flag", contexts);
1689
+ * await quonfig.flush();
1690
+ * return NextResponse.json({ value });
1691
+ * ```
1692
+ */
1693
+ async flush() {
1694
+ if (this.telemetryReporter) {
1695
+ await this.telemetryReporter.sync();
1696
+ }
1697
+ }
1667
1698
  /**
1668
1699
  * Close the SDK. Stops SSE, polling, and telemetry.
1669
1700
  */
@@ -1708,7 +1739,7 @@ var Quonfig = class {
1708
1739
  }
1709
1740
  loadLocalEnvelope() {
1710
1741
  if (this.datadir) {
1711
- return loadEnvelopeFromDatadir(this.datadir);
1742
+ return loadEnvelopeFromDatadir(this.datadir, this.requestedEnvironment);
1712
1743
  }
1713
1744
  if (typeof this.datafile === "string") {
1714
1745
  const raw = readFileSync2(this.datafile, "utf-8");