@dr-sentry/sdk 1.1.0 → 1.2.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.
- package/README.md +103 -5
- package/dist/cjs/cache.d.ts +30 -3
- package/dist/cjs/cache.d.ts.map +1 -1
- package/dist/cjs/cache.js +32 -5
- package/dist/cjs/cache.js.map +1 -1
- package/dist/cjs/client.d.ts +55 -1
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +297 -37
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/defaults.d.ts +58 -0
- package/dist/cjs/defaults.d.ts.map +1 -0
- package/dist/cjs/defaults.js +175 -0
- package/dist/cjs/defaults.js.map +1 -0
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/persistence.d.ts +26 -0
- package/dist/cjs/persistence.d.ts.map +1 -0
- package/dist/cjs/persistence.js +74 -0
- package/dist/cjs/persistence.js.map +1 -0
- package/dist/cjs/status-reporter.d.ts +42 -0
- package/dist/cjs/status-reporter.d.ts.map +1 -0
- package/dist/cjs/status-reporter.js +153 -0
- package/dist/cjs/status-reporter.js.map +1 -0
- package/dist/cjs/streaming.d.ts +10 -0
- package/dist/cjs/streaming.d.ts.map +1 -1
- package/dist/cjs/streaming.js +9 -1
- package/dist/cjs/streaming.js.map +1 -1
- package/dist/cjs/sync.d.ts +105 -0
- package/dist/cjs/sync.d.ts.map +1 -0
- package/dist/cjs/sync.js +191 -0
- package/dist/cjs/sync.js.map +1 -0
- package/dist/cjs/types.d.ts +78 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/cache.d.ts +30 -3
- package/dist/esm/cache.d.ts.map +1 -1
- package/dist/esm/cache.js +32 -5
- package/dist/esm/cache.js.map +1 -1
- package/dist/esm/client.d.ts +55 -1
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +297 -37
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/defaults.d.ts +58 -0
- package/dist/esm/defaults.d.ts.map +1 -0
- package/dist/esm/defaults.js +136 -0
- package/dist/esm/defaults.js.map +1 -0
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/persistence.d.ts +26 -0
- package/dist/esm/persistence.d.ts.map +1 -0
- package/dist/esm/persistence.js +70 -0
- package/dist/esm/persistence.js.map +1 -0
- package/dist/esm/status-reporter.d.ts +42 -0
- package/dist/esm/status-reporter.d.ts.map +1 -0
- package/dist/esm/status-reporter.js +148 -0
- package/dist/esm/status-reporter.js.map +1 -0
- package/dist/esm/streaming.d.ts +10 -0
- package/dist/esm/streaming.d.ts.map +1 -1
- package/dist/esm/streaming.js +9 -1
- package/dist/esm/streaming.js.map +1 -1
- package/dist/esm/sync.d.ts +105 -0
- package/dist/esm/sync.d.ts.map +1 -0
- package/dist/esm/sync.js +187 -0
- package/dist/esm/sync.js.map +1 -0
- package/dist/esm/types.d.ts +78 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,6 +40,42 @@ const config = await client.jsonValue('rate-limits', { rpm: 100 });
|
|
|
40
40
|
client.close();
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
## Status reporting (optional)
|
|
44
|
+
|
|
45
|
+
Enable `reportStatus` to have the SDK push version + health to DeploySentry automatically. No separate startup code needed — the SDK posts `POST /applications/:id/status` on init and on an interval.
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
const client = new DeploySentryClient({
|
|
49
|
+
apiKey: process.env.DS_API_KEY!,
|
|
50
|
+
environment: 'production',
|
|
51
|
+
project: 'my-app',
|
|
52
|
+
application: 'my-web-app',
|
|
53
|
+
|
|
54
|
+
// Agentless status reporting
|
|
55
|
+
applicationId: process.env.DS_APPLICATION_ID!, // UUID of the app
|
|
56
|
+
reportStatus: true,
|
|
57
|
+
reportStatusIntervalMs: 30_000, // default; 0 = startup-only
|
|
58
|
+
reportStatusVersion: process.env.APP_VERSION, // optional override
|
|
59
|
+
reportStatusCommitSha: process.env.GIT_SHA,
|
|
60
|
+
reportStatusDeploySlot: process.env.DS_DEPLOY_SLOT, // "stable" | "canary"
|
|
61
|
+
reportStatusTags: { region: process.env.REGION ?? 'unknown' },
|
|
62
|
+
reportStatusHealthProvider: async () => ({
|
|
63
|
+
state: (await isDbUp()) ? 'healthy' : 'degraded',
|
|
64
|
+
score: 0.99,
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
await client.initialize();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The API key must carry the `status:write` scope and be scoped to a single application + environment. When `reportStatus` is `true` but `applicationId` is omitted, the reporter logs a warning and is disabled — flag evaluation continues to work.
|
|
72
|
+
|
|
73
|
+
Without a `reportStatusHealthProvider`, the SDK sends `health: "healthy"` on every tick ("process alive" floor). Supply a provider if your app can detect degradation (stale DB, downstream outages, etc.).
|
|
74
|
+
|
|
75
|
+
Version auto-detection (when `reportStatusVersion` is omitted) checks these env vars in order: `APP_VERSION`, `GIT_SHA`, `GIT_COMMIT`, `SOURCE_COMMIT`, `RAILWAY_GIT_COMMIT_SHA`, `RENDER_GIT_COMMIT`, `VERCEL_GIT_COMMIT_SHA`, `HEROKU_SLUG_COMMIT`, `npm_package_version` — falling back to the literal string `"unknown"`.
|
|
76
|
+
|
|
77
|
+
The first `/status` report with a version DeploySentry has not seen auto-creates a `mode=record` deployment with `source="app-push"`, so deploy history populates even without a Railway/Render/etc. webhook configured.
|
|
78
|
+
|
|
43
79
|
## Evaluation Context
|
|
44
80
|
|
|
45
81
|
Pass targeting context with every evaluation:
|
|
@@ -62,7 +98,7 @@ Every flag carries structured metadata describing its purpose, ownership, and li
|
|
|
62
98
|
```typescript
|
|
63
99
|
const result = await client.detail('new-checkout');
|
|
64
100
|
|
|
65
|
-
console.log(result.metadata.category); // 'release' | 'feature' | 'experiment' | 'ops' | 'permission'
|
|
101
|
+
console.log(result.metadata.category); // 'release' | 'feature' | 'experiment' | 'ops' | 'permission' | 'envvar'
|
|
66
102
|
console.log(result.metadata.purpose); // "Gradual rollout of new checkout flow"
|
|
67
103
|
console.log(result.metadata.owners); // ["payments-team", "jane@example.com"]
|
|
68
104
|
console.log(result.metadata.isPermanent); // false
|
|
@@ -81,6 +117,7 @@ Flags are classified into categories that drive lifecycle policies:
|
|
|
81
117
|
| `experiment` | A/B tests and experiments with defined end dates |
|
|
82
118
|
| `ops` | Operational controls (kill switches, rate limits) |
|
|
83
119
|
| `permission` | Entitlement and access-control flags |
|
|
120
|
+
| `envvar` | Non-secret environment variable tracking |
|
|
84
121
|
|
|
85
122
|
Query by category:
|
|
86
123
|
|
|
@@ -113,6 +150,36 @@ List all cached flags:
|
|
|
113
150
|
const flags = client.allFlags();
|
|
114
151
|
```
|
|
115
152
|
|
|
153
|
+
## Inspecting Flag Sources (admin / support view)
|
|
154
|
+
|
|
155
|
+
`inspect()` returns a provenance-tagged snapshot of every flag the SDK currently knows about — drawn from all sources at once (live server cache, offline file config, and offline defaults). Each entry reports the resolved value, its type, **where the value came from**, an evaluation reason, and when it was last fetched. Wire it into an admin or support panel to see exactly what an application is serving and why.
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
const view = client.inspect();
|
|
159
|
+
// [
|
|
160
|
+
// {
|
|
161
|
+
// key: 'new-checkout',
|
|
162
|
+
// value: true,
|
|
163
|
+
// type: 'boolean',
|
|
164
|
+
// enabled: true,
|
|
165
|
+
// source: 'server', // 'server' | 'cache' | 'file' | 'default'
|
|
166
|
+
// reason: 'LIVE', // LIVE | CACHE | OFFLINE_FILE | OFFLINE_DEFAULT | DEFAULT
|
|
167
|
+
// fetchedAt: '2026-06-23T12:00:00.000Z',
|
|
168
|
+
// stale: false, // true when a cached value is past its TTL
|
|
169
|
+
// },
|
|
170
|
+
// ...
|
|
171
|
+
// ]
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
| `source` | Meaning |
|
|
175
|
+
| --- | --- |
|
|
176
|
+
| `server` | Fetched live from the API and still within its cache TTL. |
|
|
177
|
+
| `cache` | A previously-fetched server value past its TTL, still served because the server is currently unreachable (`stale: true`). |
|
|
178
|
+
| `file` | An offline file — a `mode: 'file'` config, or the offline defaults loaded via `loadDefaults*()` (the `reason` distinguishes `OFFLINE_FILE` vs `OFFLINE_DEFAULT`). |
|
|
179
|
+
| `default` | No value from any source; callers receive their coded `defaultValue`. |
|
|
180
|
+
|
|
181
|
+
`inspect()` is a read-only snapshot — it does not contact the server or evaluate targeting rules for a specific user.
|
|
182
|
+
|
|
116
183
|
## Register / Dispatch Pattern
|
|
117
184
|
|
|
118
185
|
The register/dispatch pattern lets you centralize all flag-gated behavior in one place instead of scattering `if/else` checks throughout your codebase. Register named operations with their handlers and optional flag keys, then dispatch by operation name at the call site.
|
|
@@ -191,6 +258,37 @@ const value = await client.boolValue('any-flag', true);
|
|
|
191
258
|
// Returns the default value: true
|
|
192
259
|
```
|
|
193
260
|
|
|
261
|
+
## Offline Defaults
|
|
262
|
+
|
|
263
|
+
For deployments where the SDK may briefly be unable to reach DeploySentry (CI runs without network, cold-start before SSE connects, air-gapped builds), commit a flag snapshot to your repo and load it as fallback. The SDK still prefers the live API; defaults only fire when both the API and the in-process cache are empty.
|
|
264
|
+
|
|
265
|
+
Generate the snapshot with the CLI:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
deploysentry flags export --application web --env production -f flags.json
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Then load it after constructing the client:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
const client = new DeploySentryClient({
|
|
275
|
+
apiKey: process.env.DEPLOYSENTRY_API_KEY!,
|
|
276
|
+
environment: 'production',
|
|
277
|
+
project: 'my-app',
|
|
278
|
+
application: 'web',
|
|
279
|
+
});
|
|
280
|
+
await client.loadDefaultsFromFile('flags.json');
|
|
281
|
+
// or sync from an already-parsed object:
|
|
282
|
+
// client.loadDefaults(JSON.parse(fs.readFileSync('flags.json', 'utf-8')));
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Evaluation order:
|
|
286
|
+
|
|
287
|
+
1. **Live API** when reachable.
|
|
288
|
+
2. **In-process cache** (entries from prior live calls).
|
|
289
|
+
3. **Offline defaults** loaded above — picks the per-environment value matching your `environment` option (by UUID first, then by name, case-insensitive). Falls back to the flag's global `default_value` when no env matches.
|
|
290
|
+
4. **Caller's `defaultValue`** when the flag isn't in the export.
|
|
291
|
+
|
|
194
292
|
## Configuration
|
|
195
293
|
|
|
196
294
|
| Option | Type | Required | Default | Description |
|
|
@@ -207,15 +305,15 @@ const value = await client.boolValue('any-flag', true);
|
|
|
207
305
|
|
|
208
306
|
## Offline / File Mode
|
|
209
307
|
|
|
210
|
-
The SDK can load flag configurations from a local YAML file
|
|
308
|
+
The SDK can load flag configurations from a local YAML/JSON file. **The server is always the source of truth** — the exported file is a *backup/fallback only*. In production use `server-with-fallback`: the SDK reaches the server first on every evaluation and consults the local file only when the server (and the in-process cache) are unreachable. Pure `file` mode (no server contact) is intended for local development, CI, and testing — not for normal production operation.
|
|
211
309
|
|
|
212
310
|
### Modes
|
|
213
311
|
|
|
214
312
|
| Mode | Behavior |
|
|
215
313
|
| --- | --- |
|
|
216
|
-
| `server` (default) | API calls + SSE streaming |
|
|
217
|
-
| `file` | Load from
|
|
218
|
-
| `server-with-fallback` |
|
|
314
|
+
| `server` (default) | API calls + SSE streaming. Server only. |
|
|
315
|
+
| `file` | Load from local file, evaluate locally. **No server contact — dev/CI/testing only.** |
|
|
316
|
+
| `server-with-fallback` | **Recommended for resilience.** Always try the server first; fall back to the local file only when the server is unreachable, then return to live as soon as it recovers. |
|
|
219
317
|
|
|
220
318
|
### Usage
|
|
221
319
|
|
package/dist/cjs/cache.d.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import { Flag } from './types';
|
|
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
|
*
|
|
@@ -13,14 +23,31 @@ export declare class FlagCache {
|
|
|
13
23
|
* Defaults to 60 000 (1 minute).
|
|
14
24
|
*/
|
|
15
25
|
constructor(ttlMs?: number);
|
|
16
|
-
/**
|
|
17
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Store or update a single flag in the cache.
|
|
28
|
+
*
|
|
29
|
+
* Pass `durable: true` for flags drawn from a full server sync (or a restored
|
|
30
|
+
* disk snapshot) so they never expire — the resilient sync engine keeps them
|
|
31
|
+
* fresh and the local copy must remain serveable while the server is
|
|
32
|
+
* unreachable. Omit it for single-flag SSE updates, which inherit the TTL.
|
|
33
|
+
*/
|
|
34
|
+
set(flag: Flag, opts?: {
|
|
35
|
+
durable?: boolean;
|
|
36
|
+
}): void;
|
|
18
37
|
/** Bulk-insert flags, replacing any stale entries. */
|
|
19
|
-
setMany(flags: Flag[]
|
|
38
|
+
setMany(flags: Flag[], opts?: {
|
|
39
|
+
durable?: boolean;
|
|
40
|
+
}): void;
|
|
20
41
|
/** Retrieve a flag by key. Returns `undefined` if missing or expired. */
|
|
21
42
|
get(key: string): Flag | undefined;
|
|
22
43
|
/** Return all non-expired flags currently in the cache. */
|
|
23
44
|
getAll(): Flag[];
|
|
45
|
+
/**
|
|
46
|
+
* Return every entry held in the cache — including stale (TTL-elapsed)
|
|
47
|
+
* entries — without evicting anything. For inspection / admin views only;
|
|
48
|
+
* read paths should use {@link get} / {@link getAll} which evict.
|
|
49
|
+
*/
|
|
50
|
+
entries(): CacheInspectionEntry[];
|
|
24
51
|
/** Remove a single key from the cache. */
|
|
25
52
|
delete(key: string): void;
|
|
26
53
|
/** Remove all expired entries. Returns the number of entries purged. */
|
package/dist/cjs/cache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;
|
|
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;;;;;;;OAOG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IASnD,sDAAsD;IACtD,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAM1D,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/cjs/cache.js
CHANGED
|
@@ -17,17 +17,26 @@ class FlagCache {
|
|
|
17
17
|
constructor(ttlMs = 60_000) {
|
|
18
18
|
this.ttlMs = ttlMs;
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Store or update a single flag in the cache.
|
|
22
|
+
*
|
|
23
|
+
* Pass `durable: true` for flags drawn from a full server sync (or a restored
|
|
24
|
+
* disk snapshot) so they never expire — the resilient sync engine keeps them
|
|
25
|
+
* fresh and the local copy must remain serveable while the server is
|
|
26
|
+
* unreachable. Omit it for single-flag SSE updates, which inherit the TTL.
|
|
27
|
+
*/
|
|
28
|
+
set(flag, opts) {
|
|
29
|
+
const now = Date.now();
|
|
22
30
|
this.store.set(flag.key, {
|
|
23
31
|
flag,
|
|
24
|
-
|
|
32
|
+
storedAt: now,
|
|
33
|
+
expiresAt: opts?.durable || this.ttlMs <= 0 ? Infinity : now + this.ttlMs,
|
|
25
34
|
});
|
|
26
35
|
}
|
|
27
36
|
/** Bulk-insert flags, replacing any stale entries. */
|
|
28
|
-
setMany(flags) {
|
|
37
|
+
setMany(flags, opts) {
|
|
29
38
|
for (const flag of flags) {
|
|
30
|
-
this.set(flag);
|
|
39
|
+
this.set(flag, opts);
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
/** Retrieve a flag by key. Returns `undefined` if missing or expired. */
|
|
@@ -55,6 +64,24 @@ class FlagCache {
|
|
|
55
64
|
}
|
|
56
65
|
return result;
|
|
57
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Return every entry held in the cache — including stale (TTL-elapsed)
|
|
69
|
+
* entries — without evicting anything. For inspection / admin views only;
|
|
70
|
+
* read paths should use {@link get} / {@link getAll} which evict.
|
|
71
|
+
*/
|
|
72
|
+
entries() {
|
|
73
|
+
const now = Date.now();
|
|
74
|
+
const result = [];
|
|
75
|
+
for (const entry of this.store.values()) {
|
|
76
|
+
result.push({
|
|
77
|
+
flag: entry.flag,
|
|
78
|
+
storedAt: entry.storedAt,
|
|
79
|
+
expiresAt: entry.expiresAt,
|
|
80
|
+
stale: now > entry.expiresAt,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
58
85
|
/** Remove a single key from the cache. */
|
|
59
86
|
delete(key) {
|
|
60
87
|
this.store.delete(key);
|
package/dist/cjs/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClientOptions, EvaluationContext, EvaluationResult, Flag, FlagCategory } from './types';
|
|
1
|
+
import { ClientOptions, EvaluationContext, EvaluationResult, Flag, FlagCategory, FlagInspection } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* DeploySentry feature-flag client.
|
|
4
4
|
*
|
|
@@ -29,9 +29,19 @@ export declare class DeploySentryClient {
|
|
|
29
29
|
private readonly onFlagChange?;
|
|
30
30
|
private readonly cache;
|
|
31
31
|
private streamClient;
|
|
32
|
+
private readonly persistence;
|
|
33
|
+
private readonly resyncIntervalMs?;
|
|
34
|
+
private syncManager;
|
|
32
35
|
private _initialized;
|
|
33
36
|
private flagConfig;
|
|
37
|
+
private offlineDefaults;
|
|
38
|
+
private offlineDefaultsEnvUUID;
|
|
39
|
+
private flagConfigLoadedAt?;
|
|
40
|
+
private offlineDefaultsLoadedAt?;
|
|
41
|
+
private flagsVersion;
|
|
34
42
|
private registry;
|
|
43
|
+
private statusReporter;
|
|
44
|
+
private readonly statusReporterOptions;
|
|
35
45
|
constructor(options: ClientOptions);
|
|
36
46
|
/**
|
|
37
47
|
* Fetch the initial flag set and open an SSE connection for real-time
|
|
@@ -40,6 +50,7 @@ export declare class DeploySentryClient {
|
|
|
40
50
|
initialize(): Promise<void>;
|
|
41
51
|
/** Tear down the SSE connection and release resources. */
|
|
42
52
|
close(): void;
|
|
53
|
+
private startStatusReporter;
|
|
43
54
|
/**
|
|
44
55
|
* Clear the local cache and re-fetch all flags from the server.
|
|
45
56
|
* Useful when session state may have changed and the client needs
|
|
@@ -69,10 +80,53 @@ export declare class DeploySentryClient {
|
|
|
69
80
|
flagOwners(key: string): string[];
|
|
70
81
|
/** Return every flag currently held in the local cache. */
|
|
71
82
|
allFlags(): Flag[];
|
|
83
|
+
/**
|
|
84
|
+
* Return a provenance-tagged view of every flag the SDK currently knows
|
|
85
|
+
* about, drawn from all sources (live server cache, offline file config,
|
|
86
|
+
* and offline defaults). Each entry reports the resolved value, its type,
|
|
87
|
+
* the {@link FlagSource | source} it came from, an evaluation reason code,
|
|
88
|
+
* and when it was last fetched / loaded.
|
|
89
|
+
*
|
|
90
|
+
* Intended for wiring into an admin or support panel so operators can see
|
|
91
|
+
* exactly what value an application is serving and where it came from. This
|
|
92
|
+
* is a read-only snapshot — it does not contact the server or evaluate
|
|
93
|
+
* targeting rules for a specific user.
|
|
94
|
+
*/
|
|
95
|
+
inspect(): FlagInspection[];
|
|
72
96
|
register<T extends (...args: any[]) => any>(operation: string, handler: T, flagKey?: string): void;
|
|
73
97
|
dispatch<T extends (...args: any[]) => any>(operation: string, _context?: EvaluationContext): T;
|
|
74
98
|
private evaluate;
|
|
99
|
+
/**
|
|
100
|
+
* Load offline default values from a flag-export file. When the live API
|
|
101
|
+
* is unreachable and the cache has no entry, the SDK falls back to these
|
|
102
|
+
* defaults for {@link boolValue} / {@link stringValue} / {@link intValue}
|
|
103
|
+
* / {@link jsonValue} calls.
|
|
104
|
+
*
|
|
105
|
+
* Accepts the JSON (default) or YAML format produced by
|
|
106
|
+
* `deploysentry flags export`.
|
|
107
|
+
*
|
|
108
|
+
* Environment matching: the SDK matches the configured `environment`
|
|
109
|
+
* option against the export's `environments[]` first by UUID, then by
|
|
110
|
+
* name (case-insensitive). When a match is found, that env's per-flag
|
|
111
|
+
* `{enabled, value}` overrides the flag's global `default_value`.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* await client.loadDefaultsFromFile('flags.json');
|
|
115
|
+
*/
|
|
116
|
+
loadDefaultsFromFile(path: string): Promise<void>;
|
|
117
|
+
/**
|
|
118
|
+
* Synchronous variant of {@link loadDefaultsFromFile} that accepts an
|
|
119
|
+
* already-parsed object (or a JSON string).
|
|
120
|
+
*/
|
|
121
|
+
loadDefaults(payload: unknown): void;
|
|
75
122
|
private fetchAllFlags;
|
|
123
|
+
/**
|
|
124
|
+
* The project's flag-set version last loaded from the server, or `null` if
|
|
125
|
+
* no successful server load has happened (offline/file mode, or boot before
|
|
126
|
+
* the first sync). The version advances on any change to the project's flag
|
|
127
|
+
* state, so it validates exactly which flag set the SDK is serving.
|
|
128
|
+
*/
|
|
129
|
+
getFlagsVersion(): number | null;
|
|
76
130
|
private fetchFlag;
|
|
77
131
|
private post;
|
|
78
132
|
private request;
|
package/dist/cjs/client.d.ts.map
CHANGED
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|