@devwithbobby/loops 0.1.13 → 0.1.16

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.
@@ -1,5 +1,5 @@
1
- import type { Mounts } from "../component/_generated/api.js";
2
- import type { RunActionCtx, RunQueryCtx, UseApi } from "./types.js";
1
+ import type { Mounts } from "../component/_generated/api";
2
+ import type { RunActionCtx, RunQueryCtx, UseApi } from "../types";
3
3
  export type LoopsComponent = UseApi<Mounts>;
4
4
  export interface ContactData {
5
5
  email: string;
@@ -13,18 +13,18 @@ export interface ContactData {
13
13
  export interface TransactionalEmailOptions {
14
14
  transactionalId: string;
15
15
  email: string;
16
- dataVariables?: Record<string, any>;
16
+ dataVariables?: Record<string, unknown>;
17
17
  }
18
18
  export interface EventOptions {
19
19
  email: string;
20
20
  eventName: string;
21
- eventProperties?: Record<string, any>;
21
+ eventProperties?: Record<string, unknown>;
22
22
  }
23
23
  export declare class Loops {
24
- private readonly component;
25
24
  readonly options?: {
26
25
  apiKey?: string;
27
26
  };
27
+ private readonly lib;
28
28
  constructor(component: LoopsComponent, options?: {
29
29
  apiKey?: string;
30
30
  });
@@ -32,41 +32,77 @@ export declare class Loops {
32
32
  /**
33
33
  * Add or update a contact in Loops
34
34
  */
35
- addContact(ctx: RunActionCtx, contact: ContactData): Promise<any>;
35
+ addContact(ctx: RunActionCtx, contact: ContactData): Promise<{
36
+ success: boolean;
37
+ id?: string | undefined;
38
+ }>;
36
39
  /**
37
40
  * Update an existing contact in Loops
38
41
  */
39
42
  updateContact(ctx: RunActionCtx, email: string, updates: Partial<ContactData> & {
40
- dataVariables?: Record<string, any>;
41
- }): Promise<any>;
43
+ dataVariables?: Record<string, unknown>;
44
+ }): Promise<{
45
+ success: boolean;
46
+ }>;
42
47
  /**
43
48
  * Send a transactional email using a transactional ID
44
49
  */
45
- sendTransactional(ctx: RunActionCtx, options: TransactionalEmailOptions): Promise<any>;
50
+ sendTransactional(ctx: RunActionCtx, options: TransactionalEmailOptions): Promise<{
51
+ success: boolean;
52
+ messageId?: string | undefined;
53
+ }>;
46
54
  /**
47
55
  * Send an event to Loops to trigger email workflows
48
56
  */
49
- sendEvent(ctx: RunActionCtx, options: EventOptions): Promise<any>;
57
+ sendEvent(ctx: RunActionCtx, options: EventOptions): Promise<{
58
+ success: boolean;
59
+ }>;
50
60
  /**
51
61
  * Find a contact by email
52
62
  * Retrieves contact information from Loops
53
63
  */
54
- findContact(ctx: RunActionCtx, email: string): Promise<any>;
64
+ findContact(ctx: RunActionCtx, email: string): Promise<{
65
+ success: boolean;
66
+ contact?: {
67
+ id?: string | null | undefined;
68
+ email?: string | null | undefined;
69
+ firstName?: string | null | undefined;
70
+ lastName?: string | null | undefined;
71
+ source?: string | null | undefined;
72
+ subscribed?: boolean | null | undefined;
73
+ userGroup?: string | null | undefined;
74
+ userId?: string | null | undefined;
75
+ createdAt?: string | null | undefined;
76
+ } | undefined;
77
+ }>;
55
78
  /**
56
79
  * Batch create contacts
57
80
  * Create multiple contacts in a single API call
58
81
  */
59
- batchCreateContacts(ctx: RunActionCtx, contacts: ContactData[]): Promise<any>;
82
+ batchCreateContacts(ctx: RunActionCtx, contacts: ContactData[]): Promise<{
83
+ success: boolean;
84
+ created?: number | undefined;
85
+ failed?: number | undefined;
86
+ results?: {
87
+ email: string;
88
+ success: boolean;
89
+ error?: string | undefined;
90
+ }[] | undefined;
91
+ }>;
60
92
  /**
61
93
  * Unsubscribe a contact
62
94
  * Unsubscribes a contact from receiving emails (they remain in the system)
63
95
  */
64
- unsubscribeContact(ctx: RunActionCtx, email: string): Promise<any>;
96
+ unsubscribeContact(ctx: RunActionCtx, email: string): Promise<{
97
+ success: boolean;
98
+ }>;
65
99
  /**
66
100
  * Resubscribe a contact
67
101
  * Resubscribes a previously unsubscribed contact
68
102
  */
69
- resubscribeContact(ctx: RunActionCtx, email: string): Promise<any>;
103
+ resubscribeContact(ctx: RunActionCtx, email: string): Promise<{
104
+ success: boolean;
105
+ }>;
70
106
  /**
71
107
  * Count contacts in the database
72
108
  * Can filter by audience criteria (userGroup, source, subscribed status)
@@ -76,7 +112,7 @@ export declare class Loops {
76
112
  userGroup?: string;
77
113
  source?: string;
78
114
  subscribed?: boolean;
79
- }): Promise<any>;
115
+ }): Promise<number>;
80
116
  /**
81
117
  * List contacts with pagination and optional filters
82
118
  * Returns actual contact data, not just a count
@@ -88,34 +124,78 @@ export declare class Loops {
88
124
  subscribed?: boolean;
89
125
  limit?: number;
90
126
  offset?: number;
91
- }): Promise<any>;
127
+ }): Promise<{
128
+ contacts: {
129
+ _id: string;
130
+ email: string;
131
+ subscribed: boolean;
132
+ createdAt: number;
133
+ updatedAt: number;
134
+ firstName?: string | undefined;
135
+ lastName?: string | undefined;
136
+ userId?: string | undefined;
137
+ source?: string | undefined;
138
+ userGroup?: string | undefined;
139
+ loopsContactId?: string | undefined;
140
+ }[];
141
+ total: number;
142
+ limit: number;
143
+ offset: number;
144
+ hasMore: boolean;
145
+ }>;
92
146
  /**
93
147
  * Detect spam patterns: emails sent to the same recipient too frequently
94
148
  */
95
149
  detectRecipientSpam(ctx: RunQueryCtx, options?: {
96
150
  timeWindowMs?: number;
97
151
  maxEmailsPerRecipient?: number;
98
- }): Promise<any>;
152
+ }): Promise<{
153
+ [x: string]: any;
154
+ email: string;
155
+ count: number;
156
+ timeWindowMs: number;
157
+ }[]>;
99
158
  /**
100
159
  * Detect spam patterns: emails sent by the same actor/user too frequently
101
160
  */
102
161
  detectActorSpam(ctx: RunQueryCtx, options?: {
103
162
  timeWindowMs?: number;
104
163
  maxEmailsPerActor?: number;
105
- }): Promise<any>;
164
+ }): Promise<{
165
+ actorId: string;
166
+ count: number;
167
+ timeWindowMs: number;
168
+ }[]>;
106
169
  /**
107
170
  * Get email operation statistics for monitoring
108
171
  */
109
172
  getEmailStats(ctx: RunQueryCtx, options?: {
110
173
  timeWindowMs?: number;
111
- }): Promise<any>;
174
+ }): Promise<{
175
+ [x: string]: any;
176
+ totalOperations: number;
177
+ successfulOperations: number;
178
+ failedOperations: number;
179
+ operationsByType: {
180
+ [x: string]: number;
181
+ };
182
+ uniqueRecipients: number;
183
+ uniqueActors: number;
184
+ }>;
112
185
  /**
113
186
  * Detect rapid-fire email sending patterns
114
187
  */
115
188
  detectRapidFirePatterns(ctx: RunQueryCtx, options?: {
116
189
  timeWindowMs?: number;
117
190
  minEmailsInWindow?: number;
118
- }): Promise<any>;
191
+ }): Promise<{
192
+ count: number;
193
+ timeWindowMs: number;
194
+ firstTimestamp: number;
195
+ lastTimestamp: number;
196
+ email?: string | undefined;
197
+ actorId?: string | undefined;
198
+ }[]>;
119
199
  /**
120
200
  * Check if an email can be sent to a recipient based on rate limits
121
201
  */
@@ -123,7 +203,14 @@ export declare class Loops {
123
203
  email: string;
124
204
  timeWindowMs: number;
125
205
  maxEmails: number;
126
- }): Promise<any>;
206
+ }): Promise<{
207
+ [x: string]: any;
208
+ allowed: boolean;
209
+ count: number;
210
+ limit: number;
211
+ timeWindowMs: number;
212
+ retryAfter?: number | undefined;
213
+ }>;
127
214
  /**
128
215
  * Check if an actor/user can send more emails based on rate limits
129
216
  */
@@ -131,18 +218,31 @@ export declare class Loops {
131
218
  actorId: string;
132
219
  timeWindowMs: number;
133
220
  maxEmails: number;
134
- }): Promise<any>;
221
+ }): Promise<{
222
+ allowed: boolean;
223
+ count: number;
224
+ limit: number;
225
+ timeWindowMs: number;
226
+ retryAfter?: number | undefined;
227
+ }>;
135
228
  /**
136
229
  * Check global email sending rate limit
137
230
  */
138
231
  checkGlobalRateLimit(ctx: RunQueryCtx, options: {
139
232
  timeWindowMs: number;
140
233
  maxEmails: number;
141
- }): Promise<any>;
234
+ }): Promise<{
235
+ allowed: boolean;
236
+ count: number;
237
+ limit: number;
238
+ timeWindowMs: number;
239
+ }>;
142
240
  /**
143
241
  * Delete a contact from Loops
144
242
  */
145
- deleteContact(ctx: RunActionCtx, email: string): Promise<any>;
243
+ deleteContact(ctx: RunActionCtx, email: string): Promise<{
244
+ success: boolean;
245
+ }>;
146
246
  /**
147
247
  * Trigger a loop for a contact
148
248
  * Loops are automated email sequences that can be triggered by events
@@ -156,9 +256,12 @@ export declare class Loops {
156
256
  triggerLoop(ctx: RunActionCtx, options: {
157
257
  loopId: string;
158
258
  email: string;
159
- dataVariables?: Record<string, any>;
259
+ dataVariables?: Record<string, unknown>;
160
260
  eventName?: string;
161
- }): Promise<any>;
261
+ }): Promise<{
262
+ success: boolean;
263
+ warning?: string | undefined;
264
+ }>;
162
265
  /**
163
266
  * For easy re-exporting.
164
267
  * Apps can do
@@ -175,7 +278,10 @@ export declare class Loops {
175
278
  subscribed?: boolean | undefined;
176
279
  userGroup?: string | undefined;
177
280
  email: string;
178
- }, Promise<any>>;
281
+ }, Promise<{
282
+ success: boolean;
283
+ id?: string | undefined;
284
+ }>>;
179
285
  updateContact: import("convex/server").RegisteredAction<"public", {
180
286
  firstName?: string | undefined;
181
287
  lastName?: string | undefined;
@@ -185,28 +291,53 @@ export declare class Loops {
185
291
  userGroup?: string | undefined;
186
292
  dataVariables?: any;
187
293
  email: string;
188
- }, Promise<any>>;
294
+ }, Promise<{
295
+ success: boolean;
296
+ }>>;
189
297
  sendTransactional: import("convex/server").RegisteredAction<"public", {
190
298
  dataVariables?: any;
191
299
  email: string;
192
300
  transactionalId: string;
193
- }, Promise<any>>;
301
+ }, Promise<{
302
+ success: boolean;
303
+ messageId?: string | undefined;
304
+ }>>;
194
305
  sendEvent: import("convex/server").RegisteredAction<"public", {
195
306
  eventProperties?: any;
196
307
  email: string;
197
308
  eventName: string;
198
- }, Promise<any>>;
309
+ }, Promise<{
310
+ success: boolean;
311
+ }>>;
199
312
  deleteContact: import("convex/server").RegisteredAction<"public", {
200
313
  email: string;
201
- }, Promise<any>>;
314
+ }, Promise<{
315
+ success: boolean;
316
+ }>>;
202
317
  triggerLoop: import("convex/server").RegisteredAction<"public", {
203
318
  dataVariables?: any;
204
319
  email: string;
205
320
  loopId: string;
206
- }, Promise<any>>;
321
+ }, Promise<{
322
+ success: boolean;
323
+ warning?: string | undefined;
324
+ }>>;
207
325
  findContact: import("convex/server").RegisteredAction<"public", {
208
326
  email: string;
209
- }, Promise<any>>;
327
+ }, Promise<{
328
+ success: boolean;
329
+ contact?: {
330
+ id?: string | null | undefined;
331
+ email?: string | null | undefined;
332
+ firstName?: string | null | undefined;
333
+ lastName?: string | null | undefined;
334
+ source?: string | null | undefined;
335
+ subscribed?: boolean | null | undefined;
336
+ userGroup?: string | null | undefined;
337
+ userId?: string | null | undefined;
338
+ createdAt?: string | null | undefined;
339
+ } | undefined;
340
+ }>>;
210
341
  batchCreateContacts: import("convex/server").RegisteredAction<"public", {
211
342
  contacts: {
212
343
  firstName?: string | undefined;
@@ -217,47 +348,104 @@ export declare class Loops {
217
348
  userGroup?: string | undefined;
218
349
  email: string;
219
350
  }[];
220
- }, Promise<any>>;
351
+ }, Promise<{
352
+ success: boolean;
353
+ created?: number | undefined;
354
+ failed?: number | undefined;
355
+ results?: {
356
+ email: string;
357
+ success: boolean;
358
+ error?: string | undefined;
359
+ }[] | undefined;
360
+ }>>;
221
361
  unsubscribeContact: import("convex/server").RegisteredAction<"public", {
222
362
  email: string;
223
- }, Promise<any>>;
363
+ }, Promise<{
364
+ success: boolean;
365
+ }>>;
224
366
  resubscribeContact: import("convex/server").RegisteredAction<"public", {
225
367
  email: string;
226
- }, Promise<any>>;
368
+ }, Promise<{
369
+ success: boolean;
370
+ }>>;
227
371
  countContacts: import("convex/server").RegisteredQuery<"public", {
228
372
  source?: string | undefined;
229
373
  subscribed?: boolean | undefined;
230
374
  userGroup?: string | undefined;
231
- }, Promise<any>>;
375
+ }, Promise<number>>;
232
376
  detectRecipientSpam: import("convex/server").RegisteredQuery<"public", {
233
377
  timeWindowMs?: number | undefined;
234
378
  maxEmailsPerRecipient?: number | undefined;
235
- }, Promise<any>>;
379
+ }, Promise<{
380
+ [x: string]: any;
381
+ email: string;
382
+ count: number;
383
+ timeWindowMs: number;
384
+ }[]>>;
236
385
  detectActorSpam: import("convex/server").RegisteredQuery<"public", {
237
386
  timeWindowMs?: number | undefined;
238
387
  maxEmailsPerActor?: number | undefined;
239
- }, Promise<any>>;
388
+ }, Promise<{
389
+ actorId: string;
390
+ count: number;
391
+ timeWindowMs: number;
392
+ }[]>>;
240
393
  getEmailStats: import("convex/server").RegisteredQuery<"public", {
241
394
  timeWindowMs?: number | undefined;
242
- }, Promise<any>>;
395
+ }, Promise<{
396
+ [x: string]: any;
397
+ totalOperations: number;
398
+ successfulOperations: number;
399
+ failedOperations: number;
400
+ operationsByType: {
401
+ [x: string]: number;
402
+ };
403
+ uniqueRecipients: number;
404
+ uniqueActors: number;
405
+ }>>;
243
406
  detectRapidFirePatterns: import("convex/server").RegisteredQuery<"public", {
244
407
  timeWindowMs?: number | undefined;
245
408
  minEmailsInWindow?: number | undefined;
246
- }, Promise<any>>;
409
+ }, Promise<{
410
+ count: number;
411
+ timeWindowMs: number;
412
+ firstTimestamp: number;
413
+ lastTimestamp: number;
414
+ email?: string | undefined;
415
+ actorId?: string | undefined;
416
+ }[]>>;
247
417
  checkRecipientRateLimit: import("convex/server").RegisteredQuery<"public", {
248
418
  email: string;
249
419
  timeWindowMs: number;
250
420
  maxEmails: number;
251
- }, Promise<any>>;
421
+ }, Promise<{
422
+ [x: string]: any;
423
+ allowed: boolean;
424
+ count: number;
425
+ limit: number;
426
+ timeWindowMs: number;
427
+ retryAfter?: number | undefined;
428
+ }>>;
252
429
  checkActorRateLimit: import("convex/server").RegisteredQuery<"public", {
253
430
  actorId: string;
254
431
  timeWindowMs: number;
255
432
  maxEmails: number;
256
- }, Promise<any>>;
433
+ }, Promise<{
434
+ allowed: boolean;
435
+ count: number;
436
+ limit: number;
437
+ timeWindowMs: number;
438
+ retryAfter?: number | undefined;
439
+ }>>;
257
440
  checkGlobalRateLimit: import("convex/server").RegisteredQuery<"public", {
258
441
  timeWindowMs: number;
259
442
  maxEmails: number;
260
- }, Promise<any>>;
443
+ }, Promise<{
444
+ allowed: boolean;
445
+ count: number;
446
+ limit: number;
447
+ timeWindowMs: number;
448
+ }>>;
261
449
  };
262
450
  }
263
451
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { actionGeneric, queryGeneric } from "convex/server";
2
2
  import { v } from "convex/values";
3
3
  export class Loops {
4
- component;
5
4
  options;
5
+ lib;
6
6
  constructor(component, options) {
7
7
  if (!component) {
8
8
  throw new Error("Loops component reference is required. " +
@@ -15,7 +15,7 @@ export class Loops {
15
15
  "Ensure the component is correctly mounted in convex.config.ts: " +
16
16
  "app.use(loops);");
17
17
  }
18
- this.component = component;
18
+ this.lib = component.lib;
19
19
  this.options = options;
20
20
  const apiKey = options?.apiKey ?? process.env.LOOPS_API_KEY;
21
21
  if (!apiKey) {
@@ -33,18 +33,7 @@ export class Loops {
33
33
  * Add or update a contact in Loops
34
34
  */
35
35
  async addContact(ctx, contact) {
36
- if (!this.component) {
37
- throw new Error("Loops component is not initialized. " +
38
- "Make sure to pass components.loops to the Loops constructor: " +
39
- "new Loops(components.loops)");
40
- }
41
- if (!this.component.lib) {
42
- throw new Error("Invalid component reference. " +
43
- "The component may not be properly mounted. " +
44
- "Ensure the component is correctly mounted in convex.config.ts: " +
45
- "app.use(loops);");
46
- }
47
- return ctx.runAction(this.component.lib.addContact, {
36
+ return ctx.runAction(this.lib.addContact, {
48
37
  apiKey: this.apiKey,
49
38
  contact,
50
39
  });
@@ -53,7 +42,7 @@ export class Loops {
53
42
  * Update an existing contact in Loops
54
43
  */
55
44
  async updateContact(ctx, email, updates) {
56
- return ctx.runAction(this.component.lib.updateContact, {
45
+ return ctx.runAction(this.lib.updateContact, {
57
46
  apiKey: this.apiKey,
58
47
  email,
59
48
  ...updates,
@@ -63,7 +52,7 @@ export class Loops {
63
52
  * Send a transactional email using a transactional ID
64
53
  */
65
54
  async sendTransactional(ctx, options) {
66
- return ctx.runAction(this.component.lib.sendTransactional, {
55
+ return ctx.runAction(this.lib.sendTransactional, {
67
56
  apiKey: this.apiKey,
68
57
  ...options,
69
58
  });
@@ -72,7 +61,7 @@ export class Loops {
72
61
  * Send an event to Loops to trigger email workflows
73
62
  */
74
63
  async sendEvent(ctx, options) {
75
- return ctx.runAction(this.component.lib.sendEvent, {
64
+ return ctx.runAction(this.lib.sendEvent, {
76
65
  apiKey: this.apiKey,
77
66
  ...options,
78
67
  });
@@ -82,7 +71,7 @@ export class Loops {
82
71
  * Retrieves contact information from Loops
83
72
  */
84
73
  async findContact(ctx, email) {
85
- return ctx.runAction(this.component.lib.findContact, {
74
+ return ctx.runAction(this.lib.findContact, {
86
75
  apiKey: this.apiKey,
87
76
  email,
88
77
  });
@@ -92,7 +81,7 @@ export class Loops {
92
81
  * Create multiple contacts in a single API call
93
82
  */
94
83
  async batchCreateContacts(ctx, contacts) {
95
- return ctx.runAction(this.component.lib.batchCreateContacts, {
84
+ return ctx.runAction(this.lib.batchCreateContacts, {
96
85
  apiKey: this.apiKey,
97
86
  contacts,
98
87
  });
@@ -102,7 +91,7 @@ export class Loops {
102
91
  * Unsubscribes a contact from receiving emails (they remain in the system)
103
92
  */
104
93
  async unsubscribeContact(ctx, email) {
105
- return ctx.runAction(this.component.lib.unsubscribeContact, {
94
+ return ctx.runAction(this.lib.unsubscribeContact, {
106
95
  apiKey: this.apiKey,
107
96
  email,
108
97
  });
@@ -112,7 +101,7 @@ export class Loops {
112
101
  * Resubscribes a previously unsubscribed contact
113
102
  */
114
103
  async resubscribeContact(ctx, email) {
115
- return ctx.runAction(this.component.lib.resubscribeContact, {
104
+ return ctx.runAction(this.lib.resubscribeContact, {
116
105
  apiKey: this.apiKey,
117
106
  email,
118
107
  });
@@ -123,7 +112,7 @@ export class Loops {
123
112
  * This queries the component's local database, not Loops API
124
113
  */
125
114
  async countContacts(ctx, options) {
126
- return ctx.runQuery(this.component.lib.countContacts, options ?? {});
115
+ return ctx.runQuery(this.lib.countContacts, options ?? {});
127
116
  }
128
117
  /**
129
118
  * List contacts with pagination and optional filters
@@ -131,7 +120,7 @@ export class Loops {
131
120
  * This queries the component's local database, not Loops API
132
121
  */
133
122
  async listContacts(ctx, options) {
134
- return ctx.runQuery(this.component.lib.listContacts, {
123
+ return ctx.runQuery(this.lib.listContacts, {
135
124
  userGroup: options?.userGroup,
136
125
  source: options?.source,
137
126
  subscribed: options?.subscribed,
@@ -143,7 +132,7 @@ export class Loops {
143
132
  * Detect spam patterns: emails sent to the same recipient too frequently
144
133
  */
145
134
  async detectRecipientSpam(ctx, options) {
146
- return ctx.runQuery(this.component.lib.detectRecipientSpam, {
135
+ return ctx.runQuery(this.lib.detectRecipientSpam, {
147
136
  timeWindowMs: options?.timeWindowMs ?? 3600000,
148
137
  maxEmailsPerRecipient: options?.maxEmailsPerRecipient ?? 10,
149
138
  });
@@ -152,7 +141,7 @@ export class Loops {
152
141
  * Detect spam patterns: emails sent by the same actor/user too frequently
153
142
  */
154
143
  async detectActorSpam(ctx, options) {
155
- return ctx.runQuery(this.component.lib.detectActorSpam, {
144
+ return ctx.runQuery(this.lib.detectActorSpam, {
156
145
  timeWindowMs: options?.timeWindowMs ?? 3600000,
157
146
  maxEmailsPerActor: options?.maxEmailsPerActor ?? 100,
158
147
  });
@@ -161,7 +150,7 @@ export class Loops {
161
150
  * Get email operation statistics for monitoring
162
151
  */
163
152
  async getEmailStats(ctx, options) {
164
- return ctx.runQuery(this.component.lib.getEmailStats, {
153
+ return ctx.runQuery(this.lib.getEmailStats, {
165
154
  timeWindowMs: options?.timeWindowMs ?? 86400000,
166
155
  });
167
156
  }
@@ -169,7 +158,7 @@ export class Loops {
169
158
  * Detect rapid-fire email sending patterns
170
159
  */
171
160
  async detectRapidFirePatterns(ctx, options) {
172
- return ctx.runQuery(this.component.lib.detectRapidFirePatterns, {
161
+ return ctx.runQuery(this.lib.detectRapidFirePatterns, {
173
162
  timeWindowMs: options?.timeWindowMs ?? 60000,
174
163
  minEmailsInWindow: options?.minEmailsInWindow ?? 5,
175
164
  });
@@ -178,25 +167,25 @@ export class Loops {
178
167
  * Check if an email can be sent to a recipient based on rate limits
179
168
  */
180
169
  async checkRecipientRateLimit(ctx, options) {
181
- return ctx.runQuery(this.component.lib.checkRecipientRateLimit, options);
170
+ return ctx.runQuery(this.lib.checkRecipientRateLimit, options);
182
171
  }
183
172
  /**
184
173
  * Check if an actor/user can send more emails based on rate limits
185
174
  */
186
175
  async checkActorRateLimit(ctx, options) {
187
- return ctx.runQuery(this.component.lib.checkActorRateLimit, options);
176
+ return ctx.runQuery(this.lib.checkActorRateLimit, options);
188
177
  }
189
178
  /**
190
179
  * Check global email sending rate limit
191
180
  */
192
181
  async checkGlobalRateLimit(ctx, options) {
193
- return ctx.runQuery(this.component.lib.checkGlobalRateLimit, options);
182
+ return ctx.runQuery(this.lib.checkGlobalRateLimit, options);
194
183
  }
195
184
  /**
196
185
  * Delete a contact from Loops
197
186
  */
198
187
  async deleteContact(ctx, email) {
199
- return ctx.runAction(this.component.lib.deleteContact, {
188
+ return ctx.runAction(this.lib.deleteContact, {
200
189
  apiKey: this.apiKey,
201
190
  email,
202
191
  });
@@ -212,7 +201,7 @@ export class Loops {
212
201
  * @param options.eventName - Optional event name. If not provided, uses `loop_{loopId}`
213
202
  */
214
203
  async triggerLoop(ctx, options) {
215
- return ctx.runAction(this.component.lib.triggerLoop, {
204
+ return ctx.runAction(this.lib.triggerLoop, {
216
205
  apiKey: this.apiKey,
217
206
  ...options,
218
207
  });
@@ -1 +1 @@
1
- {"version":3,"file":"convex.config.d.ts","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,SAAS,kDAA2B,CAAC;AAuB3C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"convex.config.d.ts","sourceRoot":"","sources":["../../src/component/convex.config.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,SAAS,kDAA2B,CAAC;AA4B3C,eAAe,SAAS,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { defineComponent } from "convex/server";
2
- import { api } from "./_generated/api.js";
2
+ import { api } from "./_generated/api";
3
3
  const component = defineComponent("loops");
4
4
  component.export(api, {
5
5
  addContact: api.lib.addContact,