@convex-dev/sharded-counter 0.1.4 → 0.1.5

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.
package/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/@convex-dev%2Fsharded-counter.svg)](https://badge.fury.io/js/@convex-dev%2Fsharded-counter)
4
4
 
5
- **Note: Convex Components are currently in beta.**
6
-
7
5
  <!-- START: Include on https://convex.dev/components -->
8
6
 
9
7
  This component adds counters to Convex. It acts as a key-value store from
@@ -101,12 +99,14 @@ await counter.add(ctx, "checkboxes", 5); // increment by 5
101
99
  await counter.inc(ctx, "checkboxes"); // increment by 1
102
100
  await counter.subtract(ctx, "checkboxes", 5); // decrement by 5
103
101
  await counter.dec(ctx, "checkboxes"); // decrement by 1
102
+ await counter.reset(ctx, "checkboxes"); // reset to 0
104
103
 
105
104
  const numCheckboxes = counter.for("checkboxes");
106
105
  await numCheckboxes.inc(ctx); // increment
107
106
  await numCheckboxes.dec(ctx); // decrement
108
107
  await numCheckboxes.add(ctx, 5); // add 5
109
108
  await numCheckboxes.subtract(ctx, 5); // subtract 5
109
+ await numCheckboxes.reset(ctx); // reset to 0
110
110
  ```
111
111
 
112
112
  And you can read the counter's value in a query, mutation, or action.
@@ -145,7 +145,7 @@ Or by setting a default that applies to all keys not specified in `shards`:
145
145
  ```ts
146
146
  const counter = new ShardedCounter(components.shardedCounter, {
147
147
  shards: { checkboxes: 100 },
148
- defaultShards: 20,
148
+ defaultShards: 8,
149
149
  });
150
150
  ```
151
151
 
@@ -187,7 +187,7 @@ number of shards to form an estimate. You can improve the estimate by reading
187
187
  from more shards, at the cost of more contention:
188
188
 
189
189
  ```ts
190
- const betterEstimatedCheckboxCount = await counter.estimateCount(ctx, "checkboxes", 3);
190
+ const estimateFromThree = await counter.estimateCount(ctx, "checkboxes", 3);
191
191
  ```
192
192
 
193
193
  If the counter was accumulated from many
@@ -261,7 +261,7 @@ async function insertUser(ctx, user) {
261
261
  }
262
262
  ```
263
263
 
264
- 3. Register a [Trigger]((https://www.npmjs.com/package/convex-helpers#triggers)),
264
+ 3. Register a [Trigger](https://www.npmjs.com/package/convex-helpers#triggers),
265
265
  which automatically runs code when a mutation changes the
266
266
  data in a table.
267
267
 
@@ -7,7 +7,6 @@ import { api } from "../component/_generated/api";
7
7
  */
8
8
  export declare class ShardedCounter<ShardsKey extends string> {
9
9
  private component;
10
- private options?;
11
10
  /**
12
11
  * A sharded counter is a map from string -> counter, where each counter can
13
12
  * be incremented or decremented.
@@ -24,9 +23,11 @@ export declare class ShardedCounter<ShardsKey extends string> {
24
23
  * keys not in `options.shards`.
25
24
  */
26
25
  constructor(component: UseApi<typeof api>, options?: {
27
- shards?: Record<ShardsKey, number> | undefined;
28
- defaultShards?: number | undefined;
29
- } | undefined);
26
+ shards?: Partial<Record<ShardsKey, number>>;
27
+ defaultShards?: number;
28
+ });
29
+ private shardsForKey;
30
+ private stickyShard;
30
31
  /**
31
32
  * Increase the counter for key `name` by `count`.
32
33
  * If `count` is negative, the counter will decrease.
@@ -34,26 +35,26 @@ export declare class ShardedCounter<ShardsKey extends string> {
34
35
  * @param name The key to update the counter for.
35
36
  * @param count The amount to increment the counter by. Defaults to 1.
36
37
  */
37
- add<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name, count?: number): Promise<null>;
38
+ add<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name, count?: number): Promise<void>;
38
39
  /**
39
40
  * Decrease the counter for key `name` by `count`.
40
41
  */
41
- subtract<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name, count?: number): Promise<null>;
42
+ subtract<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name, count?: number): Promise<void>;
42
43
  /**
43
44
  * Increment the counter for key `name` by 1.
44
45
  */
45
- inc<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<null>;
46
+ inc<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
46
47
  /**
47
48
  * Decrement the counter for key `name` by 1.
48
49
  */
49
- dec<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<null>;
50
+ dec<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
50
51
  /**
51
52
  * Gets the counter for key `name`.
52
53
  *
53
54
  * NOTE: this reads from all shards. If used in a mutation, it will contend
54
55
  * with all mutations that update the counter for this key.
55
56
  */
56
- count<Name extends string = ShardsKey>(ctx: RunQueryCtx, name: Name): Promise<number>;
57
+ count<Name extends ShardsKey>(ctx: RunQueryCtx, name: Name): Promise<number>;
57
58
  /**
58
59
  * Redistribute counts evenly across the counter's shards.
59
60
  *
@@ -66,7 +67,13 @@ export declare class ShardedCounter<ShardsKey extends string> {
66
67
  * This operation reads and writes all shards, so it can cause contention if
67
68
  * called too often.
68
69
  */
69
- rebalance<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
70
+ rebalance<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
71
+ /**
72
+ * Clear the counter for key `name`.
73
+ *
74
+ * @param name The key to clear the counter for.
75
+ */
76
+ reset<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
70
77
  /**
71
78
  * Estimate the count of a counter by only reading from a subset of shards,
72
79
  * and extrapolating the total count.
@@ -78,7 +85,7 @@ export declare class ShardedCounter<ShardsKey extends string> {
78
85
  *
79
86
  * Use this to reduce contention when reading the counter.
80
87
  */
81
- estimateCount<Name extends string = ShardsKey>(ctx: RunQueryCtx, name: Name, readFromShards?: number): Promise<number>;
88
+ estimateCount<Name extends ShardsKey>(ctx: RunQueryCtx, name: Name, readFromShards?: number): Promise<number>;
82
89
  /**
83
90
  * Returns an object with methods to update and query the counter for key
84
91
  * `name`. For fixed keys, you can call `counter.for("<key>")` to get methods
@@ -94,23 +101,23 @@ export declare class ShardedCounter<ShardsKey extends string> {
94
101
  * });
95
102
  * ```
96
103
  */
97
- for<Name extends string = ShardsKey>(name: Name): {
104
+ for<Name extends ShardsKey>(name: Name): {
98
105
  /**
99
106
  * Add `count` to the counter.
100
107
  */
101
- add: (ctx: RunMutationCtx, count?: number) => Promise<null>;
108
+ add: (ctx: RunMutationCtx, count?: number) => Promise<void>;
102
109
  /**
103
110
  * Subtract `count` from the counter.
104
111
  */
105
- subtract: (ctx: RunMutationCtx, count?: number) => Promise<null>;
112
+ subtract: (ctx: RunMutationCtx, count?: number) => Promise<void>;
106
113
  /**
107
114
  * Increment the counter by 1.
108
115
  */
109
- inc: (ctx: RunMutationCtx) => Promise<null>;
116
+ inc: (ctx: RunMutationCtx) => Promise<void>;
110
117
  /**
111
118
  * Decrement the counter by 1.
112
119
  */
113
- dec: (ctx: RunMutationCtx) => Promise<null>;
120
+ dec: (ctx: RunMutationCtx) => Promise<void>;
114
121
  /**
115
122
  * Get the current value of the counter.
116
123
  *
@@ -118,6 +125,10 @@ export declare class ShardedCounter<ShardsKey extends string> {
118
125
  * contend with all mutations that update the counter for this key.
119
126
  */
120
127
  count: (ctx: RunQueryCtx) => Promise<number>;
128
+ /**
129
+ * Reset the counter for this key.
130
+ */
131
+ reset: (ctx: RunMutationCtx) => Promise<void>;
121
132
  /**
122
133
  * Redistribute counts evenly across the counter's shards.
123
134
  *
@@ -133,8 +144,7 @@ export declare class ShardedCounter<ShardsKey extends string> {
133
144
  */
134
145
  estimateCount: (ctx: RunQueryCtx, readFromShards?: number) => Promise<number>;
135
146
  };
136
- trigger<Ctx extends RunMutationCtx, Name extends string = ShardsKey>(name: Name): Trigger<Ctx, GenericDataModel, TableNamesInDataModel<GenericDataModel>>;
137
- private shardsForKey;
147
+ trigger<Ctx extends RunMutationCtx, Name extends ShardsKey>(name: Name): Trigger<Ctx, GenericDataModel, TableNamesInDataModel<GenericDataModel>>;
138
148
  }
139
149
  export type Trigger<Ctx, DataModel extends GenericDataModel, TableName extends TableNamesInDataModel<DataModel>> = (ctx: Ctx, change: Change<DataModel, TableName>) => Promise<void>;
140
150
  export type Change<DataModel extends GenericDataModel, TableName extends TableNamesInDataModel<DataModel>> = {
@@ -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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"}
@@ -4,7 +4,6 @@
4
4
  */
5
5
  export class ShardedCounter {
6
6
  component;
7
- options;
8
7
  /**
9
8
  * A sharded counter is a map from string -> counter, where each counter can
10
9
  * be incremented or decremented.
@@ -22,8 +21,17 @@ export class ShardedCounter {
22
21
  */
23
22
  constructor(component, options) {
24
23
  this.component = component;
25
- this.options = options;
24
+ this.stickyShard = {};
25
+ const defaultShards = options?.defaultShards;
26
+ this.shardsForKey = (name) => {
27
+ const explicitShards = options?.shards?.[name];
28
+ return explicitShards ?? defaultShards;
29
+ };
26
30
  }
31
+ shardsForKey;
32
+ // Keep track of the shard for each key, so multiple mutations on the same key
33
+ // will use the same shard.
34
+ stickyShard;
27
35
  /**
28
36
  * Increase the counter for key `name` by `count`.
29
37
  * If `count` is negative, the counter will decrease.
@@ -32,11 +40,13 @@ export class ShardedCounter {
32
40
  * @param count The amount to increment the counter by. Defaults to 1.
33
41
  */
34
42
  async add(ctx, name, count = 1) {
35
- return ctx.runMutation(this.component.public.add, {
43
+ const shard = await ctx.runMutation(this.component.public.add, {
36
44
  name,
37
45
  count,
46
+ shard: this.stickyShard?.[name],
38
47
  shards: this.shardsForKey(name),
39
48
  });
49
+ this.stickyShard[name] = shard;
40
50
  }
41
51
  /**
42
52
  * Decrease the counter for key `name` by `count`.
@@ -83,6 +93,14 @@ export class ShardedCounter {
83
93
  shards: this.shardsForKey(name),
84
94
  });
85
95
  }
96
+ /**
97
+ * Clear the counter for key `name`.
98
+ *
99
+ * @param name The key to clear the counter for.
100
+ */
101
+ async reset(ctx, name) {
102
+ await ctx.runMutation(this.component.public.reset, { name });
103
+ }
86
104
  /**
87
105
  * Estimate the count of a counter by only reading from a subset of shards,
88
106
  * and extrapolating the total count.
@@ -141,6 +159,10 @@ export class ShardedCounter {
141
159
  * contend with all mutations that update the counter for this key.
142
160
  */
143
161
  count: async (ctx) => this.count(ctx, name),
162
+ /**
163
+ * Reset the counter for this key.
164
+ */
165
+ reset: async (ctx) => this.reset(ctx, name),
144
166
  /**
145
167
  * Redistribute counts evenly across the counter's shards.
146
168
  *
@@ -167,9 +189,5 @@ export class ShardedCounter {
167
189
  }
168
190
  };
169
191
  }
170
- shardsForKey(name) {
171
- const explicitShards = this.options?.shards?.[name];
172
- return explicitShards ?? this.options?.defaultShards;
173
- }
174
192
  }
175
193
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  export declare const DEFAULT_SHARD_COUNT = 16;
2
2
  export declare const add: import("convex/server").RegisteredMutation<"public", {
3
+ shard?: number | undefined;
3
4
  shards?: number | undefined;
4
5
  name: string;
5
6
  count: number;
6
- }, Promise<void>>;
7
+ }, Promise<number>>;
7
8
  export declare const count: import("convex/server").RegisteredQuery<"public", {
8
9
  name: string;
9
10
  }, Promise<number>>;
@@ -11,6 +12,9 @@ export declare const rebalance: import("convex/server").RegisteredMutation<"publ
11
12
  shards?: number | undefined;
12
13
  name: string;
13
14
  }, Promise<void>>;
15
+ export declare const reset: import("convex/server").RegisteredMutation<"public", {
16
+ name: string;
17
+ }, Promise<void>>;
14
18
  export declare const estimateCount: import("convex/server").RegisteredQuery<"public", {
15
19
  shards?: number | undefined;
16
20
  readFromShards?: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/component/public.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,eAAO,MAAM,GAAG;;;;iBAyBd,CAAC;AAEH,eAAO,MAAM,KAAK;;mBAUhB,CAAC;AAEH,eAAO,MAAM,SAAS;;;iBA2BpB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;mBAsBxB,CAAC"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/component/public.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,eAAO,MAAM,GAAG;;;;;mBA6Bd,CAAC;AAEH,eAAO,MAAM,KAAK;;mBAUhB,CAAC;AAEH,eAAO,MAAM,SAAS;;;iBA2BpB,CAAC;AAEH,eAAO,MAAM,KAAK;;iBAWhB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;mBA2BxB,CAAC"}
@@ -5,11 +5,13 @@ export const add = mutation({
5
5
  args: {
6
6
  name: v.string(),
7
7
  count: v.number(),
8
+ shard: v.optional(v.number()),
8
9
  shards: v.optional(v.number()),
9
10
  },
10
- returns: v.null(),
11
+ returns: v.number(),
11
12
  handler: async (ctx, args) => {
12
- const shard = Math.floor(Math.random() * (args.shards ?? DEFAULT_SHARD_COUNT));
13
+ const shard = args.shard ??
14
+ Math.floor(Math.random() * (args.shards ?? DEFAULT_SHARD_COUNT));
13
15
  const counter = await ctx.db
14
16
  .query("counters")
15
17
  .withIndex("name", (q) => q.eq("name", args.name).eq("shard", shard))
@@ -26,6 +28,7 @@ export const add = mutation({
26
28
  shard,
27
29
  });
28
30
  }
31
+ return shard;
29
32
  },
30
33
  });
31
34
  export const count = query({
@@ -68,6 +71,16 @@ export const rebalance = mutation({
68
71
  }
69
72
  },
70
73
  });
74
+ export const reset = mutation({
75
+ args: { name: v.string() },
76
+ handler: async (ctx, args) => {
77
+ await ctx.db
78
+ .query("counters")
79
+ .withIndex("name", (q) => q.eq("name", args.name))
80
+ .collect()
81
+ .then((counters) => Promise.all(counters.map((c) => ctx.db.delete(c._id))));
82
+ },
83
+ });
71
84
  export const estimateCount = query({
72
85
  args: {
73
86
  name: v.string(),
@@ -1 +1 @@
1
- {"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/component/public.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/component/public.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,6 @@ import { api } from "../component/_generated/api";
7
7
  */
8
8
  export declare class ShardedCounter<ShardsKey extends string> {
9
9
  private component;
10
- private options?;
11
10
  /**
12
11
  * A sharded counter is a map from string -> counter, where each counter can
13
12
  * be incremented or decremented.
@@ -24,9 +23,11 @@ export declare class ShardedCounter<ShardsKey extends string> {
24
23
  * keys not in `options.shards`.
25
24
  */
26
25
  constructor(component: UseApi<typeof api>, options?: {
27
- shards?: Record<ShardsKey, number> | undefined;
28
- defaultShards?: number | undefined;
29
- } | undefined);
26
+ shards?: Partial<Record<ShardsKey, number>>;
27
+ defaultShards?: number;
28
+ });
29
+ private shardsForKey;
30
+ private stickyShard;
30
31
  /**
31
32
  * Increase the counter for key `name` by `count`.
32
33
  * If `count` is negative, the counter will decrease.
@@ -34,26 +35,26 @@ export declare class ShardedCounter<ShardsKey extends string> {
34
35
  * @param name The key to update the counter for.
35
36
  * @param count The amount to increment the counter by. Defaults to 1.
36
37
  */
37
- add<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name, count?: number): Promise<null>;
38
+ add<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name, count?: number): Promise<void>;
38
39
  /**
39
40
  * Decrease the counter for key `name` by `count`.
40
41
  */
41
- subtract<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name, count?: number): Promise<null>;
42
+ subtract<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name, count?: number): Promise<void>;
42
43
  /**
43
44
  * Increment the counter for key `name` by 1.
44
45
  */
45
- inc<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<null>;
46
+ inc<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
46
47
  /**
47
48
  * Decrement the counter for key `name` by 1.
48
49
  */
49
- dec<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<null>;
50
+ dec<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
50
51
  /**
51
52
  * Gets the counter for key `name`.
52
53
  *
53
54
  * NOTE: this reads from all shards. If used in a mutation, it will contend
54
55
  * with all mutations that update the counter for this key.
55
56
  */
56
- count<Name extends string = ShardsKey>(ctx: RunQueryCtx, name: Name): Promise<number>;
57
+ count<Name extends ShardsKey>(ctx: RunQueryCtx, name: Name): Promise<number>;
57
58
  /**
58
59
  * Redistribute counts evenly across the counter's shards.
59
60
  *
@@ -66,7 +67,13 @@ export declare class ShardedCounter<ShardsKey extends string> {
66
67
  * This operation reads and writes all shards, so it can cause contention if
67
68
  * called too often.
68
69
  */
69
- rebalance<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
70
+ rebalance<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
71
+ /**
72
+ * Clear the counter for key `name`.
73
+ *
74
+ * @param name The key to clear the counter for.
75
+ */
76
+ reset<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name): Promise<void>;
70
77
  /**
71
78
  * Estimate the count of a counter by only reading from a subset of shards,
72
79
  * and extrapolating the total count.
@@ -78,7 +85,7 @@ export declare class ShardedCounter<ShardsKey extends string> {
78
85
  *
79
86
  * Use this to reduce contention when reading the counter.
80
87
  */
81
- estimateCount<Name extends string = ShardsKey>(ctx: RunQueryCtx, name: Name, readFromShards?: number): Promise<number>;
88
+ estimateCount<Name extends ShardsKey>(ctx: RunQueryCtx, name: Name, readFromShards?: number): Promise<number>;
82
89
  /**
83
90
  * Returns an object with methods to update and query the counter for key
84
91
  * `name`. For fixed keys, you can call `counter.for("<key>")` to get methods
@@ -94,23 +101,23 @@ export declare class ShardedCounter<ShardsKey extends string> {
94
101
  * });
95
102
  * ```
96
103
  */
97
- for<Name extends string = ShardsKey>(name: Name): {
104
+ for<Name extends ShardsKey>(name: Name): {
98
105
  /**
99
106
  * Add `count` to the counter.
100
107
  */
101
- add: (ctx: RunMutationCtx, count?: number) => Promise<null>;
108
+ add: (ctx: RunMutationCtx, count?: number) => Promise<void>;
102
109
  /**
103
110
  * Subtract `count` from the counter.
104
111
  */
105
- subtract: (ctx: RunMutationCtx, count?: number) => Promise<null>;
112
+ subtract: (ctx: RunMutationCtx, count?: number) => Promise<void>;
106
113
  /**
107
114
  * Increment the counter by 1.
108
115
  */
109
- inc: (ctx: RunMutationCtx) => Promise<null>;
116
+ inc: (ctx: RunMutationCtx) => Promise<void>;
110
117
  /**
111
118
  * Decrement the counter by 1.
112
119
  */
113
- dec: (ctx: RunMutationCtx) => Promise<null>;
120
+ dec: (ctx: RunMutationCtx) => Promise<void>;
114
121
  /**
115
122
  * Get the current value of the counter.
116
123
  *
@@ -118,6 +125,10 @@ export declare class ShardedCounter<ShardsKey extends string> {
118
125
  * contend with all mutations that update the counter for this key.
119
126
  */
120
127
  count: (ctx: RunQueryCtx) => Promise<number>;
128
+ /**
129
+ * Reset the counter for this key.
130
+ */
131
+ reset: (ctx: RunMutationCtx) => Promise<void>;
121
132
  /**
122
133
  * Redistribute counts evenly across the counter's shards.
123
134
  *
@@ -133,8 +144,7 @@ export declare class ShardedCounter<ShardsKey extends string> {
133
144
  */
134
145
  estimateCount: (ctx: RunQueryCtx, readFromShards?: number) => Promise<number>;
135
146
  };
136
- trigger<Ctx extends RunMutationCtx, Name extends string = ShardsKey>(name: Name): Trigger<Ctx, GenericDataModel, TableNamesInDataModel<GenericDataModel>>;
137
- private shardsForKey;
147
+ trigger<Ctx extends RunMutationCtx, Name extends ShardsKey>(name: Name): Trigger<Ctx, GenericDataModel, TableNamesInDataModel<GenericDataModel>>;
138
148
  }
139
149
  export type Trigger<Ctx, DataModel extends GenericDataModel, TableName extends TableNamesInDataModel<DataModel>> = (ctx: Ctx, change: Change<DataModel, TableName>) => Promise<void>;
140
150
  export type Change<DataModel extends GenericDataModel, TableName extends TableNamesInDataModel<DataModel>> = {
@@ -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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"}
@@ -4,7 +4,6 @@
4
4
  */
5
5
  export class ShardedCounter {
6
6
  component;
7
- options;
8
7
  /**
9
8
  * A sharded counter is a map from string -> counter, where each counter can
10
9
  * be incremented or decremented.
@@ -22,8 +21,17 @@ export class ShardedCounter {
22
21
  */
23
22
  constructor(component, options) {
24
23
  this.component = component;
25
- this.options = options;
24
+ this.stickyShard = {};
25
+ const defaultShards = options?.defaultShards;
26
+ this.shardsForKey = (name) => {
27
+ const explicitShards = options?.shards?.[name];
28
+ return explicitShards ?? defaultShards;
29
+ };
26
30
  }
31
+ shardsForKey;
32
+ // Keep track of the shard for each key, so multiple mutations on the same key
33
+ // will use the same shard.
34
+ stickyShard;
27
35
  /**
28
36
  * Increase the counter for key `name` by `count`.
29
37
  * If `count` is negative, the counter will decrease.
@@ -32,11 +40,13 @@ export class ShardedCounter {
32
40
  * @param count The amount to increment the counter by. Defaults to 1.
33
41
  */
34
42
  async add(ctx, name, count = 1) {
35
- return ctx.runMutation(this.component.public.add, {
43
+ const shard = await ctx.runMutation(this.component.public.add, {
36
44
  name,
37
45
  count,
46
+ shard: this.stickyShard?.[name],
38
47
  shards: this.shardsForKey(name),
39
48
  });
49
+ this.stickyShard[name] = shard;
40
50
  }
41
51
  /**
42
52
  * Decrease the counter for key `name` by `count`.
@@ -83,6 +93,14 @@ export class ShardedCounter {
83
93
  shards: this.shardsForKey(name),
84
94
  });
85
95
  }
96
+ /**
97
+ * Clear the counter for key `name`.
98
+ *
99
+ * @param name The key to clear the counter for.
100
+ */
101
+ async reset(ctx, name) {
102
+ await ctx.runMutation(this.component.public.reset, { name });
103
+ }
86
104
  /**
87
105
  * Estimate the count of a counter by only reading from a subset of shards,
88
106
  * and extrapolating the total count.
@@ -141,6 +159,10 @@ export class ShardedCounter {
141
159
  * contend with all mutations that update the counter for this key.
142
160
  */
143
161
  count: async (ctx) => this.count(ctx, name),
162
+ /**
163
+ * Reset the counter for this key.
164
+ */
165
+ reset: async (ctx) => this.reset(ctx, name),
144
166
  /**
145
167
  * Redistribute counts evenly across the counter's shards.
146
168
  *
@@ -167,9 +189,5 @@ export class ShardedCounter {
167
189
  }
168
190
  };
169
191
  }
170
- shardsForKey(name) {
171
- const explicitShards = this.options?.shards?.[name];
172
- return explicitShards ?? this.options?.defaultShards;
173
- }
174
192
  }
175
193
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  export declare const DEFAULT_SHARD_COUNT = 16;
2
2
  export declare const add: import("convex/server").RegisteredMutation<"public", {
3
+ shard?: number | undefined;
3
4
  shards?: number | undefined;
4
5
  name: string;
5
6
  count: number;
6
- }, Promise<void>>;
7
+ }, Promise<number>>;
7
8
  export declare const count: import("convex/server").RegisteredQuery<"public", {
8
9
  name: string;
9
10
  }, Promise<number>>;
@@ -11,6 +12,9 @@ export declare const rebalance: import("convex/server").RegisteredMutation<"publ
11
12
  shards?: number | undefined;
12
13
  name: string;
13
14
  }, Promise<void>>;
15
+ export declare const reset: import("convex/server").RegisteredMutation<"public", {
16
+ name: string;
17
+ }, Promise<void>>;
14
18
  export declare const estimateCount: import("convex/server").RegisteredQuery<"public", {
15
19
  shards?: number | undefined;
16
20
  readFromShards?: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/component/public.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,eAAO,MAAM,GAAG;;;;iBAyBd,CAAC;AAEH,eAAO,MAAM,KAAK;;mBAUhB,CAAC;AAEH,eAAO,MAAM,SAAS;;;iBA2BpB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;mBAsBxB,CAAC"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/component/public.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,eAAO,MAAM,GAAG;;;;;mBA6Bd,CAAC;AAEH,eAAO,MAAM,KAAK;;mBAUhB,CAAC;AAEH,eAAO,MAAM,SAAS;;;iBA2BpB,CAAC;AAEH,eAAO,MAAM,KAAK;;iBAWhB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;mBA2BxB,CAAC"}
@@ -5,11 +5,13 @@ export const add = mutation({
5
5
  args: {
6
6
  name: v.string(),
7
7
  count: v.number(),
8
+ shard: v.optional(v.number()),
8
9
  shards: v.optional(v.number()),
9
10
  },
10
- returns: v.null(),
11
+ returns: v.number(),
11
12
  handler: async (ctx, args) => {
12
- const shard = Math.floor(Math.random() * (args.shards ?? DEFAULT_SHARD_COUNT));
13
+ const shard = args.shard ??
14
+ Math.floor(Math.random() * (args.shards ?? DEFAULT_SHARD_COUNT));
13
15
  const counter = await ctx.db
14
16
  .query("counters")
15
17
  .withIndex("name", (q) => q.eq("name", args.name).eq("shard", shard))
@@ -26,6 +28,7 @@ export const add = mutation({
26
28
  shard,
27
29
  });
28
30
  }
31
+ return shard;
29
32
  },
30
33
  });
31
34
  export const count = query({
@@ -68,6 +71,16 @@ export const rebalance = mutation({
68
71
  }
69
72
  },
70
73
  });
74
+ export const reset = mutation({
75
+ args: { name: v.string() },
76
+ handler: async (ctx, args) => {
77
+ await ctx.db
78
+ .query("counters")
79
+ .withIndex("name", (q) => q.eq("name", args.name))
80
+ .collect()
81
+ .then((counters) => Promise.all(counters.map((c) => ctx.db.delete(c._id))));
82
+ },
83
+ });
71
84
  export const estimateCount = query({
72
85
  args: {
73
86
  name: v.string(),
@@ -1 +1 @@
1
- {"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/component/public.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/component/public.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "email": "support@convex.dev",
8
8
  "url": "https://github.com/get-convex/sharded-counter/issues"
9
9
  },
10
- "version": "0.1.4",
10
+ "version": "0.1.5",
11
11
  "license": "Apache-2.0",
12
12
  "keywords": [
13
13
  "convex",
@@ -22,7 +22,7 @@
22
22
  "dev": "cd example; npm run dev",
23
23
  "typecheck": "tsc --noEmit",
24
24
  "prepare": "npm run build",
25
- "test": "vitest run",
25
+ "test": "vitest",
26
26
  "test:debug": "vitest --inspect-brk --no-file-parallelism",
27
27
  "test:coverage": "vitest run --coverage --coverage.reporter=text"
28
28
  },
@@ -18,13 +18,13 @@ export class ShardedCounter<ShardsKey extends string> {
18
18
  /**
19
19
  * A sharded counter is a map from string -> counter, where each counter can
20
20
  * be incremented or decremented.
21
- *
21
+ *
22
22
  * The counter is sharded into multiple documents to allow for higher
23
23
  * throughput of updates. The default number of shards is 16.
24
- *
24
+ *
25
25
  * - More shards => higher throughput of updates.
26
26
  * - Fewer shards => lower latency when querying the counter.
27
- *
27
+ *
28
28
  * @param options.shards The number of shards for each counter, for fixed
29
29
  * keys.
30
30
  * @param options.defaultShards The number of shards for each counter, for
@@ -32,93 +32,121 @@ export class ShardedCounter<ShardsKey extends string> {
32
32
  */
33
33
  constructor(
34
34
  private component: UseApi<typeof api>,
35
- private options?: { shards?: Record<ShardsKey, number>; defaultShards?: number }
36
- ) {}
35
+ options?: {
36
+ shards?: Partial<Record<ShardsKey, number>>;
37
+ defaultShards?: number;
38
+ },
39
+ ) {
40
+ this.stickyShard = {};
41
+ const defaultShards = options?.defaultShards;
42
+ this.shardsForKey = (name: ShardsKey) => {
43
+ const explicitShards = options?.shards?.[name];
44
+ return explicitShards ?? defaultShards;
45
+ };
46
+ }
47
+
48
+ private shardsForKey: (name: ShardsKey) => number | undefined;
49
+
50
+ // Keep track of the shard for each key, so multiple mutations on the same key
51
+ // will use the same shard.
52
+ private stickyShard: Record<string, number>;
53
+
37
54
  /**
38
55
  * Increase the counter for key `name` by `count`.
39
56
  * If `count` is negative, the counter will decrease.
40
- *
57
+ *
41
58
  * @param name The key to update the counter for.
42
59
  * @param count The amount to increment the counter by. Defaults to 1.
43
60
  */
44
- async add<Name extends string = ShardsKey>(
61
+ async add<Name extends ShardsKey>(
45
62
  ctx: RunMutationCtx,
46
63
  name: Name,
47
- count: number = 1
64
+ count: number = 1,
48
65
  ) {
49
- return ctx.runMutation(this.component.public.add, {
66
+ const shard = await ctx.runMutation(this.component.public.add, {
50
67
  name,
51
68
  count,
69
+ shard: this.stickyShard?.[name],
52
70
  shards: this.shardsForKey(name),
53
71
  });
72
+ this.stickyShard[name] = shard;
54
73
  }
74
+
55
75
  /**
56
76
  * Decrease the counter for key `name` by `count`.
57
77
  */
58
- async subtract<Name extends string = ShardsKey>(
78
+ async subtract<Name extends ShardsKey>(
59
79
  ctx: RunMutationCtx,
60
80
  name: Name,
61
- count: number = 1
81
+ count: number = 1,
62
82
  ) {
63
83
  return this.add(ctx, name, -count);
64
84
  }
85
+
65
86
  /**
66
87
  * Increment the counter for key `name` by 1.
67
88
  */
68
- async inc<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name) {
89
+ async inc<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name) {
69
90
  return this.add(ctx, name, 1);
70
91
  }
92
+
71
93
  /**
72
94
  * Decrement the counter for key `name` by 1.
73
95
  */
74
- async dec<Name extends string = ShardsKey>(ctx: RunMutationCtx, name: Name) {
96
+ async dec<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name) {
75
97
  return this.add(ctx, name, -1);
76
98
  }
99
+
77
100
  /**
78
101
  * Gets the counter for key `name`.
79
102
  *
80
103
  * NOTE: this reads from all shards. If used in a mutation, it will contend
81
104
  * with all mutations that update the counter for this key.
82
105
  */
83
- async count<Name extends string = ShardsKey>(
84
- ctx: RunQueryCtx,
85
- name: Name
86
- ) {
106
+ async count<Name extends ShardsKey>(ctx: RunQueryCtx, name: Name) {
87
107
  return ctx.runQuery(this.component.public.count, { name });
88
108
  }
109
+
89
110
  /**
90
111
  * Redistribute counts evenly across the counter's shards.
91
- *
112
+ *
92
113
  * If there were more shards for this counter at some point, those shards
93
114
  * will be removed.
94
- *
115
+ *
95
116
  * If there were fewer shards for this counter, or if the random distribution
96
117
  * of counts is uneven, the counts will be redistributed evenly.
97
- *
118
+ *
98
119
  * This operation reads and writes all shards, so it can cause contention if
99
120
  * called too often.
100
121
  */
101
- async rebalance<Name extends string = ShardsKey>(
102
- ctx: RunMutationCtx,
103
- name: Name,
104
- ) {
122
+ async rebalance<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name) {
105
123
  await ctx.runMutation(this.component.public.rebalance, {
106
124
  name,
107
125
  shards: this.shardsForKey(name),
108
126
  });
109
127
  }
128
+
129
+ /**
130
+ * Clear the counter for key `name`.
131
+ *
132
+ * @param name The key to clear the counter for.
133
+ */
134
+ async reset<Name extends ShardsKey>(ctx: RunMutationCtx, name: Name) {
135
+ await ctx.runMutation(this.component.public.reset, { name });
136
+ }
137
+
110
138
  /**
111
139
  * Estimate the count of a counter by only reading from a subset of shards,
112
140
  * and extrapolating the total count.
113
- *
141
+ *
114
142
  * After a `rebalance`, or if there were a lot of data points to yield a
115
143
  * random distribution across shards, this should be a good approximation of
116
144
  * the total count. If there are few data points, which are not evenly
117
145
  * distributed across shards, this will be a poor approximation.
118
- *
146
+ *
119
147
  * Use this to reduce contention when reading the counter.
120
148
  */
121
- async estimateCount<Name extends string = ShardsKey>(
149
+ async estimateCount<Name extends ShardsKey>(
122
150
  ctx: RunQueryCtx,
123
151
  name: Name,
124
152
  readFromShards: number = 1,
@@ -144,7 +172,7 @@ export class ShardedCounter<ShardsKey extends string> {
144
172
  * });
145
173
  * ```
146
174
  */
147
- for<Name extends string = ShardsKey>(name: Name) {
175
+ for<Name extends ShardsKey>(name: Name) {
148
176
  return {
149
177
  /**
150
178
  * Add `count` to the counter.
@@ -166,14 +194,18 @@ export class ShardedCounter<ShardsKey extends string> {
166
194
  dec: async (ctx: RunMutationCtx) => this.add(ctx, name, -1),
167
195
  /**
168
196
  * Get the current value of the counter.
169
- *
197
+ *
170
198
  * NOTE: this reads from all shards. If used in a mutation, it will
171
199
  * contend with all mutations that update the counter for this key.
172
200
  */
173
201
  count: async (ctx: RunQueryCtx) => this.count(ctx, name),
202
+ /**
203
+ * Reset the counter for this key.
204
+ */
205
+ reset: async (ctx: RunMutationCtx) => this.reset(ctx, name),
174
206
  /**
175
207
  * Redistribute counts evenly across the counter's shards.
176
- *
208
+ *
177
209
  * This operation reads and writes all shards, so it can cause contention
178
210
  * if called too often.
179
211
  */
@@ -181,17 +213,14 @@ export class ShardedCounter<ShardsKey extends string> {
181
213
  /**
182
214
  * Estimate the counter by only reading from a subset of shards,
183
215
  * and extrapolating the total count.
184
- *
216
+ *
185
217
  * Use this to reduce contention when reading the counter.
186
218
  */
187
219
  estimateCount: async (ctx: RunQueryCtx, readFromShards: number = 1) =>
188
220
  this.estimateCount(ctx, name, readFromShards),
189
221
  };
190
222
  }
191
- trigger<
192
- Ctx extends RunMutationCtx,
193
- Name extends string = ShardsKey,
194
- >(
223
+ trigger<Ctx extends RunMutationCtx, Name extends ShardsKey>(
195
224
  name: Name,
196
225
  ): Trigger<Ctx, GenericDataModel, TableNamesInDataModel<GenericDataModel>> {
197
226
  return async (ctx, change) => {
@@ -202,10 +231,6 @@ export class ShardedCounter<ShardsKey extends string> {
202
231
  }
203
232
  };
204
233
  }
205
- private shardsForKey<Name extends string = ShardsKey>(name: Name) {
206
- const explicitShards = this.options?.shards?.[name as string as ShardsKey];
207
- return explicitShards ?? this.options?.defaultShards;
208
- }
209
234
  }
210
235
 
211
236
  /* Type utils follow */
@@ -221,19 +246,23 @@ export type Change<
221
246
  TableName extends TableNamesInDataModel<DataModel>,
222
247
  > = {
223
248
  id: GenericId<TableName>;
224
- } & ({
225
- operation: "insert";
226
- oldDoc: null
227
- newDoc: DocumentByName<DataModel, TableName>;
228
- } | {
229
- operation: "update";
230
- oldDoc: DocumentByName<DataModel, TableName>;
231
- newDoc: DocumentByName<DataModel, TableName>;
232
- } | {
233
- operation: "delete";
234
- oldDoc: DocumentByName<DataModel, TableName>;
235
- newDoc: null;
236
- });
249
+ } & (
250
+ | {
251
+ operation: "insert";
252
+ oldDoc: null;
253
+ newDoc: DocumentByName<DataModel, TableName>;
254
+ }
255
+ | {
256
+ operation: "update";
257
+ oldDoc: DocumentByName<DataModel, TableName>;
258
+ newDoc: DocumentByName<DataModel, TableName>;
259
+ }
260
+ | {
261
+ operation: "delete";
262
+ oldDoc: DocumentByName<DataModel, TableName>;
263
+ newDoc: null;
264
+ }
265
+ );
237
266
 
238
267
  type RunQueryCtx = {
239
268
  runQuery: GenericQueryCtx<GenericDataModel>["runQuery"];
@@ -31,8 +31,8 @@ export type Mounts = {
31
31
  add: FunctionReference<
32
32
  "mutation",
33
33
  "public",
34
- { count: number; name: string; shards?: number },
35
- null
34
+ { count: number; name: string; shard?: number; shards?: number },
35
+ number
36
36
  >;
37
37
  count: FunctionReference<"query", "public", { name: string }, number>;
38
38
  estimateCount: FunctionReference<
@@ -47,6 +47,7 @@ export type Mounts = {
47
47
  { name: string; shards?: number },
48
48
  any
49
49
  >;
50
+ reset: FunctionReference<"mutation", "public", { name: string }, any>;
50
51
  };
51
52
  };
52
53
  // For now fullApiWithMounts is only fullApi which provides
@@ -22,14 +22,39 @@ describe("counter", () => {
22
22
  expect(await t.query(api.public.count, { name: "beans" })).toEqual(10);
23
23
  expect(await t.query(api.public.count, { name: "friends" })).toEqual(11);
24
24
  });
25
+ test("respects shard argument", async () => {
26
+ const t = convexTest(schema, modules);
27
+ await t.mutation(api.public.add, { name: "beans", count: 10, shard: 1 });
28
+ await t.mutation(api.public.add, { name: "beans", count: 5, shard: 2 });
29
+ const values = await t.run(async (ctx) => {
30
+ const shard1 = await ctx.db
31
+ .query("counters")
32
+ .withIndex("name", (q) => q.eq("name", "beans").eq("shard", 1))
33
+ .unique();
34
+ const shard2 = await ctx.db
35
+ .query("counters")
36
+ .withIndex("name", (q) => q.eq("name", "beans").eq("shard", 2))
37
+ .unique();
38
+ return [shard1?.value, shard2?.value];
39
+ });
40
+ expect(values).toEqual([10, 5]);
41
+ });
42
+ test("reset", async () => {
43
+ const t = convexTest(schema, modules);
44
+ await t.mutation(api.public.add, { name: "beans", count: 10 });
45
+ await t.mutation(api.public.reset, { name: "beans" });
46
+ expect(await t.query(api.public.count, { name: "beans" })).toEqual(0);
47
+ });
25
48
  });
26
49
 
27
50
  fcTest.prop({
28
- updates: fc.array(fc.record({
29
- v: fc.integer({ min: -10000, max: 10000 }).map((i) => i / 100),
30
- key: fc.string(),
31
- shards: fc.option(fc.integer({ min: 1, max: 100 })),
32
- })),
51
+ updates: fc.array(
52
+ fc.record({
53
+ v: fc.integer({ min: -10000, max: 10000 }).map((i) => i / 100),
54
+ key: fc.string(),
55
+ shards: fc.option(fc.integer({ min: 1, max: 100 })),
56
+ }),
57
+ ),
33
58
  })(
34
59
  "updates to counter should match in-memory counter which ignores sharding",
35
60
  async ({ updates }) => {
@@ -37,7 +62,11 @@ fcTest.prop({
37
62
  const counter = new Map<string, number>();
38
63
  for (const { v, key, shards } of updates) {
39
64
  counter.set(key, (counter.get(key) ?? 0) + v);
40
- await t.mutation(api.public.add, { name: key, count: v, shards: shards ?? undefined });
65
+ await t.mutation(api.public.add, {
66
+ name: key,
67
+ count: v,
68
+ shards: shards ?? undefined,
69
+ });
41
70
  const count = await t.query(api.public.count, { name: key });
42
71
  expect(count).toBeCloseTo(counter.get(key)!);
43
72
  }
@@ -47,7 +76,10 @@ fcTest.prop({
47
76
  const count = await t.query(api.public.count, { name: key });
48
77
  expect(count).toBeCloseTo(value);
49
78
  for (let i = 1; i <= 16; i++) {
50
- const estimate = await t.query(api.public.estimateCount, { name: key, readFromShards: i });
79
+ const estimate = await t.query(api.public.estimateCount, {
80
+ name: key,
81
+ readFromShards: i,
82
+ });
51
83
  expect(estimate).toBeCloseTo(value);
52
84
  }
53
85
  }
@@ -7,11 +7,14 @@ export const add = mutation({
7
7
  args: {
8
8
  name: v.string(),
9
9
  count: v.number(),
10
+ shard: v.optional(v.number()),
10
11
  shards: v.optional(v.number()),
11
12
  },
12
- returns: v.null(),
13
+ returns: v.number(),
13
14
  handler: async (ctx, args) => {
14
- const shard = Math.floor(Math.random() * (args.shards ?? DEFAULT_SHARD_COUNT));
15
+ const shard =
16
+ args.shard ??
17
+ Math.floor(Math.random() * (args.shards ?? DEFAULT_SHARD_COUNT));
15
18
  const counter = await ctx.db
16
19
  .query("counters")
17
20
  .withIndex("name", (q) => q.eq("name", args.name).eq("shard", shard))
@@ -27,6 +30,7 @@ export const add = mutation({
27
30
  shard,
28
31
  });
29
32
  }
33
+ return shard;
30
34
  },
31
35
  });
32
36
 
@@ -71,6 +75,19 @@ export const rebalance = mutation({
71
75
  },
72
76
  });
73
77
 
78
+ export const reset = mutation({
79
+ args: { name: v.string() },
80
+ handler: async (ctx, args) => {
81
+ await ctx.db
82
+ .query("counters")
83
+ .withIndex("name", (q) => q.eq("name", args.name))
84
+ .collect()
85
+ .then((counters) =>
86
+ Promise.all(counters.map((c) => ctx.db.delete(c._id))),
87
+ );
88
+ },
89
+ });
90
+
74
91
  export const estimateCount = query({
75
92
  args: {
76
93
  name: v.string(),
@@ -79,8 +96,13 @@ export const estimateCount = query({
79
96
  },
80
97
  handler: async (ctx, args) => {
81
98
  const shardCount = args.shards ?? DEFAULT_SHARD_COUNT;
82
- const readFromShards = Math.min(Math.max(1, args.readFromShards ?? 1), shardCount);
83
- const shards = shuffle(Array.from({ length: shardCount }, (_, i) => i)).slice(0, readFromShards);
99
+ const readFromShards = Math.min(
100
+ Math.max(1, args.readFromShards ?? 1),
101
+ shardCount,
102
+ );
103
+ const shards = shuffle(
104
+ Array.from({ length: shardCount }, (_, i) => i),
105
+ ).slice(0, readFromShards);
84
106
  let readCount = 0;
85
107
  for (const shard of shards) {
86
108
  const counter = await ctx.db