@jr200-labs/xstate-nats 0.9.13 → 0.9.14

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 (40) hide show
  1. package/dist/actions/kv.d.ts +1 -0
  2. package/dist/actions/kv.d.ts.map +1 -1
  3. package/dist/actions/kv.js +9 -2
  4. package/dist/actions/kv.js.map +1 -1
  5. package/dist/actions/subject.d.ts +2 -0
  6. package/dist/actions/subject.d.ts.map +1 -1
  7. package/dist/actions/subject.js +8 -12
  8. package/dist/actions/subject.js.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/machines/kv.d.ts +17 -3
  14. package/dist/machines/kv.d.ts.map +1 -1
  15. package/dist/machines/kv.js +46 -10
  16. package/dist/machines/kv.js.map +1 -1
  17. package/dist/machines/root.d.ts +51 -5
  18. package/dist/machines/root.d.ts.map +1 -1
  19. package/dist/machines/root.js +9 -0
  20. package/dist/machines/root.js.map +1 -1
  21. package/dist/machines/subject.d.ts +17 -3
  22. package/dist/machines/subject.d.ts.map +1 -1
  23. package/dist/machines/subject.js +56 -10
  24. package/dist/machines/subject.js.map +1 -1
  25. package/dist/traffic.d.ts +33 -0
  26. package/dist/traffic.d.ts.map +1 -0
  27. package/dist/traffic.js +99 -0
  28. package/dist/traffic.js.map +1 -0
  29. package/package.json +1 -1
  30. package/src/actions/kv.test.ts +59 -0
  31. package/src/actions/kv.ts +10 -2
  32. package/src/actions/subject.test.ts +41 -0
  33. package/src/actions/subject.ts +10 -14
  34. package/src/index.ts +14 -0
  35. package/src/machines/kv.ts +63 -11
  36. package/src/machines/root.ts +11 -0
  37. package/src/machines/subject.test.ts +86 -1
  38. package/src/machines/subject.ts +74 -11
  39. package/src/traffic.test.ts +62 -0
  40. package/src/traffic.ts +150 -0
@@ -1,9 +1,10 @@
1
1
  import { Subscription, PublishOptions, NatsConnection, RequestOptions } from '@nats-io/nats-core';
2
2
  import { RequestResult, SubjectSubscriptionConfig } from '../actions/subject';
3
+ import { NatsTrafficMetrics, NatsTrafficRecordEvent, NatsTrafficResetEvent } from '../traffic';
3
4
  type InternalEvents = {
4
5
  type: 'ERROR';
5
6
  error: Error;
6
- };
7
+ } | NatsTrafficRecordEvent;
7
8
  export type ExternalEvents = {
8
9
  type: 'SUBJECT.CONNECT';
9
10
  connection: NatsConnection;
@@ -37,7 +38,7 @@ export type ExternalEvents = {
37
38
  subject: string;
38
39
  } | {
39
40
  type: 'SUBJECT.UNSUBSCRIBE_ALL';
40
- };
41
+ } | NatsTrafficResetEvent;
41
42
  export type Events = InternalEvents | ExternalEvents;
42
43
  export interface Context {
43
44
  uid: string;
@@ -45,9 +46,22 @@ export interface Context {
45
46
  subscriptions: Map<string, Subscription>;
46
47
  subscriptionConfigs: Map<string, SubjectSubscriptionConfig>;
47
48
  syncRequired: number;
49
+ trafficMetrics: NatsTrafficMetrics;
48
50
  error?: Error;
49
51
  }
50
- export declare const subjectManagerLogic: import("xstate").StateMachine<Context, InternalEvents | {
52
+ export declare const subjectManagerLogic: import("xstate").StateMachine<Context, NatsTrafficRecordEvent | {
53
+ type: "METRICS.RESET_UPLOAD";
54
+ source?: import("..").NatsTrafficMetricSource;
55
+ } | {
56
+ type: "METRICS.RESET_DOWNLOAD";
57
+ source?: import("..").NatsTrafficMetricSource;
58
+ } | {
59
+ type: "METRICS.RESET_ALL";
60
+ source?: import("..").NatsTrafficMetricSource;
61
+ } | {
62
+ type: "ERROR";
63
+ error: Error;
64
+ } | {
51
65
  type: "SUBJECT.CONNECT";
52
66
  connection: NatsConnection;
53
67
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../../src/machines/subject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEjG,OAAO,EACL,aAAa,EACb,yBAAyB,EAI1B,MAAM,oBAAoB,CAAA;AAG3B,KAAK,cAAc,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAA;AAGrD,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,UAAU,EAAE,cAAc,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,sBAAsB,CAAA;CAAE,GAChC;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,GAAG,CAAA;IACZ,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,CAAA;CAC/E,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,GAAG,CAAA;IACZ,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;IAC7B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAA;CAClD,GACD;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,yBAAyB,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,yBAAyB,CAAA;CAAE,CAAA;AAEvC,MAAM,MAAM,MAAM,GAAG,cAAc,GAAG,cAAc,CAAA;AAEpD,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,gBAAgB,EAAE,cAAc,GAAG,IAAI,CAAA;IACvC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACxC,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAA;IAC3D,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,eAAO,MAAM,mBAAmB;UAjCpB,iBAAiB;gBAAc,cAAc;;UAC7C,mBAAmB;;UACnB,sBAAsB;;UAEtB,iBAAiB;aACd,MAAM;aACN,GAAG;WACL,cAAc;sBACH,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI;;UAGxE,iBAAiB;aACd,MAAM;aACN,GAAG;WACL,cAAc;cACX,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI;sBACX,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI;;UAE3C,mBAAmB;YAAU,yBAAyB;;UACtD,qBAAqB;aAAW,MAAM;;UACtC,yBAAyB;;;;;;;;;;;;;EAgNnC,CAAA"}
1
+ {"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../../src/machines/subject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEjG,OAAO,EACL,aAAa,EACb,yBAAyB,EAI1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAGL,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EAKtB,MAAM,YAAY,CAAA;AAGnB,KAAK,cAAc,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,sBAAsB,CAAA;AAG9E,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,UAAU,EAAE,cAAc,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,sBAAsB,CAAA;CAAE,GAChC;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,GAAG,CAAA;IACZ,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,CAAA;CAC/E,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,GAAG,CAAA;IACZ,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;IAC7B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAA;CAClD,GACD;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,yBAAyB,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,yBAAyB,CAAA;CAAE,GACnC,qBAAqB,CAAA;AAEzB,MAAM,MAAM,MAAM,GAAG,cAAc,GAAG,cAAc,CAAA;AAEpD,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,gBAAgB,EAAE,cAAc,GAAG,IAAI,CAAA;IACvC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACxC,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAA;IAC3D,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,kBAAkB,CAAA;IAClC,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;UAvCF,OAAO;WAAS,KAAK;;UAIvC,iBAAiB;gBAAc,cAAc;;UAC7C,mBAAmB;;UACnB,sBAAsB;;UAEtB,iBAAiB;aACd,MAAM;aACN,GAAG;WACL,cAAc;sBACH,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI;;UAGxE,iBAAiB;aACd,MAAM;aACN,GAAG;WACL,cAAc;cACX,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI;sBACX,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI;;UAE3C,mBAAmB;YAAU,yBAAyB;;UACtD,qBAAqB;aAAW,MAAM;;UACtC,yBAAyB;;;;;;;;;;;;;EAoQnC,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { assign, sendParent, setup } from 'xstate';
2
2
  import { subjectConsolidateState, subjectRequest, subjectPublish, } from '../actions/subject';
3
+ import { byteLength, createEmptyTrafficMetrics, recordTrafficMetric, resetTrafficAll, resetTrafficDownload, resetTrafficUpload, } from '../traffic';
3
4
  export const subjectManagerLogic = setup({
4
5
  types: {
5
6
  context: {},
@@ -19,19 +20,49 @@ export const subjectManagerLogic = setup({
19
20
  subscriptionConfigs: new Map(),
20
21
  cachedConnection: null,
21
22
  syncRequired: 0,
23
+ trafficMetrics: createEmptyTrafficMetrics(),
22
24
  error: undefined,
23
25
  },
24
26
  on: {
27
+ 'METRICS.RECORD': {
28
+ actions: assign({
29
+ trafficMetrics: ({ context, event }) => recordTrafficMetric(context.trafficMetrics, event),
30
+ }),
31
+ },
32
+ 'METRICS.RESET_UPLOAD': {
33
+ actions: assign({
34
+ trafficMetrics: ({ context, event }) => resetTrafficUpload(context.trafficMetrics, event.source),
35
+ }),
36
+ },
37
+ 'METRICS.RESET_DOWNLOAD': {
38
+ actions: assign({
39
+ trafficMetrics: ({ context, event }) => resetTrafficDownload(context.trafficMetrics, event.source),
40
+ }),
41
+ },
42
+ 'METRICS.RESET_ALL': {
43
+ actions: assign({
44
+ trafficMetrics: ({ context, event }) => resetTrafficAll(context.trafficMetrics, event.source),
45
+ }),
46
+ },
25
47
  'SUBJECT.SUBSCRIBE': {
26
48
  actions: [
27
- assign({
28
- subscriptionConfigs: ({ context, event }) => {
29
- const { config } = event;
30
- const newConfigs = new Map(context.subscriptionConfigs);
31
- newConfigs.set(config.subject, config);
32
- return newConfigs;
33
- },
34
- syncRequired: ({ context }) => context.syncRequired + 1,
49
+ assign(({ context, event, self }) => {
50
+ if (event.type !== 'SUBJECT.SUBSCRIBE')
51
+ return {};
52
+ const config = {
53
+ ...event.config,
54
+ onDownloadBytes: (bytes) => self.send({
55
+ type: 'METRICS.RECORD',
56
+ source: 'nats.subscribe',
57
+ downloadBytes: bytes,
58
+ }),
59
+ };
60
+ const newConfigs = new Map(context.subscriptionConfigs);
61
+ newConfigs.set(config.subject, config);
62
+ return {
63
+ subscriptionConfigs: newConfigs,
64
+ syncRequired: context.syncRequired + 1,
65
+ };
35
66
  }),
36
67
  ],
37
68
  },
@@ -103,7 +134,12 @@ export const subjectManagerLogic = setup({
103
134
  target: 'subject_disconnecting',
104
135
  },
105
136
  'SUBJECT.REQUEST': {
106
- actions: assign(({ event, context }) => {
137
+ actions: assign(({ event, context, self }) => {
138
+ self.send({
139
+ type: 'METRICS.RECORD',
140
+ source: 'nats.request',
141
+ uploadBytes: byteLength(event.payload),
142
+ });
107
143
  subjectRequest({
108
144
  input: {
109
145
  connection: context.cachedConnection,
@@ -112,6 +148,11 @@ export const subjectManagerLogic = setup({
112
148
  opts: event.opts,
113
149
  callback: event.callback,
114
150
  onRequestResult: event.onRequestResult,
151
+ onDownloadBytes: (bytes) => self.send({
152
+ type: 'METRICS.RECORD',
153
+ source: 'nats.request',
154
+ downloadBytes: bytes,
155
+ }),
115
156
  },
116
157
  });
117
158
  return {};
@@ -119,7 +160,12 @@ export const subjectManagerLogic = setup({
119
160
  },
120
161
  'SUBJECT.PUBLISH': {
121
162
  actions: [
122
- ({ context, event }) => {
163
+ ({ context, event, self }) => {
164
+ self.send({
165
+ type: 'METRICS.RECORD',
166
+ source: 'nats.publish',
167
+ uploadBytes: byteLength(event.payload),
168
+ });
123
169
  subjectPublish({
124
170
  input: {
125
171
  connection: context.cachedConnection,
@@ -1 +1 @@
1
- {"version":3,"file":"subject.js","sourceRoot":"","sources":["../../src/machines/subject.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subject.js","sourceRoot":"","sources":["../../src/machines/subject.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export type NatsTrafficMetricSource = 'nats.publish' | 'nats.request' | 'nats.subscribe' | 'nats.kv';
2
+ export type NatsTrafficDirection = 'upload' | 'download';
3
+ export interface NatsTrafficMetricBucket {
4
+ uploadBytes: number;
5
+ downloadBytes: number;
6
+ }
7
+ export interface NatsTrafficMetrics extends NatsTrafficMetricBucket {
8
+ bySource: Partial<Record<NatsTrafficMetricSource, NatsTrafficMetricBucket>>;
9
+ }
10
+ export type NatsTrafficRecordEvent = {
11
+ type: 'METRICS.RECORD';
12
+ source: NatsTrafficMetricSource;
13
+ uploadBytes?: number;
14
+ downloadBytes?: number;
15
+ };
16
+ export type NatsTrafficResetEvent = {
17
+ type: 'METRICS.RESET_UPLOAD';
18
+ source?: NatsTrafficMetricSource;
19
+ } | {
20
+ type: 'METRICS.RESET_DOWNLOAD';
21
+ source?: NatsTrafficMetricSource;
22
+ } | {
23
+ type: 'METRICS.RESET_ALL';
24
+ source?: NatsTrafficMetricSource;
25
+ };
26
+ export type NatsTrafficEvent = NatsTrafficRecordEvent | NatsTrafficResetEvent;
27
+ export declare function createEmptyTrafficMetrics(): NatsTrafficMetrics;
28
+ export declare function byteLength(value: unknown): number;
29
+ export declare function recordTrafficMetric(metrics: NatsTrafficMetrics, event: NatsTrafficRecordEvent): NatsTrafficMetrics;
30
+ export declare function resetTrafficUpload(metrics: NatsTrafficMetrics, source?: NatsTrafficMetricSource): NatsTrafficMetrics;
31
+ export declare function resetTrafficDownload(metrics: NatsTrafficMetrics, source?: NatsTrafficMetricSource): NatsTrafficMetrics;
32
+ export declare function resetTrafficAll(metrics: NatsTrafficMetrics, source?: NatsTrafficMetricSource): NatsTrafficMetrics;
33
+ //# sourceMappingURL=traffic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traffic.d.ts","sourceRoot":"","sources":["../src/traffic.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,cAAc,GAAG,cAAc,GAAG,gBAAgB,GAAG,SAAS,CAAA;AAEpG,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,UAAU,CAAA;AAExD,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IACjE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,uBAAuB,EAAE,uBAAuB,CAAC,CAAC,CAAA;CAC5E;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,gBAAgB,CAAA;IACtB,MAAM,EAAE,uBAAuB,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,MAAM,CAAC,EAAE,uBAAuB,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,wBAAwB,CAAC;IAAC,MAAM,CAAC,EAAE,uBAAuB,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAAA;AAEnE,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,GAAG,qBAAqB,CAAA;AAI7E,wBAAgB,yBAAyB,IAAI,kBAAkB,CAM9D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAYjD;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,kBAAkB,EAC3B,KAAK,EAAE,sBAAsB,GAC5B,kBAAkB,CAkBpB;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,CAAC,EAAE,uBAAuB,GAC/B,kBAAkB,CAEpB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,CAAC,EAAE,uBAAuB,GAC/B,kBAAkB,CAEpB;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,kBAAkB,EAC3B,MAAM,CAAC,EAAE,uBAAuB,GAC/B,kBAAkB,CAYpB"}
@@ -0,0 +1,99 @@
1
+ const textEncoder = new TextEncoder();
2
+ export function createEmptyTrafficMetrics() {
3
+ return {
4
+ uploadBytes: 0,
5
+ downloadBytes: 0,
6
+ bySource: {},
7
+ };
8
+ }
9
+ export function byteLength(value) {
10
+ if (value == null)
11
+ return 0;
12
+ if (value instanceof Uint8Array)
13
+ return value.byteLength;
14
+ if (value instanceof ArrayBuffer)
15
+ return value.byteLength;
16
+ if (ArrayBuffer.isView(value))
17
+ return value.byteLength;
18
+ if (typeof value === 'string')
19
+ return textEncoder.encode(value).byteLength;
20
+ try {
21
+ return textEncoder.encode(JSON.stringify(value)).byteLength;
22
+ }
23
+ catch {
24
+ return 0;
25
+ }
26
+ }
27
+ export function recordTrafficMetric(metrics, event) {
28
+ const uploadBytes = normaliseByteCount(event.uploadBytes);
29
+ const downloadBytes = normaliseByteCount(event.downloadBytes);
30
+ if (uploadBytes === 0 && downloadBytes === 0)
31
+ return metrics;
32
+ const currentSource = metrics.bySource[event.source] ?? { uploadBytes: 0, downloadBytes: 0 };
33
+ return {
34
+ uploadBytes: metrics.uploadBytes + uploadBytes,
35
+ downloadBytes: metrics.downloadBytes + downloadBytes,
36
+ bySource: {
37
+ ...metrics.bySource,
38
+ [event.source]: {
39
+ uploadBytes: currentSource.uploadBytes + uploadBytes,
40
+ downloadBytes: currentSource.downloadBytes + downloadBytes,
41
+ },
42
+ },
43
+ };
44
+ }
45
+ export function resetTrafficUpload(metrics, source) {
46
+ return resetTrafficDirection(metrics, 'upload', source);
47
+ }
48
+ export function resetTrafficDownload(metrics, source) {
49
+ return resetTrafficDirection(metrics, 'download', source);
50
+ }
51
+ export function resetTrafficAll(metrics, source) {
52
+ if (!source)
53
+ return createEmptyTrafficMetrics();
54
+ const sourceMetrics = metrics.bySource[source] ?? { uploadBytes: 0, downloadBytes: 0 };
55
+ const bySource = { ...metrics.bySource };
56
+ delete bySource[source];
57
+ return {
58
+ uploadBytes: metrics.uploadBytes - sourceMetrics.uploadBytes,
59
+ downloadBytes: metrics.downloadBytes - sourceMetrics.downloadBytes,
60
+ bySource,
61
+ };
62
+ }
63
+ function resetTrafficDirection(metrics, direction, source) {
64
+ const key = direction === 'upload' ? 'uploadBytes' : 'downloadBytes';
65
+ if (!source) {
66
+ const bySource = Object.fromEntries(Object.entries(metrics.bySource).map(([sourceName, sourceMetrics]) => [
67
+ sourceName,
68
+ {
69
+ ...sourceMetrics,
70
+ [key]: 0,
71
+ },
72
+ ]));
73
+ return {
74
+ ...metrics,
75
+ [key]: 0,
76
+ bySource,
77
+ };
78
+ }
79
+ const sourceMetrics = metrics.bySource[source];
80
+ if (!sourceMetrics)
81
+ return metrics;
82
+ return {
83
+ ...metrics,
84
+ [key]: metrics[key] - sourceMetrics[key],
85
+ bySource: {
86
+ ...metrics.bySource,
87
+ [source]: {
88
+ ...sourceMetrics,
89
+ [key]: 0,
90
+ },
91
+ },
92
+ };
93
+ }
94
+ function normaliseByteCount(value) {
95
+ if (!Number.isFinite(value) || value === undefined || value <= 0)
96
+ return 0;
97
+ return Math.floor(value);
98
+ }
99
+ //# sourceMappingURL=traffic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traffic.js","sourceRoot":"","sources":["../src/traffic.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jr200-labs/xstate-nats",
3
- "version": "0.9.13",
3
+ "version": "0.9.14",
4
4
  "description": "XState machine for NATS",
5
5
  "license": "MIT",
6
6
  "author": "Jayshan Raghunandan",
@@ -181,6 +181,65 @@ describe('kvConsolidateState', () => {
181
181
  expect(result.subscriptions.has('Pair(bucket, key1)')).toBe(true)
182
182
  })
183
183
 
184
+ it('should report KV watch entry download bytes', async () => {
185
+ const rawValue = '{"value":"hello"}'
186
+ let delivered = false
187
+ let resolveIterator: () => void
188
+ const iteratorDone = new Promise<void>((resolve) => {
189
+ resolveIterator = resolve
190
+ })
191
+ const mockWatcher = {
192
+ [Symbol.asyncIterator]: () => ({
193
+ next: () => {
194
+ if (!delivered) {
195
+ delivered = true
196
+ return Promise.resolve({
197
+ value: {
198
+ operation: 'PUT',
199
+ string: () => rawValue,
200
+ },
201
+ done: false,
202
+ })
203
+ }
204
+ resolveIterator()
205
+ return new Promise(() => {})
206
+ },
207
+ }),
208
+ }
209
+ const mockKv = {
210
+ watch: vi.fn().mockResolvedValue(mockWatcher),
211
+ }
212
+ const mockKvm = {
213
+ open: vi.fn().mockResolvedValue(mockKv),
214
+ }
215
+ const onDownloadBytes = vi.fn()
216
+
217
+ const actor = createActor(kvConsolidateState, {
218
+ input: {
219
+ kvm: mockKvm as any,
220
+ connection: {} as any,
221
+ currentState: new Map(),
222
+ targetState: new Map([
223
+ [
224
+ 'Pair(bucket, key1)',
225
+ {
226
+ bucket: 'bucket',
227
+ key: 'key1',
228
+ callback: vi.fn(),
229
+ onDownloadBytes,
230
+ },
231
+ ],
232
+ ]) as any,
233
+ },
234
+ })
235
+
236
+ actor.start()
237
+ await iteratorDone
238
+ await new Promise((r) => setTimeout(r, 10))
239
+ expect(onDownloadBytes).toHaveBeenCalledWith(new TextEncoder().encode(rawValue).byteLength)
240
+ actor.stop()
241
+ })
242
+
184
243
  it('should keep existing subscriptions that are still in target', async () => {
185
244
  const existingWatcher = { stop: vi.fn() } as any
186
245
  const currentState = new Map([['Pair(bucket, key1)', existingWatcher]])
package/src/actions/kv.ts CHANGED
@@ -3,6 +3,7 @@ import { Kvm, KvWatchEntry, KvWatchOptions } from '@nats-io/kv'
3
3
  import { Pair } from '../utils'
4
4
  import { fromPromise } from 'xstate'
5
5
  import { recordError, withSpan } from '../telemetry'
6
+ import { byteLength } from '../traffic'
6
7
 
7
8
  export class KvSubscriptionKey extends Pair<string, string> {}
8
9
 
@@ -12,6 +13,7 @@ export type KvSubscriptionConfig = {
12
13
  callback: (data: any) => void
13
14
  opts?: KvWatchOptions
14
15
  replayOnReconnect?: boolean
16
+ onDownloadBytes?: (bytes: number) => void
15
17
  }
16
18
 
17
19
  export const kvConsolidateState = fromPromise(
@@ -80,13 +82,19 @@ export const kvConsolidateState = fromPromise(
80
82
  },
81
83
  (span) => {
82
84
  let parsedValue
85
+ let rawValue: string
83
86
  try {
84
- parsedValue = JSON.parse(e.string())
87
+ rawValue = e.string()
88
+ parsedValue = JSON.parse(rawValue)
85
89
  } catch {
86
- parsedValue = e.string()
90
+ rawValue = e.string()
91
+ parsedValue = rawValue
87
92
  }
88
93
 
89
94
  try {
95
+ // KvWatchEntry does not expose the raw wire payload on this path; the
96
+ // UTF-8 byte length of string() is the measurable application payload.
97
+ config.onDownloadBytes?.(byteLength(rawValue))
90
98
  config.callback({
91
99
  bucket: config.bucket,
92
100
  key: config.key,
@@ -199,6 +199,47 @@ describe('subjectConsolidateState', () => {
199
199
  expect(callback).toHaveBeenCalledWith({ id: 2 })
200
200
  })
201
201
 
202
+ it('should report subscription message download bytes', async () => {
203
+ const connection = createMockConnection()
204
+ const payload = new TextEncoder().encode('{"id":1}')
205
+ let resolveIterator: () => void
206
+ const iteratorDone = new Promise<void>((r) => (resolveIterator = r))
207
+ let delivered = false
208
+
209
+ const mockSub = {
210
+ unsubscribe: vi.fn(),
211
+ [Symbol.asyncIterator]: () => ({
212
+ next: () => {
213
+ if (!delivered) {
214
+ delivered = true
215
+ return Promise.resolve({
216
+ value: { data: payload, json: () => ({ id: 1 }), string: () => '{"id":1}' },
217
+ done: false,
218
+ })
219
+ }
220
+ resolveIterator!()
221
+ return new Promise(() => {})
222
+ },
223
+ }),
224
+ } as any
225
+ connection.subscribe.mockReturnValue(mockSub)
226
+
227
+ const onDownloadBytes = vi.fn()
228
+ subjectConsolidateState({
229
+ input: {
230
+ connection,
231
+ currentSubscriptions: new Map(),
232
+ targetSubscriptions: new Map([
233
+ ['test.subject', { subject: 'test.subject', callback: vi.fn(), onDownloadBytes }],
234
+ ]),
235
+ },
236
+ })
237
+
238
+ await iteratorDone
239
+ await new Promise((r) => setTimeout(r, 10))
240
+ expect(onDownloadBytes).toHaveBeenCalledWith(payload.byteLength)
241
+ })
242
+
202
243
  it('should handle callback errors in the message loop', async () => {
203
244
  const connection = createMockConnection()
204
245
  let resolveIterator: () => void
@@ -13,11 +13,13 @@ import {
13
13
  recordError,
14
14
  withSpan,
15
15
  } from '../telemetry'
16
+ import { byteLength } from '../traffic'
16
17
 
17
18
  export type SubjectSubscriptionConfig = {
18
19
  subject: string
19
20
  callback: (data: any) => void
20
21
  opts?: SubscriptionOptions
22
+ onDownloadBytes?: (bytes: number) => void
21
23
  }
22
24
 
23
25
  export type RequestResult = { ok: true } | { ok: false; error: Error }
@@ -70,15 +72,17 @@ export const subjectConsolidateState = ({
70
72
  try {
71
73
  for await (const msg of sub) {
72
74
  const parentCtx = extractContextFromHeaders((msg as Msg).headers)
75
+ const payloadBytes = (msg as Msg).data?.length ?? 0
73
76
  await withSpan(
74
77
  'xstate.nats.message',
75
78
  'xstate.nats.error',
76
79
  {
77
80
  subject,
78
- 'payload.bytes': (msg as Msg).data?.length,
81
+ 'payload.bytes': payloadBytes,
79
82
  },
80
83
  (span) => {
81
84
  try {
85
+ subscriptionConfig.onDownloadBytes?.(payloadBytes)
82
86
  subscriptionConfig?.callback(parseNatsResult(msg))
83
87
  } catch (callbackError) {
84
88
  // Record on span AND preserve the existing console.error
@@ -117,19 +121,15 @@ export const subjectRequest = ({
117
121
  opts?: RequestOptions
118
122
  callback: (data: any) => void
119
123
  onRequestResult?: (result: RequestResult) => void
124
+ onDownloadBytes?: (bytes: number) => void
120
125
  }
121
126
  }) => {
122
- const { connection, subject, payload, opts, callback, onRequestResult } = input
127
+ const { connection, subject, payload, opts, callback, onRequestResult, onDownloadBytes } = input
123
128
  if (!connection) {
124
129
  throw new Error('NATS connection is not available')
125
130
  }
126
131
 
127
- const payloadBytes =
128
- payload instanceof Uint8Array
129
- ? payload.byteLength
130
- : typeof payload === 'string'
131
- ? payload.length
132
- : undefined
132
+ const payloadBytes = byteLength(payload)
133
133
 
134
134
  void withSpan(
135
135
  'xstate.nats.request',
@@ -151,6 +151,7 @@ export const subjectRequest = ({
151
151
  return connection
152
152
  .request(subject, payload, requestOpts)
153
153
  .then((msg: Msg) => {
154
+ onDownloadBytes?.(msg.data?.length ?? 0)
154
155
  callback(parseNatsResult(msg))
155
156
  onRequestResult?.({ ok: true })
156
157
  })
@@ -185,12 +186,7 @@ export const subjectPublish = ({
185
186
  throw new Error('NATS connection is not available')
186
187
  }
187
188
 
188
- const payloadBytes =
189
- payload instanceof Uint8Array
190
- ? payload.byteLength
191
- : typeof payload === 'string'
192
- ? payload.length
193
- : undefined
189
+ const payloadBytes = byteLength(payload)
194
190
 
195
191
  try {
196
192
  withSpan(
package/src/index.ts CHANGED
@@ -12,6 +12,20 @@ export {
12
12
  export { KvSubscriptionKey, type KvSubscriptionConfig } from './actions/kv'
13
13
  export { parseNatsResult } from './actions/connection'
14
14
  export { type AuthConfig } from './actions/types'
15
+ export {
16
+ byteLength as natsTrafficByteLength,
17
+ createEmptyTrafficMetrics,
18
+ recordTrafficMetric,
19
+ resetTrafficAll,
20
+ resetTrafficDownload,
21
+ resetTrafficUpload,
22
+ type NatsTrafficEvent,
23
+ type NatsTrafficMetricBucket,
24
+ type NatsTrafficMetrics,
25
+ type NatsTrafficMetricSource,
26
+ type NatsTrafficRecordEvent,
27
+ type NatsTrafficResetEvent,
28
+ } from './traffic'
15
29
 
16
30
  export {
17
31
  type NatsConnectionConfig,