@wardx/core 0.1.3 → 0.1.4

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 (2) hide show
  1. package/package.json +8 -3
  2. package/src/index.d.ts +410 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wardx/core",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Runtime-agnostic Wardx engine for metrics, events, logs, Remote Config, and experiments.",
5
5
  "keywords": [
6
6
  "wardx",
@@ -27,8 +27,13 @@
27
27
  "node": ">=20"
28
28
  },
29
29
  "exports": {
30
- ".": "./src/index.js"
30
+ ".": {
31
+ "types": "./src/index.d.ts",
32
+ "import": "./src/index.js",
33
+ "default": "./src/index.js"
34
+ }
31
35
  },
36
+ "types": "./src/index.d.ts",
32
37
  "files": [
33
38
  "src",
34
39
  "defaults.json"
@@ -36,4 +41,4 @@
36
41
  "publishConfig": {
37
42
  "access": "public"
38
43
  }
39
- }
44
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,410 @@
1
+ export const PROTOCOL_VERSION: 1;
2
+ export const SDK_NAME: 'wardx-node';
3
+ export const PLATFORM: 'node';
4
+
5
+ export const INTERNAL: {
6
+ readonly eventsBuffered: 'wardx.internal.events_buffered';
7
+ readonly logsBuffered: 'wardx.internal.logs_buffered';
8
+ readonly eventsDropped: 'wardx.internal.events_dropped';
9
+ readonly logsDropped: 'wardx.internal.logs_dropped';
10
+ readonly cardinalityDropped: 'wardx.internal.cardinality_dropped';
11
+ readonly framesSent: 'wardx.internal.frames_sent';
12
+ readonly framesFailed: 'wardx.internal.frames_failed';
13
+ readonly bytesUncompressed: 'wardx.internal.bytes_uncompressed';
14
+ readonly bytesCompressed: 'wardx.internal.bytes_compressed';
15
+ readonly lastSyncMs: 'wardx.internal.last_sync_ms';
16
+ readonly configVersion: 'wardx.internal.config_version';
17
+ readonly processRssBytes: 'wardx.internal.process_rss_bytes';
18
+ };
19
+
20
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
21
+ export type DimensionValue = string | number | boolean;
22
+ export interface Dimensions {
23
+ [name: string]: DimensionValue;
24
+ }
25
+ export type Attrs = Record<string, unknown>;
26
+ export type ConfigValue = string | number | boolean;
27
+
28
+ export interface HistogramOptions {
29
+ buckets?: number[];
30
+ [dimension: string]: DimensionValue | number[] | undefined;
31
+ }
32
+
33
+ export interface CounterHandle {
34
+ inc(): void;
35
+ add(n: number): void;
36
+ }
37
+
38
+ export interface GaugeHandle {
39
+ set(value: number): void;
40
+ }
41
+
42
+ export interface HistogramHandle {
43
+ observe(value: number, attrs?: Dimensions | null): void;
44
+ }
45
+
46
+ export type StopTimer = (dims?: Dimensions | null) => void;
47
+
48
+ export interface SdkDefaults {
49
+ aggregateIntervalMs: number;
50
+ syncIntervalMs: number;
51
+ syncJitterMin: number;
52
+ syncJitterMax: number;
53
+ maxBufferedEvents: number;
54
+ maxBufferedLogs: number;
55
+ maxFrameBytes: number;
56
+ maxSeriesPerMetric: number;
57
+ maxDimensionKeys: number;
58
+ maxDimensionValueLength: number;
59
+ httpTimeoutMs: number;
60
+ histogramBuckets: number[];
61
+ }
62
+
63
+ export interface CreateWardxOptions extends Partial<SdkDefaults> {
64
+ endpoint: string;
65
+ projectKey: string;
66
+ project: string;
67
+ role: string;
68
+ appVersion: string;
69
+ environment: string;
70
+ privacySalt?: string;
71
+ tracer?: Tracer | null;
72
+ }
73
+
74
+ export interface CoreSettings extends SdkDefaults {
75
+ privacySalt: string;
76
+ endpoint?: string;
77
+ projectKey?: string;
78
+ project?: string;
79
+ role?: string;
80
+ appVersion?: string;
81
+ environment?: string;
82
+ tracer?: Tracer | null;
83
+ }
84
+
85
+ export interface ResolvedSettings extends SdkDefaults {
86
+ endpoint: string;
87
+ projectKey: string;
88
+ project: string;
89
+ role: string;
90
+ appVersion: string;
91
+ environment: string;
92
+ privacySalt: string;
93
+ tracer?: Tracer | null;
94
+ }
95
+
96
+ export interface SubjectContext {
97
+ subjectId?: string | null;
98
+ }
99
+
100
+ export interface ExperimentGoalContext extends SubjectContext {
101
+ value?: number;
102
+ }
103
+
104
+ export interface ExperimentVariant {
105
+ key: string;
106
+ weight: number;
107
+ values: Record<string, ConfigValue>;
108
+ }
109
+
110
+ export interface Experiment {
111
+ id: string;
112
+ enabled: boolean;
113
+ allocation: number;
114
+ salt: string;
115
+ primaryMetric?: string;
116
+ variants: ExperimentVariant[];
117
+ }
118
+
119
+ export interface ConfigSnapshot {
120
+ values?: Record<string, ConfigValue>;
121
+ experiments?: Experiment[];
122
+ }
123
+
124
+ export interface Assignment {
125
+ experiment: string;
126
+ variant: string;
127
+ }
128
+
129
+ export interface ExposurePayload {
130
+ experiment: string;
131
+ variant: string;
132
+ subject: string;
133
+ }
134
+
135
+ export type EventRow = [timestamp: number, name: string, attrs: Attrs | null];
136
+ export type LogRow = [timestamp: number, level: LogLevel, message: string, attrs: Attrs | null];
137
+ export type CounterRow = [name: string, dims: Dimensions | null, value: number];
138
+ export type GaugeRow = [name: string, dims: Dimensions | null, value: number, timestamp: number];
139
+ export type HistogramRow = [name: string, dims: Dimensions | null, snapshot: HistogramSnapshot];
140
+
141
+ export interface HistogramExemplar {
142
+ value: number;
143
+ attrs: Dimensions;
144
+ }
145
+
146
+ export interface HistogramSnapshot {
147
+ count: number;
148
+ sum: number;
149
+ min: number;
150
+ max: number;
151
+ buckets: Array<[bound: number, count: number]>;
152
+ exemplar?: HistogramExemplar;
153
+ }
154
+
155
+ export interface MetricsSnapshot {
156
+ counters: CounterRow[];
157
+ gauges: GaugeRow[];
158
+ histograms: HistogramRow[];
159
+ }
160
+
161
+ export interface Frame {
162
+ seq: number;
163
+ from: number;
164
+ to: number;
165
+ metrics: MetricsSnapshot;
166
+ events: EventRow[];
167
+ logs: LogRow[];
168
+ }
169
+
170
+ export interface FittedFrame {
171
+ frame: Frame;
172
+ json: string;
173
+ droppedLogs: number;
174
+ droppedEvents: number;
175
+ }
176
+
177
+ export interface InternalSnapshot {
178
+ eventsDropped: number;
179
+ logsDropped: number;
180
+ cardinalityDropped: number;
181
+ framesSent: number;
182
+ framesFailed: number;
183
+ bytesUncompressed: number;
184
+ bytesCompressed: number;
185
+ eventsBuffered: number;
186
+ logsBuffered: number;
187
+ lastSyncMs: number;
188
+ configVersion: number;
189
+ processRssBytes: number;
190
+ }
191
+
192
+ export interface MeasureTraceRecord {
193
+ type: 'counter' | 'gauge' | 'histogram';
194
+ name: string;
195
+ dims: Dimensions | null;
196
+ op: 'inc' | 'add' | 'set' | 'observe';
197
+ value: number;
198
+ attrs?: Dimensions | null;
199
+ noop: boolean;
200
+ }
201
+
202
+ export interface EventTraceRecord {
203
+ name: string;
204
+ attrs: Attrs | null;
205
+ dropped: boolean;
206
+ }
207
+
208
+ export interface LogTraceRecord {
209
+ level: LogLevel;
210
+ message: string;
211
+ attrs: Attrs | null;
212
+ dropped: boolean;
213
+ }
214
+
215
+ export interface FrameTraceRecord {
216
+ seq: number;
217
+ from: number;
218
+ to: number;
219
+ counters: number;
220
+ gauges: number;
221
+ histograms: number;
222
+ events: number;
223
+ logs: number;
224
+ droppedLogs: number;
225
+ droppedEvents: number;
226
+ }
227
+
228
+ export interface SyncTraceRecord {
229
+ phase: 'bootstrap' | 'flush' | 'tick';
230
+ frames: number;
231
+ bytesUncompressed: number;
232
+ bytesCompressed: number;
233
+ ms: number;
234
+ ok: boolean;
235
+ status?: number;
236
+ configVersion?: number;
237
+ appliedConfig?: boolean;
238
+ }
239
+
240
+ export interface Tracer {
241
+ measure?(record: MeasureTraceRecord): void;
242
+ event?(record: EventTraceRecord): void;
243
+ log?(record: LogTraceRecord): void;
244
+ frame?(record: FrameTraceRecord): void;
245
+ sync?(record: SyncTraceRecord): void;
246
+ }
247
+
248
+ export interface LogApi {
249
+ debug(message: string, attrs?: Attrs | null): void;
250
+ info(message: string, attrs?: Attrs | null): void;
251
+ warn(message: string, attrs?: Attrs | null): void;
252
+ error(message: string, attrs?: Attrs | null): void;
253
+ }
254
+
255
+ export interface InternalMetricsState extends InternalSnapshot {
256
+ hasCounterActivity(): boolean;
257
+ snapshotAndReset(): InternalSnapshot;
258
+ }
259
+
260
+ export class Counter implements CounterHandle {
261
+ name: string;
262
+ dims: Dimensions | null;
263
+ value: number;
264
+ constructor(name: string, dims?: Dimensions | null);
265
+ inc(): void;
266
+ add(n: number): void;
267
+ }
268
+
269
+ export class Gauge implements GaugeHandle {
270
+ name: string;
271
+ dims: Dimensions | null;
272
+ value: number;
273
+ timestamp: number;
274
+ dirty: boolean;
275
+ constructor(name: string, dims?: Dimensions | null);
276
+ set(value: number): void;
277
+ }
278
+
279
+ export class Histogram implements HistogramHandle {
280
+ name: string;
281
+ dims: Dimensions | null;
282
+ bounds: number[];
283
+ maxDimensionKeys: number | null;
284
+ maxDimensionValueLength: number | null;
285
+ counts: number[];
286
+ count: number;
287
+ sum: number;
288
+ min: number;
289
+ max: number;
290
+ exemplar: HistogramExemplar | null;
291
+ constructor(
292
+ name: string,
293
+ dims: Dimensions | null,
294
+ bounds: number[],
295
+ limits?: { maxDimensionKeys: number; maxDimensionValueLength: number } | null
296
+ );
297
+ observe(value: number, attrs?: Dimensions | null): void;
298
+ snapshot(): HistogramSnapshot;
299
+ reset(): void;
300
+ }
301
+
302
+ export interface MetricsRegistryOptions {
303
+ maxSeriesPerMetric: number;
304
+ maxDimensionKeys: number;
305
+ maxDimensionValueLength: number;
306
+ defaultHistogramBuckets: number[];
307
+ onCardinalityDropped: () => void;
308
+ }
309
+
310
+ export class MetricsRegistry {
311
+ constructor(options: MetricsRegistryOptions);
312
+ counter(name: string, dims?: Dimensions | null): CounterHandle;
313
+ gauge(name: string, dims?: Dimensions | null): GaugeHandle;
314
+ histogram(name: string, a?: HistogramOptions | null, b?: HistogramOptions | null): HistogramHandle;
315
+ timer(name: string, dims?: Dimensions | null): StopTimer;
316
+ snapshotAndReset(): MetricsSnapshot;
317
+ isDirty(): boolean;
318
+ }
319
+
320
+ export class EventBuffer {
321
+ max: number;
322
+ constructor(maxBufferedEvents: number);
323
+ get length(): number;
324
+ push(name: string, attrs?: Attrs | null): boolean;
325
+ swap(): EventRow[];
326
+ }
327
+
328
+ export class LogBuffer {
329
+ max: number;
330
+ constructor(maxBufferedLogs: number);
331
+ get length(): number;
332
+ push(level: LogLevel, message: string, attrs?: Attrs | null): boolean;
333
+ swap(): LogRow[];
334
+ }
335
+
336
+ export class ConfigStore {
337
+ version: number;
338
+ values: Record<string, ConfigValue>;
339
+ experiments: Experiment[];
340
+ experimentsByKey: Map<string, Experiment[]>;
341
+ applySnapshot(snapshot: { version: number } & ConfigSnapshot): void;
342
+ has(key: string): boolean;
343
+ getRaw(key: string): ConfigValue | undefined;
344
+ }
345
+
346
+ export class ExperimentResolver {
347
+ constructor(options: { privacySalt: string; onExposure: (payload: ExposurePayload) => void });
348
+ hashSubject(subjectId: string): string;
349
+ recordAssignment(subjectId: string, experiment: Experiment, variant: ExperimentVariant): void;
350
+ assignmentsFor(subjectId: string): Assignment[];
351
+ resolve(
352
+ key: string,
353
+ remoteValue: ConfigValue,
354
+ subjectId: string | null | undefined,
355
+ experimentsByKey: Map<string, Experiment[]>
356
+ ): ConfigValue;
357
+ relevantExperiments(subjectId: string, experiments: Experiment[]): Assignment[];
358
+ }
359
+
360
+ export class FrameBuilder {
361
+ static build(input: {
362
+ seq: number;
363
+ from: number;
364
+ to: number;
365
+ metrics: MetricsSnapshot;
366
+ events: EventRow[];
367
+ logs: LogRow[];
368
+ internal: InternalSnapshot;
369
+ }): Frame;
370
+ static mergeInternal(counters: CounterRow[], gauges: GaugeRow[], internal: InternalSnapshot): void;
371
+ static fitToMaxBytes(frame: Frame, maxFrameBytes: number): FittedFrame;
372
+ }
373
+
374
+ export class WardxCore {
375
+ settings: CoreSettings;
376
+ stopped: boolean;
377
+ internal: InternalMetricsState;
378
+ metrics: MetricsRegistry;
379
+ events: EventBuffer;
380
+ logs: LogBuffer;
381
+ configStore: ConfigStore;
382
+ experiments: ExperimentResolver;
383
+ seq: number;
384
+ pendingFrames: Frame[];
385
+ windowStart: number;
386
+ log: LogApi;
387
+ constructor(settings: CoreSettings);
388
+ counter(name: string, dims?: Dimensions | null): CounterHandle;
389
+ gauge(name: string, dims?: Dimensions | null): GaugeHandle;
390
+ histogram(name: string, a?: HistogramOptions | null, b?: HistogramOptions | null): HistogramHandle;
391
+ timer(name: string, dims?: Dimensions | null): StopTimer;
392
+ event(name: string, attrs?: Attrs | null): void;
393
+ identify(subjectId: string | null | undefined): void;
394
+ configGet<T>(key: string, fallback: T, context?: SubjectContext): T;
395
+ experimentGoal(name: string, context?: ExperimentGoalContext): void;
396
+ applyConfig(version: number, config: ConfigSnapshot): void;
397
+ snapshotIfDirty(): FittedFrame | null;
398
+ snapshotFrame(): FittedFrame;
399
+ takePendingFrames(): Frame[];
400
+ }
401
+
402
+ export function fnv1a32(input: string | Uint8Array): number;
403
+ export function assignmentHash(experimentId: string, subjectId: string, salt: string): number;
404
+ export function hashToUnitInterval(hash: number): number;
405
+ export function subjectHash(projectSalt: string, subjectId: string): string;
406
+ export function assignVariant(experiment: Experiment, subjectId: string): ExperimentVariant | null;
407
+ export function resolveSettings(options: CreateWardxOptions): ResolvedSettings;
408
+ export function loadSdkDefaults(): SdkDefaults;
409
+ export function nextSyncDelayMs(settings: Pick<ResolvedSettings, 'syncIntervalMs' | 'syncJitterMin' | 'syncJitterMax'>): number;
410
+ export function ulid(now?: number): string;