@barekey/sdk 0.1.0 → 0.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAiB/C,OAAO,KAAK,EACV,oBAAoB,EAEpB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAiDpB,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgD;IAChF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4C;IAC5E,OAAO,CAAC,qBAAqB,CAA+C;IAC5E,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,qBAAqB,CAAS;;gBAG1B,OAAO,EAAE;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACpD,OAAO,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;KAC3C;gBACW,OAAO,EAAE;QACnB,IAAI,EAAE,iBAAiB,CAAC;QACxB,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACpD,OAAO,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;KAC3C;IAMD,GAAG,CAAC,IAAI,SAAS,eAAe,EAC9B,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,iBAAiB,GAC1B,gBAAgB,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAClD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,CAAC;IAOnE,OAAO,IAAI,OAAO,CAAC,oBAAoB,CAAC;YAahC,iBAAiB;YAajB,oBAAoB;IAclC,OAAO,CAAC,oBAAoB;YAWd,mBAAmB;IAoEjC,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,uBAAuB;YAejB,gBAAgB;YAsBhB,2BAA2B;YA4B3B,mBAAmB;YAiBnB,kBAAkB;YAQlB,mBAAmB;YAkEnB,qBAAqB;CAYpC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAkB/C,OAAO,KAAK,EACV,oBAAoB,EAEpB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAiDpB,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgD;IAChF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4C;IAC5E,OAAO,CAAC,qBAAqB,CAA+C;IAC5E,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,qBAAqB,CAAS;;gBAG1B,OAAO,EAAE;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACpD,OAAO,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;KAC3C;gBACW,OAAO,EAAE;QACnB,IAAI,EAAE,iBAAiB,CAAC;QACxB,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACpD,OAAO,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;KAC3C;IAMD,GAAG,CAAC,IAAI,SAAS,eAAe,EAC9B,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,iBAAiB,GAC1B,gBAAgB,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAClD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,CAAC;IAOnE,OAAO,IAAI,OAAO,CAAC,oBAAoB,CAAC;YAkBhC,iBAAiB;YAajB,oBAAoB;IAclC,OAAO,CAAC,oBAAoB;YAWd,mBAAmB;IA6EjC,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,uBAAuB;YAejB,gBAAgB;YAsBhB,2BAA2B;YA4B3B,mBAAmB;YAiBnB,kBAAkB;YAQlB,mBAAmB;YAkEnB,qBAAqB;CAYpC"}
package/dist/client.js CHANGED
@@ -6,7 +6,7 @@ import { validateRequirements } from "./internal/requirements.js";
6
6
  import { resolveRuntimeContext } from "./internal/runtime.js";
7
7
  import { MemoryCache } from "./internal/cache.js";
8
8
  import { DEFAULT_TYPEGEN_TTL_MS, resolveTtlMilliseconds } from "./internal/ttl.js";
9
- import { resolveInstalledSdkGeneratedTypesPath, writeInstalledSdkGeneratedTypes, } from "./internal/typegen.js";
9
+ import { hasFreshInstalledSdkTypegen, resolveInstalledSdkGeneratedTypesPath, writeInstalledSdkGeneratedTypes, } from "./internal/typegen.js";
10
10
  const sharedTypegenWatchers = new Map();
11
11
  function createDefaultFetch() {
12
12
  if (typeof globalThis.fetch === "function") {
@@ -53,7 +53,12 @@ export class BarekeyClient {
53
53
  });
54
54
  }
55
55
  const manifest = await this.fetchTypegenManifest(context);
56
- return await writeInstalledSdkGeneratedTypes(manifest);
56
+ return await writeInstalledSdkGeneratedTypes(manifest, {
57
+ baseUrl: context.baseUrl,
58
+ orgSlug: context.organization,
59
+ projectSlug: context.project,
60
+ stageSlug: context.environment,
61
+ });
57
62
  }
58
63
  async getRuntimeContext() {
59
64
  if (this.runtimeContextPromise === null) {
@@ -146,7 +151,14 @@ export class BarekeyClient {
146
151
  }, intervalMs),
147
152
  };
148
153
  sharedTypegenWatchers.set(watcherKey, watcher);
149
- void runWatcher(watcher);
154
+ if (!(await hasFreshInstalledSdkTypegen(intervalMs, {
155
+ baseUrl: context.baseUrl,
156
+ orgSlug: context.organization,
157
+ projectSlug: context.project,
158
+ stageSlug: context.environment,
159
+ }))) {
160
+ void runWatcher(watcher);
161
+ }
150
162
  }
151
163
  ensureTypegenWatcher(context) {
152
164
  if (this.typegenWatcherStarted || this.options.typegen === false || context.environment !== "development") {
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/internal/evaluate.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAEjB,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAgDrB,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAKxE;AA4CD,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,yBAAyB,EACrC,OAAO,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,KAAK,CAAC,GAChD,OAAO,CAAC,qBAAqB,CAAC,CAsDhC;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,GAAG,GAAG,GAAG,GAAG,SAAS,CAQ9F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,GAAG,OAAO,CAiB5F;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,qBAAqB,EAC/B,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CA0BT"}
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/internal/evaluate.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EAIjB,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAgDrB,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAKxE;AAqHD,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,yBAAyB,EACrC,OAAO,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,KAAK,CAAC,GAChD,OAAO,CAAC,qBAAqB,CAAC,CAuDhC;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,GAAG,GAAG,GAAG,GAAG,SAAS,CAQ9F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,GAAG,OAAO,CAiB5F;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,qBAAqB,EAC/B,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CA0BT"}
@@ -50,13 +50,51 @@ async function deterministicBucket(input) {
50
50
  return (value >>> 0) / 4294967296;
51
51
  }
52
52
  function resolveLinearRolloutChance(input) {
53
+ return resolveRolloutChance({
54
+ function: "linear",
55
+ milestones: input.milestones,
56
+ nowMs: input.nowMs,
57
+ }).chance;
58
+ }
59
+ function smoothstep(progress) {
60
+ return progress * progress * (3 - 2 * progress);
61
+ }
62
+ function resolveSegmentPercentage(input) {
63
+ if (input.function === "step") {
64
+ return input.currentPercentage;
65
+ }
66
+ if (input.function === "ease_in_out") {
67
+ const easedProgress = smoothstep(input.progress);
68
+ return (input.currentPercentage +
69
+ (input.nextPercentage - input.currentPercentage) * easedProgress);
70
+ }
71
+ return (input.currentPercentage +
72
+ (input.nextPercentage - input.currentPercentage) * input.progress);
73
+ }
74
+ function matchedRuleForRolloutFunction(value) {
75
+ if (value === "step") {
76
+ return "step_rollout";
77
+ }
78
+ if (value === "ease_in_out") {
79
+ return "ease_in_out_rollout";
80
+ }
81
+ return "linear_rollout";
82
+ }
83
+ function resolveRolloutChance(input) {
53
84
  const milestones = normalizeRolloutMilestones(input.milestones);
85
+ const matchedRule = matchedRuleForRolloutFunction(input.function);
54
86
  const first = milestones[0];
55
87
  if (first === undefined) {
56
- return 0;
88
+ return {
89
+ chance: 0,
90
+ matchedRule,
91
+ };
57
92
  }
58
93
  if (input.nowMs < parseRolloutInstant(first.at)) {
59
- return 0;
94
+ return {
95
+ chance: 0,
96
+ matchedRule,
97
+ };
60
98
  }
61
99
  for (let index = 0; index < milestones.length - 1; index += 1) {
62
100
  const current = milestones[index];
@@ -68,12 +106,23 @@ function resolveLinearRolloutChance(input) {
68
106
  const nextAtMs = parseRolloutInstant(next.at);
69
107
  if (input.nowMs >= currentAtMs && input.nowMs < nextAtMs) {
70
108
  const progress = (input.nowMs - currentAtMs) / (nextAtMs - currentAtMs);
71
- const percentage = current.percentage + (next.percentage - current.percentage) * progress;
72
- return percentage / 100;
109
+ const percentage = resolveSegmentPercentage({
110
+ function: input.function,
111
+ currentPercentage: current.percentage,
112
+ nextPercentage: next.percentage,
113
+ progress,
114
+ });
115
+ return {
116
+ chance: percentage / 100,
117
+ matchedRule,
118
+ };
73
119
  }
74
120
  }
75
121
  const last = milestones[milestones.length - 1];
76
- return last === undefined ? 0 : last.percentage / 100;
122
+ return {
123
+ chance: last === undefined ? 0 : last.percentage / 100,
124
+ matchedRule,
125
+ };
77
126
  }
78
127
  export async function evaluateDefinition(definition, options) {
79
128
  if (definition.kind === "secret") {
@@ -106,7 +155,8 @@ export async function evaluateDefinition(definition, options) {
106
155
  },
107
156
  };
108
157
  }
109
- const chance = resolveLinearRolloutChance({
158
+ const { chance, matchedRule } = resolveRolloutChance({
159
+ function: definition.rolloutFunction,
110
160
  milestones: definition.rolloutMilestones,
111
161
  nowMs: Date.now(),
112
162
  });
@@ -122,7 +172,7 @@ export async function evaluateDefinition(definition, options) {
122
172
  chance,
123
173
  seed: seed.length > 0 ? seed : undefined,
124
174
  key: key.length > 0 ? key : undefined,
125
- matchedRule: "linear_rollout",
175
+ matchedRule,
126
176
  },
127
177
  };
128
178
  }
@@ -11,6 +11,7 @@ export declare function loadCliSessionAuthResolver(fetchFn: typeof globalThis.fe
11
11
  type InstalledSdkTypegenTarget = {
12
12
  packageRoot: string;
13
13
  generatedTypesPath: string;
14
+ typegenMetadataPath: string;
14
15
  };
15
16
  export declare function resolveInstalledSdkTypegenTarget(): Promise<InstalledSdkTypegenTarget | null>;
16
17
  export declare function readTextFile(filePath: string): Promise<string | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"node-runtime.d.ts","sourceRoot":"","sources":["../../src/internal/node-runtime.ts"],"names":[],"mappings":"AA4VA,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE9D;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GAAG,IAAI,CAAC,CAwCR;AAED,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,GAAG,IAAI,CAAC,CAoER;AAOD,KAAK,yBAAyB,GAAG;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAsDlG;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkB3E;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBxF"}
1
+ {"version":3,"file":"node-runtime.d.ts","sourceRoot":"","sources":["../../src/internal/node-runtime.ts"],"names":[],"mappings":"AA4VA,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE9D;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GAAG,IAAI,CAAC,CAwCR;AAED,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,GAAG,IAAI,CAAC,CAoER;AAOD,KAAK,yBAAyB,GAAG;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAuDlG;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkB3E;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBxF"}
@@ -364,6 +364,7 @@ export async function resolveInstalledSdkTypegenTarget() {
364
364
  return {
365
365
  packageRoot: current,
366
366
  generatedTypesPath,
367
+ typegenMetadataPath: runtime.path.join(current, "typegen.json"),
367
368
  };
368
369
  }
369
370
  const parent = runtime.path.dirname(current);
@@ -1,4 +1,4 @@
1
- import type { BarekeyRolloutMilestone, BarekeyTypegenResult } from "../types.js";
1
+ import type { BarekeyRolloutFunction, BarekeyRolloutMilestone, BarekeyTypegenResult } from "../types.js";
2
2
  export type TypegenManifestVariable = {
3
3
  name: string;
4
4
  kind: "secret" | "ab_roll" | "rollout";
@@ -8,7 +8,7 @@ export type TypegenManifestVariable = {
8
8
  typeScriptType: string;
9
9
  valueATypeScriptType: string | null;
10
10
  valueBTypeScriptType: string | null;
11
- rolloutFunction: "linear" | null;
11
+ rolloutFunction: BarekeyRolloutFunction | null;
12
12
  rolloutMilestones: Array<BarekeyRolloutMilestone> | null;
13
13
  };
14
14
  export type TypegenManifest = {
@@ -20,6 +20,14 @@ export type TypegenManifest = {
20
20
  manifestVersion: string;
21
21
  variables: Array<TypegenManifestVariable>;
22
22
  };
23
+ type TypegenMetadataIdentity = {
24
+ baseUrl: string;
25
+ orgSlug: string;
26
+ projectSlug: string;
27
+ stageSlug: string;
28
+ };
23
29
  export declare function resolveInstalledSdkGeneratedTypesPath(): Promise<string | null>;
24
- export declare function writeInstalledSdkGeneratedTypes(manifest: TypegenManifest): Promise<BarekeyTypegenResult>;
30
+ export declare function hasFreshInstalledSdkTypegen(intervalMs: number, identity: TypegenMetadataIdentity): Promise<boolean>;
31
+ export declare function writeInstalledSdkGeneratedTypes(manifest: TypegenManifest, identity: TypegenMetadataIdentity): Promise<BarekeyTypegenResult>;
32
+ export {};
25
33
  //# sourceMappingURL=typegen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typegen.d.ts","sourceRoot":"","sources":["../../src/internal/typegen.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEjF,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IACvC,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACzE,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,eAAe,EAAE,QAAQ,GAAG,IAAI,CAAC;IACjC,iBAAiB,EAAE,KAAK,CAAC,uBAAuB,CAAC,GAAG,IAAI,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;CAC3C,CAAC;AA+DF,wBAAsB,qCAAqC,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGpF;AAED,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,oBAAoB,CAAC,CAyB/B"}
1
+ {"version":3,"file":"typegen.d.ts","sourceRoot":"","sources":["../../src/internal/typegen.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IACvC,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACzE,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,eAAe,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC/C,iBAAiB,EAAE,KAAK,CAAC,uBAAuB,CAAC,GAAG,IAAI,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;CAC3C,CAAC;AAcF,KAAK,uBAAuB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AA4IF,wBAAsB,qCAAqC,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGpF;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAAC,oBAAoB,CAAC,CAiC/B"}
@@ -1,5 +1,6 @@
1
1
  import { readTextFile, resolveInstalledSdkTypegenTarget, writeTextFileAtomic, } from "./node-runtime.js";
2
2
  const MANIFEST_VERSION_PATTERN = /\/\* barekey-manifest-version: ([^\n]+) \*\//;
3
+ const TYPEGEN_METADATA_VERSION = 1;
3
4
  function renderLinearMilestones(milestones) {
4
5
  if (milestones.length === 0) {
5
6
  return "readonly []";
@@ -8,6 +9,16 @@ function renderLinearMilestones(milestones) {
8
9
  .map((milestone) => `readonly [${JSON.stringify(milestone.at)}, ${String(milestone.percentage)}]`)
9
10
  .join(", ")}]`;
10
11
  }
12
+ function renderRolloutMetadataType(row) {
13
+ const renderedMilestones = renderLinearMilestones(row.rolloutMilestones ?? []);
14
+ if (row.rolloutFunction === "step") {
15
+ return `Step<${renderedMilestones}>`;
16
+ }
17
+ if (row.rolloutFunction === "ease_in_out") {
18
+ return `EaseInOut<${renderedMilestones}>`;
19
+ }
20
+ return `Linear<${renderedMilestones}>`;
21
+ }
11
22
  function renderVariableType(row) {
12
23
  if (row.kind === "secret") {
13
24
  return `Env<Secret, ${row.typeScriptType}>`;
@@ -15,7 +26,7 @@ function renderVariableType(row) {
15
26
  if (row.kind === "ab_roll") {
16
27
  return `Env<AB, ${row.typeScriptType}>`;
17
28
  }
18
- return `Env<AB, ${row.typeScriptType}, Linear<${renderLinearMilestones(row.rolloutMilestones ?? [])}>>`;
29
+ return `Env<AB, ${row.typeScriptType}, ${renderRolloutMetadataType(row)}>`;
19
30
  }
20
31
  function buildGeneratedTypesContents(manifest) {
21
32
  const mapLines = manifest.variables
@@ -27,7 +38,7 @@ function buildGeneratedTypesContents(manifest) {
27
38
  /* This file is generated by barekey typegen. */
28
39
  /* barekey-manifest-version: ${manifest.manifestVersion} */
29
40
 
30
- import type { AB, Env, Linear, Secret } from "./dist/types.js";
41
+ import type { AB, EaseInOut, Env, Linear, Secret, Step } from "./dist/types.js";
31
42
 
32
43
  declare module "./dist/types.js" {
33
44
  interface BarekeyGeneratedTypeMap {
@@ -45,11 +56,78 @@ function readManifestVersion(contents) {
45
56
  const match = contents.match(MANIFEST_VERSION_PATTERN);
46
57
  return match?.[1]?.trim() ?? null;
47
58
  }
59
+ function parseTypegenMetadata(contents) {
60
+ if (contents === null) {
61
+ return null;
62
+ }
63
+ try {
64
+ const parsed = JSON.parse(contents);
65
+ if (typeof parsed !== "object" || parsed === null) {
66
+ return null;
67
+ }
68
+ const candidate = parsed;
69
+ if (candidate.version !== TYPEGEN_METADATA_VERSION ||
70
+ typeof candidate.last !== "string" ||
71
+ (candidate.baseUrl !== undefined &&
72
+ candidate.baseUrl !== null &&
73
+ typeof candidate.baseUrl !== "string") ||
74
+ (candidate.orgSlug !== undefined &&
75
+ candidate.orgSlug !== null &&
76
+ typeof candidate.orgSlug !== "string") ||
77
+ (candidate.projectSlug !== undefined &&
78
+ candidate.projectSlug !== null &&
79
+ typeof candidate.projectSlug !== "string") ||
80
+ (candidate.stageSlug !== undefined &&
81
+ candidate.stageSlug !== null &&
82
+ typeof candidate.stageSlug !== "string") ||
83
+ !Number.isFinite(Date.parse(candidate.last))) {
84
+ return null;
85
+ }
86
+ return {
87
+ version: TYPEGEN_METADATA_VERSION,
88
+ last: candidate.last,
89
+ baseUrl: candidate.baseUrl ?? null,
90
+ orgSlug: candidate.orgSlug ?? null,
91
+ projectSlug: candidate.projectSlug ?? null,
92
+ stageSlug: candidate.stageSlug ?? null,
93
+ };
94
+ }
95
+ catch {
96
+ return null;
97
+ }
98
+ }
99
+ function buildTypegenMetadataContents(lastGeneratedAt, identity) {
100
+ return `${JSON.stringify({
101
+ version: TYPEGEN_METADATA_VERSION,
102
+ last: lastGeneratedAt.toISOString(),
103
+ baseUrl: identity.baseUrl,
104
+ orgSlug: identity.orgSlug,
105
+ projectSlug: identity.projectSlug,
106
+ stageSlug: identity.stageSlug,
107
+ }, null, 2)}\n`;
108
+ }
48
109
  export async function resolveInstalledSdkGeneratedTypesPath() {
49
110
  const target = await resolveInstalledSdkTypegenTarget();
50
111
  return target?.generatedTypesPath ?? null;
51
112
  }
52
- export async function writeInstalledSdkGeneratedTypes(manifest) {
113
+ export async function hasFreshInstalledSdkTypegen(intervalMs, identity) {
114
+ const target = await resolveInstalledSdkTypegenTarget();
115
+ if (target === null) {
116
+ return false;
117
+ }
118
+ const metadata = parseTypegenMetadata(await readTextFile(target.typegenMetadataPath));
119
+ if (metadata === null) {
120
+ return false;
121
+ }
122
+ if (metadata.baseUrl !== identity.baseUrl ||
123
+ metadata.orgSlug !== identity.orgSlug ||
124
+ metadata.projectSlug !== identity.projectSlug ||
125
+ metadata.stageSlug !== identity.stageSlug) {
126
+ return false;
127
+ }
128
+ return Date.now() - Date.parse(metadata.last) < intervalMs;
129
+ }
130
+ export async function writeInstalledSdkGeneratedTypes(manifest, identity) {
53
131
  const target = await resolveInstalledSdkTypegenTarget();
54
132
  if (target === null) {
55
133
  return {
@@ -60,6 +138,7 @@ export async function writeInstalledSdkGeneratedTypes(manifest) {
60
138
  }
61
139
  const existingContents = await readTextFile(target.generatedTypesPath);
62
140
  if (readManifestVersion(existingContents) === manifest.manifestVersion) {
141
+ await writeTextFileAtomic(target.typegenMetadataPath, buildTypegenMetadataContents(new Date(), identity));
63
142
  return {
64
143
  written: false,
65
144
  path: target.generatedTypesPath,
@@ -67,6 +146,7 @@ export async function writeInstalledSdkGeneratedTypes(manifest) {
67
146
  };
68
147
  }
69
148
  await writeTextFileAtomic(target.generatedTypesPath, buildGeneratedTypesContents(manifest));
149
+ await writeTextFileAtomic(target.typegenMetadataPath, buildTypegenMetadataContents(new Date(), identity));
70
150
  return {
71
151
  written: true,
72
152
  path: target.generatedTypesPath,
package/dist/types.d.ts CHANGED
@@ -15,6 +15,14 @@ export type Linear<TMilestones extends ReadonlyArray<readonly [string, number]>
15
15
  readonly kind: "linear";
16
16
  readonly milestones: TMilestones;
17
17
  };
18
+ export type Step<TMilestones extends ReadonlyArray<readonly [string, number]> = ReadonlyArray<readonly [string, number]>> = {
19
+ readonly kind: "step";
20
+ readonly milestones: TMilestones;
21
+ };
22
+ export type EaseInOut<TMilestones extends ReadonlyArray<readonly [string, number]> = ReadonlyArray<readonly [string, number]>> = {
23
+ readonly kind: "ease_in_out";
24
+ readonly milestones: TMilestones;
25
+ };
18
26
  export type Env<TMode, TValue, TFunction = never> = TValue & {
19
27
  readonly __barekey?: {
20
28
  readonly mode: TMode;
@@ -29,12 +37,14 @@ export type BarekeyRolloutMilestone = {
29
37
  at: string;
30
38
  percentage: number;
31
39
  };
40
+ export type BarekeyRolloutFunction = "linear" | "step" | "ease_in_out";
41
+ export type BarekeyRolloutMatchedRule = "linear_rollout" | "step_rollout" | "ease_in_out_rollout";
32
42
  export type BarekeyDecision = {
33
43
  bucket: number;
34
44
  chance: number;
35
45
  seed?: string;
36
46
  key?: string;
37
- matchedRule: "ab_roll" | "linear_rollout";
47
+ matchedRule: "ab_roll" | BarekeyRolloutMatchedRule;
38
48
  };
39
49
  export type BarekeyEvaluatedValue = {
40
50
  name: string;
@@ -62,7 +72,7 @@ export type BarekeyVariableDefinition = {
62
72
  declaredType: BarekeyDeclaredType;
63
73
  valueA: string;
64
74
  valueB: string;
65
- rolloutFunction: "linear";
75
+ rolloutFunction: BarekeyRolloutFunction;
66
76
  rolloutMilestones: Array<BarekeyRolloutMilestone>;
67
77
  };
68
78
  export type BarekeyGetOptions = {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAEnE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7F,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,MAAM,IAAI,MAAM,CAAC;IACjB,QAAQ,IAAI,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,IAAI,GAAG,0BAA0B,CAAC;AAEzE,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC;AAE9B,MAAM,MAAM,EAAE,GAAG,IAAI,CAAC;AAEtB,MAAM,MAAM,MAAM,CAChB,WAAW,SAAS,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,aAAa,CAC1E,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAC1B,IACC;IACF,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,IAAI,CACd,WAAW,SAAS,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,aAAa,CAC1E,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAC1B,IACC;IACF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,SAAS,CACnB,WAAW,SAAS,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,aAAa,CAC1E,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAC1B,IACC;IACF,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAG,KAAK,IAAI,MAAM,GAAG;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE;QACnB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7F,MAAM,WAAW,uBAAuB;CAAG;AAE3C,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,uBAAuB,EAAE,MAAM,CAAC,CAAC;AAE7E,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;AAEvE,MAAM,MAAM,yBAAyB,GACjC,gBAAgB,GAChB,cAAc,GACd,qBAAqB,CAAC;AAE1B,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,SAAS,GAAG,yBAAyB,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,mBAAmB,CAAC;IAC1B,YAAY,EAAE,mBAAmB,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,WAAW,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,mBAAmB,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,sBAAsB,CAAC;IACxC,iBAAiB,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;CACnD,CAAC;AAEN,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,IAAI,GAAG;QAAE,GAAG,EAAE,eAAe,CAAA;KAAE,CAAC;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACnC;IACE,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB,GACD;IACE,MAAM,EAAE,aAAa,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,aAAa,CAAC,gCAAgC,CAAC,CAAC;KACxD,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEN,MAAM,MAAM,gCAAgC,GACxC,WAAW,GACX;IACE,GAAG,EAAE,WAAW,CAAC;CAClB,CAAC;AAEN,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;QACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,2BAA2B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;KAC9F,CAAC;CACH,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,OAAO,CAAC,EAAE,KAAK,GAAG;QAAE,GAAG,CAAC,EAAE,eAAe,CAAA;KAAE,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC5B,CAAC,wBAAwB,GAAG;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,KAAK,CAAC;CACd,CAAC,GACF,CAAC,wBAAwB,GAAG;IAC1B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB,CAAC,GACF,CAAC,wBAAwB,GAAG;IAC1B,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,IAAI,CAAC,EAAE,KAAK,CAAC;CACd,CAAC,CAAC;AAEP,MAAM,MAAM,gBAAgB,GACxB,kBAAkB,GAClB,2BAA2B,GAC3B,gCAAgC,GAChC,yBAAyB,GACzB,8BAA8B,GAC9B,yBAAyB,GACzB,gCAAgC,GAChC,eAAe,GACf,eAAe,GACf,wBAAwB,GACxB,sBAAsB,GACtB,yBAAyB,GACzB,qBAAqB,GACrB,sBAAsB,GACtB,cAAc,GACd,mBAAmB,GACnB,mBAAmB,GACnB,cAAc,GACd,iBAAiB,GACjB,oBAAoB,GACpB,mBAAmB,GACnB,sBAAsB,GACtB,qBAAqB,GACrB,uBAAuB,GACvB,qBAAqB,GACrB,mBAAmB,GACnB,uBAAuB,GACvB,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barekey/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Barekey TypeScript SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/client.ts CHANGED
@@ -17,6 +17,7 @@ import { resolveRuntimeContext, type BarekeyRuntimeContext } from "./internal/ru
17
17
  import { MemoryCache } from "./internal/cache.js";
18
18
  import { DEFAULT_TYPEGEN_TTL_MS, resolveTtlMilliseconds } from "./internal/ttl.js";
19
19
  import {
20
+ hasFreshInstalledSdkTypegen,
20
21
  resolveInstalledSdkGeneratedTypesPath,
21
22
  type TypegenManifest,
22
23
  writeInstalledSdkGeneratedTypes,
@@ -127,7 +128,12 @@ export class BarekeyClient {
127
128
  }
128
129
 
129
130
  const manifest = await this.fetchTypegenManifest(context);
130
- return await writeInstalledSdkGeneratedTypes(manifest);
131
+ return await writeInstalledSdkGeneratedTypes(manifest, {
132
+ baseUrl: context.baseUrl,
133
+ orgSlug: context.organization,
134
+ projectSlug: context.project,
135
+ stageSlug: context.environment,
136
+ });
131
137
  }
132
138
 
133
139
  private async getRuntimeContext(): Promise<BarekeyRuntimeContext> {
@@ -233,7 +239,16 @@ export class BarekeyClient {
233
239
  }, intervalMs),
234
240
  };
235
241
  sharedTypegenWatchers.set(watcherKey, watcher);
236
- void runWatcher(watcher);
242
+ if (
243
+ !(await hasFreshInstalledSdkTypegen(intervalMs, {
244
+ baseUrl: context.baseUrl,
245
+ orgSlug: context.organization,
246
+ projectSlug: context.project,
247
+ stageSlug: context.environment,
248
+ }))
249
+ ) {
250
+ void runWatcher(watcher);
251
+ }
237
252
  }
238
253
 
239
254
  private ensureTypegenWatcher(context: BarekeyRuntimeContext): void {
@@ -13,6 +13,8 @@ import type {
13
13
  BarekeyDecision,
14
14
  BarekeyEvaluatedValue,
15
15
  BarekeyGetOptions,
16
+ BarekeyRolloutFunction,
17
+ BarekeyRolloutMatchedRule,
16
18
  BarekeyRolloutMilestone,
17
19
  BarekeyVariableDefinition,
18
20
  } from "../types.js";
@@ -82,14 +84,76 @@ function resolveLinearRolloutChance(input: {
82
84
  milestones: Array<BarekeyRolloutMilestone>;
83
85
  nowMs: number;
84
86
  }): number {
87
+ return resolveRolloutChance({
88
+ function: "linear",
89
+ milestones: input.milestones,
90
+ nowMs: input.nowMs,
91
+ }).chance;
92
+ }
93
+
94
+ function smoothstep(progress: number): number {
95
+ return progress * progress * (3 - 2 * progress);
96
+ }
97
+
98
+ function resolveSegmentPercentage(input: {
99
+ function: BarekeyRolloutFunction;
100
+ currentPercentage: number;
101
+ nextPercentage: number;
102
+ progress: number;
103
+ }): number {
104
+ if (input.function === "step") {
105
+ return input.currentPercentage;
106
+ }
107
+
108
+ if (input.function === "ease_in_out") {
109
+ const easedProgress = smoothstep(input.progress);
110
+ return (
111
+ input.currentPercentage +
112
+ (input.nextPercentage - input.currentPercentage) * easedProgress
113
+ );
114
+ }
115
+
116
+ return (
117
+ input.currentPercentage +
118
+ (input.nextPercentage - input.currentPercentage) * input.progress
119
+ );
120
+ }
121
+
122
+ function matchedRuleForRolloutFunction(
123
+ value: BarekeyRolloutFunction,
124
+ ): BarekeyRolloutMatchedRule {
125
+ if (value === "step") {
126
+ return "step_rollout";
127
+ }
128
+ if (value === "ease_in_out") {
129
+ return "ease_in_out_rollout";
130
+ }
131
+ return "linear_rollout";
132
+ }
133
+
134
+ function resolveRolloutChance(input: {
135
+ function: BarekeyRolloutFunction;
136
+ milestones: Array<BarekeyRolloutMilestone>;
137
+ nowMs: number;
138
+ }): {
139
+ chance: number;
140
+ matchedRule: BarekeyRolloutMatchedRule;
141
+ } {
85
142
  const milestones = normalizeRolloutMilestones(input.milestones);
143
+ const matchedRule = matchedRuleForRolloutFunction(input.function);
86
144
  const first = milestones[0];
87
145
  if (first === undefined) {
88
- return 0;
146
+ return {
147
+ chance: 0,
148
+ matchedRule,
149
+ };
89
150
  }
90
151
 
91
152
  if (input.nowMs < parseRolloutInstant(first.at)) {
92
- return 0;
153
+ return {
154
+ chance: 0,
155
+ matchedRule,
156
+ };
93
157
  }
94
158
 
95
159
  for (let index = 0; index < milestones.length - 1; index += 1) {
@@ -103,13 +167,24 @@ function resolveLinearRolloutChance(input: {
103
167
  const nextAtMs = parseRolloutInstant(next.at);
104
168
  if (input.nowMs >= currentAtMs && input.nowMs < nextAtMs) {
105
169
  const progress = (input.nowMs - currentAtMs) / (nextAtMs - currentAtMs);
106
- const percentage = current.percentage + (next.percentage - current.percentage) * progress;
107
- return percentage / 100;
170
+ const percentage = resolveSegmentPercentage({
171
+ function: input.function,
172
+ currentPercentage: current.percentage,
173
+ nextPercentage: next.percentage,
174
+ progress,
175
+ });
176
+ return {
177
+ chance: percentage / 100,
178
+ matchedRule,
179
+ };
108
180
  }
109
181
  }
110
182
 
111
183
  const last = milestones[milestones.length - 1];
112
- return last === undefined ? 0 : last.percentage / 100;
184
+ return {
185
+ chance: last === undefined ? 0 : last.percentage / 100,
186
+ matchedRule,
187
+ };
113
188
  }
114
189
 
115
190
  export async function evaluateDefinition(
@@ -150,7 +225,8 @@ export async function evaluateDefinition(
150
225
  };
151
226
  }
152
227
 
153
- const chance = resolveLinearRolloutChance({
228
+ const { chance, matchedRule } = resolveRolloutChance({
229
+ function: definition.rolloutFunction,
154
230
  milestones: definition.rolloutMilestones,
155
231
  nowMs: Date.now(),
156
232
  });
@@ -166,7 +242,7 @@ export async function evaluateDefinition(
166
242
  chance,
167
243
  seed: seed.length > 0 ? seed : undefined,
168
244
  key: key.length > 0 ? key : undefined,
169
- matchedRule: "linear_rollout",
245
+ matchedRule,
170
246
  },
171
247
  };
172
248
  }
@@ -477,6 +477,7 @@ function isMissingModuleError(error: unknown): boolean {
477
477
  type InstalledSdkTypegenTarget = {
478
478
  packageRoot: string;
479
479
  generatedTypesPath: string;
480
+ typegenMetadataPath: string;
480
481
  };
481
482
 
482
483
  export async function resolveInstalledSdkTypegenTarget(): Promise<InstalledSdkTypegenTarget | null> {
@@ -520,6 +521,7 @@ export async function resolveInstalledSdkTypegenTarget(): Promise<InstalledSdkTy
520
521
  return {
521
522
  packageRoot: current,
522
523
  generatedTypesPath,
524
+ typegenMetadataPath: runtime.path.join(current, "typegen.json"),
523
525
  };
524
526
  }
525
527
 
@@ -3,7 +3,11 @@ import {
3
3
  resolveInstalledSdkTypegenTarget,
4
4
  writeTextFileAtomic,
5
5
  } from "./node-runtime.js";
6
- import type { BarekeyRolloutMilestone, BarekeyTypegenResult } from "../types.js";
6
+ import type {
7
+ BarekeyRolloutFunction,
8
+ BarekeyRolloutMilestone,
9
+ BarekeyTypegenResult,
10
+ } from "../types.js";
7
11
 
8
12
  export type TypegenManifestVariable = {
9
13
  name: string;
@@ -14,7 +18,7 @@ export type TypegenManifestVariable = {
14
18
  typeScriptType: string;
15
19
  valueATypeScriptType: string | null;
16
20
  valueBTypeScriptType: string | null;
17
- rolloutFunction: "linear" | null;
21
+ rolloutFunction: BarekeyRolloutFunction | null;
18
22
  rolloutMilestones: Array<BarekeyRolloutMilestone> | null;
19
23
  };
20
24
 
@@ -29,6 +33,23 @@ export type TypegenManifest = {
29
33
  };
30
34
 
31
35
  const MANIFEST_VERSION_PATTERN = /\/\* barekey-manifest-version: ([^\n]+) \*\//;
36
+ const TYPEGEN_METADATA_VERSION = 1;
37
+
38
+ type TypegenMetadata = {
39
+ version: number;
40
+ last: string;
41
+ baseUrl: string | null;
42
+ orgSlug: string | null;
43
+ projectSlug: string | null;
44
+ stageSlug: string | null;
45
+ };
46
+
47
+ type TypegenMetadataIdentity = {
48
+ baseUrl: string;
49
+ orgSlug: string;
50
+ projectSlug: string;
51
+ stageSlug: string;
52
+ };
32
53
 
33
54
  function renderLinearMilestones(milestones: Array<BarekeyRolloutMilestone>): string {
34
55
  if (milestones.length === 0) {
@@ -43,6 +64,17 @@ function renderLinearMilestones(milestones: Array<BarekeyRolloutMilestone>): str
43
64
  .join(", ")}]`;
44
65
  }
45
66
 
67
+ function renderRolloutMetadataType(row: TypegenManifestVariable): string {
68
+ const renderedMilestones = renderLinearMilestones(row.rolloutMilestones ?? []);
69
+ if (row.rolloutFunction === "step") {
70
+ return `Step<${renderedMilestones}>`;
71
+ }
72
+ if (row.rolloutFunction === "ease_in_out") {
73
+ return `EaseInOut<${renderedMilestones}>`;
74
+ }
75
+ return `Linear<${renderedMilestones}>`;
76
+ }
77
+
46
78
  function renderVariableType(row: TypegenManifestVariable): string {
47
79
  if (row.kind === "secret") {
48
80
  return `Env<Secret, ${row.typeScriptType}>`;
@@ -52,9 +84,7 @@ function renderVariableType(row: TypegenManifestVariable): string {
52
84
  return `Env<AB, ${row.typeScriptType}>`;
53
85
  }
54
86
 
55
- return `Env<AB, ${row.typeScriptType}, Linear<${renderLinearMilestones(
56
- row.rolloutMilestones ?? [],
57
- )}>>`;
87
+ return `Env<AB, ${row.typeScriptType}, ${renderRolloutMetadataType(row)}>`;
58
88
  }
59
89
 
60
90
  function buildGeneratedTypesContents(manifest: TypegenManifest): string {
@@ -68,7 +98,7 @@ function buildGeneratedTypesContents(manifest: TypegenManifest): string {
68
98
  /* This file is generated by barekey typegen. */
69
99
  /* barekey-manifest-version: ${manifest.manifestVersion} */
70
100
 
71
- import type { AB, Env, Linear, Secret } from "./dist/types.js";
101
+ import type { AB, EaseInOut, Env, Linear, Secret, Step } from "./dist/types.js";
72
102
 
73
103
  declare module "./dist/types.js" {
74
104
  interface BarekeyGeneratedTypeMap {
@@ -89,13 +119,110 @@ function readManifestVersion(contents: string | null): string | null {
89
119
  return match?.[1]?.trim() ?? null;
90
120
  }
91
121
 
122
+ function parseTypegenMetadata(contents: string | null): TypegenMetadata | null {
123
+ if (contents === null) {
124
+ return null;
125
+ }
126
+
127
+ try {
128
+ const parsed = JSON.parse(contents) as unknown;
129
+ if (typeof parsed !== "object" || parsed === null) {
130
+ return null;
131
+ }
132
+
133
+ const candidate = parsed as {
134
+ version?: unknown;
135
+ last?: unknown;
136
+ baseUrl?: unknown;
137
+ orgSlug?: unknown;
138
+ projectSlug?: unknown;
139
+ stageSlug?: unknown;
140
+ };
141
+ if (
142
+ candidate.version !== TYPEGEN_METADATA_VERSION ||
143
+ typeof candidate.last !== "string" ||
144
+ (candidate.baseUrl !== undefined &&
145
+ candidate.baseUrl !== null &&
146
+ typeof candidate.baseUrl !== "string") ||
147
+ (candidate.orgSlug !== undefined &&
148
+ candidate.orgSlug !== null &&
149
+ typeof candidate.orgSlug !== "string") ||
150
+ (candidate.projectSlug !== undefined &&
151
+ candidate.projectSlug !== null &&
152
+ typeof candidate.projectSlug !== "string") ||
153
+ (candidate.stageSlug !== undefined &&
154
+ candidate.stageSlug !== null &&
155
+ typeof candidate.stageSlug !== "string") ||
156
+ !Number.isFinite(Date.parse(candidate.last))
157
+ ) {
158
+ return null;
159
+ }
160
+
161
+ return {
162
+ version: TYPEGEN_METADATA_VERSION,
163
+ last: candidate.last,
164
+ baseUrl: candidate.baseUrl ?? null,
165
+ orgSlug: candidate.orgSlug ?? null,
166
+ projectSlug: candidate.projectSlug ?? null,
167
+ stageSlug: candidate.stageSlug ?? null,
168
+ };
169
+ } catch {
170
+ return null;
171
+ }
172
+ }
173
+
174
+ function buildTypegenMetadataContents(
175
+ lastGeneratedAt: Date,
176
+ identity: TypegenMetadataIdentity,
177
+ ): string {
178
+ return `${JSON.stringify(
179
+ {
180
+ version: TYPEGEN_METADATA_VERSION,
181
+ last: lastGeneratedAt.toISOString(),
182
+ baseUrl: identity.baseUrl,
183
+ orgSlug: identity.orgSlug,
184
+ projectSlug: identity.projectSlug,
185
+ stageSlug: identity.stageSlug,
186
+ },
187
+ null,
188
+ 2,
189
+ )}\n`;
190
+ }
191
+
92
192
  export async function resolveInstalledSdkGeneratedTypesPath(): Promise<string | null> {
93
193
  const target = await resolveInstalledSdkTypegenTarget();
94
194
  return target?.generatedTypesPath ?? null;
95
195
  }
96
196
 
197
+ export async function hasFreshInstalledSdkTypegen(
198
+ intervalMs: number,
199
+ identity: TypegenMetadataIdentity,
200
+ ): Promise<boolean> {
201
+ const target = await resolveInstalledSdkTypegenTarget();
202
+ if (target === null) {
203
+ return false;
204
+ }
205
+
206
+ const metadata = parseTypegenMetadata(await readTextFile(target.typegenMetadataPath));
207
+ if (metadata === null) {
208
+ return false;
209
+ }
210
+
211
+ if (
212
+ metadata.baseUrl !== identity.baseUrl ||
213
+ metadata.orgSlug !== identity.orgSlug ||
214
+ metadata.projectSlug !== identity.projectSlug ||
215
+ metadata.stageSlug !== identity.stageSlug
216
+ ) {
217
+ return false;
218
+ }
219
+
220
+ return Date.now() - Date.parse(metadata.last) < intervalMs;
221
+ }
222
+
97
223
  export async function writeInstalledSdkGeneratedTypes(
98
224
  manifest: TypegenManifest,
225
+ identity: TypegenMetadataIdentity,
99
226
  ): Promise<BarekeyTypegenResult> {
100
227
  const target = await resolveInstalledSdkTypegenTarget();
101
228
  if (target === null) {
@@ -108,6 +235,10 @@ export async function writeInstalledSdkGeneratedTypes(
108
235
 
109
236
  const existingContents = await readTextFile(target.generatedTypesPath);
110
237
  if (readManifestVersion(existingContents) === manifest.manifestVersion) {
238
+ await writeTextFileAtomic(
239
+ target.typegenMetadataPath,
240
+ buildTypegenMetadataContents(new Date(), identity),
241
+ );
111
242
  return {
112
243
  written: false,
113
244
  path: target.generatedTypesPath,
@@ -116,6 +247,10 @@ export async function writeInstalledSdkGeneratedTypes(
116
247
  }
117
248
 
118
249
  await writeTextFileAtomic(target.generatedTypesPath, buildGeneratedTypesContents(manifest));
250
+ await writeTextFileAtomic(
251
+ target.typegenMetadataPath,
252
+ buildTypegenMetadataContents(new Date(), identity),
253
+ );
119
254
  return {
120
255
  written: true,
121
256
  path: target.generatedTypesPath,
package/src/types.ts CHANGED
@@ -27,6 +27,24 @@ export type Linear<
27
27
  readonly milestones: TMilestones;
28
28
  };
29
29
 
30
+ export type Step<
31
+ TMilestones extends ReadonlyArray<readonly [string, number]> = ReadonlyArray<
32
+ readonly [string, number]
33
+ >,
34
+ > = {
35
+ readonly kind: "step";
36
+ readonly milestones: TMilestones;
37
+ };
38
+
39
+ export type EaseInOut<
40
+ TMilestones extends ReadonlyArray<readonly [string, number]> = ReadonlyArray<
41
+ readonly [string, number]
42
+ >,
43
+ > = {
44
+ readonly kind: "ease_in_out";
45
+ readonly milestones: TMilestones;
46
+ };
47
+
30
48
  export type Env<TMode, TValue, TFunction = never> = TValue & {
31
49
  readonly __barekey?: {
32
50
  readonly mode: TMode;
@@ -45,12 +63,19 @@ export type BarekeyRolloutMilestone = {
45
63
  percentage: number;
46
64
  };
47
65
 
66
+ export type BarekeyRolloutFunction = "linear" | "step" | "ease_in_out";
67
+
68
+ export type BarekeyRolloutMatchedRule =
69
+ | "linear_rollout"
70
+ | "step_rollout"
71
+ | "ease_in_out_rollout";
72
+
48
73
  export type BarekeyDecision = {
49
74
  bucket: number;
50
75
  chance: number;
51
76
  seed?: string;
52
77
  key?: string;
53
- matchedRule: "ab_roll" | "linear_rollout";
78
+ matchedRule: "ab_roll" | BarekeyRolloutMatchedRule;
54
79
  };
55
80
 
56
81
  export type BarekeyEvaluatedValue = {
@@ -83,7 +108,7 @@ export type BarekeyVariableDefinition =
83
108
  declaredType: BarekeyDeclaredType;
84
109
  valueA: string;
85
110
  valueB: string;
86
- rolloutFunction: "linear";
111
+ rolloutFunction: BarekeyRolloutFunction;
87
112
  rolloutMilestones: Array<BarekeyRolloutMilestone>;
88
113
  };
89
114