@dr-sentry/sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +285 -0
  2. package/dist/cjs/cache.d.ts +33 -0
  3. package/dist/cjs/cache.d.ts.map +1 -0
  4. package/dist/cjs/cache.js +84 -0
  5. package/dist/cjs/cache.js.map +1 -0
  6. package/dist/cjs/client.d.ts +81 -0
  7. package/dist/cjs/client.d.ts.map +1 -0
  8. package/dist/cjs/client.js +362 -0
  9. package/dist/cjs/client.js.map +1 -0
  10. package/dist/cjs/file-loader.d.ts +3 -0
  11. package/dist/cjs/file-loader.d.ts.map +1 -0
  12. package/dist/cjs/file-loader.js +53 -0
  13. package/dist/cjs/file-loader.js.map +1 -0
  14. package/dist/cjs/index.d.ts +29 -0
  15. package/dist/cjs/index.d.ts.map +1 -0
  16. package/dist/cjs/index.js +36 -0
  17. package/dist/cjs/index.js.map +1 -0
  18. package/dist/cjs/local-evaluator.d.ts +6 -0
  19. package/dist/cjs/local-evaluator.d.ts.map +1 -0
  20. package/dist/cjs/local-evaluator.js +40 -0
  21. package/dist/cjs/local-evaluator.js.map +1 -0
  22. package/dist/cjs/package.json +1 -0
  23. package/dist/cjs/streaming.d.ts +42 -0
  24. package/dist/cjs/streaming.d.ts.map +1 -0
  25. package/dist/cjs/streaming.js +140 -0
  26. package/dist/cjs/streaming.js.map +1 -0
  27. package/dist/cjs/types.d.ts +126 -0
  28. package/dist/cjs/types.d.ts.map +1 -0
  29. package/dist/cjs/types.js +6 -0
  30. package/dist/cjs/types.js.map +1 -0
  31. package/dist/esm/cache.d.ts +33 -0
  32. package/dist/esm/cache.d.ts.map +1 -0
  33. package/dist/esm/cache.js +80 -0
  34. package/dist/esm/cache.js.map +1 -0
  35. package/dist/esm/client.d.ts +81 -0
  36. package/dist/esm/client.d.ts.map +1 -0
  37. package/dist/esm/client.js +358 -0
  38. package/dist/esm/client.js.map +1 -0
  39. package/dist/esm/file-loader.d.ts +3 -0
  40. package/dist/esm/file-loader.d.ts.map +1 -0
  41. package/dist/esm/file-loader.js +17 -0
  42. package/dist/esm/file-loader.js.map +1 -0
  43. package/dist/esm/index.d.ts +29 -0
  44. package/dist/esm/index.d.ts.map +1 -0
  45. package/dist/esm/index.js +28 -0
  46. package/dist/esm/index.js.map +1 -0
  47. package/dist/esm/local-evaluator.d.ts +6 -0
  48. package/dist/esm/local-evaluator.d.ts.map +1 -0
  49. package/dist/esm/local-evaluator.js +37 -0
  50. package/dist/esm/local-evaluator.js.map +1 -0
  51. package/dist/esm/streaming.d.ts +42 -0
  52. package/dist/esm/streaming.d.ts.map +1 -0
  53. package/dist/esm/streaming.js +136 -0
  54. package/dist/esm/streaming.js.map +1 -0
  55. package/dist/esm/types.d.ts +126 -0
  56. package/dist/esm/types.d.ts.map +1 -0
  57. package/dist/esm/types.js +5 -0
  58. package/dist/esm/types.js.map +1 -0
  59. package/package.json +62 -0
@@ -0,0 +1,358 @@
1
+ import { FlagCache } from './cache';
2
+ import { FlagStreamClient } from './streaming';
3
+ import { loadFlagConfig } from './file-loader';
4
+ import { evaluateLocal } from './local-evaluator';
5
+ const DEFAULT_BASE_URL = 'https://api.dr-sentry.com';
6
+ const DEFAULT_CACHE_TIMEOUT_MS = 60_000;
7
+ /**
8
+ * DeploySentry feature-flag client.
9
+ *
10
+ * ```ts
11
+ * const client = new DeploySentryClient({
12
+ * apiKey: 'ds_live_xxx',
13
+ * environment: 'production',
14
+ * project: 'my-app',
15
+ * });
16
+ *
17
+ * await client.initialize();
18
+ *
19
+ * const darkMode = client.boolValue('dark-mode', false, { userId: 'u1' });
20
+ *
21
+ * client.close();
22
+ * ```
23
+ */
24
+ export class DeploySentryClient {
25
+ apiKey;
26
+ baseURL;
27
+ environment;
28
+ project;
29
+ application;
30
+ offlineMode;
31
+ sessionId;
32
+ mode;
33
+ flagFilePath;
34
+ cache;
35
+ streamClient = null;
36
+ _initialized = false;
37
+ flagConfig = null;
38
+ registry = new Map();
39
+ constructor(options) {
40
+ if (!options.apiKey)
41
+ throw new Error('apiKey is required');
42
+ if (!options.environment)
43
+ throw new Error('environment is required');
44
+ if (!options.project)
45
+ throw new Error('project is required');
46
+ if (!options.application)
47
+ throw new Error('application is required');
48
+ this.apiKey = options.apiKey;
49
+ this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
50
+ this.environment = options.environment;
51
+ this.project = options.project;
52
+ this.application = options.application;
53
+ this.offlineMode = options.offlineMode ?? false;
54
+ this.sessionId = options.sessionId;
55
+ this.mode = options.mode ?? 'server';
56
+ this.flagFilePath = options.flagFilePath;
57
+ this.cache = new FlagCache(options.cacheTimeout ?? DEFAULT_CACHE_TIMEOUT_MS);
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // Lifecycle
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * Fetch the initial flag set and open an SSE connection for real-time
64
+ * updates. Must be called before evaluating flags.
65
+ */
66
+ async initialize() {
67
+ if (this.mode === 'file') {
68
+ this.flagConfig = loadFlagConfig(this.flagFilePath);
69
+ this._initialized = true;
70
+ return;
71
+ }
72
+ if (this.offlineMode) {
73
+ this._initialized = true;
74
+ return;
75
+ }
76
+ try {
77
+ // Fetch all flags for the project so the cache is warm.
78
+ const flags = await this.fetchAllFlags();
79
+ this.cache.setMany(flags);
80
+ // Start streaming updates.
81
+ this.streamClient = new FlagStreamClient({
82
+ url: `${this.baseURL}/api/v1/flags/stream?project_id=${enc(this.project)}&environment_id=${enc(this.environment)}&application=${enc(this.application)}`,
83
+ headers: this.authHeaders(),
84
+ onUpdate: (updated) => this.cache.setMany(updated),
85
+ onError: (err) => {
86
+ // Surface errors but do not crash – the cache still serves stale data.
87
+ console.error('[DeploySentry] stream error:', err.message);
88
+ },
89
+ });
90
+ // Fire-and-forget; the stream reconnects automatically.
91
+ this.streamClient.connect();
92
+ this._initialized = true;
93
+ }
94
+ catch (err) {
95
+ if (this.mode === 'server-with-fallback') {
96
+ console.warn('[DeploySentry] Server unavailable, falling back to flag config file');
97
+ this.flagConfig = loadFlagConfig(this.flagFilePath);
98
+ this._initialized = true;
99
+ return;
100
+ }
101
+ throw err;
102
+ }
103
+ }
104
+ /** Tear down the SSE connection and release resources. */
105
+ close() {
106
+ this.streamClient?.close();
107
+ this.streamClient = null;
108
+ this.cache.clear();
109
+ this._initialized = false;
110
+ }
111
+ /**
112
+ * Clear the local cache and re-fetch all flags from the server.
113
+ * Useful when session state may have changed and the client needs
114
+ * fresh evaluations.
115
+ */
116
+ async refreshSession() {
117
+ if (this.offlineMode)
118
+ return;
119
+ this.cache.clear();
120
+ const flags = await this.fetchAllFlags();
121
+ this.cache.setMany(flags);
122
+ }
123
+ /** Whether {@link initialize} has been called successfully. */
124
+ get isInitialized() {
125
+ return this._initialized;
126
+ }
127
+ // ---------------------------------------------------------------------------
128
+ // Typed value helpers
129
+ // ---------------------------------------------------------------------------
130
+ /** Evaluate a flag as a boolean. */
131
+ async boolValue(key, defaultValue, context) {
132
+ const result = await this.evaluate(key, defaultValue, context);
133
+ if (typeof result === 'boolean')
134
+ return result;
135
+ // The backend stores `default_value` as a string, so the evaluation
136
+ // endpoint commonly returns "true"/"false". Coerce so SDK callers see
137
+ // a real boolean instead of falling back to the literal default.
138
+ if (typeof result === 'string') {
139
+ const lowered = result.toLowerCase();
140
+ if (lowered === 'true')
141
+ return true;
142
+ if (lowered === 'false')
143
+ return false;
144
+ }
145
+ return defaultValue;
146
+ }
147
+ /** Evaluate a flag as a string. */
148
+ async stringValue(key, defaultValue, context) {
149
+ const result = await this.evaluate(key, defaultValue, context);
150
+ return typeof result === 'string' ? result : defaultValue;
151
+ }
152
+ /** Evaluate a flag as an integer. */
153
+ async intValue(key, defaultValue, context) {
154
+ const result = await this.evaluate(key, defaultValue, context);
155
+ return typeof result === 'number' && Number.isInteger(result)
156
+ ? result
157
+ : defaultValue;
158
+ }
159
+ /** Evaluate a flag and return the value as a parsed JSON object. */
160
+ async jsonValue(key, defaultValue, context) {
161
+ const result = await this.evaluate(key, defaultValue, context);
162
+ return result ?? defaultValue;
163
+ }
164
+ // ---------------------------------------------------------------------------
165
+ // Detail evaluation
166
+ // ---------------------------------------------------------------------------
167
+ /**
168
+ * Return the full {@link EvaluationResult} for a flag including metadata,
169
+ * reason, and resolved value.
170
+ */
171
+ async detail(key, context) {
172
+ if (this.offlineMode) {
173
+ return this.offlineResult(key);
174
+ }
175
+ try {
176
+ const body = await this.post('/api/v1/flags/evaluate', {
177
+ project_id: this.project,
178
+ environment_id: this.environment,
179
+ application: this.application,
180
+ flag_key: key,
181
+ context: context ?? {},
182
+ ...(this.sessionId ? { session_id: this.sessionId } : {}),
183
+ });
184
+ return body;
185
+ }
186
+ catch {
187
+ return this.cachedResult(key);
188
+ }
189
+ }
190
+ // ---------------------------------------------------------------------------
191
+ // Metadata helpers
192
+ // ---------------------------------------------------------------------------
193
+ /** Return all cached flags belonging to a given category. */
194
+ flagsByCategory(category) {
195
+ return this.cache.getAll().filter((f) => f.metadata.category === category);
196
+ }
197
+ /** Return all cached flags whose `expiresAt` is in the past. */
198
+ expiredFlags() {
199
+ const now = new Date().toISOString();
200
+ return this.cache.getAll().filter((f) => {
201
+ return f.metadata.expiresAt && f.metadata.expiresAt < now;
202
+ });
203
+ }
204
+ /** Return the owners array for a given flag key. */
205
+ flagOwners(key) {
206
+ const flag = this.cache.get(key);
207
+ return flag?.metadata.owners ?? [];
208
+ }
209
+ /** Return every flag currently held in the local cache. */
210
+ allFlags() {
211
+ return this.cache.getAll();
212
+ }
213
+ // ---------------------------------------------------------------------------
214
+ // Register / Dispatch
215
+ // ---------------------------------------------------------------------------
216
+ register(operation, handler, flagKey) {
217
+ let list = this.registry.get(operation);
218
+ if (!list) {
219
+ list = [];
220
+ this.registry.set(operation, list);
221
+ }
222
+ if (flagKey === undefined) {
223
+ const idx = list.findIndex((r) => r.flagKey === undefined);
224
+ if (idx !== -1)
225
+ list[idx] = { handler };
226
+ else
227
+ list.push({ handler });
228
+ }
229
+ else {
230
+ list.push({ handler, flagKey });
231
+ }
232
+ }
233
+ dispatch(operation, _context) {
234
+ const list = this.registry.get(operation);
235
+ if (!list || list.length === 0) {
236
+ throw new Error(`No handlers registered for operation '${operation}'. Call register() before dispatch().`);
237
+ }
238
+ for (const reg of list) {
239
+ if (reg.flagKey !== undefined) {
240
+ const flag = this.cache.get(reg.flagKey);
241
+ if (flag && flag.enabled)
242
+ return reg.handler;
243
+ }
244
+ }
245
+ const defaultReg = list.find((r) => r.flagKey === undefined);
246
+ if (!defaultReg) {
247
+ throw new Error(`No matching handler for operation '${operation}' and no default registered. Register a default handler (no flagKey) as the last registration.`);
248
+ }
249
+ return defaultReg.handler;
250
+ }
251
+ // ---------------------------------------------------------------------------
252
+ // Private helpers
253
+ // ---------------------------------------------------------------------------
254
+ async evaluate(key, defaultValue, context) {
255
+ if (this.flagConfig) {
256
+ const result = evaluateLocal(this.flagConfig, this.environment, key, context);
257
+ if (result.reason === 'flag_not_found')
258
+ return defaultValue;
259
+ return result.value;
260
+ }
261
+ if (this.offlineMode)
262
+ return defaultValue;
263
+ // Prefer server-side evaluation so targeting rules are applied.
264
+ try {
265
+ const result = await this.post('/api/v1/flags/evaluate', {
266
+ project_id: this.project,
267
+ environment_id: this.environment,
268
+ application: this.application,
269
+ flag_key: key,
270
+ context: context ?? {},
271
+ ...(this.sessionId ? { session_id: this.sessionId } : {}),
272
+ });
273
+ return result.value;
274
+ }
275
+ catch {
276
+ // Fall back to the cached flag value.
277
+ const cached = this.cache.get(key);
278
+ return cached?.value ?? defaultValue;
279
+ }
280
+ }
281
+ async fetchAllFlags() {
282
+ const response = await this.request('GET', `/api/v1/flags?project_id=${enc(this.project)}&application=${enc(this.application)}`);
283
+ return response.flags ?? [];
284
+ }
285
+ async post(path, body) {
286
+ return this.request('POST', path, body);
287
+ }
288
+ async request(method, path, body) {
289
+ const url = `${this.baseURL}${path}`;
290
+ const init = {
291
+ method,
292
+ headers: {
293
+ ...this.authHeaders(),
294
+ 'Content-Type': 'application/json',
295
+ Accept: 'application/json',
296
+ },
297
+ };
298
+ if (body !== undefined) {
299
+ init.body = JSON.stringify(body);
300
+ }
301
+ const response = await fetch(url, init);
302
+ if (!response.ok) {
303
+ const text = await response.text().catch(() => '');
304
+ throw new Error(`DeploySentry API error: ${response.status} ${response.statusText} – ${text}`);
305
+ }
306
+ return response.json();
307
+ }
308
+ authHeaders() {
309
+ const headers = {
310
+ Authorization: `ApiKey ${this.apiKey}`,
311
+ };
312
+ if (this.sessionId) {
313
+ headers['X-DeploySentry-Session'] = this.sessionId;
314
+ }
315
+ return headers;
316
+ }
317
+ offlineResult(key) {
318
+ const flag = this.cache.get(key);
319
+ const metadata = flag?.metadata ?? {
320
+ category: 'feature',
321
+ purpose: '',
322
+ owners: [],
323
+ isPermanent: false,
324
+ tags: [],
325
+ };
326
+ return {
327
+ key,
328
+ value: flag?.value ?? null,
329
+ enabled: flag?.enabled ?? false,
330
+ reason: 'OFFLINE',
331
+ metadata,
332
+ evaluatedAt: new Date().toISOString(),
333
+ };
334
+ }
335
+ cachedResult(key) {
336
+ const flag = this.cache.get(key);
337
+ const metadata = flag?.metadata ?? {
338
+ category: 'feature',
339
+ purpose: '',
340
+ owners: [],
341
+ isPermanent: false,
342
+ tags: [],
343
+ };
344
+ return {
345
+ key,
346
+ value: flag?.value ?? null,
347
+ enabled: flag?.enabled ?? false,
348
+ reason: flag ? 'CACHE' : 'ERROR',
349
+ metadata,
350
+ evaluatedAt: new Date().toISOString(),
351
+ };
352
+ }
353
+ }
354
+ /** Percent-encode a value for use in a URL query parameter. */
355
+ function enc(value) {
356
+ return encodeURIComponent(value);
357
+ }
358
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { FlagConfig } from './types';
2
+ export declare function loadFlagConfig(filePath?: string): FlagConfig;
3
+ //# sourceMappingURL=file-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-loader.d.ts","sourceRoot":"","sources":["../../src/file-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,CAW5D"}
@@ -0,0 +1,17 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as yaml from 'js-yaml';
4
+ const DEFAULT_PATH = '.deploysentry/flags.yaml';
5
+ export function loadFlagConfig(filePath) {
6
+ const resolved = path.resolve(filePath ?? DEFAULT_PATH);
7
+ if (!fs.existsSync(resolved)) {
8
+ throw new Error(`Flag config file not found: ${resolved}`);
9
+ }
10
+ const content = fs.readFileSync(resolved, 'utf-8');
11
+ const parsed = yaml.load(content);
12
+ if (!parsed || typeof parsed !== 'object' || !parsed.version || !parsed.flags) {
13
+ throw new Error(`Invalid flag config file: ${resolved}`);
14
+ }
15
+ return parsed;
16
+ }
17
+ //# sourceMappingURL=file-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-loader.js","sourceRoot":"","sources":["../../src/file-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAGhC,MAAM,YAAY,GAAG,0BAA0B,CAAC;AAEhD,MAAM,UAAU,cAAc,CAAC,QAAiB;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAe,CAAC;IAChD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @deploysentry/sdk – Official Node.js/TypeScript SDK for DeploySentry.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { DeploySentryClient } from '@deploysentry/sdk';
7
+ *
8
+ * const client = new DeploySentryClient({
9
+ * apiKey: 'ds_live_xxx',
10
+ * environment: 'production',
11
+ * project: 'my-app',
12
+ * });
13
+ *
14
+ * await client.initialize();
15
+ *
16
+ * const enabled = await client.boolValue('new-checkout', false, {
17
+ * userId: 'user-42',
18
+ * });
19
+ * ```
20
+ *
21
+ * @packageDocumentation
22
+ */
23
+ export { DeploySentryClient } from './client';
24
+ export { FlagCache } from './cache';
25
+ export { FlagStreamClient } from './streaming';
26
+ export { loadFlagConfig } from './file-loader';
27
+ export { evaluateLocal } from './local-evaluator';
28
+ export type { ClientOptions, EvaluationContext, EvaluationResult, Flag, FlagCategory, FlagMetadata, FlagConfig, FlagConfigFlag, FlagConfigRule, FlagConfigEnvironment, ApiError, } from './types';
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,IAAI,EACJ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,QAAQ,GACT,MAAM,SAAS,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @deploysentry/sdk – Official Node.js/TypeScript SDK for DeploySentry.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { DeploySentryClient } from '@deploysentry/sdk';
7
+ *
8
+ * const client = new DeploySentryClient({
9
+ * apiKey: 'ds_live_xxx',
10
+ * environment: 'production',
11
+ * project: 'my-app',
12
+ * });
13
+ *
14
+ * await client.initialize();
15
+ *
16
+ * const enabled = await client.boolValue('new-checkout', false, {
17
+ * userId: 'user-42',
18
+ * });
19
+ * ```
20
+ *
21
+ * @packageDocumentation
22
+ */
23
+ export { DeploySentryClient } from './client';
24
+ export { FlagCache } from './cache';
25
+ export { FlagStreamClient } from './streaming';
26
+ export { loadFlagConfig } from './file-loader';
27
+ export { evaluateLocal } from './local-evaluator';
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { EvaluationContext, FlagConfig } from './types';
2
+ export declare function evaluateLocal(config: FlagConfig, environment: string, key: string, context?: EvaluationContext): {
3
+ value: string;
4
+ reason: string;
5
+ };
6
+ //# sourceMappingURL=local-evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-evaluator.d.ts","sourceRoot":"","sources":["../../src/local-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAkB,MAAM,SAAS,CAAC;AAE7E,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,iBAAiB,GAC1B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoBnC"}
@@ -0,0 +1,37 @@
1
+ export function evaluateLocal(config, environment, key, context) {
2
+ const flag = config.flags.find((f) => f.key === key);
3
+ if (!flag)
4
+ return { value: '', reason: 'flag_not_found' };
5
+ const envState = flag.environments[environment];
6
+ if (!envState || !envState.enabled) {
7
+ return { value: flag.default_value, reason: 'env_disabled' };
8
+ }
9
+ if (flag.rules && context) {
10
+ const sorted = [...flag.rules].sort((a, b) => a.priority - b.priority);
11
+ for (const rule of sorted) {
12
+ if (!rule.environments[environment])
13
+ continue;
14
+ if (matchRule(rule, context)) {
15
+ return { value: rule.value, reason: 'rule_match' };
16
+ }
17
+ }
18
+ }
19
+ return { value: envState.value || flag.default_value, reason: 'default' };
20
+ }
21
+ function matchRule(rule, context) {
22
+ const val = context.attributes?.[rule.attribute] ?? '';
23
+ const targets = rule.target_values ?? [];
24
+ switch (rule.operator) {
25
+ case 'equals': return targets.length > 0 && val === targets[0];
26
+ case 'not_equals': return targets.length > 0 && val !== targets[0];
27
+ case 'in': return targets.includes(val);
28
+ case 'not_in': return !targets.includes(val);
29
+ case 'contains': return targets.length > 0 && val.includes(targets[0]);
30
+ case 'starts_with': return targets.length > 0 && val.startsWith(targets[0]);
31
+ case 'ends_with': return targets.length > 0 && val.endsWith(targets[0]);
32
+ case 'greater_than': return targets.length > 0 && parseFloat(val) > parseFloat(targets[0]);
33
+ case 'less_than': return targets.length > 0 && parseFloat(val) < parseFloat(targets[0]);
34
+ default: return false;
35
+ }
36
+ }
37
+ //# sourceMappingURL=local-evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-evaluator.js","sourceRoot":"","sources":["../../src/local-evaluator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { Flag } from './types';
2
+ /** Callback invoked whenever a flag update arrives over SSE. */
3
+ export type FlagUpdateHandler = (flags: Flag[]) => void;
4
+ /** Callback invoked when the SSE connection encounters an error. */
5
+ export type StreamErrorHandler = (error: Error) => void;
6
+ interface StreamOptions {
7
+ /** Full URL of the SSE endpoint including query parameters. */
8
+ url: string;
9
+ /** Headers to attach to the request (e.g. Authorization). */
10
+ headers: Record<string, string>;
11
+ /** Called when one or more flag updates are received. */
12
+ onUpdate: FlagUpdateHandler;
13
+ /** Called when the stream encounters an error. */
14
+ onError?: StreamErrorHandler;
15
+ }
16
+ /**
17
+ * Lightweight SSE streaming client that keeps the local flag cache
18
+ * synchronised with the DeploySentry service.
19
+ *
20
+ * Uses the built-in `fetch` readable stream API available in Node 18+
21
+ * to avoid external EventSource dependencies.
22
+ */
23
+ export declare class FlagStreamClient {
24
+ private abortController;
25
+ private reconnectTimer;
26
+ private closed;
27
+ private retryMs;
28
+ private readonly url;
29
+ private readonly headers;
30
+ private readonly onUpdate;
31
+ private readonly onError;
32
+ constructor(options: StreamOptions);
33
+ /** Open the SSE connection and start processing events. */
34
+ connect(): Promise<void>;
35
+ /** Close the connection and stop reconnection attempts. */
36
+ close(): void;
37
+ private consumeStream;
38
+ private processEvent;
39
+ private scheduleReconnect;
40
+ }
41
+ export {};
42
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,gEAAgE;AAChE,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAExD,oEAAoE;AACpE,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAOxD,UAAU,aAAa;IACrB,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,yDAAyD;IACzD,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,kDAAkD;IAClD,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,OAAO,EAAE,aAAa;IAOlC,2DAA2D;IACrD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC9B,2DAA2D;IAC3D,KAAK,IAAI,IAAI;YAkBC,aAAa;IA8B3B,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,iBAAiB;CAgB1B"}