@dr-sentry/sdk 1.0.4 → 1.1.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.
Files changed (54) hide show
  1. package/README.md +101 -4
  2. package/dist/cjs/cache.d.ts +16 -0
  3. package/dist/cjs/cache.d.ts.map +1 -1
  4. package/dist/cjs/cache.js +21 -1
  5. package/dist/cjs/cache.js.map +1 -1
  6. package/dist/cjs/client.d.ts +46 -1
  7. package/dist/cjs/client.d.ts.map +1 -1
  8. package/dist/cjs/client.js +236 -9
  9. package/dist/cjs/client.js.map +1 -1
  10. package/dist/cjs/defaults.d.ts +58 -0
  11. package/dist/cjs/defaults.d.ts.map +1 -0
  12. package/dist/cjs/defaults.js +175 -0
  13. package/dist/cjs/defaults.js.map +1 -0
  14. package/dist/cjs/index.d.ts +2 -1
  15. package/dist/cjs/index.d.ts.map +1 -1
  16. package/dist/cjs/index.js +4 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/status-reporter.d.ts +42 -0
  19. package/dist/cjs/status-reporter.d.ts.map +1 -0
  20. package/dist/cjs/status-reporter.js +153 -0
  21. package/dist/cjs/status-reporter.js.map +1 -0
  22. package/dist/cjs/streaming.d.ts +8 -2
  23. package/dist/cjs/streaming.d.ts.map +1 -1
  24. package/dist/cjs/streaming.js +17 -4
  25. package/dist/cjs/streaming.js.map +1 -1
  26. package/dist/cjs/types.d.ts +65 -0
  27. package/dist/cjs/types.d.ts.map +1 -1
  28. package/dist/esm/cache.d.ts +16 -0
  29. package/dist/esm/cache.d.ts.map +1 -1
  30. package/dist/esm/cache.js +21 -1
  31. package/dist/esm/cache.js.map +1 -1
  32. package/dist/esm/client.d.ts +46 -1
  33. package/dist/esm/client.d.ts.map +1 -1
  34. package/dist/esm/client.js +236 -9
  35. package/dist/esm/client.js.map +1 -1
  36. package/dist/esm/defaults.d.ts +58 -0
  37. package/dist/esm/defaults.d.ts.map +1 -0
  38. package/dist/esm/defaults.js +136 -0
  39. package/dist/esm/defaults.js.map +1 -0
  40. package/dist/esm/index.d.ts +2 -1
  41. package/dist/esm/index.d.ts.map +1 -1
  42. package/dist/esm/index.js +1 -0
  43. package/dist/esm/index.js.map +1 -1
  44. package/dist/esm/status-reporter.d.ts +42 -0
  45. package/dist/esm/status-reporter.d.ts.map +1 -0
  46. package/dist/esm/status-reporter.js +148 -0
  47. package/dist/esm/status-reporter.js.map +1 -0
  48. package/dist/esm/streaming.d.ts +8 -2
  49. package/dist/esm/streaming.d.ts.map +1 -1
  50. package/dist/esm/streaming.js +17 -4
  51. package/dist/esm/streaming.js.map +1 -1
  52. package/dist/esm/types.d.ts +65 -0
  53. package/dist/esm/types.d.ts.map +1 -1
  54. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../src/streaming.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../src/streaming.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,40 @@ export interface Flag {
31
31
  /** ISO-8601 timestamp of the last update. */
32
32
  updatedAt: string;
33
33
  }
34
+ /**
35
+ * Where an inspected flag's current value originated.
36
+ *
37
+ * - `server` — fetched live from the API and still within its cache TTL.
38
+ * - `cache` — a previously-fetched server value whose TTL has elapsed but
39
+ * is still being served (server currently unreachable).
40
+ * - `file` — an offline file: a `mode: 'file'` config, or the offline
41
+ * defaults loaded via `loadDefaults*()` used as a fallback.
42
+ * - `default`— no value from any source; callers receive their coded default.
43
+ */
44
+ export type FlagSource = 'server' | 'cache' | 'file' | 'default';
45
+ /**
46
+ * A read-only view of a single flag's resolved value and provenance,
47
+ * suitable for wiring into an admin or support panel. Produced by
48
+ * {@link DeploySentryClient.inspect}.
49
+ */
50
+ export interface FlagInspection {
51
+ /** The flag key. */
52
+ key: string;
53
+ /** The currently-resolved value (parsed to its declared type). */
54
+ value: unknown;
55
+ /** The flag's value type. `unknown` when it cannot be determined. */
56
+ type: 'boolean' | 'integer' | 'number' | 'string' | 'json' | 'unknown';
57
+ /** Whether the flag is enabled in the resolved environment. */
58
+ enabled: boolean;
59
+ /** Where {@link value} came from. */
60
+ source: FlagSource;
61
+ /** Evaluation reason code (e.g. LIVE, CACHE, OFFLINE_FILE, OFFLINE_DEFAULT, DEFAULT). */
62
+ reason: string;
63
+ /** ISO-8601 timestamp the value was last fetched / loaded. Undefined for `default`. */
64
+ fetchedAt?: string;
65
+ /** True when {@link source} is `cache` and the entry is past its TTL. */
66
+ stale: boolean;
67
+ }
34
68
  /** Contextual information sent with every evaluation request. */
35
69
  export interface EvaluationContext {
36
70
  /** Identifier of the user being evaluated. */
@@ -77,6 +111,37 @@ export interface ClientOptions {
77
111
  mode?: 'server' | 'file' | 'server-with-fallback';
78
112
  /** Path to a local YAML flag config file. Defaults to .deploysentry/flags.yaml. */
79
113
  flagFilePath?: string;
114
+ /** Called whenever the flag cache is refreshed from an SSE change event. */
115
+ onFlagChange?: (flags: Flag[]) => void;
116
+ /**
117
+ * Application UUID. Required when `reportStatus` is true. Distinct from
118
+ * `application` (the slug used for flag evaluation) because the status
119
+ * endpoint is keyed on the UUID.
120
+ */
121
+ applicationId?: string;
122
+ /** Enable the status reporter. Default: false. */
123
+ reportStatus?: boolean;
124
+ /** Interval in ms between status reports. Default: 30_000. 0 = send once on init. */
125
+ reportStatusIntervalMs?: number;
126
+ /** Override the auto-detected version string. */
127
+ reportStatusVersion?: string;
128
+ /** Commit SHA reported alongside the version. */
129
+ reportStatusCommitSha?: string;
130
+ /** Optional deploy-slot tag (`stable` / `canary`). */
131
+ reportStatusDeploySlot?: string;
132
+ /** Arbitrary tags attached to every report. */
133
+ reportStatusTags?: Record<string, string>;
134
+ /**
135
+ * Optional callback resolving the current health. If omitted the reporter
136
+ * sends `state: 'healthy'` on every tick (the "process alive" floor).
137
+ */
138
+ reportStatusHealthProvider?: () => HealthReport | Promise<HealthReport>;
139
+ }
140
+ /** Shape returned by a status reporter's health provider. */
141
+ export interface HealthReport {
142
+ state: 'healthy' | 'degraded' | 'unhealthy' | 'unknown';
143
+ score?: number;
144
+ reason?: string;
80
145
  }
81
146
  export interface FlagConfig {
82
147
  version: number;
@@ -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":"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"}
@@ -1,4 +1,14 @@
1
1
  import { Flag } from './types.js';
2
+ /** A cache entry exposed for inspection, including staleness. */
3
+ export interface CacheInspectionEntry {
4
+ flag: Flag;
5
+ /** Epoch-ms when the entry was last written. */
6
+ storedAt: number;
7
+ /** Epoch-ms when the entry's TTL elapses. */
8
+ expiresAt: number;
9
+ /** True when the TTL has elapsed but the entry is still held. */
10
+ stale: boolean;
11
+ }
2
12
  /**
3
13
  * In-memory flag cache with per-entry TTL support.
4
14
  *
@@ -21,6 +31,12 @@ export declare class FlagCache {
21
31
  get(key: string): Flag | undefined;
22
32
  /** Return all non-expired flags currently in the cache. */
23
33
  getAll(): Flag[];
34
+ /**
35
+ * Return every entry held in the cache — including stale (TTL-elapsed)
36
+ * entries — without evicting anything. For inspection / admin views only;
37
+ * read paths should use {@link get} / {@link getAll} which evict.
38
+ */
39
+ entries(): CacheInspectionEntry[];
24
40
  /** Remove a single key from the cache. */
25
41
  delete(key: string): void;
26
42
  /** Remove all expired entries. Returns the number of entries purged. */
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAO/B;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B;;;OAGG;gBACS,KAAK,GAAE,MAAe;IAIlC,kDAAkD;IAClD,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAOrB,sDAAsD;IACtD,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAM5B,yEAAyE;IACzE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAYlC,2DAA2D;IAC3D,MAAM,IAAI,IAAI,EAAE;IAehB,0CAA0C;IAC1C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,wEAAwE;IACxE,YAAY,IAAI,MAAM;IActB,uCAAuC;IACvC,KAAK,IAAI,IAAI;IAIb,8DAA8D;IAC9D,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAQ/B,iEAAiE;AACjE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,IAAI,CAAC;IACX,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B;;;OAGG;gBACS,KAAK,GAAE,MAAe;IAIlC,kDAAkD;IAClD,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IASrB,sDAAsD;IACtD,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAM5B,yEAAyE;IACzE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAYlC,2DAA2D;IAC3D,MAAM,IAAI,IAAI,EAAE;IAehB;;;;OAIG;IACH,OAAO,IAAI,oBAAoB,EAAE;IAcjC,0CAA0C;IAC1C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,wEAAwE;IACxE,YAAY,IAAI,MAAM;IActB,uCAAuC;IACvC,KAAK,IAAI,IAAI;IAIb,8DAA8D;IAC9D,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
package/dist/esm/cache.js CHANGED
@@ -16,9 +16,11 @@ export class FlagCache {
16
16
  }
17
17
  /** Store or update a single flag in the cache. */
18
18
  set(flag) {
19
+ const now = Date.now();
19
20
  this.store.set(flag.key, {
20
21
  flag,
21
- expiresAt: Date.now() + this.ttlMs,
22
+ storedAt: now,
23
+ expiresAt: now + this.ttlMs,
22
24
  });
23
25
  }
24
26
  /** Bulk-insert flags, replacing any stale entries. */
@@ -52,6 +54,24 @@ export class FlagCache {
52
54
  }
53
55
  return result;
54
56
  }
57
+ /**
58
+ * Return every entry held in the cache — including stale (TTL-elapsed)
59
+ * entries — without evicting anything. For inspection / admin views only;
60
+ * read paths should use {@link get} / {@link getAll} which evict.
61
+ */
62
+ entries() {
63
+ const now = Date.now();
64
+ const result = [];
65
+ for (const entry of this.store.values()) {
66
+ result.push({
67
+ flag: entry.flag,
68
+ storedAt: entry.storedAt,
69
+ expiresAt: entry.expiresAt,
70
+ stale: now > entry.expiresAt,
71
+ });
72
+ }
73
+ return result;
74
+ }
55
75
  /** Remove a single key from the cache. */
56
76
  delete(key) {
57
77
  this.store.delete(key);
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,MAAM,OAAO,SAAS;IACH,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IACtC,KAAK,CAAS;IAE/B;;;OAGG;IACH,YAAY,QAAgB,MAAM;QAChC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,kDAAkD;IAClD,GAAG,CAAC,IAAU;QACZ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE;YACvB,IAAI;YACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK;SACnC,CAAC,CAAC;IACL,CAAC;IAED,sDAAsD;IACtD,OAAO,CAAC,KAAa;QACnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAE7B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IAED,2DAA2D;IAC3D,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAW,EAAE,CAAC;QAE1B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtC,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,0CAA0C;IAC1C,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,wEAAwE;IACxE,YAAY;QACV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtC,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvB,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,uCAAuC;IACvC,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,8DAA8D;IAC9D,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ClientOptions, EvaluationContext, EvaluationResult, Flag, FlagCategory } from './types.js';
1
+ import { ClientOptions, EvaluationContext, EvaluationResult, Flag, FlagCategory, FlagInspection } from './types.js';
2
2
  /**
3
3
  * DeploySentry feature-flag client.
4
4
  *
@@ -26,11 +26,18 @@ export declare class DeploySentryClient {
26
26
  private readonly sessionId;
27
27
  private readonly mode;
28
28
  private readonly flagFilePath?;
29
+ private readonly onFlagChange?;
29
30
  private readonly cache;
30
31
  private streamClient;
31
32
  private _initialized;
32
33
  private flagConfig;
34
+ private offlineDefaults;
35
+ private offlineDefaultsEnvUUID;
36
+ private flagConfigLoadedAt?;
37
+ private offlineDefaultsLoadedAt?;
33
38
  private registry;
39
+ private statusReporter;
40
+ private readonly statusReporterOptions;
34
41
  constructor(options: ClientOptions);
35
42
  /**
36
43
  * Fetch the initial flag set and open an SSE connection for real-time
@@ -39,6 +46,7 @@ export declare class DeploySentryClient {
39
46
  initialize(): Promise<void>;
40
47
  /** Tear down the SSE connection and release resources. */
41
48
  close(): void;
49
+ private startStatusReporter;
42
50
  /**
43
51
  * Clear the local cache and re-fetch all flags from the server.
44
52
  * Useful when session state may have changed and the client needs
@@ -68,10 +76,47 @@ export declare class DeploySentryClient {
68
76
  flagOwners(key: string): string[];
69
77
  /** Return every flag currently held in the local cache. */
70
78
  allFlags(): Flag[];
79
+ /**
80
+ * Return a provenance-tagged view of every flag the SDK currently knows
81
+ * about, drawn from all sources (live server cache, offline file config,
82
+ * and offline defaults). Each entry reports the resolved value, its type,
83
+ * the {@link FlagSource | source} it came from, an evaluation reason code,
84
+ * and when it was last fetched / loaded.
85
+ *
86
+ * Intended for wiring into an admin or support panel so operators can see
87
+ * exactly what value an application is serving and where it came from. This
88
+ * is a read-only snapshot — it does not contact the server or evaluate
89
+ * targeting rules for a specific user.
90
+ */
91
+ inspect(): FlagInspection[];
71
92
  register<T extends (...args: any[]) => any>(operation: string, handler: T, flagKey?: string): void;
72
93
  dispatch<T extends (...args: any[]) => any>(operation: string, _context?: EvaluationContext): T;
73
94
  private evaluate;
95
+ /**
96
+ * Load offline default values from a flag-export file. When the live API
97
+ * is unreachable and the cache has no entry, the SDK falls back to these
98
+ * defaults for {@link boolValue} / {@link stringValue} / {@link intValue}
99
+ * / {@link jsonValue} calls.
100
+ *
101
+ * Accepts the JSON (default) or YAML format produced by
102
+ * `deploysentry flags export`.
103
+ *
104
+ * Environment matching: the SDK matches the configured `environment`
105
+ * option against the export's `environments[]` first by UUID, then by
106
+ * name (case-insensitive). When a match is found, that env's per-flag
107
+ * `{enabled, value}` overrides the flag's global `default_value`.
108
+ *
109
+ * @example
110
+ * await client.loadDefaultsFromFile('flags.json');
111
+ */
112
+ loadDefaultsFromFile(path: string): Promise<void>;
113
+ /**
114
+ * Synchronous variant of {@link loadDefaultsFromFile} that accepts an
115
+ * already-parsed object (or a JSON string).
116
+ */
117
+ loadDefaults(payload: unknown): void;
74
118
  private fetchAllFlags;
119
+ private fetchFlag;
75
120
  private post;
76
121
  private request;
77
122
  private authHeaders;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,IAAI,EACJ,YAAY,EAEb,MAAM,SAAS,CAAC;AA2CjB;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6C;IAClE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IAEvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,QAAQ,CAA0C;gBAE9C,OAAO,EAAE,aAAa;IAuBlC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA8CjC,0DAA0D;IAC1D,KAAK,IAAI,IAAI;IAOb;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrC,+DAA+D;IAC/D,IAAI,aAAa,IAAI,OAAO,CAE3B;IAMD,oCAAoC;IAC9B,SAAS,CACb,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,OAAO,EACrB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,OAAO,CAAC;IAcnB,mCAAmC;IAC7B,WAAW,CACf,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC;IAKlB,qCAAqC;IAC/B,QAAQ,CACZ,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC;IAOlB,oEAAoE;IAC9D,SAAS,CAAC,CAAC,GAAG,OAAO,EACzB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,CAAC,EACf,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,CAAC,CAAC;IASb;;;OAGG;IACG,MAAM,CACV,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IA2B5B,6DAA6D;IAC7D,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,EAAE;IAI/C,gEAAgE;IAChE,YAAY,IAAI,IAAI,EAAE;IAOtB,oDAAoD;IACpD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;IAKjC,2DAA2D;IAC3D,QAAQ,IAAI,IAAI,EAAE;IAQlB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,EACV,OAAO,CAAC,EAAE,MAAM,GACf,IAAI;IAeP,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxC,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,iBAAiB,GAC3B,CAAC;YA0BU,QAAQ;YAkCR,aAAa;YAQb,IAAI;YAIJ,OAAO;IAgCrB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,YAAY;CAmBrB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
@@ -2,13 +2,32 @@ import { FlagCache } from './cache.js';
2
2
  import { FlagStreamClient } from './streaming.js';
3
3
  import { loadFlagConfig } from './file-loader.js';
4
4
  import { evaluateLocal } from './local-evaluator.js';
5
+ import { coerceOfflineValue, lookupOfflineDefault, parseDefaults, readDefaultsFile, } from './defaults.js';
6
+ import { StatusReporter } from './status-reporter.js';
5
7
  const DEFAULT_BASE_URL = 'https://api.dr-sentry.com';
8
+ /** Parse a string value into its typed representation based on flag_type. */
9
+ function parseValue(raw, flagType) {
10
+ if (!raw && raw !== '0')
11
+ return undefined;
12
+ switch (flagType) {
13
+ case 'boolean': return raw === 'true';
14
+ case 'integer':
15
+ case 'number': return Number(raw);
16
+ case 'json': try {
17
+ return JSON.parse(raw);
18
+ }
19
+ catch {
20
+ return raw;
21
+ }
22
+ default: return raw;
23
+ }
24
+ }
6
25
  /** Map the API's snake_case flag response to the SDK's Flag type. */
7
26
  function mapRawFlag(raw) {
8
27
  return {
9
28
  key: raw.key,
10
29
  enabled: raw.enabled,
11
- value: raw.default_value,
30
+ value: parseValue(raw.default_value, raw.flag_type),
12
31
  metadata: {
13
32
  category: raw.category,
14
33
  purpose: raw.purpose ?? '',
@@ -48,11 +67,18 @@ export class DeploySentryClient {
48
67
  sessionId;
49
68
  mode;
50
69
  flagFilePath;
70
+ onFlagChange;
51
71
  cache;
52
72
  streamClient = null;
53
73
  _initialized = false;
54
74
  flagConfig = null;
75
+ offlineDefaults = null;
76
+ offlineDefaultsEnvUUID = '';
77
+ flagConfigLoadedAt;
78
+ offlineDefaultsLoadedAt;
55
79
  registry = new Map();
80
+ statusReporter = null;
81
+ statusReporterOptions;
56
82
  constructor(options) {
57
83
  if (!options.apiKey)
58
84
  throw new Error('apiKey is required');
@@ -71,7 +97,9 @@ export class DeploySentryClient {
71
97
  this.sessionId = options.sessionId;
72
98
  this.mode = options.mode ?? 'server';
73
99
  this.flagFilePath = options.flagFilePath;
100
+ this.onFlagChange = options.onFlagChange;
74
101
  this.cache = new FlagCache(options.cacheTimeout ?? DEFAULT_CACHE_TIMEOUT_MS);
102
+ this.statusReporterOptions = options;
75
103
  }
76
104
  // ---------------------------------------------------------------------------
77
105
  // Lifecycle
@@ -83,6 +111,7 @@ export class DeploySentryClient {
83
111
  async initialize() {
84
112
  if (this.mode === 'file') {
85
113
  this.flagConfig = loadFlagConfig(this.flagFilePath);
114
+ this.flagConfigLoadedAt = new Date().toISOString();
86
115
  this._initialized = true;
87
116
  return;
88
117
  }
@@ -94,13 +123,21 @@ export class DeploySentryClient {
94
123
  // Fetch all flags for the project so the cache is warm.
95
124
  const flags = await this.fetchAllFlags();
96
125
  this.cache.setMany(flags);
97
- // Start streaming updates.
126
+ // Start streaming updates. Each SSE event identifies the changed flag
127
+ // by ID — fetch just that flag to get the authoritative state.
98
128
  this.streamClient = new FlagStreamClient({
99
129
  url: `${this.baseURL}/api/v1/flags/stream?project_id=${enc(this.project)}&environment_id=${enc(this.environment)}&application=${enc(this.application)}`,
100
130
  headers: this.authHeaders(),
101
- onChange: () => {
102
- this.fetchAllFlags()
103
- .then((flags) => this.cache.setMany(flags))
131
+ onChange: (change) => {
132
+ if (!change.flagId)
133
+ return;
134
+ this.fetchFlag(change.flagId)
135
+ .then((flag) => {
136
+ if (flag) {
137
+ this.cache.set(flag);
138
+ this.onFlagChange?.([flag]);
139
+ }
140
+ })
104
141
  .catch(() => { }); // stale cache still serves
105
142
  },
106
143
  onError: (err) => {
@@ -111,11 +148,13 @@ export class DeploySentryClient {
111
148
  // Fire-and-forget; the stream reconnects automatically.
112
149
  this.streamClient.connect();
113
150
  this._initialized = true;
151
+ this.startStatusReporter();
114
152
  }
115
153
  catch (err) {
116
154
  if (this.mode === 'server-with-fallback') {
117
155
  console.warn('[DeploySentry] Server unavailable, falling back to flag config file');
118
156
  this.flagConfig = loadFlagConfig(this.flagFilePath);
157
+ this.flagConfigLoadedAt = new Date().toISOString();
119
158
  this._initialized = true;
120
159
  return;
121
160
  }
@@ -126,9 +165,32 @@ export class DeploySentryClient {
126
165
  close() {
127
166
  this.streamClient?.close();
128
167
  this.streamClient = null;
168
+ this.statusReporter?.stop();
169
+ this.statusReporter = null;
129
170
  this.cache.clear();
130
171
  this._initialized = false;
131
172
  }
173
+ startStatusReporter() {
174
+ const o = this.statusReporterOptions;
175
+ if (!o.reportStatus)
176
+ return;
177
+ if (!o.applicationId) {
178
+ console.warn('[DeploySentry] reportStatus=true but applicationId is not set; status reporter disabled');
179
+ return;
180
+ }
181
+ this.statusReporter = new StatusReporter({
182
+ baseURL: this.baseURL,
183
+ apiKey: this.apiKey,
184
+ applicationId: o.applicationId,
185
+ intervalMs: o.reportStatusIntervalMs,
186
+ version: o.reportStatusVersion,
187
+ commitSha: o.reportStatusCommitSha,
188
+ deploySlot: o.reportStatusDeploySlot,
189
+ tags: o.reportStatusTags,
190
+ healthProvider: o.reportStatusHealthProvider,
191
+ });
192
+ this.statusReporter.start();
193
+ }
132
194
  /**
133
195
  * Clear the local cache and re-fetch all flags from the server.
134
196
  * Useful when session state may have changed and the client needs
@@ -231,6 +293,72 @@ export class DeploySentryClient {
231
293
  allFlags() {
232
294
  return this.cache.getAll();
233
295
  }
296
+ /**
297
+ * Return a provenance-tagged view of every flag the SDK currently knows
298
+ * about, drawn from all sources (live server cache, offline file config,
299
+ * and offline defaults). Each entry reports the resolved value, its type,
300
+ * the {@link FlagSource | source} it came from, an evaluation reason code,
301
+ * and when it was last fetched / loaded.
302
+ *
303
+ * Intended for wiring into an admin or support panel so operators can see
304
+ * exactly what value an application is serving and where it came from. This
305
+ * is a read-only snapshot — it does not contact the server or evaluate
306
+ * targeting rules for a specific user.
307
+ */
308
+ inspect() {
309
+ const byKey = new Map();
310
+ // 1) Server cache (live + stale). Highest-fidelity source; recorded first.
311
+ for (const e of this.cache.entries()) {
312
+ byKey.set(e.flag.key, {
313
+ key: e.flag.key,
314
+ value: e.flag.value,
315
+ type: typeOfValue(e.flag.value),
316
+ enabled: e.flag.enabled,
317
+ source: e.stale ? 'cache' : 'server',
318
+ reason: e.stale ? 'CACHE' : 'LIVE',
319
+ fetchedAt: new Date(e.storedAt).toISOString(),
320
+ stale: e.stale,
321
+ });
322
+ }
323
+ // 2) Offline file config (mode 'file' or fallback). Only fills gaps.
324
+ if (this.flagConfig) {
325
+ for (const f of this.flagConfig.flags) {
326
+ if (byKey.has(f.key))
327
+ continue;
328
+ const result = evaluateLocal(this.flagConfig, this.environment, f.key);
329
+ const envState = f.environments[this.environment];
330
+ byKey.set(f.key, {
331
+ key: f.key,
332
+ value: parseValue(result.value, f.flag_type),
333
+ type: typeOfFlagType(f.flag_type),
334
+ enabled: envState?.enabled ?? false,
335
+ source: 'file',
336
+ reason: 'OFFLINE_FILE',
337
+ fetchedAt: this.flagConfigLoadedAt,
338
+ stale: false,
339
+ });
340
+ }
341
+ }
342
+ // 3) Offline defaults loaded via loadDefaults*(). Only fills gaps.
343
+ if (this.offlineDefaults) {
344
+ for (const [key, def] of this.offlineDefaults) {
345
+ if (byKey.has(key))
346
+ continue;
347
+ const resolved = lookupOfflineDefault(this.offlineDefaults, this.offlineDefaultsEnvUUID, key);
348
+ byKey.set(key, {
349
+ key,
350
+ value: resolved ? parseValue(resolved.value, def.flagType) : undefined,
351
+ type: typeOfFlagType(def.flagType),
352
+ enabled: resolved?.enabled ?? false,
353
+ source: 'file',
354
+ reason: 'OFFLINE_DEFAULT',
355
+ fetchedAt: this.offlineDefaultsLoadedAt,
356
+ stale: false,
357
+ });
358
+ }
359
+ }
360
+ return [...byKey.values()];
361
+ }
234
362
  // ---------------------------------------------------------------------------
235
363
  // Register / Dispatch
236
364
  // ---------------------------------------------------------------------------
@@ -294,14 +422,78 @@ export class DeploySentryClient {
294
422
  return result.value;
295
423
  }
296
424
  catch {
297
- // Fall back to the cached flag value.
425
+ // 1) Cached value (from a prior live call) wins over offline defaults.
298
426
  const cached = this.cache.get(key);
299
- return cached?.value ?? defaultValue;
427
+ if (cached?.value !== undefined)
428
+ return cached.value;
429
+ // 2) Offline defaults loaded via loadDefaults*().
430
+ const offline = this.offlineDefaults
431
+ ? lookupOfflineDefault(this.offlineDefaults, this.offlineDefaultsEnvUUID, key)
432
+ : undefined;
433
+ if (offline) {
434
+ const requested = inferRequestedType(defaultValue);
435
+ const coerced = coerceOfflineValue(offline.value, requested);
436
+ if (coerced !== undefined)
437
+ return coerced;
438
+ }
439
+ return defaultValue;
300
440
  }
301
441
  }
442
+ // ---------------------------------------------------------------------------
443
+ // Offline defaults
444
+ // ---------------------------------------------------------------------------
445
+ /**
446
+ * Load offline default values from a flag-export file. When the live API
447
+ * is unreachable and the cache has no entry, the SDK falls back to these
448
+ * defaults for {@link boolValue} / {@link stringValue} / {@link intValue}
449
+ * / {@link jsonValue} calls.
450
+ *
451
+ * Accepts the JSON (default) or YAML format produced by
452
+ * `deploysentry flags export`.
453
+ *
454
+ * Environment matching: the SDK matches the configured `environment`
455
+ * option against the export's `environments[]` first by UUID, then by
456
+ * name (case-insensitive). When a match is found, that env's per-flag
457
+ * `{enabled, value}` overrides the flag's global `default_value`.
458
+ *
459
+ * @example
460
+ * await client.loadDefaultsFromFile('flags.json');
461
+ */
462
+ async loadDefaultsFromFile(path) {
463
+ const payload = await readDefaultsFile(path);
464
+ this.loadDefaults(payload);
465
+ }
466
+ /**
467
+ * Synchronous variant of {@link loadDefaultsFromFile} that accepts an
468
+ * already-parsed object (or a JSON string).
469
+ */
470
+ loadDefaults(payload) {
471
+ const data = typeof payload === 'string' ? JSON.parse(payload) : payload;
472
+ const { defaults, envUUID } = parseDefaults(data, this.environment);
473
+ this.offlineDefaults = defaults;
474
+ this.offlineDefaultsEnvUUID = envUUID;
475
+ this.offlineDefaultsLoadedAt = new Date().toISOString();
476
+ }
302
477
  async fetchAllFlags() {
303
- const response = await this.request('GET', `/api/v1/flags?project_id=${enc(this.project)}&application=${enc(this.application)}`);
304
- return (response.flags ?? []).map(mapRawFlag);
478
+ const pageSize = 500;
479
+ const flags = [];
480
+ let offset = 0;
481
+ for (;;) {
482
+ const response = await this.request('GET', `/api/v1/flags?project_id=${enc(this.project)}&application=${enc(this.application)}&environment_id=${enc(this.environment)}&limit=${pageSize}&offset=${offset}`);
483
+ const page = Array.isArray(response) ? response : (response.flags ?? []);
484
+ flags.push(...page);
485
+ const total = Array.isArray(response) ? undefined : response.total_count;
486
+ if (Array.isArray(response) || page.length === 0 || total === undefined || flags.length >= total)
487
+ break;
488
+ offset += page.length;
489
+ }
490
+ return flags.map(mapRawFlag);
491
+ }
492
+ async fetchFlag(flagId) {
493
+ const raw = await this.request('GET', `/api/v1/flags/${enc(flagId)}?environment_id=${enc(this.environment)}`);
494
+ if (!raw?.key)
495
+ return null;
496
+ return mapRawFlag(raw);
305
497
  }
306
498
  async post(path, body) {
307
499
  return this.request('POST', path, body);
@@ -376,4 +568,39 @@ export class DeploySentryClient {
376
568
  function enc(value) {
377
569
  return encodeURIComponent(value);
378
570
  }
571
+ /** Map a flag_type string to the inspection `type` field. */
572
+ function typeOfFlagType(flagType) {
573
+ switch (flagType) {
574
+ case 'boolean': return 'boolean';
575
+ case 'integer': return 'integer';
576
+ case 'number': return 'number';
577
+ case 'json': return 'json';
578
+ case 'string': return 'string';
579
+ default: return 'unknown';
580
+ }
581
+ }
582
+ /** Infer the inspection `type` field from an already-parsed value. */
583
+ function typeOfValue(value) {
584
+ switch (typeof value) {
585
+ case 'boolean': return 'boolean';
586
+ case 'number': return Number.isInteger(value) ? 'integer' : 'number';
587
+ case 'string': return 'string';
588
+ case 'object': return value === null ? 'unknown' : 'json';
589
+ default: return 'unknown';
590
+ }
591
+ }
592
+ /**
593
+ * Infer which coercion to apply to an offline-default raw value based on
594
+ * the caller's `defaultValue` type. Falls back to 'json' for objects /
595
+ * arrays so JSON-typed flags round-trip correctly.
596
+ */
597
+ function inferRequestedType(defaultValue) {
598
+ if (typeof defaultValue === 'boolean')
599
+ return 'bool';
600
+ if (typeof defaultValue === 'string')
601
+ return 'string';
602
+ if (typeof defaultValue === 'number')
603
+ return 'number';
604
+ return 'json';
605
+ }
379
606
  //# sourceMappingURL=client.js.map