alchemy 0.51.1 → 0.51.3

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 (42) hide show
  1. package/lib/apply.js +1 -1
  2. package/lib/apply.js.map +1 -1
  3. package/lib/cloudflare/miniflare/miniflare-worker-options.js +2 -2
  4. package/lib/cloudflare/miniflare/miniflare-worker-options.js.map +1 -1
  5. package/lib/cloudflare/miniflare/miniflare-worker-proxy.d.ts +14 -14
  6. package/lib/cloudflare/miniflare/miniflare-worker-proxy.d.ts.map +1 -1
  7. package/lib/cloudflare/miniflare/miniflare-worker-proxy.js +123 -66
  8. package/lib/cloudflare/miniflare/miniflare-worker-proxy.js.map +1 -1
  9. package/lib/cloudflare/miniflare/miniflare.d.ts +12 -7
  10. package/lib/cloudflare/miniflare/miniflare.d.ts.map +1 -1
  11. package/lib/cloudflare/miniflare/miniflare.js +17 -55
  12. package/lib/cloudflare/miniflare/miniflare.js.map +1 -1
  13. package/lib/cloudflare/zone.d.ts.map +1 -1
  14. package/lib/cloudflare/zone.js +2 -2
  15. package/lib/cloudflare/zone.js.map +1 -1
  16. package/lib/scope.d.ts.map +1 -1
  17. package/lib/scope.js +4 -3
  18. package/lib/scope.js.map +1 -1
  19. package/lib/state/cloudflare-state-store.d.ts +3 -1
  20. package/lib/state/cloudflare-state-store.d.ts.map +1 -1
  21. package/lib/state/cloudflare-state-store.js +11 -2
  22. package/lib/state/cloudflare-state-store.js.map +1 -1
  23. package/lib/state/instrumented-state-store.d.ts +19 -0
  24. package/lib/state/instrumented-state-store.d.ts.map +1 -0
  25. package/lib/state/instrumented-state-store.js +59 -0
  26. package/lib/state/instrumented-state-store.js.map +1 -0
  27. package/lib/util/telemetry/client.d.ts.map +1 -1
  28. package/lib/util/telemetry/client.js +14 -12
  29. package/lib/util/telemetry/client.js.map +1 -1
  30. package/lib/util/telemetry/types.d.ts +8 -3
  31. package/lib/util/telemetry/types.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/src/apply.ts +1 -1
  34. package/src/cloudflare/miniflare/miniflare-worker-options.ts +2 -2
  35. package/src/cloudflare/miniflare/miniflare-worker-proxy.ts +148 -77
  36. package/src/cloudflare/miniflare/miniflare.ts +23 -79
  37. package/src/cloudflare/zone.ts +9 -8
  38. package/src/scope.ts +7 -3
  39. package/src/state/cloudflare-state-store.ts +73 -54
  40. package/src/state/instrumented-state-store.ts +97 -0
  41. package/src/util/telemetry/client.ts +14 -12
  42. package/src/util/telemetry/types.ts +18 -2
@@ -0,0 +1,97 @@
1
+ import type { State, StateStore } from "../state.ts";
2
+ import type { ITelemetryClient } from "../util/telemetry/client.ts";
3
+ import type { Telemetry } from "../util/telemetry/types.ts";
4
+
5
+ //todo(michael): we should also handle serde here
6
+ export class InstrumentedStateStore<T extends StateStore>
7
+ implements StateStore
8
+ {
9
+ private readonly stateStore: StateStore;
10
+ private readonly telemetryClient: ITelemetryClient;
11
+ private readonly stateStoreClass: string;
12
+
13
+ constructor(stateStore: StateStore, telemetryClient: ITelemetryClient) {
14
+ this.stateStore = stateStore;
15
+ this.telemetryClient = telemetryClient;
16
+ this.stateStoreClass = stateStore.constructor.name;
17
+ }
18
+
19
+ private async callWithTelemetry<T>(
20
+ event: Telemetry.StateStoreEvent["event"],
21
+ fn: () => Promise<T>,
22
+ ): Promise<T> {
23
+ const start = performance.now();
24
+ let error: unknown;
25
+ return await fn()
26
+ .catch((err) => (error = err))
27
+ .finally(() => {
28
+ this.telemetryClient.record({
29
+ event,
30
+ stateStoreClass: this.stateStoreClass,
31
+ elapsed: performance.now() - start,
32
+ error: error instanceof Error ? error : new Error(String(error)),
33
+ });
34
+ });
35
+ }
36
+
37
+ async init() {
38
+ if (this.stateStore.init == null) {
39
+ return;
40
+ }
41
+ await this.callWithTelemetry(
42
+ "stateStore.init",
43
+ this.stateStore.init.bind(this.stateStore),
44
+ );
45
+ }
46
+ async deinit() {
47
+ if (this.stateStore.deinit == null) {
48
+ return;
49
+ }
50
+ await this.callWithTelemetry(
51
+ "stateStore.deinit",
52
+ this.stateStore.deinit.bind(this.stateStore),
53
+ );
54
+ }
55
+ async list() {
56
+ return await this.callWithTelemetry(
57
+ "stateStore.list",
58
+ this.stateStore.list.bind(this.stateStore),
59
+ );
60
+ }
61
+ async count() {
62
+ return await this.callWithTelemetry(
63
+ "stateStore.count",
64
+ this.stateStore.count.bind(this.stateStore),
65
+ );
66
+ }
67
+ async get(key: string) {
68
+ return await this.callWithTelemetry(
69
+ "stateStore.get",
70
+ this.stateStore.get.bind(this.stateStore, key),
71
+ );
72
+ }
73
+ async getBatch(ids: string[]) {
74
+ return await this.callWithTelemetry(
75
+ "stateStore.getBatch",
76
+ this.stateStore.getBatch.bind(this.stateStore, ids),
77
+ );
78
+ }
79
+ async all() {
80
+ return await this.callWithTelemetry(
81
+ "stateStore.all",
82
+ this.stateStore.all.bind(this.stateStore),
83
+ );
84
+ }
85
+ async set(key: string, value: State) {
86
+ await this.callWithTelemetry(
87
+ "stateStore.set",
88
+ this.stateStore.set.bind(this.stateStore, key, value),
89
+ );
90
+ }
91
+ async delete(key: string) {
92
+ await this.callWithTelemetry(
93
+ "stateStore.delete",
94
+ this.stateStore.delete.bind(this.stateStore, key),
95
+ );
96
+ }
97
+ }
@@ -54,13 +54,9 @@ export class TelemetryClient implements ITelemetryClient {
54
54
  }
55
55
 
56
56
  record(event: Telemetry.EventInput, timestamp = Date.now()) {
57
- if (!this.context) {
58
- return;
59
- }
60
57
  const payload = {
61
58
  ...event,
62
59
  error: this.serializeError(event.error),
63
- context: this.context,
64
60
  timestamp,
65
61
  } as Telemetry.Event;
66
62
  this.events.push(payload);
@@ -93,9 +89,10 @@ export class TelemetryClient implements ITelemetryClient {
93
89
  }
94
90
 
95
91
  private async send(events: Telemetry.Event[]) {
96
- if (events.length === 0) {
92
+ if (events.length === 0 || this.context) {
97
93
  return;
98
94
  }
95
+ const { userId, ...data } = this.context!;
99
96
  const response = await fetch(`${POSTHOG_CLIENT_API_HOST}/batch`, {
100
97
  method: "POST",
101
98
  headers: {
@@ -104,13 +101,18 @@ export class TelemetryClient implements ITelemetryClient {
104
101
  body: JSON.stringify({
105
102
  api_key: POSTHOG_PROJECT_ID,
106
103
  historical_migration: false,
107
- batch: events.map((e) => ({
108
- event: e.event,
109
- properties: {
110
- distinct_id: this.context?.sessionId,
111
- },
112
- timestamp: new Date(e.timestamp).toISOString(),
113
- })),
104
+ batch: events.map((e) => {
105
+ const { event, ...eventData } = e;
106
+ return {
107
+ event: event,
108
+ properties: {
109
+ distinct_id: userId,
110
+ ...data,
111
+ ...eventData,
112
+ },
113
+ timestamp: new Date(e.timestamp).toISOString(),
114
+ };
115
+ }),
114
116
  }),
115
117
  });
116
118
  if (!response.ok) {
@@ -35,7 +35,6 @@ export namespace Telemetry {
35
35
 
36
36
  export interface BaseEvent {
37
37
  event: string;
38
- context: Context;
39
38
  timestamp: number;
40
39
  }
41
40
 
@@ -73,10 +72,27 @@ export namespace Telemetry {
73
72
  replaced?: boolean;
74
73
  }
75
74
 
76
- export type Event = AppEvent | ResourceEvent;
75
+ export interface StateStoreEvent extends BaseEvent {
76
+ event:
77
+ | "stateStore.init"
78
+ | "stateStore.deinit"
79
+ | "stateStore.list"
80
+ | "stateStore.count"
81
+ | "stateStore.get"
82
+ | "stateStore.getBatch"
83
+ | "stateStore.all"
84
+ | "stateStore.set"
85
+ | "stateStore.delete";
86
+ stateStoreClass: string;
87
+ elapsed?: number;
88
+ error?: SerializedError;
89
+ }
90
+
91
+ export type Event = AppEvent | ResourceEvent | StateStoreEvent;
77
92
  export type EventInput = (
78
93
  | Omit<AppEvent, "context" | "timestamp" | "error">
79
94
  | Omit<ResourceEvent, "context" | "timestamp" | "error">
95
+ | Omit<StateStoreEvent, "context" | "timestamp" | "error">
80
96
  ) & {
81
97
  error?: ErrorInput;
82
98
  };