gramobase 1.0.11 → 1.0.13

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
@@ -9,15 +9,42 @@
9
9
 
10
10
  **Telegram as a free, infinite, production-grade backend database.**
11
11
 
12
- Every Telegram channel is a collection. Every message is a document. Zero infrastructure needed all you need is a free Telegram account.
12
+ Every Telegram channel is a collection. Every message is a document. Zero infrastructure needed. All you need is a free Telegram account.
13
+
14
+ ---
15
+
16
+ ## Quick Start
17
+
18
+ ### 1. Installation
19
+
20
+ ```bash
21
+ npm install gramobase
22
+ ```
23
+
24
+ ### 2. Setup
25
+
26
+ Initialize your project with the auto-detect wizard:
27
+
28
+ ```bash
29
+ npx gramobase init
30
+ ```
31
+
32
+ This interactive wizard walks you through setting up your backend. It features **Auto-Detect** technology and **Anti-Flood** scaling: it will ask you how many Bot Tokens you want to configure (for 30 req/s scaling per bot). Provide your tokens, and leave the Channel ID blank! By sending a message in your channel, `gramobase` will automatically fetch your hidden Telegram Channel ID for you and generate your `.env` and `gramobase.config.ts`.
33
+
34
+ **Prerequisites:**
35
+ 1. Create a bot via [@BotFather](https://t.me/BotFather) on Telegram — takes 30 seconds
36
+ 2. Create a private Telegram channel
37
+ 3. Add your bot as an **Administrator** with full permissions to the channel
38
+
39
+ ### 3. Usage
13
40
 
14
41
  ```ts
15
42
  import { createClient } from 'gramobase';
16
43
  import { z } from 'zod';
17
44
 
18
45
  const db = await createClient({
19
- botToken: process.env.BOT_TOKEN!,
20
- channelId: process.env.CHANNEL_ID!,
46
+ botToken: process.env.GRAMOBASE_BOT_TOKEN_1!,
47
+ channelId: process.env.GRAMOBASE_CHANNEL_ID!,
21
48
  }).connect();
22
49
 
23
50
  const users = db.collection('users', {
@@ -28,6 +55,44 @@ await users.insertOne({ name: 'Aarav', email: 'aarav@example.com' });
28
55
  const user = await users.findOne({ name: { $eq: 'Aarav' } });
29
56
  ```
30
57
 
58
+ > [!IMPORTANT]
59
+ > **Next.js & Hot-Reloading Environments:**
60
+ > In development environments that support hot-reloading (like Next.js), the module cache is frequently cleared, which can instantiate multiple database clients and trigger write lease lock collisions. To prevent this, choose one of the following methods to cache your client:
61
+ >
62
+ > **Option A: Built-in `global` config option (Recommended)**
63
+ > Pass `global: true` in your client config to automatically handle global caching inside the package:
64
+ >
65
+ > ```ts
66
+ > import { createClient } from 'gramobase';
67
+ >
68
+ > const client = createClient({
69
+ > botToken: process.env.GRAMOBASE_BOT_TOKEN_1!,
70
+ > channelId: process.env.GRAMOBASE_CHANNEL_ID!,
71
+ > global: true, // Automatically caches the client instance globally
72
+ > });
73
+ > const db = await client.connect();
74
+ > ```
75
+ >
76
+ > **Option B: Manual `globalThis` caching**
77
+ > Alternatively, you can manage caching manually on the global scope:
78
+ >
79
+ > ```ts
80
+ > import { createClient } from 'gramobase';
81
+ >
82
+ > const globalForDb = globalThis as unknown as { dbClient: any };
83
+ >
84
+ > export async function getDb() {
85
+ > if (!globalForDb.dbClient) {
86
+ > const client = createClient({
87
+ > botToken: process.env.GRAMOBASE_BOT_TOKEN_1!,
88
+ > channelId: process.env.GRAMOBASE_CHANNEL_ID!,
89
+ > });
90
+ > globalForDb.dbClient = await client.connect();
91
+ > }
92
+ > return globalForDb.dbClient;
93
+ > }
94
+ > ```
95
+
31
96
  ---
32
97
 
33
98
  ## Why gramobase?
@@ -45,12 +110,6 @@ const user = await users.findOne({ name: { $eq: 'Aarav' } });
45
110
 
46
111
  ---
47
112
 
48
- ## Installation
49
-
50
- ```bash
51
- npm install gramobase
52
- ```
53
-
54
113
  ### Running Tests
55
114
 
56
115
  To run the suite of 40 unit tests checking the ORM, caching, queue/worker pooling, and authentication:
@@ -59,20 +118,6 @@ To run the suite of 40 unit tests checking the ORM, caching, queue/worker poolin
59
118
  npm run test
60
119
  ```
61
120
 
62
- ### Setup
63
-
64
- ```bash
65
- npx gramobase init
66
- ```
67
-
68
- This interactive wizard walks you through setting up your backend.
69
- It features **Auto-Detect** technology and **Anti-Flood** scaling: it will ask you how many Bot Tokens you want to configure (for 30 req/s scaling per bot). Provide your tokens, and leave the Channel ID blank! By sending a message in your channel, `gramobase` will automatically fetch your hidden Telegram Channel ID for you and generate your `.env` and `gramobase.config.ts`.
70
-
71
- **Prerequisites:**
72
- 1. Create a bot via [@BotFather](https://t.me/BotFather) on Telegram — takes 30 seconds
73
- 2. Create a private Telegram channel
74
- 3. Add your bot as an **Administrator** with full permissions to the channel
75
-
76
121
  ---
77
122
 
78
123
  ## Core API
@@ -274,17 +319,17 @@ Developer API (ORM, Auth, Files, Realtime)
274
319
 
275
320
  Telegram Bot API ─────────────────────────────────┐
276
321
  │ │
277
- Private Channel File Storage Realtime
278
- (messages = docs, (sendDocument, (webhook +
279
- pinned = index) file_id refs) SSE bridge)
322
+ Private Channel File Storage Realtime
323
+ (messages = docs, (sendDocument, (webhook +
324
+ pinned = registry) file_id refs) SSE bridge)
280
325
  ```
281
326
 
282
327
  ### Storage model
283
328
 
284
329
  - Each collection maps to a private Telegram channel (or shares one via namespaced message tags)
285
- - A **pinned index message** stores `{ idmsgId }` for O(1) lookups
330
+ - A **pinned registry message** acts as a distributed write lock across processes and stores the master index mapping of collection names to their respective index message IDs (`{ collectionNameindexMsgId }`)
331
+ - Individual **index messages** (unpinned) store `{ id → msgId }` for O(1) document lookups
286
332
  - The **Write-Ahead Log** channel stores operation logs for crash recovery
287
- - A **registry message** acts as a distributed write lock across processes
288
333
 
289
334
  ### Limits
290
335
 
@@ -343,6 +388,7 @@ const db = createClient({
343
388
  concurrency?: number, // max concurrent requests per token, default 25
344
389
  webhookUrl?: string, // enables webhook mode for realtime
345
390
  debug?: boolean,
391
+ global?: boolean, // auto-cache client globally (default: false)
346
392
  });
347
393
  ```
348
394
 
@@ -1,4 +1,3 @@
1
- import { z } from 'zod';
2
1
  import TelegramBot from 'node-telegram-bot-api';
3
2
  import EventEmitter from 'eventemitter3';
4
3
 
@@ -11,7 +10,11 @@ interface GramoBaseDocument {
11
10
  [key: string]: unknown;
12
11
  }
13
12
  type WithId<T> = T & GramoBaseDocument;
14
- interface CollectionConfig<T extends z.ZodType> {
13
+ interface SchemaLike<Output = any> {
14
+ parse(data: unknown): Output;
15
+ }
16
+ type InferSchema<T extends SchemaLike> = ReturnType<T['parse']>;
17
+ interface CollectionConfig<T extends SchemaLike> {
15
18
  schema: T;
16
19
  /** Channel override — uses the default if omitted */
17
20
  channelId?: string | undefined;
@@ -157,6 +160,8 @@ interface GramoBaseConfig {
157
160
  webhookUrl?: string | undefined;
158
161
  /** Enable verbose debug logging */
159
162
  debug?: boolean | undefined;
163
+ /** Auto-cache client globally on globalThis in dev mode to prevent lease collisions in serverless/hot-reloading environments */
164
+ global?: boolean | undefined;
160
165
  }
161
166
 
162
167
  interface WorkerStats {
@@ -198,4 +203,4 @@ declare class BotWorkerPool extends EventEmitter {
198
203
  destroy(): Promise<void>;
199
204
  }
200
205
 
201
- export { type AuthConfig as A, BotWorkerPool as B, type CollectionConfig as C, type FileRecord as F, type GramoBaseEvent as G, type Lease as L, type Migration as M, type Session as S, type UploadOptions as U, type WorkerStats as W, type GramoBaseConfig as a, type ComparisonOperator as b, type Filter as c, type FindOptions as d, type GramoBaseDocument as e, type UpdateOperators as f, type User as g, type WalEntry as h, type WalOpType as i, type WithId as j };
206
+ export { type AuthConfig as A, BotWorkerPool as B, type CollectionConfig as C, type FileRecord as F, type GramoBaseEvent as G, type InferSchema as I, type Lease as L, type Migration as M, type SchemaLike as S, type UploadOptions as U, type WorkerStats as W, type GramoBaseConfig as a, type ComparisonOperator as b, type Filter as c, type FindOptions as d, type GramoBaseDocument as e, type Session as f, type UpdateOperators as g, type User as h, type WalEntry as i, type WalOpType as j, type WithId as k };
@@ -1,4 +1,3 @@
1
- import { z } from 'zod';
2
1
  import TelegramBot from 'node-telegram-bot-api';
3
2
  import EventEmitter from 'eventemitter3';
4
3
 
@@ -11,7 +10,11 @@ interface GramoBaseDocument {
11
10
  [key: string]: unknown;
12
11
  }
13
12
  type WithId<T> = T & GramoBaseDocument;
14
- interface CollectionConfig<T extends z.ZodType> {
13
+ interface SchemaLike<Output = any> {
14
+ parse(data: unknown): Output;
15
+ }
16
+ type InferSchema<T extends SchemaLike> = ReturnType<T['parse']>;
17
+ interface CollectionConfig<T extends SchemaLike> {
15
18
  schema: T;
16
19
  /** Channel override — uses the default if omitted */
17
20
  channelId?: string | undefined;
@@ -157,6 +160,8 @@ interface GramoBaseConfig {
157
160
  webhookUrl?: string | undefined;
158
161
  /** Enable verbose debug logging */
159
162
  debug?: boolean | undefined;
163
+ /** Auto-cache client globally on globalThis in dev mode to prevent lease collisions in serverless/hot-reloading environments */
164
+ global?: boolean | undefined;
160
165
  }
161
166
 
162
167
  interface WorkerStats {
@@ -198,4 +203,4 @@ declare class BotWorkerPool extends EventEmitter {
198
203
  destroy(): Promise<void>;
199
204
  }
200
205
 
201
- export { type AuthConfig as A, BotWorkerPool as B, type CollectionConfig as C, type FileRecord as F, type GramoBaseEvent as G, type Lease as L, type Migration as M, type Session as S, type UploadOptions as U, type WorkerStats as W, type GramoBaseConfig as a, type ComparisonOperator as b, type Filter as c, type FindOptions as d, type GramoBaseDocument as e, type UpdateOperators as f, type User as g, type WalEntry as h, type WalOpType as i, type WithId as j };
206
+ export { type AuthConfig as A, BotWorkerPool as B, type CollectionConfig as C, type FileRecord as F, type GramoBaseEvent as G, type InferSchema as I, type Lease as L, type Migration as M, type SchemaLike as S, type UploadOptions as U, type WorkerStats as W, type GramoBaseConfig as a, type ComparisonOperator as b, type Filter as c, type FindOptions as d, type GramoBaseDocument as e, type Session as f, type UpdateOperators as g, type User as h, type WalEntry as i, type WalOpType as j, type WithId as k };
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { B as BotWorkerPool, e as GramoBaseDocument, i as WalOpType, h as WalEntry, C as CollectionConfig, j as WithId, c as Filter, d as FindOptions, f as UpdateOperators, A as AuthConfig, g as User, S as Session } from './BotWorkerPool-9ndHQt2g.js';
2
+ import { B as BotWorkerPool, L as Lease, e as GramoBaseDocument, j as WalOpType, i as WalEntry, S as SchemaLike, C as CollectionConfig, I as InferSchema, k as WithId, c as Filter, d as FindOptions, g as UpdateOperators, A as AuthConfig, h as User, f as Session } from './BotWorkerPool-h_8a20dt.js';
3
3
  import EventEmitter from 'eventemitter3';
4
4
 
5
5
  /**
@@ -41,6 +41,41 @@ declare class HotCache extends EventEmitter {
41
41
  private docKey;
42
42
  }
43
43
 
44
+ /**
45
+ * Registry uses a pinned Telegram message as a distributed lock.
46
+ *
47
+ * When a gramobase instance starts up, it reads the registry message.
48
+ * If no lease exists or the existing lease is expired, it writes a new
49
+ * lease with its own instanceId and begins sending heartbeats.
50
+ *
51
+ * This prevents multiple writer processes from corrupting the index
52
+ * (last-write-wins races on the pinned index message).
53
+ *
54
+ * Read-only operations are always permitted. Only index mutations
55
+ * require holding the write lease.
56
+ */
57
+ declare class Registry {
58
+ private pool;
59
+ private channelId;
60
+ private debug;
61
+ private state;
62
+ private readonly instanceId;
63
+ constructor(pool: BotWorkerPool, channelId: string, debug?: boolean);
64
+ acquireWriteLease(options?: {
65
+ wait?: boolean;
66
+ }): Promise<Lease>;
67
+ releaseWriteLease(): Promise<void>;
68
+ forceRelease(): Promise<void>;
69
+ isWriteLeaseHeld(): Promise<boolean>;
70
+ private heartbeat;
71
+ private readRegistryMessage;
72
+ private writeRegistryMessage;
73
+ getCollectionIndexMsgId(collection: string): Promise<number | null>;
74
+ setCollectionIndexMsgId(collection: string, msgId: number): Promise<void>;
75
+ getInstanceId(): string;
76
+ getCurrentLease(): Lease | null;
77
+ }
78
+
44
79
  interface IndexMessage {
45
80
  collection: string;
46
81
  entries: Record<string, number>;
@@ -60,10 +95,12 @@ interface IndexMessage {
60
95
  declare class TelegramStorage {
61
96
  private pool;
62
97
  private defaultChannelId;
98
+ private registry;
63
99
  private debug;
64
100
  private encryptionKey;
65
101
  private indexMsgIds;
66
- constructor(pool: BotWorkerPool, defaultChannelId: string, encryptionKey?: string, debug?: boolean);
102
+ constructor(pool: BotWorkerPool, defaultChannelId: string, registry: Registry, encryptionKey?: string, debug?: boolean);
103
+ private readRawMessageText;
67
104
  loadIndex(collection: string, channelId?: string): Promise<IndexMessage>;
68
105
  saveIndex(index: IndexMessage, channelId?: string): Promise<void>;
69
106
  writeDocument(doc: GramoBaseDocument, channelId?: string): Promise<number>;
@@ -122,7 +159,7 @@ declare class WriteAheadLog {
122
159
  getCurrentSeq(): number;
123
160
  }
124
161
 
125
- type DocOf<T extends z.ZodType> = WithId<z.infer<T>>;
162
+ type DocOf<T extends SchemaLike> = WithId<InferSchema<T>>;
126
163
  /**
127
164
  * Collection<T> is the main ORM interface.
128
165
  *
@@ -133,7 +170,7 @@ type DocOf<T extends z.ZodType> = WithId<z.infer<T>>;
133
170
  * - Index management (id → msgId map, stored as a pinned message)
134
171
  * - Filter/sort/skip/limit in memory after cache warm-up
135
172
  */
136
- declare class Collection<T extends z.ZodType> {
173
+ declare class Collection<T extends SchemaLike> {
137
174
  private name;
138
175
  private config;
139
176
  private cache;
@@ -143,18 +180,18 @@ declare class Collection<T extends z.ZodType> {
143
180
  private indexLoaded;
144
181
  constructor(name: string, config: CollectionConfig<T>, cache: HotCache, storage: TelegramStorage, wal: WriteAheadLog, defaultChannelId: string);
145
182
  ensureIndexLoaded(): Promise<void>;
146
- insertOne(data: z.infer<T>): Promise<DocOf<T>>;
147
- insertMany(items: z.infer<T>[]): Promise<DocOf<T>[]>;
183
+ insertOne(data: InferSchema<T>): Promise<DocOf<T>>;
184
+ insertMany(items: InferSchema<T>[]): Promise<DocOf<T>[]>;
148
185
  findById(id: string): Promise<DocOf<T> | null>;
149
- findOne(filter?: Filter<z.infer<T>>): Promise<DocOf<T> | null>;
150
- find(options?: FindOptions<z.infer<T>>): Promise<DocOf<T>[]>;
151
- count(filter?: Filter<z.infer<T>>): Promise<number>;
152
- updateOne(filter: Filter<z.infer<T>>, update: UpdateOperators<z.infer<T>>): Promise<DocOf<T> | null>;
153
- updateMany(filter: Filter<z.infer<T>>, update: UpdateOperators<z.infer<T>>): Promise<DocOf<T>[]>;
154
- findByIdAndUpdate(id: string, update: UpdateOperators<z.infer<T>>): Promise<DocOf<T> | null>;
186
+ findOne(filter?: Filter<InferSchema<T>>): Promise<DocOf<T> | null>;
187
+ find(options?: FindOptions<InferSchema<T>>): Promise<DocOf<T>[]>;
188
+ count(filter?: Filter<InferSchema<T>>): Promise<number>;
189
+ updateOne(filter: Filter<InferSchema<T>>, update: UpdateOperators<InferSchema<T>>): Promise<DocOf<T> | null>;
190
+ updateMany(filter: Filter<InferSchema<T>>, update: UpdateOperators<InferSchema<T>>): Promise<DocOf<T>[]>;
191
+ findByIdAndUpdate(id: string, update: UpdateOperators<InferSchema<T>>): Promise<DocOf<T> | null>;
155
192
  private applyUpdate;
156
- deleteOne(filter: Filter<z.infer<T>>): Promise<boolean>;
157
- deleteMany(filter: Filter<z.infer<T>>): Promise<number>;
193
+ deleteOne(filter: Filter<InferSchema<T>>): Promise<boolean>;
194
+ deleteMany(filter: Filter<InferSchema<T>>): Promise<number>;
158
195
  deleteById(id: string): Promise<boolean>;
159
196
  private flushIndex;
160
197
  private matchesFilter;
@@ -215,4 +252,4 @@ declare class GramoBaseAuth {
215
252
  requireRoleMiddleware(role: string): (req: any, res: any, next: any) => void;
216
253
  }
217
254
 
218
- export { Collection as C, GramoBaseAuth as G };
255
+ export { Collection as C, GramoBaseAuth as G, Registry as R };
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { B as BotWorkerPool, e as GramoBaseDocument, i as WalOpType, h as WalEntry, C as CollectionConfig, j as WithId, c as Filter, d as FindOptions, f as UpdateOperators, A as AuthConfig, g as User, S as Session } from './BotWorkerPool-9ndHQt2g.cjs';
2
+ import { B as BotWorkerPool, L as Lease, e as GramoBaseDocument, j as WalOpType, i as WalEntry, S as SchemaLike, C as CollectionConfig, I as InferSchema, k as WithId, c as Filter, d as FindOptions, g as UpdateOperators, A as AuthConfig, h as User, f as Session } from './BotWorkerPool-h_8a20dt.cjs';
3
3
  import EventEmitter from 'eventemitter3';
4
4
 
5
5
  /**
@@ -41,6 +41,41 @@ declare class HotCache extends EventEmitter {
41
41
  private docKey;
42
42
  }
43
43
 
44
+ /**
45
+ * Registry uses a pinned Telegram message as a distributed lock.
46
+ *
47
+ * When a gramobase instance starts up, it reads the registry message.
48
+ * If no lease exists or the existing lease is expired, it writes a new
49
+ * lease with its own instanceId and begins sending heartbeats.
50
+ *
51
+ * This prevents multiple writer processes from corrupting the index
52
+ * (last-write-wins races on the pinned index message).
53
+ *
54
+ * Read-only operations are always permitted. Only index mutations
55
+ * require holding the write lease.
56
+ */
57
+ declare class Registry {
58
+ private pool;
59
+ private channelId;
60
+ private debug;
61
+ private state;
62
+ private readonly instanceId;
63
+ constructor(pool: BotWorkerPool, channelId: string, debug?: boolean);
64
+ acquireWriteLease(options?: {
65
+ wait?: boolean;
66
+ }): Promise<Lease>;
67
+ releaseWriteLease(): Promise<void>;
68
+ forceRelease(): Promise<void>;
69
+ isWriteLeaseHeld(): Promise<boolean>;
70
+ private heartbeat;
71
+ private readRegistryMessage;
72
+ private writeRegistryMessage;
73
+ getCollectionIndexMsgId(collection: string): Promise<number | null>;
74
+ setCollectionIndexMsgId(collection: string, msgId: number): Promise<void>;
75
+ getInstanceId(): string;
76
+ getCurrentLease(): Lease | null;
77
+ }
78
+
44
79
  interface IndexMessage {
45
80
  collection: string;
46
81
  entries: Record<string, number>;
@@ -60,10 +95,12 @@ interface IndexMessage {
60
95
  declare class TelegramStorage {
61
96
  private pool;
62
97
  private defaultChannelId;
98
+ private registry;
63
99
  private debug;
64
100
  private encryptionKey;
65
101
  private indexMsgIds;
66
- constructor(pool: BotWorkerPool, defaultChannelId: string, encryptionKey?: string, debug?: boolean);
102
+ constructor(pool: BotWorkerPool, defaultChannelId: string, registry: Registry, encryptionKey?: string, debug?: boolean);
103
+ private readRawMessageText;
67
104
  loadIndex(collection: string, channelId?: string): Promise<IndexMessage>;
68
105
  saveIndex(index: IndexMessage, channelId?: string): Promise<void>;
69
106
  writeDocument(doc: GramoBaseDocument, channelId?: string): Promise<number>;
@@ -122,7 +159,7 @@ declare class WriteAheadLog {
122
159
  getCurrentSeq(): number;
123
160
  }
124
161
 
125
- type DocOf<T extends z.ZodType> = WithId<z.infer<T>>;
162
+ type DocOf<T extends SchemaLike> = WithId<InferSchema<T>>;
126
163
  /**
127
164
  * Collection<T> is the main ORM interface.
128
165
  *
@@ -133,7 +170,7 @@ type DocOf<T extends z.ZodType> = WithId<z.infer<T>>;
133
170
  * - Index management (id → msgId map, stored as a pinned message)
134
171
  * - Filter/sort/skip/limit in memory after cache warm-up
135
172
  */
136
- declare class Collection<T extends z.ZodType> {
173
+ declare class Collection<T extends SchemaLike> {
137
174
  private name;
138
175
  private config;
139
176
  private cache;
@@ -143,18 +180,18 @@ declare class Collection<T extends z.ZodType> {
143
180
  private indexLoaded;
144
181
  constructor(name: string, config: CollectionConfig<T>, cache: HotCache, storage: TelegramStorage, wal: WriteAheadLog, defaultChannelId: string);
145
182
  ensureIndexLoaded(): Promise<void>;
146
- insertOne(data: z.infer<T>): Promise<DocOf<T>>;
147
- insertMany(items: z.infer<T>[]): Promise<DocOf<T>[]>;
183
+ insertOne(data: InferSchema<T>): Promise<DocOf<T>>;
184
+ insertMany(items: InferSchema<T>[]): Promise<DocOf<T>[]>;
148
185
  findById(id: string): Promise<DocOf<T> | null>;
149
- findOne(filter?: Filter<z.infer<T>>): Promise<DocOf<T> | null>;
150
- find(options?: FindOptions<z.infer<T>>): Promise<DocOf<T>[]>;
151
- count(filter?: Filter<z.infer<T>>): Promise<number>;
152
- updateOne(filter: Filter<z.infer<T>>, update: UpdateOperators<z.infer<T>>): Promise<DocOf<T> | null>;
153
- updateMany(filter: Filter<z.infer<T>>, update: UpdateOperators<z.infer<T>>): Promise<DocOf<T>[]>;
154
- findByIdAndUpdate(id: string, update: UpdateOperators<z.infer<T>>): Promise<DocOf<T> | null>;
186
+ findOne(filter?: Filter<InferSchema<T>>): Promise<DocOf<T> | null>;
187
+ find(options?: FindOptions<InferSchema<T>>): Promise<DocOf<T>[]>;
188
+ count(filter?: Filter<InferSchema<T>>): Promise<number>;
189
+ updateOne(filter: Filter<InferSchema<T>>, update: UpdateOperators<InferSchema<T>>): Promise<DocOf<T> | null>;
190
+ updateMany(filter: Filter<InferSchema<T>>, update: UpdateOperators<InferSchema<T>>): Promise<DocOf<T>[]>;
191
+ findByIdAndUpdate(id: string, update: UpdateOperators<InferSchema<T>>): Promise<DocOf<T> | null>;
155
192
  private applyUpdate;
156
- deleteOne(filter: Filter<z.infer<T>>): Promise<boolean>;
157
- deleteMany(filter: Filter<z.infer<T>>): Promise<number>;
193
+ deleteOne(filter: Filter<InferSchema<T>>): Promise<boolean>;
194
+ deleteMany(filter: Filter<InferSchema<T>>): Promise<number>;
158
195
  deleteById(id: string): Promise<boolean>;
159
196
  private flushIndex;
160
197
  private matchesFilter;
@@ -215,4 +252,4 @@ declare class GramoBaseAuth {
215
252
  requireRoleMiddleware(role: string): (req: any, res: any, next: any) => void;
216
253
  }
217
254
 
218
- export { Collection as C, GramoBaseAuth as G };
255
+ export { Collection as C, GramoBaseAuth as G, Registry as R };
@@ -1,5 +1,5 @@
1
1
  import 'zod';
2
- import '../BotWorkerPool-9ndHQt2g.cjs';
3
- export { G as GramoBaseAuth } from '../GramoBaseAuth-CHNn2_e5.cjs';
2
+ import '../BotWorkerPool-h_8a20dt.cjs';
3
+ export { G as GramoBaseAuth } from '../GramoBaseAuth-ObeOxqKj.cjs';
4
4
  import 'node-telegram-bot-api';
5
5
  import 'eventemitter3';
@@ -1,5 +1,5 @@
1
1
  import 'zod';
2
- import '../BotWorkerPool-9ndHQt2g.js';
3
- export { G as GramoBaseAuth } from '../GramoBaseAuth-00fg0u_b.js';
2
+ import '../BotWorkerPool-h_8a20dt.js';
3
+ export { G as GramoBaseAuth } from '../GramoBaseAuth-DfRKq2yW.js';
4
4
  import 'node-telegram-bot-api';
5
5
  import 'eventemitter3';