@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
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Flag } from './types';
|
|
2
|
+
/** Timing knobs for the resilient sync engine. All values in milliseconds. */
|
|
3
|
+
export interface SyncTiming {
|
|
4
|
+
/** Steady-state full-resync interval while the SSE stream is healthy. */
|
|
5
|
+
steadyIntervalMs: number;
|
|
6
|
+
/** Resync interval while the stream is down but the server is reachable. */
|
|
7
|
+
streamDownResyncMs: number;
|
|
8
|
+
/** First retry delay after a failed full fetch (escalates to max). */
|
|
9
|
+
retryInitialMs: number;
|
|
10
|
+
/** Cap on the escalating retry delay after repeated fetch failures. */
|
|
11
|
+
retryMaxMs: number;
|
|
12
|
+
/** No stream activity within this window marks the stream unhealthy. */
|
|
13
|
+
streamStaleAfterMs: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const DEFAULT_SYNC_TIMING: SyncTiming;
|
|
16
|
+
interface SyncManagerOptions {
|
|
17
|
+
/** Fetch the full flag set from the server. Throws on failure. */
|
|
18
|
+
fetchAll: () => Promise<Flag[]>;
|
|
19
|
+
/** Called with the authoritative full flag set after every successful sync. */
|
|
20
|
+
onSynced: (flags: Flag[]) => void;
|
|
21
|
+
timing?: Partial<SyncTiming>;
|
|
22
|
+
/** Returns epoch-ms; injectable for tests. Defaults to Date.now. */
|
|
23
|
+
now?: () => number;
|
|
24
|
+
log?: (msg: string) => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Drives full flag resynchronisation so the local copy is never out of sync
|
|
28
|
+
* with the server unless the connection is completely down.
|
|
29
|
+
*
|
|
30
|
+
* Cadence is chosen each tick from observed health:
|
|
31
|
+
*
|
|
32
|
+
* - **Last fetch failed** → aggressive retry (escalating {@link SyncTiming.retryInitialMs}
|
|
33
|
+
* → {@link SyncTiming.retryMaxMs}). Covers both boot and mid-flight outages:
|
|
34
|
+
* "retry frequently until successful".
|
|
35
|
+
* - **Stream healthy** (recent ping) → steady 10-minute safety-net resync;
|
|
36
|
+
* SSE delivers individual changes in between.
|
|
37
|
+
* - **Stream down but server reachable** → fast 30-second resync so flags
|
|
38
|
+
* cannot drift while the realtime channel is dead.
|
|
39
|
+
*
|
|
40
|
+
* A stream reconnect triggers an immediate resync to recover any change events
|
|
41
|
+
* missed while disconnected.
|
|
42
|
+
*/
|
|
43
|
+
export declare class SyncManager {
|
|
44
|
+
private readonly fetchAll;
|
|
45
|
+
private readonly onSynced;
|
|
46
|
+
private readonly timing;
|
|
47
|
+
private readonly now;
|
|
48
|
+
private readonly log;
|
|
49
|
+
private timer;
|
|
50
|
+
private stopped;
|
|
51
|
+
private running;
|
|
52
|
+
private lastFetchOk;
|
|
53
|
+
private retryMs;
|
|
54
|
+
private streamConnected;
|
|
55
|
+
private lastStreamActivity;
|
|
56
|
+
private streamDropped;
|
|
57
|
+
/** Resolves once the first successful full sync completes. */
|
|
58
|
+
readonly firstSync: Promise<void>;
|
|
59
|
+
private resolveFirstSync;
|
|
60
|
+
constructor(options: SyncManagerOptions);
|
|
61
|
+
/** True once at least one full sync has succeeded. */
|
|
62
|
+
get isSynced(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Begin the sync loop. Runs one sync immediately, then self-schedules.
|
|
65
|
+
* Returns when the loop is armed (does not wait for the first sync — await
|
|
66
|
+
* {@link firstSync} for that).
|
|
67
|
+
*/
|
|
68
|
+
start(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Seed the engine with an already-fetched flag set (e.g. the boot fetch) so
|
|
71
|
+
* it applies it via {@link SyncManagerOptions.onSynced} and schedules the
|
|
72
|
+
* next resync, avoiding an immediate duplicate fetch.
|
|
73
|
+
*/
|
|
74
|
+
seed(flags: Flag[]): void;
|
|
75
|
+
/** Stop all scheduled syncs. */
|
|
76
|
+
stop(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Record that the SSE stream connected.
|
|
79
|
+
*
|
|
80
|
+
* On a reconnect after a drop, resync immediately to recover change events
|
|
81
|
+
* missed while disconnected. The first-ever open is benign — boot already
|
|
82
|
+
* loaded the full set (via {@link seed} or the initial fetch) — so it only
|
|
83
|
+
* reschedules the next tick to reflect the now-healthy steady cadence
|
|
84
|
+
* instead of forcing a redundant fetch.
|
|
85
|
+
*/
|
|
86
|
+
noteStreamOpen(): void;
|
|
87
|
+
/** Record inbound stream activity (heartbeat or data event). */
|
|
88
|
+
noteStreamActivity(): void;
|
|
89
|
+
/** Record that the SSE stream errored / closed. */
|
|
90
|
+
noteStreamError(): void;
|
|
91
|
+
private streamHealthy;
|
|
92
|
+
/** Force a resync as soon as possible without waiting for the next tick. */
|
|
93
|
+
private triggerNow;
|
|
94
|
+
/**
|
|
95
|
+
* Recompute the next tick's delay from current health without fetching.
|
|
96
|
+
* Used when stream health changes (e.g. the first open turns an unhealthy
|
|
97
|
+
* 30s cadence into the steady 10-minute one) but no immediate resync is
|
|
98
|
+
* warranted.
|
|
99
|
+
*/
|
|
100
|
+
private reschedule;
|
|
101
|
+
private tick;
|
|
102
|
+
private schedule;
|
|
103
|
+
}
|
|
104
|
+
export {};
|
|
105
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,mBAAmB,EAAE,UAMjC,CAAC;AAEF,UAAU,kBAAkB;IAC1B,kEAAkE;IAClE,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,+EAA+E;IAC/E,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7B,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAwB;IAE5C,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,aAAa,CAAS;IAE9B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO,CAAC,gBAAgB,CAAc;gBAE1B,OAAO,EAAE,kBAAkB;IAYvC,sDAAsD;IACtD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAKb;;;;OAIG;IACH,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IASzB,gCAAgC;IAChC,IAAI,IAAI,IAAI;IAQZ;;;;;;;;OAQG;IACH,cAAc,IAAI,IAAI;IAWtB,gEAAgE;IAChE,kBAAkB,IAAI,IAAI;IAI1B,mDAAmD;IACnD,eAAe,IAAI,IAAI;IAKvB,OAAO,CAAC,aAAa;IAOrB,4EAA4E;IAC5E,OAAO,CAAC,UAAU;IASlB;;;;;OAKG;IACH,OAAO,CAAC,UAAU;YASJ,IAAI;IAkBlB,OAAO,CAAC,QAAQ;CAkBjB"}
|
package/dist/cjs/sync.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SyncManager = exports.DEFAULT_SYNC_TIMING = void 0;
|
|
4
|
+
exports.DEFAULT_SYNC_TIMING = {
|
|
5
|
+
steadyIntervalMs: 600_000, // 10 minutes — safety net while SSE keeps us live.
|
|
6
|
+
streamDownResyncMs: 30_000, // poll every 30s when the stream is dead.
|
|
7
|
+
retryInitialMs: 1_000,
|
|
8
|
+
retryMaxMs: 15_000,
|
|
9
|
+
streamStaleAfterMs: 30_000, // server pings every ~10s; 30s = three missed.
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Drives full flag resynchronisation so the local copy is never out of sync
|
|
13
|
+
* with the server unless the connection is completely down.
|
|
14
|
+
*
|
|
15
|
+
* Cadence is chosen each tick from observed health:
|
|
16
|
+
*
|
|
17
|
+
* - **Last fetch failed** → aggressive retry (escalating {@link SyncTiming.retryInitialMs}
|
|
18
|
+
* → {@link SyncTiming.retryMaxMs}). Covers both boot and mid-flight outages:
|
|
19
|
+
* "retry frequently until successful".
|
|
20
|
+
* - **Stream healthy** (recent ping) → steady 10-minute safety-net resync;
|
|
21
|
+
* SSE delivers individual changes in between.
|
|
22
|
+
* - **Stream down but server reachable** → fast 30-second resync so flags
|
|
23
|
+
* cannot drift while the realtime channel is dead.
|
|
24
|
+
*
|
|
25
|
+
* A stream reconnect triggers an immediate resync to recover any change events
|
|
26
|
+
* missed while disconnected.
|
|
27
|
+
*/
|
|
28
|
+
class SyncManager {
|
|
29
|
+
fetchAll;
|
|
30
|
+
onSynced;
|
|
31
|
+
timing;
|
|
32
|
+
now;
|
|
33
|
+
log;
|
|
34
|
+
timer = null;
|
|
35
|
+
stopped = false;
|
|
36
|
+
running = false;
|
|
37
|
+
lastFetchOk = false;
|
|
38
|
+
retryMs;
|
|
39
|
+
streamConnected = false;
|
|
40
|
+
lastStreamActivity = 0;
|
|
41
|
+
streamDropped = false;
|
|
42
|
+
/** Resolves once the first successful full sync completes. */
|
|
43
|
+
firstSync;
|
|
44
|
+
resolveFirstSync;
|
|
45
|
+
constructor(options) {
|
|
46
|
+
this.fetchAll = options.fetchAll;
|
|
47
|
+
this.onSynced = options.onSynced;
|
|
48
|
+
this.timing = { ...exports.DEFAULT_SYNC_TIMING, ...(options.timing ?? {}) };
|
|
49
|
+
this.now = options.now ?? Date.now;
|
|
50
|
+
this.log = options.log ?? (() => { });
|
|
51
|
+
this.retryMs = this.timing.retryInitialMs;
|
|
52
|
+
this.firstSync = new Promise((resolve) => {
|
|
53
|
+
this.resolveFirstSync = resolve;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/** True once at least one full sync has succeeded. */
|
|
57
|
+
get isSynced() {
|
|
58
|
+
return this.lastFetchOk;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Begin the sync loop. Runs one sync immediately, then self-schedules.
|
|
62
|
+
* Returns when the loop is armed (does not wait for the first sync — await
|
|
63
|
+
* {@link firstSync} for that).
|
|
64
|
+
*/
|
|
65
|
+
start() {
|
|
66
|
+
if (this.stopped)
|
|
67
|
+
return;
|
|
68
|
+
void this.tick();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Seed the engine with an already-fetched flag set (e.g. the boot fetch) so
|
|
72
|
+
* it applies it via {@link SyncManagerOptions.onSynced} and schedules the
|
|
73
|
+
* next resync, avoiding an immediate duplicate fetch.
|
|
74
|
+
*/
|
|
75
|
+
seed(flags) {
|
|
76
|
+
if (this.stopped)
|
|
77
|
+
return;
|
|
78
|
+
this.lastFetchOk = true;
|
|
79
|
+
this.retryMs = this.timing.retryInitialMs;
|
|
80
|
+
this.onSynced(flags);
|
|
81
|
+
this.resolveFirstSync();
|
|
82
|
+
this.schedule();
|
|
83
|
+
}
|
|
84
|
+
/** Stop all scheduled syncs. */
|
|
85
|
+
stop() {
|
|
86
|
+
this.stopped = true;
|
|
87
|
+
if (this.timer) {
|
|
88
|
+
clearTimeout(this.timer);
|
|
89
|
+
this.timer = null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Record that the SSE stream connected.
|
|
94
|
+
*
|
|
95
|
+
* On a reconnect after a drop, resync immediately to recover change events
|
|
96
|
+
* missed while disconnected. The first-ever open is benign — boot already
|
|
97
|
+
* loaded the full set (via {@link seed} or the initial fetch) — so it only
|
|
98
|
+
* reschedules the next tick to reflect the now-healthy steady cadence
|
|
99
|
+
* instead of forcing a redundant fetch.
|
|
100
|
+
*/
|
|
101
|
+
noteStreamOpen() {
|
|
102
|
+
this.streamConnected = true;
|
|
103
|
+
this.lastStreamActivity = this.now();
|
|
104
|
+
if (this.streamDropped) {
|
|
105
|
+
this.streamDropped = false;
|
|
106
|
+
this.triggerNow();
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.reschedule();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** Record inbound stream activity (heartbeat or data event). */
|
|
113
|
+
noteStreamActivity() {
|
|
114
|
+
this.lastStreamActivity = this.now();
|
|
115
|
+
}
|
|
116
|
+
/** Record that the SSE stream errored / closed. */
|
|
117
|
+
noteStreamError() {
|
|
118
|
+
this.streamConnected = false;
|
|
119
|
+
this.streamDropped = true;
|
|
120
|
+
}
|
|
121
|
+
streamHealthy() {
|
|
122
|
+
return (this.streamConnected &&
|
|
123
|
+
this.now() - this.lastStreamActivity <= this.timing.streamStaleAfterMs);
|
|
124
|
+
}
|
|
125
|
+
/** Force a resync as soon as possible without waiting for the next tick. */
|
|
126
|
+
triggerNow() {
|
|
127
|
+
if (this.stopped || this.running)
|
|
128
|
+
return;
|
|
129
|
+
if (this.timer) {
|
|
130
|
+
clearTimeout(this.timer);
|
|
131
|
+
this.timer = null;
|
|
132
|
+
}
|
|
133
|
+
void this.tick();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Recompute the next tick's delay from current health without fetching.
|
|
137
|
+
* Used when stream health changes (e.g. the first open turns an unhealthy
|
|
138
|
+
* 30s cadence into the steady 10-minute one) but no immediate resync is
|
|
139
|
+
* warranted.
|
|
140
|
+
*/
|
|
141
|
+
reschedule() {
|
|
142
|
+
if (this.stopped || this.running)
|
|
143
|
+
return;
|
|
144
|
+
if (this.timer) {
|
|
145
|
+
clearTimeout(this.timer);
|
|
146
|
+
this.timer = null;
|
|
147
|
+
}
|
|
148
|
+
this.schedule();
|
|
149
|
+
}
|
|
150
|
+
async tick() {
|
|
151
|
+
if (this.stopped || this.running)
|
|
152
|
+
return;
|
|
153
|
+
this.running = true;
|
|
154
|
+
try {
|
|
155
|
+
const flags = await this.fetchAll();
|
|
156
|
+
this.lastFetchOk = true;
|
|
157
|
+
this.retryMs = this.timing.retryInitialMs;
|
|
158
|
+
this.onSynced(flags);
|
|
159
|
+
this.resolveFirstSync();
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
this.lastFetchOk = false;
|
|
163
|
+
this.log(`full resync failed: ${String(err)}`);
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
this.running = false;
|
|
167
|
+
this.schedule();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
schedule() {
|
|
171
|
+
if (this.stopped)
|
|
172
|
+
return;
|
|
173
|
+
let delay;
|
|
174
|
+
if (!this.lastFetchOk) {
|
|
175
|
+
delay = this.retryMs;
|
|
176
|
+
this.retryMs = Math.min(this.retryMs * 2, this.timing.retryMaxMs);
|
|
177
|
+
}
|
|
178
|
+
else if (this.streamHealthy()) {
|
|
179
|
+
delay = this.timing.steadyIntervalMs;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
delay = this.timing.streamDownResyncMs;
|
|
183
|
+
}
|
|
184
|
+
this.timer = setTimeout(() => {
|
|
185
|
+
this.timer = null;
|
|
186
|
+
void this.tick();
|
|
187
|
+
}, delay);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
exports.SyncManager = SyncManager;
|
|
191
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/sync.ts"],"names":[],"mappings":";;;AAgBa,QAAA,mBAAmB,GAAe;IAC7C,gBAAgB,EAAE,OAAO,EAAE,mDAAmD;IAC9E,kBAAkB,EAAE,MAAM,EAAE,0CAA0C;IACtE,cAAc,EAAE,KAAK;IACrB,UAAU,EAAE,MAAM;IAClB,kBAAkB,EAAE,MAAM,EAAE,+CAA+C;CAC5E,CAAC;AAaF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,WAAW;IACL,QAAQ,CAAwB;IAChC,QAAQ,CAA0B;IAClC,MAAM,CAAa;IACnB,GAAG,CAAe;IAClB,GAAG,CAAwB;IAEpC,KAAK,GAAyC,IAAI,CAAC;IACnD,OAAO,GAAG,KAAK,CAAC;IAChB,OAAO,GAAG,KAAK,CAAC;IAChB,WAAW,GAAG,KAAK,CAAC;IACpB,OAAO,CAAS;IAEhB,eAAe,GAAG,KAAK,CAAC;IACxB,kBAAkB,GAAG,CAAC,CAAC;IACvB,aAAa,GAAG,KAAK,CAAC;IAE9B,8DAA8D;IACrD,SAAS,CAAgB;IAC1B,gBAAgB,CAAc;IAEtC,YAAY,OAA2B;QACrC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,2BAAmB,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QACnC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACvC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sDAAsD;IACtD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,KAAa;QAChB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,gCAAgC;IAChC,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,cAAc;QACZ,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,kBAAkB;QAChB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvC,CAAC;IAED,mDAAmD;IACnD,eAAe;QACb,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAEO,aAAa;QACnB,OAAO,CACL,IAAI,CAAC,eAAe;YACpB,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,MAAM,CAAC,kBAAkB,CACvE,CAAC;IACJ,CAAC;IAED,4EAA4E;IACpE,UAAU;QAChB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACK,UAAU;QAChB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAEO,QAAQ;QACd,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAEzB,IAAI,KAAa,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC;YACrB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpE,CAAC;aAAM,IAAI,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YAChC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;QACzC,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QACnB,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;CACF;AA1KD,kCA0KC"}
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* DeploySentry SDK type definitions.
|
|
3
3
|
*/
|
|
4
4
|
/** Categories that classify the intent and lifecycle of a feature flag. */
|
|
5
|
-
export type FlagCategory = 'release' | 'feature' | 'experiment' | 'ops' | 'permission';
|
|
5
|
+
export type FlagCategory = 'release' | 'feature' | 'experiment' | 'ops' | 'permission' | 'envvar';
|
|
6
6
|
/** Rich metadata attached to every feature flag. */
|
|
7
7
|
export interface FlagMetadata {
|
|
8
8
|
/** Categorisation that drives lifecycle policies. */
|
|
@@ -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. */
|
|
@@ -79,6 +113,49 @@ export interface ClientOptions {
|
|
|
79
113
|
flagFilePath?: string;
|
|
80
114
|
/** Called whenever the flag cache is refreshed from an SSE change event. */
|
|
81
115
|
onFlagChange?: (flags: Flag[]) => void;
|
|
116
|
+
/**
|
|
117
|
+
* Path to a local JSON file where the SDK persists the last fully-synced
|
|
118
|
+
* flag set. When set, the client survives a server outage on boot by
|
|
119
|
+
* restoring this snapshot, and the resilient sync engine retries the initial
|
|
120
|
+
* fetch in the background until it succeeds instead of throwing. Omit to keep
|
|
121
|
+
* the legacy in-memory-only behaviour (boot fetch failure throws).
|
|
122
|
+
*/
|
|
123
|
+
persistencePath?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Steady-state full-resync interval in ms while the SSE stream is healthy.
|
|
126
|
+
* Default: 600_000 (10 minutes). When the stream goes quiet the engine
|
|
127
|
+
* resyncs far more aggressively regardless of this value.
|
|
128
|
+
*/
|
|
129
|
+
resyncIntervalMs?: number;
|
|
130
|
+
/**
|
|
131
|
+
* Application UUID. Required when `reportStatus` is true. Distinct from
|
|
132
|
+
* `application` (the slug used for flag evaluation) because the status
|
|
133
|
+
* endpoint is keyed on the UUID.
|
|
134
|
+
*/
|
|
135
|
+
applicationId?: string;
|
|
136
|
+
/** Enable the status reporter. Default: false. */
|
|
137
|
+
reportStatus?: boolean;
|
|
138
|
+
/** Interval in ms between status reports. Default: 30_000. 0 = send once on init. */
|
|
139
|
+
reportStatusIntervalMs?: number;
|
|
140
|
+
/** Override the auto-detected version string. */
|
|
141
|
+
reportStatusVersion?: string;
|
|
142
|
+
/** Commit SHA reported alongside the version. */
|
|
143
|
+
reportStatusCommitSha?: string;
|
|
144
|
+
/** Optional deploy-slot tag (`stable` / `canary`). */
|
|
145
|
+
reportStatusDeploySlot?: string;
|
|
146
|
+
/** Arbitrary tags attached to every report. */
|
|
147
|
+
reportStatusTags?: Record<string, string>;
|
|
148
|
+
/**
|
|
149
|
+
* Optional callback resolving the current health. If omitted the reporter
|
|
150
|
+
* sends `state: 'healthy'` on every tick (the "process alive" floor).
|
|
151
|
+
*/
|
|
152
|
+
reportStatusHealthProvider?: () => HealthReport | Promise<HealthReport>;
|
|
153
|
+
}
|
|
154
|
+
/** Shape returned by a status reporter's health provider. */
|
|
155
|
+
export interface HealthReport {
|
|
156
|
+
state: 'healthy' | 'degraded' | 'unhealthy' | 'unknown';
|
|
157
|
+
score?: number;
|
|
158
|
+
reason?: string;
|
|
82
159
|
}
|
|
83
160
|
export interface FlagConfig {
|
|
84
161
|
version: number;
|
package/dist/cjs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,KAAK,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/cache.d.ts
CHANGED
|
@@ -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
|
*
|
|
@@ -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/esm/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/esm/cache.js
CHANGED
|
@@ -14,17 +14,26 @@ export class FlagCache {
|
|
|
14
14
|
constructor(ttlMs = 60_000) {
|
|
15
15
|
this.ttlMs = ttlMs;
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Store or update a single flag in the cache.
|
|
19
|
+
*
|
|
20
|
+
* Pass `durable: true` for flags drawn from a full server sync (or a restored
|
|
21
|
+
* disk snapshot) so they never expire — the resilient sync engine keeps them
|
|
22
|
+
* fresh and the local copy must remain serveable while the server is
|
|
23
|
+
* unreachable. Omit it for single-flag SSE updates, which inherit the TTL.
|
|
24
|
+
*/
|
|
25
|
+
set(flag, opts) {
|
|
26
|
+
const now = Date.now();
|
|
19
27
|
this.store.set(flag.key, {
|
|
20
28
|
flag,
|
|
21
|
-
|
|
29
|
+
storedAt: now,
|
|
30
|
+
expiresAt: opts?.durable || this.ttlMs <= 0 ? Infinity : now + this.ttlMs,
|
|
22
31
|
});
|
|
23
32
|
}
|
|
24
33
|
/** Bulk-insert flags, replacing any stale entries. */
|
|
25
|
-
setMany(flags) {
|
|
34
|
+
setMany(flags, opts) {
|
|
26
35
|
for (const flag of flags) {
|
|
27
|
-
this.set(flag);
|
|
36
|
+
this.set(flag, opts);
|
|
28
37
|
}
|
|
29
38
|
}
|
|
30
39
|
/** Retrieve a flag by key. Returns `undefined` if missing or expired. */
|
|
@@ -52,6 +61,24 @@ export class FlagCache {
|
|
|
52
61
|
}
|
|
53
62
|
return result;
|
|
54
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Return every entry held in the cache — including stale (TTL-elapsed)
|
|
66
|
+
* entries — without evicting anything. For inspection / admin views only;
|
|
67
|
+
* read paths should use {@link get} / {@link getAll} which evict.
|
|
68
|
+
*/
|
|
69
|
+
entries() {
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
const result = [];
|
|
72
|
+
for (const entry of this.store.values()) {
|
|
73
|
+
result.push({
|
|
74
|
+
flag: entry.flag,
|
|
75
|
+
storedAt: entry.storedAt,
|
|
76
|
+
expiresAt: entry.expiresAt,
|
|
77
|
+
stale: now > entry.expiresAt,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
55
82
|
/** Remove a single key from the cache. */
|
|
56
83
|
delete(key) {
|
|
57
84
|
this.store.delete(key);
|
package/dist/esm/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/esm/client.d.ts
CHANGED
|
@@ -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
|
*
|
|
@@ -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/esm/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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"}
|