@shipeasy/sdk 5.4.0 → 6.0.0

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.
@@ -20,14 +20,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/client/index.ts
21
21
  var client_exports = {};
22
22
  __export(client_exports, {
23
+ Client: () => Client,
24
+ Engine: () => Engine,
23
25
  FLAG_REASONS: () => FLAG_REASONS,
24
- FlagsClientBrowser: () => FlagsClientBrowser,
25
26
  LABEL_MARKER_END: () => LABEL_MARKER_END,
26
27
  LABEL_MARKER_RE: () => LABEL_MARKER_RE,
27
28
  LABEL_MARKER_SEP: () => LABEL_MARKER_SEP,
28
29
  LABEL_MARKER_START: () => LABEL_MARKER_START,
30
+ _resetConfigureForTests: () => _resetConfigureForTests,
29
31
  _resetShipeasyForTests: () => _resetShipeasyForTests,
30
32
  attachDevtools: () => attachDevtools,
33
+ configure: () => configure,
31
34
  configureShipeasy: () => configureShipeasy,
32
35
  encodeLabelMarker: () => encodeLabelMarker,
33
36
  flags: () => flags,
@@ -912,7 +915,7 @@ function readExperimentOverridesFromUrl() {
912
915
  }
913
916
  return out;
914
917
  }
915
- var FlagsClientBrowser = class _FlagsClientBrowser {
918
+ var Engine = class _Engine {
916
919
  sdkKey;
917
920
  baseUrl;
918
921
  autoGuardrails;
@@ -934,7 +937,7 @@ var FlagsClientBrowser = class _FlagsClientBrowser {
934
937
  // Monotonic counter so a later identify() always wins even if its /sdk/evaluate
935
938
  // response races and lands before an earlier in-flight call's response.
936
939
  identifySeq = 0;
937
- // Test mode: built by `FlagsClientBrowser.forTesting()`. When set, identify()
940
+ // Test mode: built by `Engine.forTesting()`. When set, identify()
938
941
  // never fetches, track() is a no-op, telemetry is off, and the client is
939
942
  // already ready with an empty eval result.
940
943
  testMode;
@@ -988,13 +991,13 @@ var FlagsClientBrowser = class _FlagsClientBrowser {
988
991
  * key required.
989
992
  *
990
993
  * ```ts
991
- * const client = FlagsClientBrowser.forTesting();
994
+ * const client = Engine.forTesting();
992
995
  * client.overrideFlag("new_checkout", true);
993
996
  * client.getFlag("new_checkout"); // true
994
997
  * ```
995
998
  */
996
999
  static forTesting(opts) {
997
- return new _FlagsClientBrowser({
1000
+ return new _Engine({
998
1001
  sdkKey: "",
999
1002
  autoGuardrails: false,
1000
1003
  ...opts,
@@ -1415,7 +1418,7 @@ function shipeasy(opts) {
1415
1418
  }
1416
1419
  function configureShipeasy(opts) {
1417
1420
  if (_client) return _client;
1418
- _client = new FlagsClientBrowser(opts);
1421
+ _client = new Engine(opts);
1419
1422
  return _client;
1420
1423
  }
1421
1424
  function getShipeasyClient() {
@@ -1554,7 +1557,7 @@ var flags = {
1554
1557
  return typeof decodeOrOpts === "function" ? _client.getExperiment(name, defaultParams, decodeOrOpts, variants) : _client.getExperiment(name, defaultParams, decodeOrOpts ?? {});
1555
1558
  },
1556
1559
  /** Manually log an exposure for an enrolled experiment. See
1557
- * {@link FlagsClientBrowser.logExposure}. No-op before configure(). */
1560
+ * {@link Engine.logExposure}. No-op before configure(). */
1558
1561
  logExposure(name) {
1559
1562
  _client?.logExposure(name);
1560
1563
  },
@@ -1611,6 +1614,55 @@ var flags = {
1611
1614
  return _client?.ready ?? false;
1612
1615
  }
1613
1616
  };
1617
+ var _identityAttributes = (user) => user && typeof user === "object" ? user : {};
1618
+ var _attributes = _identityAttributes;
1619
+ function configure(opts) {
1620
+ const { attributes, ...clientConfig } = opts;
1621
+ _attributes = attributes ?? _identityAttributes;
1622
+ return shipeasy({ autoIdentify: false, ...clientConfig });
1623
+ }
1624
+ function _resetConfigureForTests() {
1625
+ _attributes = _identityAttributes;
1626
+ }
1627
+ var Client = class {
1628
+ engine;
1629
+ /** The resolved attribute bag this handle evaluates against. */
1630
+ attributes;
1631
+ _identify;
1632
+ constructor(user) {
1633
+ const engine = getShipeasyClient();
1634
+ if (!engine) {
1635
+ throw new Error(
1636
+ "[shipeasy] new Client(user) called before configure({ clientKey }). Call configure() once at app boot from @shipeasy/sdk/client."
1637
+ );
1638
+ }
1639
+ this.engine = engine;
1640
+ this.attributes = _attributes(user);
1641
+ this._identify = this.engine.identify(this.attributes).catch((err) => {
1642
+ console.warn("[shipeasy] Client identify failed:", String(err));
1643
+ });
1644
+ }
1645
+ /** Resolves once the engine's identify() for this user has completed. */
1646
+ ready() {
1647
+ return this._identify;
1648
+ }
1649
+ getFlag(name, defaultValue = false) {
1650
+ return this.engine.getFlag(name, defaultValue);
1651
+ }
1652
+ getFlagDetail(name) {
1653
+ return this.engine.getFlagDetail(name);
1654
+ }
1655
+ getConfig(name, decodeOrOpts) {
1656
+ return this.engine.getConfig(name, decodeOrOpts);
1657
+ }
1658
+ getExperiment(name, defaultParams, decode) {
1659
+ return this.engine.getExperiment(name, defaultParams, decode);
1660
+ }
1661
+ /** Read a killswitch (not user-bound; mirrors {@link Engine.getKillswitch}). */
1662
+ getKillswitch(name, switchKey) {
1663
+ return this.engine.getKillswitch(name, switchKey);
1664
+ }
1665
+ };
1614
1666
  function dispatchSee(problem, consequence, extras, kind) {
1615
1667
  if (!_client) {
1616
1668
  console.warn("[shipeasy] see() called before shipeasy({ clientKey }) \u2014 error dropped");
@@ -1859,14 +1911,17 @@ var i18n = {
1859
1911
  };
1860
1912
  // Annotate the CommonJS export names for ESM import in node:
1861
1913
  0 && (module.exports = {
1914
+ Client,
1915
+ Engine,
1862
1916
  FLAG_REASONS,
1863
- FlagsClientBrowser,
1864
1917
  LABEL_MARKER_END,
1865
1918
  LABEL_MARKER_RE,
1866
1919
  LABEL_MARKER_SEP,
1867
1920
  LABEL_MARKER_START,
1921
+ _resetConfigureForTests,
1868
1922
  _resetShipeasyForTests,
1869
1923
  attachDevtools,
1924
+ configure,
1870
1925
  configureShipeasy,
1871
1926
  encodeLabelMarker,
1872
1927
  flags,
@@ -863,7 +863,7 @@ function readExperimentOverridesFromUrl() {
863
863
  }
864
864
  return out;
865
865
  }
866
- var FlagsClientBrowser = class _FlagsClientBrowser {
866
+ var Engine = class _Engine {
867
867
  sdkKey;
868
868
  baseUrl;
869
869
  autoGuardrails;
@@ -885,7 +885,7 @@ var FlagsClientBrowser = class _FlagsClientBrowser {
885
885
  // Monotonic counter so a later identify() always wins even if its /sdk/evaluate
886
886
  // response races and lands before an earlier in-flight call's response.
887
887
  identifySeq = 0;
888
- // Test mode: built by `FlagsClientBrowser.forTesting()`. When set, identify()
888
+ // Test mode: built by `Engine.forTesting()`. When set, identify()
889
889
  // never fetches, track() is a no-op, telemetry is off, and the client is
890
890
  // already ready with an empty eval result.
891
891
  testMode;
@@ -939,13 +939,13 @@ var FlagsClientBrowser = class _FlagsClientBrowser {
939
939
  * key required.
940
940
  *
941
941
  * ```ts
942
- * const client = FlagsClientBrowser.forTesting();
942
+ * const client = Engine.forTesting();
943
943
  * client.overrideFlag("new_checkout", true);
944
944
  * client.getFlag("new_checkout"); // true
945
945
  * ```
946
946
  */
947
947
  static forTesting(opts) {
948
- return new _FlagsClientBrowser({
948
+ return new _Engine({
949
949
  sdkKey: "",
950
950
  autoGuardrails: false,
951
951
  ...opts,
@@ -1366,7 +1366,7 @@ function shipeasy(opts) {
1366
1366
  }
1367
1367
  function configureShipeasy(opts) {
1368
1368
  if (_client) return _client;
1369
- _client = new FlagsClientBrowser(opts);
1369
+ _client = new Engine(opts);
1370
1370
  return _client;
1371
1371
  }
1372
1372
  function getShipeasyClient() {
@@ -1505,7 +1505,7 @@ var flags = {
1505
1505
  return typeof decodeOrOpts === "function" ? _client.getExperiment(name, defaultParams, decodeOrOpts, variants) : _client.getExperiment(name, defaultParams, decodeOrOpts ?? {});
1506
1506
  },
1507
1507
  /** Manually log an exposure for an enrolled experiment. See
1508
- * {@link FlagsClientBrowser.logExposure}. No-op before configure(). */
1508
+ * {@link Engine.logExposure}. No-op before configure(). */
1509
1509
  logExposure(name) {
1510
1510
  _client?.logExposure(name);
1511
1511
  },
@@ -1562,6 +1562,55 @@ var flags = {
1562
1562
  return _client?.ready ?? false;
1563
1563
  }
1564
1564
  };
1565
+ var _identityAttributes = (user) => user && typeof user === "object" ? user : {};
1566
+ var _attributes = _identityAttributes;
1567
+ function configure(opts) {
1568
+ const { attributes, ...clientConfig } = opts;
1569
+ _attributes = attributes ?? _identityAttributes;
1570
+ return shipeasy({ autoIdentify: false, ...clientConfig });
1571
+ }
1572
+ function _resetConfigureForTests() {
1573
+ _attributes = _identityAttributes;
1574
+ }
1575
+ var Client = class {
1576
+ engine;
1577
+ /** The resolved attribute bag this handle evaluates against. */
1578
+ attributes;
1579
+ _identify;
1580
+ constructor(user) {
1581
+ const engine = getShipeasyClient();
1582
+ if (!engine) {
1583
+ throw new Error(
1584
+ "[shipeasy] new Client(user) called before configure({ clientKey }). Call configure() once at app boot from @shipeasy/sdk/client."
1585
+ );
1586
+ }
1587
+ this.engine = engine;
1588
+ this.attributes = _attributes(user);
1589
+ this._identify = this.engine.identify(this.attributes).catch((err) => {
1590
+ console.warn("[shipeasy] Client identify failed:", String(err));
1591
+ });
1592
+ }
1593
+ /** Resolves once the engine's identify() for this user has completed. */
1594
+ ready() {
1595
+ return this._identify;
1596
+ }
1597
+ getFlag(name, defaultValue = false) {
1598
+ return this.engine.getFlag(name, defaultValue);
1599
+ }
1600
+ getFlagDetail(name) {
1601
+ return this.engine.getFlagDetail(name);
1602
+ }
1603
+ getConfig(name, decodeOrOpts) {
1604
+ return this.engine.getConfig(name, decodeOrOpts);
1605
+ }
1606
+ getExperiment(name, defaultParams, decode) {
1607
+ return this.engine.getExperiment(name, defaultParams, decode);
1608
+ }
1609
+ /** Read a killswitch (not user-bound; mirrors {@link Engine.getKillswitch}). */
1610
+ getKillswitch(name, switchKey) {
1611
+ return this.engine.getKillswitch(name, switchKey);
1612
+ }
1613
+ };
1565
1614
  function dispatchSee(problem, consequence, extras, kind) {
1566
1615
  if (!_client) {
1567
1616
  console.warn("[shipeasy] see() called before shipeasy({ clientKey }) \u2014 error dropped");
@@ -1809,14 +1858,17 @@ var i18n = {
1809
1858
  }
1810
1859
  };
1811
1860
  export {
1861
+ Client,
1862
+ Engine,
1812
1863
  FLAG_REASONS,
1813
- FlagsClientBrowser,
1814
1864
  LABEL_MARKER_END,
1815
1865
  LABEL_MARKER_RE,
1816
1866
  LABEL_MARKER_SEP,
1817
1867
  LABEL_MARKER_START,
1868
+ _resetConfigureForTests,
1818
1869
  _resetShipeasyForTests,
1819
1870
  attachDevtools,
1871
+ configure,
1820
1872
  configureShipeasy,
1821
1873
  encodeLabelMarker,
1822
1874
  flags,
@@ -78,7 +78,7 @@ interface StickyEntry {
78
78
  /**
79
79
  * Pluggable sticky-bucketing store for the server (doc 20 §2). Keyed by the
80
80
  * bucketing unit; the value is that unit's per-experiment assignments. Absent
81
- * from {@link FlagsClientOptions} ⇒ today's deterministic behaviour. Use
81
+ * from {@link EngineOptions} ⇒ today's deterministic behaviour. Use
82
82
  * {@link createInMemoryStickyStore} or a cookie-bridge built from request
83
83
  * cookies.
84
84
  */
@@ -93,7 +93,7 @@ interface Killswitch {
93
93
  killed: 0 | 1 | boolean;
94
94
  switches?: Record<string, 0 | 1 | boolean>;
95
95
  }
96
- /** Body of `GET /sdk/flags` — the snapshot's `flags` field. See {@link FlagsClient.fromSnapshot}. */
96
+ /** Body of `GET /sdk/flags` — the snapshot's `flags` field. See {@link Engine.fromSnapshot}. */
97
97
  interface FlagsBlob {
98
98
  version: string;
99
99
  plan: string;
@@ -103,7 +103,7 @@ interface FlagsBlob {
103
103
  }>;
104
104
  killswitches: Record<string, Killswitch>;
105
105
  }
106
- /** Body of `GET /sdk/experiments` — the snapshot's `experiments` field. See {@link FlagsClient.fromSnapshot}. */
106
+ /** Body of `GET /sdk/experiments` — the snapshot's `experiments` field. See {@link Engine.fromSnapshot}. */
107
107
  interface ExpsBlob {
108
108
  version: string;
109
109
  universes: Record<string, Universe>;
@@ -115,12 +115,12 @@ interface BootstrapPayload {
115
115
  experiments: Record<string, ExperimentResult<Record<string, unknown>>>;
116
116
  killswitches: Record<string, boolean | Record<string, boolean>>;
117
117
  }
118
- type FlagsClientEnv = "dev" | "staging" | "prod";
119
- interface FlagsClientOptions {
118
+ type EngineEnv = "dev" | "staging" | "prod";
119
+ interface EngineOptions {
120
120
  apiKey: string;
121
121
  baseUrl?: string;
122
122
  /** Which published env to read values from. Defaults to "prod". */
123
- env?: FlagsClientEnv;
123
+ env?: EngineEnv;
124
124
  /**
125
125
  * Preload the flags blob synchronously without a network fetch. Primarily
126
126
  * for tests; production callers should rely on init()/initOnce().
@@ -155,12 +155,12 @@ interface FlagsClientOptions {
155
155
  /**
156
156
  * Test mode — no network at all. init()/initOnce() are no-ops (never fetch),
157
157
  * track() is a no-op, telemetry is forced off, and the client starts
158
- * "initialized" with an empty blob. Prefer the {@link FlagsClient.forTesting}
158
+ * "initialized" with an empty blob. Prefer the {@link Engine.forTesting}
159
159
  * factory over passing this directly.
160
160
  */
161
161
  testMode?: boolean;
162
162
  }
163
- declare class FlagsClient {
163
+ declare class Engine {
164
164
  private readonly apiKey;
165
165
  private readonly baseUrl;
166
166
  private readonly env;
@@ -180,7 +180,7 @@ declare class FlagsClient {
180
180
  private readonly configOverrides;
181
181
  private readonly experimentOverrides;
182
182
  private readonly changeListeners;
183
- constructor(opts: FlagsClientOptions);
183
+ constructor(opts: EngineOptions);
184
184
  /**
185
185
  * Build a no-network, immediately-usable client for tests (Statsig-style).
186
186
  * init()/initOnce() are no-ops (never fetch), track() is a no-op, telemetry
@@ -188,12 +188,12 @@ declare class FlagsClient {
188
188
  * with overrideFlag/overrideConfig/overrideExperiment. No SDK key required.
189
189
  *
190
190
  * ```ts
191
- * const client = FlagsClient.forTesting();
191
+ * const client = Engine.forTesting();
192
192
  * client.overrideFlag("new_checkout", true);
193
193
  * client.getFlag("new_checkout", { user_id: "u1" }); // true
194
194
  * ```
195
195
  */
196
- static forTesting(opts?: Partial<FlagsClientOptions>): FlagsClient;
196
+ static forTesting(opts?: Partial<EngineOptions>): Engine;
197
197
  /**
198
198
  * Build a fully OFFLINE client from a pre-captured snapshot — no network ever.
199
199
  * Reuses the test-mode plumbing (init()/initOnce()/track() are no-ops,
@@ -207,14 +207,14 @@ declare class FlagsClient {
207
207
  static fromSnapshot(snapshot: {
208
208
  flags: FlagsBlob;
209
209
  experiments: ExpsBlob;
210
- }): FlagsClient;
210
+ }): Engine;
211
211
  /**
212
212
  * Build a fully OFFLINE client from a snapshot JSON file on disk (Node only —
213
213
  * not available in the browser entrypoint). The file must contain
214
214
  * `{ "flags": <GET /sdk/flags body>, "experiments": <GET /sdk/experiments body> }`.
215
- * See {@link FlagsClient.fromSnapshot}.
215
+ * See {@link Engine.fromSnapshot}.
216
216
  */
217
- static fromFile(path: string): FlagsClient;
217
+ static fromFile(path: string): Engine;
218
218
  init(): Promise<void>;
219
219
  initOnce(): Promise<void>;
220
220
  /** Force `getFlag(name, …)` to return `value`, ignoring the fetched gate. */
@@ -298,22 +298,22 @@ declare class FlagsClient {
298
298
  *
299
299
  * ```ts
300
300
  * import { OpenFeature } from "@openfeature/server-sdk";
301
- * import { FlagsClient } from "@shipeasy/sdk/server";
301
+ * import { Engine } from "@shipeasy/sdk/server";
302
302
  * import { ShipeasyProvider } from "@shipeasy/sdk/openfeature-server";
303
303
  *
304
- * const client = new FlagsClient({ apiKey: process.env.SHIPEASY_SERVER_KEY! });
304
+ * const client = new Engine({ apiKey: process.env.SHIPEASY_SERVER_KEY! });
305
305
  * await OpenFeature.setProviderAndWait(new ShipeasyProvider(client));
306
306
  *
307
307
  * const ofClient = OpenFeature.getClient();
308
308
  * const on = await ofClient.getBooleanValue("new_checkout", false, { targetingKey: "u1" });
309
309
  * ```
310
310
  *
311
- * Pure adapter over `FlagsClient` — no change to evaluation. `@openfeature/server-sdk`
311
+ * Pure adapter over `Engine` — no change to evaluation. `@openfeature/server-sdk`
312
312
  * is an optional peer dependency; install it in the consuming app.
313
313
  */
314
314
 
315
315
  /**
316
- * Shipeasy OpenFeature provider (server paradigm). Wraps a `FlagsClient`;
316
+ * Shipeasy OpenFeature provider (server paradigm). Wraps an `Engine`;
317
317
  * evaluation is local against the cached blob, so resolution is effectively
318
318
  * synchronous (the methods are `async` only to satisfy the server contract).
319
319
  */
@@ -323,7 +323,7 @@ declare class ShipeasyProvider implements Provider {
323
323
  readonly name: "shipeasy";
324
324
  };
325
325
  readonly runsOn: "server";
326
- constructor(client: FlagsClient);
326
+ constructor(client: Engine);
327
327
  /** Fetch the rules blob once. The SDK fires `Ready` when this resolves. */
328
328
  initialize(): Promise<void>;
329
329
  onClose(): Promise<void>;
@@ -78,7 +78,7 @@ interface StickyEntry {
78
78
  /**
79
79
  * Pluggable sticky-bucketing store for the server (doc 20 §2). Keyed by the
80
80
  * bucketing unit; the value is that unit's per-experiment assignments. Absent
81
- * from {@link FlagsClientOptions} ⇒ today's deterministic behaviour. Use
81
+ * from {@link EngineOptions} ⇒ today's deterministic behaviour. Use
82
82
  * {@link createInMemoryStickyStore} or a cookie-bridge built from request
83
83
  * cookies.
84
84
  */
@@ -93,7 +93,7 @@ interface Killswitch {
93
93
  killed: 0 | 1 | boolean;
94
94
  switches?: Record<string, 0 | 1 | boolean>;
95
95
  }
96
- /** Body of `GET /sdk/flags` — the snapshot's `flags` field. See {@link FlagsClient.fromSnapshot}. */
96
+ /** Body of `GET /sdk/flags` — the snapshot's `flags` field. See {@link Engine.fromSnapshot}. */
97
97
  interface FlagsBlob {
98
98
  version: string;
99
99
  plan: string;
@@ -103,7 +103,7 @@ interface FlagsBlob {
103
103
  }>;
104
104
  killswitches: Record<string, Killswitch>;
105
105
  }
106
- /** Body of `GET /sdk/experiments` — the snapshot's `experiments` field. See {@link FlagsClient.fromSnapshot}. */
106
+ /** Body of `GET /sdk/experiments` — the snapshot's `experiments` field. See {@link Engine.fromSnapshot}. */
107
107
  interface ExpsBlob {
108
108
  version: string;
109
109
  universes: Record<string, Universe>;
@@ -115,12 +115,12 @@ interface BootstrapPayload {
115
115
  experiments: Record<string, ExperimentResult<Record<string, unknown>>>;
116
116
  killswitches: Record<string, boolean | Record<string, boolean>>;
117
117
  }
118
- type FlagsClientEnv = "dev" | "staging" | "prod";
119
- interface FlagsClientOptions {
118
+ type EngineEnv = "dev" | "staging" | "prod";
119
+ interface EngineOptions {
120
120
  apiKey: string;
121
121
  baseUrl?: string;
122
122
  /** Which published env to read values from. Defaults to "prod". */
123
- env?: FlagsClientEnv;
123
+ env?: EngineEnv;
124
124
  /**
125
125
  * Preload the flags blob synchronously without a network fetch. Primarily
126
126
  * for tests; production callers should rely on init()/initOnce().
@@ -155,12 +155,12 @@ interface FlagsClientOptions {
155
155
  /**
156
156
  * Test mode — no network at all. init()/initOnce() are no-ops (never fetch),
157
157
  * track() is a no-op, telemetry is forced off, and the client starts
158
- * "initialized" with an empty blob. Prefer the {@link FlagsClient.forTesting}
158
+ * "initialized" with an empty blob. Prefer the {@link Engine.forTesting}
159
159
  * factory over passing this directly.
160
160
  */
161
161
  testMode?: boolean;
162
162
  }
163
- declare class FlagsClient {
163
+ declare class Engine {
164
164
  private readonly apiKey;
165
165
  private readonly baseUrl;
166
166
  private readonly env;
@@ -180,7 +180,7 @@ declare class FlagsClient {
180
180
  private readonly configOverrides;
181
181
  private readonly experimentOverrides;
182
182
  private readonly changeListeners;
183
- constructor(opts: FlagsClientOptions);
183
+ constructor(opts: EngineOptions);
184
184
  /**
185
185
  * Build a no-network, immediately-usable client for tests (Statsig-style).
186
186
  * init()/initOnce() are no-ops (never fetch), track() is a no-op, telemetry
@@ -188,12 +188,12 @@ declare class FlagsClient {
188
188
  * with overrideFlag/overrideConfig/overrideExperiment. No SDK key required.
189
189
  *
190
190
  * ```ts
191
- * const client = FlagsClient.forTesting();
191
+ * const client = Engine.forTesting();
192
192
  * client.overrideFlag("new_checkout", true);
193
193
  * client.getFlag("new_checkout", { user_id: "u1" }); // true
194
194
  * ```
195
195
  */
196
- static forTesting(opts?: Partial<FlagsClientOptions>): FlagsClient;
196
+ static forTesting(opts?: Partial<EngineOptions>): Engine;
197
197
  /**
198
198
  * Build a fully OFFLINE client from a pre-captured snapshot — no network ever.
199
199
  * Reuses the test-mode plumbing (init()/initOnce()/track() are no-ops,
@@ -207,14 +207,14 @@ declare class FlagsClient {
207
207
  static fromSnapshot(snapshot: {
208
208
  flags: FlagsBlob;
209
209
  experiments: ExpsBlob;
210
- }): FlagsClient;
210
+ }): Engine;
211
211
  /**
212
212
  * Build a fully OFFLINE client from a snapshot JSON file on disk (Node only —
213
213
  * not available in the browser entrypoint). The file must contain
214
214
  * `{ "flags": <GET /sdk/flags body>, "experiments": <GET /sdk/experiments body> }`.
215
- * See {@link FlagsClient.fromSnapshot}.
215
+ * See {@link Engine.fromSnapshot}.
216
216
  */
217
- static fromFile(path: string): FlagsClient;
217
+ static fromFile(path: string): Engine;
218
218
  init(): Promise<void>;
219
219
  initOnce(): Promise<void>;
220
220
  /** Force `getFlag(name, …)` to return `value`, ignoring the fetched gate. */
@@ -298,22 +298,22 @@ declare class FlagsClient {
298
298
  *
299
299
  * ```ts
300
300
  * import { OpenFeature } from "@openfeature/server-sdk";
301
- * import { FlagsClient } from "@shipeasy/sdk/server";
301
+ * import { Engine } from "@shipeasy/sdk/server";
302
302
  * import { ShipeasyProvider } from "@shipeasy/sdk/openfeature-server";
303
303
  *
304
- * const client = new FlagsClient({ apiKey: process.env.SHIPEASY_SERVER_KEY! });
304
+ * const client = new Engine({ apiKey: process.env.SHIPEASY_SERVER_KEY! });
305
305
  * await OpenFeature.setProviderAndWait(new ShipeasyProvider(client));
306
306
  *
307
307
  * const ofClient = OpenFeature.getClient();
308
308
  * const on = await ofClient.getBooleanValue("new_checkout", false, { targetingKey: "u1" });
309
309
  * ```
310
310
  *
311
- * Pure adapter over `FlagsClient` — no change to evaluation. `@openfeature/server-sdk`
311
+ * Pure adapter over `Engine` — no change to evaluation. `@openfeature/server-sdk`
312
312
  * is an optional peer dependency; install it in the consuming app.
313
313
  */
314
314
 
315
315
  /**
316
- * Shipeasy OpenFeature provider (server paradigm). Wraps a `FlagsClient`;
316
+ * Shipeasy OpenFeature provider (server paradigm). Wraps an `Engine`;
317
317
  * evaluation is local against the cached blob, so resolution is effectively
318
318
  * synchronous (the methods are `async` only to satisfy the server contract).
319
319
  */
@@ -323,7 +323,7 @@ declare class ShipeasyProvider implements Provider {
323
323
  readonly name: "shipeasy";
324
324
  };
325
325
  readonly runsOn: "server";
326
- constructor(client: FlagsClient);
326
+ constructor(client: Engine);
327
327
  /** Fetch the rules blob once. The SDK fires `Ready` when this resolves. */
328
328
  initialize(): Promise<void>;
329
329
  onClose(): Promise<void>;
@@ -101,8 +101,8 @@ interface AutoCollectGroups {
101
101
  errors: boolean;
102
102
  engagement: boolean;
103
103
  }
104
- type FlagsClientBrowserEnv = "dev" | "staging" | "prod";
105
- interface FlagsClientBrowserOptions {
104
+ type EngineEnv = "dev" | "staging" | "prod";
105
+ interface EngineOptions {
106
106
  sdkKey: string;
107
107
  baseUrl?: string;
108
108
  autoGuardrails?: boolean;
@@ -121,7 +121,7 @@ interface FlagsClientBrowserOptions {
121
121
  */
122
122
  autoCollectAlways?: boolean;
123
123
  /** Which published env to read values from. Defaults to "prod". */
124
- env?: FlagsClientBrowserEnv;
124
+ env?: EngineEnv;
125
125
  /**
126
126
  * Per-evaluation usage telemetry. ON by default — each getFlag/getConfig/
127
127
  * getExperiment/getKillswitch call fires one fire-and-forget sendBeacon so
@@ -158,11 +158,11 @@ interface FlagsClientBrowserOptions {
158
158
  * Test mode — no network at all. identify()/init are no-ops (never call
159
159
  * /sdk/evaluate), track() is a no-op, telemetry is forced off, and the client
160
160
  * starts "ready" with an empty eval result. Prefer the
161
- * {@link FlagsClientBrowser.forTesting} factory over passing this directly.
161
+ * {@link Engine.forTesting} factory over passing this directly.
162
162
  */
163
163
  testMode?: boolean;
164
164
  }
165
- declare class FlagsClientBrowser {
165
+ declare class Engine {
166
166
  private readonly sdkKey;
167
167
  private readonly baseUrl;
168
168
  private readonly autoGuardrails;
@@ -187,7 +187,7 @@ declare class FlagsClientBrowser {
187
187
  private readonly configOverrides;
188
188
  private readonly experimentOverrides;
189
189
  private onOverrideChange;
190
- constructor(opts: FlagsClientBrowserOptions);
190
+ constructor(opts: EngineOptions);
191
191
  /**
192
192
  * Build a no-network, immediately-usable browser client for tests
193
193
  * (Statsig-style). identify() is a no-op (never calls /sdk/evaluate), track()
@@ -196,12 +196,12 @@ declare class FlagsClientBrowser {
196
196
  * key required.
197
197
  *
198
198
  * ```ts
199
- * const client = FlagsClientBrowser.forTesting();
199
+ * const client = Engine.forTesting();
200
200
  * client.overrideFlag("new_checkout", true);
201
201
  * client.getFlag("new_checkout"); // true
202
202
  * ```
203
203
  */
204
- static forTesting(opts?: Partial<FlagsClientBrowserOptions>): FlagsClientBrowser;
204
+ static forTesting(opts?: Partial<EngineOptions>): Engine;
205
205
  identify(user: User): Promise<void>;
206
206
  /**
207
207
  * Report a structured error into the errors primitive. Flushes immediately
@@ -289,10 +289,10 @@ interface ShipeasySdkBridge {
289
289
  *
290
290
  * ```ts
291
291
  * import { OpenFeature } from "@openfeature/web-sdk";
292
- * import { FlagsClientBrowser } from "@shipeasy/sdk/client";
292
+ * import { Engine } from "@shipeasy/sdk/client";
293
293
  * import { ShipeasyProvider } from "@shipeasy/sdk/openfeature-web";
294
294
  *
295
- * const client = new FlagsClientBrowser({ sdkKey: NEXT_PUBLIC_SHIPEASY_CLIENT_KEY });
295
+ * const client = new Engine({ sdkKey: NEXT_PUBLIC_SHIPEASY_CLIENT_KEY });
296
296
  * await OpenFeature.setContext({ targetingKey: "u1", plan: "pro" });
297
297
  * await OpenFeature.setProviderAndWait(new ShipeasyProvider(client));
298
298
  *
@@ -307,7 +307,7 @@ interface ShipeasySdkBridge {
307
307
 
308
308
  /**
309
309
  * Shipeasy OpenFeature provider (client/web paradigm). Wraps a
310
- * `FlagsClientBrowser`. Context changes are reconciled through `identify()`;
310
+ * `Engine`. Context changes are reconciled through `identify()`;
311
311
  * flag reads come from the cached eval result.
312
312
  */
313
313
  declare class ShipeasyProvider implements Provider {
@@ -316,7 +316,7 @@ declare class ShipeasyProvider implements Provider {
316
316
  readonly name: "shipeasy";
317
317
  };
318
318
  readonly runsOn: "client";
319
- constructor(client: FlagsClientBrowser);
319
+ constructor(client: Engine);
320
320
  /** Identify with the initial static context so the first read is warm. */
321
321
  initialize(context?: EvaluationContext): Promise<void>;
322
322
  /** Re-identify when the application author changes the static context. */