pbtsdb 0.0.1 → 0.1.1
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 +546 -574
- package/dist/index.d.ts +376 -403
- package/dist/index.js +280 -477
- package/dist/index.js.map +1 -1
- package/llms.txt +163 -22
- package/package.json +20 -20
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { Collection, InsertMutationFn, UpdateMutationFn, DeleteMutationFn } from '@tanstack/db';
|
|
2
|
+
import PocketBase from 'pocketbase';
|
|
3
|
+
import { Collection as Collection$1 } from '@tanstack/react-db';
|
|
4
|
+
import { QueryCollectionUtils } from '@tanstack/query-db-collection';
|
|
3
5
|
import { QueryClient } from '@tanstack/react-query';
|
|
4
|
-
import
|
|
5
|
-
import { ReactNode } from 'react';
|
|
6
|
+
import React, { ReactNode } from 'react';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Base record type required by PocketBase collections.
|
|
10
|
+
* All records must have an 'id' field.
|
|
11
|
+
*/
|
|
12
|
+
interface BaseRecord {
|
|
13
|
+
id: string;
|
|
14
|
+
}
|
|
7
15
|
/**
|
|
8
16
|
* Schema declaration for type-safe collection management.
|
|
9
17
|
* Define your PocketBase collections with their record types and relations.
|
|
@@ -22,98 +30,37 @@ import { ReactNode } from 'react';
|
|
|
22
30
|
*/
|
|
23
31
|
interface SchemaDeclaration {
|
|
24
32
|
[collectionName: string]: {
|
|
25
|
-
type:
|
|
33
|
+
type: BaseRecord;
|
|
26
34
|
relations?: {
|
|
27
|
-
[fieldName: string]:
|
|
35
|
+
[fieldName: string]: BaseRecord | BaseRecord[];
|
|
28
36
|
};
|
|
29
37
|
};
|
|
30
38
|
}
|
|
31
39
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*/
|
|
35
|
-
interface RealtimeEvent<T extends object = object> {
|
|
36
|
-
action: string;
|
|
37
|
-
record: T;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Internal state tracking for subscription management.
|
|
41
|
-
* Includes reconnection logic and record-specific subscriptions.
|
|
42
|
-
*/
|
|
43
|
-
interface SubscriptionState {
|
|
44
|
-
unsubscribe: UnsubscribeFunc;
|
|
45
|
-
recordId?: string;
|
|
46
|
-
reconnectAttempts: number;
|
|
47
|
-
isReconnecting: boolean;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Enhanced collection interface with subscription management capabilities.
|
|
51
|
-
* Provides methods to control real-time updates from PocketBase.
|
|
40
|
+
* Extracts the record type from a schema collection.
|
|
41
|
+
* @internal
|
|
52
42
|
*/
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Subscribe to real-time updates for this collection.
|
|
56
|
-
* @param recordId - Optional: Subscribe to a specific record, or omit for collection-wide updates
|
|
57
|
-
*/
|
|
58
|
-
subscribe: (recordId?: string) => Promise<void>;
|
|
59
|
-
/**
|
|
60
|
-
* Unsubscribe from real-time updates.
|
|
61
|
-
* @param recordId - Optional: Unsubscribe from a specific record, or omit for collection-wide
|
|
62
|
-
*/
|
|
63
|
-
unsubscribe: (recordId?: string) => void;
|
|
64
|
-
/**
|
|
65
|
-
* Unsubscribe from all subscriptions for this collection.
|
|
66
|
-
*/
|
|
67
|
-
unsubscribeAll: () => void;
|
|
68
|
-
/**
|
|
69
|
-
* Check if currently subscribed to updates.
|
|
70
|
-
* @param recordId - Optional: Check a specific record subscription, or omit for collection-wide
|
|
71
|
-
*/
|
|
72
|
-
isSubscribed: (recordId?: string) => boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Wait for a subscription to be fully established (useful for testing).
|
|
75
|
-
* @param recordId - Optional record ID
|
|
76
|
-
* @param timeoutMs - Timeout in milliseconds (default: 5000)
|
|
77
|
-
*/
|
|
78
|
-
waitForSubscription: (recordId?: string, timeoutMs?: number) => Promise<void>;
|
|
79
|
-
}
|
|
43
|
+
type ExtractRecordType<Schema extends SchemaDeclaration, CollectionName extends keyof Schema> = Schema[CollectionName]['type'];
|
|
80
44
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
45
|
+
* Valid field names that can be omitted during insert operations.
|
|
46
|
+
* Excludes 'id' which is always required for TanStack DB record tracking.
|
|
47
|
+
* @internal
|
|
83
48
|
*/
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Get a pre-configured collection for joining a relation field.
|
|
87
|
-
* This returns the related collection that can be used with TanStack DB's .join() method.
|
|
88
|
-
*
|
|
89
|
-
* @param fieldName - The relation field name to join
|
|
90
|
-
* @returns The collection for the related entity, or undefined if not configured
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* ```ts
|
|
94
|
-
* const jobsCollection = factory.create('jobs', {
|
|
95
|
-
* relations: {
|
|
96
|
-
* customer: customersCollection,
|
|
97
|
-
* address: addressesCollection
|
|
98
|
-
* }
|
|
99
|
-
* });
|
|
100
|
-
*
|
|
101
|
-
* // Use with TanStack DB joins
|
|
102
|
-
* const query = q.from({ job: jobsCollection })
|
|
103
|
-
* .join(
|
|
104
|
-
* { customer: jobsCollection.relations.customer },
|
|
105
|
-
* ({ job, customer }) => eq(job.customer, customer.id),
|
|
106
|
-
* 'left'
|
|
107
|
-
* );
|
|
108
|
-
* ```
|
|
109
|
-
*/
|
|
110
|
-
relations: RelationsConfig<Schema, CollectionName>;
|
|
111
|
-
}
|
|
49
|
+
type OmittableFields<T extends object> = Exclude<keyof T, 'id'>;
|
|
112
50
|
/**
|
|
113
|
-
*
|
|
51
|
+
* Computes the insert input type by making specified fields optional.
|
|
52
|
+
* Used to support omitting server-generated fields (created, updated) during insertion.
|
|
53
|
+
*
|
|
54
|
+
* IMPORTANT: The 'id' field can NEVER be omitted as TanStack DB requires it for record tracking.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* type BookInsert = ComputeInsertType<Books, ['created', 'updated']>
|
|
59
|
+
* // Result: Omit<Books, 'created' | 'updated'> & Partial<Pick<Books, 'created' | 'updated'>>
|
|
60
|
+
* ```
|
|
114
61
|
* @internal
|
|
115
62
|
*/
|
|
116
|
-
type
|
|
63
|
+
type ComputeInsertType<T extends object, OmitFields extends readonly OmittableFields<T>[]> = Omit<T, OmitFields[number]> & Partial<Pick<T, OmitFields[number]>>;
|
|
117
64
|
/**
|
|
118
65
|
* Extracts the relations object from a schema collection.
|
|
119
66
|
* Returns never if the collection has no relations defined.
|
|
@@ -122,12 +69,6 @@ type ExtractRecordType<Schema extends SchemaDeclaration, CollectionName extends
|
|
|
122
69
|
type ExtractRelations<Schema extends SchemaDeclaration, CollectionName extends keyof Schema> = Schema[CollectionName] extends {
|
|
123
70
|
relations: infer R;
|
|
124
71
|
} ? R : never;
|
|
125
|
-
/**
|
|
126
|
-
* Extracts expandable field names from a schema collection.
|
|
127
|
-
* Returns the union of all relation field names that can be expanded.
|
|
128
|
-
* @internal
|
|
129
|
-
*/
|
|
130
|
-
type ExpandableFields<Schema extends SchemaDeclaration, CollectionName extends keyof Schema> = ExtractRelations<Schema, CollectionName> extends never ? never : keyof ExtractRelations<Schema, CollectionName> & string;
|
|
131
72
|
/**
|
|
132
73
|
* Parses comma-separated relation field names into a union type.
|
|
133
74
|
* Recursively processes "field1,field2,field3" into "field1" | "field2" | "field3".
|
|
@@ -162,186 +103,366 @@ type WithExpand<Schema extends SchemaDeclaration, CollectionName extends keyof S
|
|
|
162
103
|
* Used to unwrap optional relation types.
|
|
163
104
|
*
|
|
164
105
|
* @example
|
|
165
|
-
*
|
|
106
|
+
* ExcludeUndefined<Customer | undefined> => Customer
|
|
166
107
|
* @internal
|
|
167
108
|
*/
|
|
168
|
-
type
|
|
109
|
+
type ExcludeUndefined<T> = T extends (infer U) | undefined ? U : T;
|
|
169
110
|
/**
|
|
170
|
-
* Converts a schema relation type to its corresponding Collection
|
|
111
|
+
* Converts a schema relation type to its corresponding Collection constraint.
|
|
171
112
|
* Handles both single relations (T) and array relations (T[]).
|
|
113
|
+
* Accepts collections with any insert type to support omitOnInsert configurations.
|
|
114
|
+
*
|
|
115
|
+
* Uses constraint (extends Collection<T, ...>) rather than exact type to allow
|
|
116
|
+
* collections with different TInput types (from omitOnInsert) to be compatible.
|
|
172
117
|
*
|
|
173
118
|
* @example
|
|
174
|
-
* RelationAsCollection<Customer> => Collection<Customer>
|
|
175
|
-
* RelationAsCollection<Customer[]> => Collection<Customer>
|
|
119
|
+
* RelationAsCollection<Customer> => Collection<Customer, string | number, any, any, any>
|
|
120
|
+
* RelationAsCollection<Customer[]> => Collection<Customer, string | number, any, any, any>
|
|
176
121
|
* @internal
|
|
177
122
|
*/
|
|
178
|
-
type RelationAsCollection<T> = T extends Array<infer U> ? U extends object ? Collection<U> : Collection<object> : T extends object ? Collection<T> : Collection<object>;
|
|
123
|
+
type RelationAsCollection<T> = T extends Array<infer U> ? U extends object ? Collection<U, string | number, any, any, any> : Collection<object, string | number, any, any, any> : T extends object ? Collection<T, string | number, any, any, any> : Collection<object, string | number, any, any, any>;
|
|
179
124
|
/**
|
|
180
|
-
* Configuration for
|
|
181
|
-
*
|
|
125
|
+
* Configuration for per-collection expand - maps relation field names to their target collections.
|
|
126
|
+
* Relations configured here are automatically expanded on every fetch and auto-upserted into target collections.
|
|
182
127
|
*
|
|
183
128
|
* @example
|
|
184
129
|
* ```ts
|
|
185
|
-
* const
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
130
|
+
* const authorsCollection = createCollection<Schema>(pb, queryClient)('authors');
|
|
131
|
+
* const booksCollection = createCollection<Schema>(pb, queryClient)('books', {
|
|
132
|
+
* expand: {
|
|
133
|
+
* author: authorsCollection // Always expand 'author', upsert into authorsCollection
|
|
134
|
+
* }
|
|
135
|
+
* });
|
|
189
136
|
* ```
|
|
190
137
|
*/
|
|
191
|
-
type
|
|
192
|
-
[K in keyof ExtractRelations<Schema, CollectionName>]: RelationAsCollection<
|
|
138
|
+
type ExpandConfig<Schema extends SchemaDeclaration, CollectionName extends keyof Schema> = ExtractRelations<Schema, CollectionName> extends never ? Record<string, never> : Partial<{
|
|
139
|
+
[K in keyof ExtractRelations<Schema, CollectionName>]: RelationAsCollection<ExcludeUndefined<ExtractRelations<Schema, CollectionName>[K]>>;
|
|
193
140
|
}>;
|
|
194
141
|
/**
|
|
195
|
-
* Options for creating a collection
|
|
142
|
+
* Options for creating a collection.
|
|
196
143
|
*/
|
|
197
|
-
interface CreateCollectionOptions<Schema extends SchemaDeclaration, CollectionName extends keyof Schema
|
|
144
|
+
interface CreateCollectionOptions<Schema extends SchemaDeclaration, CollectionName extends keyof Schema> {
|
|
145
|
+
/**
|
|
146
|
+
* Configure relations to automatically expand on every fetch.
|
|
147
|
+
* Maps relation field names to their target collections for auto-upsert.
|
|
148
|
+
*
|
|
149
|
+
* Expanded records are automatically inserted into their target collections.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* const authorsCollection = createCollection<Schema>(pb, queryClient)('authors');
|
|
154
|
+
* const booksCollection = createCollection<Schema>(pb, queryClient)('books', {
|
|
155
|
+
* expand: {
|
|
156
|
+
* author: authorsCollection // Always expand, auto-upsert into authorsCollection
|
|
157
|
+
* }
|
|
158
|
+
* });
|
|
159
|
+
*
|
|
160
|
+
* // Expand is automatic - no .expand() call needed
|
|
161
|
+
* const { data } = useLiveQuery((q) => q.from({ books: booksCollection }));
|
|
162
|
+
* // data[0].expand.author is typed and populated
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
expand?: ExpandConfig<Schema, CollectionName>;
|
|
166
|
+
/**
|
|
167
|
+
* Fields that can be omitted during insert operations.
|
|
168
|
+
* Useful for server-generated fields like 'created', 'updated'.
|
|
169
|
+
*
|
|
170
|
+
* When specified, the insert() method will accept records without these fields,
|
|
171
|
+
* and the omitted fields become optional in the insert input type.
|
|
172
|
+
*
|
|
173
|
+
* **Type safety:** Only valid field names from the record type are accepted.
|
|
174
|
+
* **IMPORTANT:** The 'id' field can NEVER be omitted as TanStack DB requires it.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* // Allow inserting without created, updated (server-generated timestamps)
|
|
179
|
+
* const booksCollection = createCollection<Schema>(pb, queryClient)('books', {
|
|
180
|
+
* omitOnInsert: ['created', 'updated'] as const
|
|
181
|
+
* });
|
|
182
|
+
*
|
|
183
|
+
* // Now insert() accepts records without those fields
|
|
184
|
+
* booksCollection.insert({
|
|
185
|
+
* id: newRecordId(), // id is always required
|
|
186
|
+
* title: 'New Book',
|
|
187
|
+
* isbn: '1234567890',
|
|
188
|
+
* genre: 'Fiction',
|
|
189
|
+
* author: authorId
|
|
190
|
+
* // created, updated are optional
|
|
191
|
+
* });
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
omitOnInsert?: readonly OmittableFields<ExtractRecordType<Schema, CollectionName>>[];
|
|
198
195
|
/**
|
|
199
|
-
*
|
|
196
|
+
* Custom handler for insert mutations.
|
|
197
|
+
*
|
|
198
|
+
* **Default behavior (not provided):** Automatically creates records in PocketBase,
|
|
199
|
+
* excluding auto-generated fields (id, created, updated, collectionId, collectionName).
|
|
200
|
+
*
|
|
201
|
+
* **Custom handler:** Provide your own handler to customize insert behavior.
|
|
202
|
+
*
|
|
203
|
+
* **Disable:** Set to `false` to disable insert mutations entirely (will throw error if insert is called).
|
|
200
204
|
*
|
|
201
205
|
* @example
|
|
202
206
|
* ```ts
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
+
* // Use default automatic handler (recommended)
|
|
208
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books');
|
|
209
|
+
*
|
|
210
|
+
* // Custom handler
|
|
211
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books', {
|
|
212
|
+
* onInsert: async ({ transaction }) => {
|
|
213
|
+
* for (const mutation of transaction.mutations) {
|
|
214
|
+
* await customInsertLogic(mutation.modified);
|
|
215
|
+
* }
|
|
216
|
+
* await queryClient.invalidateQueries({ queryKey: ['books'] });
|
|
207
217
|
* }
|
|
208
218
|
* });
|
|
219
|
+
*
|
|
220
|
+
* // Disable inserts (read-only collection)
|
|
221
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books', {
|
|
222
|
+
* onInsert: false
|
|
223
|
+
* });
|
|
209
224
|
* ```
|
|
210
225
|
*/
|
|
211
|
-
|
|
226
|
+
onInsert?: InsertMutationFn<ExtractRecordType<Schema, CollectionName>> | false;
|
|
212
227
|
/**
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
228
|
+
* Custom handler for update mutations.
|
|
229
|
+
*
|
|
230
|
+
* **Default behavior (not provided):** Automatically updates records in PocketBase
|
|
231
|
+
* with the changed fields.
|
|
232
|
+
*
|
|
233
|
+
* **Custom handler:** Provide your own handler to customize update behavior.
|
|
234
|
+
*
|
|
235
|
+
* **Disable:** Set to `false` to disable update mutations entirely (will throw error if update is called).
|
|
216
236
|
*
|
|
217
237
|
* @example
|
|
218
238
|
* ```ts
|
|
219
|
-
* //
|
|
220
|
-
* const
|
|
221
|
-
*
|
|
239
|
+
* // Use default automatic handler (recommended)
|
|
240
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books');
|
|
241
|
+
*
|
|
242
|
+
* // Custom handler
|
|
243
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books', {
|
|
244
|
+
* onUpdate: async ({ transaction }) => {
|
|
245
|
+
* for (const mutation of transaction.mutations) {
|
|
246
|
+
* await customUpdateLogic(mutation.original.id, mutation.changes);
|
|
247
|
+
* }
|
|
248
|
+
* await queryClient.invalidateQueries({ queryKey: ['books'] });
|
|
249
|
+
* }
|
|
250
|
+
* });
|
|
251
|
+
*
|
|
252
|
+
* // Disable updates (read-only collection)
|
|
253
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books', {
|
|
254
|
+
* onUpdate: false
|
|
255
|
+
* });
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
onUpdate?: UpdateMutationFn<ExtractRecordType<Schema, CollectionName>> | false;
|
|
259
|
+
/**
|
|
260
|
+
* Custom handler for delete mutations.
|
|
261
|
+
*
|
|
262
|
+
* **Default behavior (not provided):** Automatically deletes records from PocketBase.
|
|
263
|
+
*
|
|
264
|
+
* **Custom handler:** Provide your own handler to customize delete behavior.
|
|
265
|
+
*
|
|
266
|
+
* **Disable:** Set to `false` to disable delete mutations entirely (will throw error if delete is called).
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* // Use default automatic handler (recommended)
|
|
271
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books');
|
|
272
|
+
*
|
|
273
|
+
* // Custom handler
|
|
274
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books', {
|
|
275
|
+
* onDelete: async ({ transaction }) => {
|
|
276
|
+
* for (const mutation of transaction.mutations) {
|
|
277
|
+
* await customDeleteLogic(mutation.original.id);
|
|
278
|
+
* }
|
|
279
|
+
* await queryClient.invalidateQueries({ queryKey: ['books'] });
|
|
280
|
+
* }
|
|
222
281
|
* });
|
|
223
282
|
*
|
|
224
|
-
* //
|
|
225
|
-
* const
|
|
226
|
-
*
|
|
283
|
+
* // Disable deletes (read-only collection)
|
|
284
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books', {
|
|
285
|
+
* onDelete: false
|
|
227
286
|
* });
|
|
228
287
|
* ```
|
|
229
288
|
*/
|
|
230
|
-
|
|
289
|
+
onDelete?: DeleteMutationFn<ExtractRecordType<Schema, CollectionName>> | false;
|
|
231
290
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
291
|
+
* Sync mode for the collection. Controls when and how data is fetched from PocketBase.
|
|
292
|
+
*
|
|
293
|
+
* - `'eager'` (default): Fetches all data immediately when collection is created.
|
|
294
|
+
* Queries are evaluated client-side against the cached data. Fast for small datasets
|
|
295
|
+
* but loads entire collection into memory. Matches TanStack DB default.
|
|
296
|
+
*
|
|
297
|
+
* - `'on-demand'`: Fetches data only when queries execute. Each query with different
|
|
298
|
+
* filters/sorting triggers a new fetch from PocketBase. Enables true server-side
|
|
299
|
+
* filtering and is better for large datasets.
|
|
300
|
+
*
|
|
301
|
+
* @default 'eager'
|
|
234
302
|
*
|
|
235
303
|
* @example
|
|
236
304
|
* ```ts
|
|
237
|
-
* //
|
|
238
|
-
* const
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* const jobsCollection = factory.create('jobs', {
|
|
244
|
-
* startSync: true
|
|
305
|
+
* // Default: eager mode - client-side filtering
|
|
306
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books');
|
|
307
|
+
*
|
|
308
|
+
* // On-demand mode - server-side filtering
|
|
309
|
+
* const collection = createCollection<Schema>(pb, queryClient)('books', {
|
|
310
|
+
* syncMode: 'on-demand'
|
|
245
311
|
* });
|
|
246
312
|
* ```
|
|
247
313
|
*/
|
|
248
|
-
|
|
314
|
+
syncMode?: 'eager' | 'on-demand';
|
|
249
315
|
}
|
|
250
316
|
|
|
251
317
|
/**
|
|
252
|
-
*
|
|
253
|
-
*
|
|
318
|
+
* Compute the record type with expand property when expand option is configured.
|
|
319
|
+
* @internal
|
|
320
|
+
*/
|
|
321
|
+
type WithExpandFromConfig<Schema extends SchemaDeclaration, C extends keyof Schema, Opts> = Opts extends {
|
|
322
|
+
expand: infer E;
|
|
323
|
+
} ? ExtractRecordType<Schema, C> & {
|
|
324
|
+
expand?: {
|
|
325
|
+
[K in keyof E]: K extends keyof ExtractRelations<Schema, C> ? ExtractRelations<Schema, C>[K] extends Array<infer U> ? U[] : ExtractRelations<Schema, C>[K] : never;
|
|
326
|
+
};
|
|
327
|
+
} : ExtractRecordType<Schema, C>;
|
|
328
|
+
/**
|
|
329
|
+
* Subscription helpers added to collection instances.
|
|
330
|
+
* @internal
|
|
331
|
+
*/
|
|
332
|
+
interface CollectionSubscriptionHelpers {
|
|
333
|
+
/** The PocketBase collection name */
|
|
334
|
+
collectionName: string;
|
|
335
|
+
/** Wait for subscription to be established (useful in tests) */
|
|
336
|
+
waitForSubscription: (timeout?: number) => Promise<void>;
|
|
337
|
+
/** Check if collection has an active subscription */
|
|
338
|
+
isSubscribed: () => boolean;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Inferred collection type from config options.
|
|
342
|
+
* @internal
|
|
343
|
+
*/
|
|
344
|
+
type InferCollectionType<Schema extends SchemaDeclaration, C extends keyof Schema, Opts extends CreateCollectionOptions<Schema, C>> = Collection$1<WithExpandFromConfig<Schema, C, Opts>, string | number, QueryCollectionUtils<WithExpandFromConfig<Schema, C, Opts>, string | number, WithExpandFromConfig<Schema, C, Opts>>, never, Opts extends {
|
|
345
|
+
omitOnInsert: infer O extends readonly OmittableFields<ExtractRecordType<Schema, C>>[];
|
|
346
|
+
} ? ComputeInsertType<ExtractRecordType<Schema, C>, O> : ExtractRecordType<Schema, C>> & CollectionSubscriptionHelpers;
|
|
347
|
+
/**
|
|
348
|
+
* Creates a type-safe TanStack DB collection backed by PocketBase.
|
|
349
|
+
* Use this when you need fine-grained control or need to create collections with dependencies.
|
|
350
|
+
*
|
|
351
|
+
* @param pb - PocketBase client instance
|
|
352
|
+
* @param queryClient - TanStack Query client
|
|
353
|
+
* @returns A curried function that takes collection name and options
|
|
254
354
|
*
|
|
255
355
|
* @example
|
|
356
|
+
* Basic usage:
|
|
256
357
|
* ```ts
|
|
257
|
-
* const
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
*
|
|
358
|
+
* const booksCollection = createCollection<Schema>(pb, queryClient)('books', {});
|
|
359
|
+
*
|
|
360
|
+
* // Use directly
|
|
361
|
+
* const books = await booksCollection.getFullList();
|
|
362
|
+
* ```
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* With auto-expand relations:
|
|
366
|
+
* ```ts
|
|
367
|
+
* const authorsCollection = createCollection<Schema>(pb, queryClient)('authors', {});
|
|
368
|
+
* const booksCollection = createCollection<Schema>(pb, queryClient)('books', {
|
|
369
|
+
* expand: {
|
|
370
|
+
* author: authorsCollection // Always expand, auto-upsert into authorsCollection
|
|
371
|
+
* }
|
|
372
|
+
* });
|
|
373
|
+
*
|
|
374
|
+
* // Expand is automatic - no .expand() call needed
|
|
375
|
+
* const { data } = useLiveQuery((q) => q.from({ books: booksCollection }));
|
|
376
|
+
* // data[0].expand.author is typed and populated
|
|
262
377
|
* ```
|
|
263
378
|
*/
|
|
264
|
-
|
|
379
|
+
declare function createCollection<Schema extends SchemaDeclaration>(pb: PocketBase, queryClient: QueryClient): <C extends keyof Schema & string, Opts extends CreateCollectionOptions<Schema, C> = CreateCollectionOptions<Schema, C>>(collectionName: C, options?: Opts) => InferCollectionType<Schema, C, Opts>;
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* UseStore hook type for variadic collection access.
|
|
383
|
+
* @internal
|
|
384
|
+
*/
|
|
385
|
+
type UseStoreFn<CollectionsMap> = <K extends (keyof CollectionsMap)[]>(...keys: K) => {
|
|
386
|
+
[I in keyof K]: K[I] extends keyof CollectionsMap ? CollectionsMap[K[I]] : never;
|
|
387
|
+
};
|
|
265
388
|
/**
|
|
266
|
-
*
|
|
389
|
+
* Return type for createReactProvider function.
|
|
267
390
|
*/
|
|
268
|
-
interface
|
|
269
|
-
/**
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
391
|
+
interface ReactProviderResult<CollectionsMap> {
|
|
392
|
+
/**
|
|
393
|
+
* React Context Provider component.
|
|
394
|
+
* Wrap your app with this provider to make collections available to useStore.
|
|
395
|
+
*/
|
|
396
|
+
Provider: React.FC<{
|
|
397
|
+
children: ReactNode;
|
|
398
|
+
}>;
|
|
399
|
+
/**
|
|
400
|
+
* Hook to access collections from the provider.
|
|
401
|
+
* Uses variadic arguments for clean syntax with automatic type inference.
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```tsx
|
|
405
|
+
* // Single collection
|
|
406
|
+
* const [books] = useStore('books');
|
|
407
|
+
*
|
|
408
|
+
* // Multiple collections (no 'as const' needed!)
|
|
409
|
+
* const [books, authors] = useStore('books', 'authors');
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
412
|
+
useStore: UseStoreFn<CollectionsMap>;
|
|
273
413
|
}
|
|
274
414
|
/**
|
|
275
|
-
*
|
|
276
|
-
*
|
|
415
|
+
* Creates a React Provider and useStore hook from a collections map.
|
|
416
|
+
*
|
|
417
|
+
* @param collections - Map of collection keys to Collection instances
|
|
418
|
+
* @returns Object containing Provider component and useStore hook
|
|
277
419
|
*
|
|
278
420
|
* @example
|
|
421
|
+
* Basic usage:
|
|
279
422
|
* ```tsx
|
|
280
|
-
*
|
|
423
|
+
* import { createCollection, createReactProvider } from 'pbtsdb';
|
|
424
|
+
* import { useLiveQuery } from '@tanstack/react-db';
|
|
425
|
+
*
|
|
426
|
+
* // Step 1: Create collections
|
|
427
|
+
* const c = createCollection<Schema>(pb, queryClient);
|
|
281
428
|
* const collections = {
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
* addresses: factory.create('addresses')
|
|
429
|
+
* books: c('books', {}),
|
|
430
|
+
* authors: c('authors', {}),
|
|
285
431
|
* };
|
|
286
432
|
*
|
|
433
|
+
* // Step 2: Wrap for React
|
|
434
|
+
* const { Provider, useStore } = createReactProvider(collections);
|
|
435
|
+
*
|
|
436
|
+
* // Step 3: Wrap your app
|
|
287
437
|
* function App() {
|
|
288
438
|
* return (
|
|
289
|
-
* <
|
|
290
|
-
* <
|
|
291
|
-
*
|
|
439
|
+
* <QueryClientProvider client={queryClient}>
|
|
440
|
+
* <Provider>
|
|
441
|
+
* <BooksList />
|
|
442
|
+
* </Provider>
|
|
443
|
+
* </QueryClientProvider>
|
|
292
444
|
* );
|
|
293
445
|
* }
|
|
294
|
-
* ```
|
|
295
|
-
*/
|
|
296
|
-
declare function CollectionsProvider({ collections, children }: CollectionsProviderProps): react_jsx_runtime.JSX.Element;
|
|
297
|
-
/**
|
|
298
|
-
* Hook to access a single collection from the provider.
|
|
299
|
-
* Returns the Collection instance for the specified key.
|
|
300
446
|
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
* @example
|
|
307
|
-
* ```tsx
|
|
308
|
-
* function JobsList() {
|
|
309
|
-
* const jobsCollection = useStore<JobsRecord>('jobs');
|
|
310
|
-
*
|
|
311
|
-
* const { data } = useLiveQuery((q) =>
|
|
312
|
-
* q.from({ jobs: jobsCollection })
|
|
313
|
-
* );
|
|
314
|
-
*
|
|
315
|
-
* return (
|
|
316
|
-
* <ul>
|
|
317
|
-
* {data?.map(job => <li key={job.id}>{job.name}</li>)}
|
|
318
|
-
* </ul>
|
|
319
|
-
* );
|
|
447
|
+
* // Step 4: Use in components
|
|
448
|
+
* function BooksList() {
|
|
449
|
+
* const [books] = useStore('books');
|
|
450
|
+
* const { data } = useLiveQuery((q) => q.from({ books }));
|
|
451
|
+
* return <div>{data?.map(book => <p key={book.id}>{book.title}</p>)}</div>;
|
|
320
452
|
* }
|
|
321
453
|
* ```
|
|
322
|
-
*/
|
|
323
|
-
declare function useStore<T extends object = object>(key: string): Collection<T>;
|
|
324
|
-
/**
|
|
325
|
-
* Hook to access multiple collections from the provider.
|
|
326
|
-
* Returns an array of Collection instances matching the order of the keys array.
|
|
327
|
-
*
|
|
328
|
-
* @template T - Tuple type of record types for each collection
|
|
329
|
-
* @param keys - Array of collection keys as defined in the provider
|
|
330
|
-
* @returns Array of Collection instances in the same order as keys
|
|
331
|
-
* @throws Error if used outside of CollectionsProvider or if any key doesn't exist
|
|
332
454
|
*
|
|
333
455
|
* @example
|
|
456
|
+
* Variadic useStore pattern:
|
|
334
457
|
* ```tsx
|
|
335
|
-
* function
|
|
336
|
-
* const [
|
|
337
|
-
* [JobsRecord, CustomersRecord]
|
|
338
|
-
* >(['jobs', 'customers']);
|
|
458
|
+
* function BooksWithAuthors() {
|
|
459
|
+
* const [books, authors] = useStore('books', 'authors');
|
|
339
460
|
*
|
|
340
461
|
* const { data } = useLiveQuery((q) =>
|
|
341
|
-
* q.from({
|
|
462
|
+
* q.from({ book: books })
|
|
342
463
|
* .join(
|
|
343
|
-
* {
|
|
344
|
-
* ({
|
|
464
|
+
* { author: authors },
|
|
465
|
+
* ({ book, author }) => eq(book.author, author.id),
|
|
345
466
|
* 'left'
|
|
346
467
|
* )
|
|
347
468
|
* );
|
|
@@ -349,201 +470,37 @@ declare function useStore<T extends object = object>(key: string): Collection<T>
|
|
|
349
470
|
* return <div>...</div>;
|
|
350
471
|
* }
|
|
351
472
|
* ```
|
|
352
|
-
*/
|
|
353
|
-
declare function useStores<T extends readonly object[]>(keys: readonly string[]): {
|
|
354
|
-
[K in keyof T]: Collection<T[K]>;
|
|
355
|
-
};
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Factory for creating type-safe TanStack DB collections backed by PocketBase.
|
|
359
|
-
* Integrates real-time subscriptions with automatic synchronization.
|
|
360
|
-
*/
|
|
361
|
-
declare class CollectionFactory<Schema extends SchemaDeclaration, TMaxDepth extends 0 | 1 | 2 | 3 | 4 | 5 | 6 = 2> {
|
|
362
|
-
pocketbase: PocketBase;
|
|
363
|
-
queryClient: QueryClient;
|
|
364
|
-
private subscriptionManager;
|
|
365
|
-
constructor(pocketbase: PocketBase, queryClient: QueryClient);
|
|
366
|
-
/**
|
|
367
|
-
* Setup automatic subscription lifecycle management.
|
|
368
|
-
* Hooks into TanStack DB's subscriber events to manage real-time subscriptions.
|
|
369
|
-
*/
|
|
370
|
-
private setupSubscriptionLifecycle;
|
|
371
|
-
/**
|
|
372
|
-
* Create a TanStack DB collection from a PocketBase collection.
|
|
373
|
-
*
|
|
374
|
-
* Collections are lazy by default - they don't fetch data or subscribe until queried.
|
|
375
|
-
* Real-time subscriptions automatically start when the first query becomes active
|
|
376
|
-
* and stop when the last query unmounts (with a cleanup delay to prevent thrashing).
|
|
377
|
-
*
|
|
378
|
-
* @param collection - The name of the collection
|
|
379
|
-
* @param options - Optional configuration including relations and expand
|
|
380
|
-
*
|
|
381
|
-
* @example
|
|
382
|
-
* Basic usage with automatic lifecycle management:
|
|
383
|
-
* ```ts
|
|
384
|
-
* const jobsCollection = factory.create('jobs');
|
|
385
|
-
*
|
|
386
|
-
* // In your component - subscription starts automatically
|
|
387
|
-
* const { data } = useLiveQuery((q) =>
|
|
388
|
-
* q.from({ jobs: jobsCollection })
|
|
389
|
-
* );
|
|
390
|
-
* // Subscription stops automatically when component unmounts
|
|
391
|
-
* ```
|
|
392
|
-
*
|
|
393
|
-
* @example
|
|
394
|
-
* With query operators (filters, sorting):
|
|
395
|
-
* ```ts
|
|
396
|
-
* const jobsCollection = factory.create('jobs');
|
|
397
|
-
*
|
|
398
|
-
* // In your component:
|
|
399
|
-
* const { data } = useLiveQuery((q) =>
|
|
400
|
-
* q.from({ jobs: jobsCollection })
|
|
401
|
-
* .where(({ jobs }) => and(
|
|
402
|
-
* eq(jobs.status, 'ACTIVE'),
|
|
403
|
-
* gt(jobs.created, new Date('2025-01-01'))
|
|
404
|
-
* ))
|
|
405
|
-
* .orderBy(({ jobs }) => jobs.created, 'desc')
|
|
406
|
-
* );
|
|
407
|
-
* ```
|
|
408
|
-
*
|
|
409
|
-
* @example
|
|
410
|
-
* With relation expansion:
|
|
411
|
-
* ```ts
|
|
412
|
-
* const jobsCollection = factory.create('jobs', {
|
|
413
|
-
* expand: 'customer,location'
|
|
414
|
-
* });
|
|
415
|
-
*
|
|
416
|
-
* // Expanded relations available in record.expand
|
|
417
|
-
* ```
|
|
418
|
-
*
|
|
419
|
-
* @example
|
|
420
|
-
* With relations (for manual joins):
|
|
421
|
-
* ```ts
|
|
422
|
-
* const customersCollection = factory.create('customers');
|
|
423
|
-
* const jobsCollection = factory.create('jobs', {
|
|
424
|
-
* relations: { customer: customersCollection }
|
|
425
|
-
* });
|
|
426
|
-
*
|
|
427
|
-
* // In your component, manually build joins:
|
|
428
|
-
* const { data } = useLiveQuery((q) =>
|
|
429
|
-
* q.from({ job: jobsCollection })
|
|
430
|
-
* .join(
|
|
431
|
-
* { customer: customersCollection },
|
|
432
|
-
* ({ job, customer }) => eq(job.customer, customer.id),
|
|
433
|
-
* "left"
|
|
434
|
-
* )
|
|
435
|
-
* .select(({ job, customer }) => ({
|
|
436
|
-
* ...job,
|
|
437
|
-
* expand: {
|
|
438
|
-
* customer: customer ? { ...customer } : undefined
|
|
439
|
-
* }
|
|
440
|
-
* }))
|
|
441
|
-
* );
|
|
442
|
-
* ```
|
|
443
|
-
*
|
|
444
|
-
* @example
|
|
445
|
-
* Manual subscription control (advanced):
|
|
446
|
-
* ```ts
|
|
447
|
-
* const jobsCollection = factory.create('jobs');
|
|
448
|
-
*
|
|
449
|
-
* // Manually subscribe to specific record (bypasses automatic lifecycle)
|
|
450
|
-
* await jobsCollection.subscribe('record_id_123');
|
|
451
|
-
*
|
|
452
|
-
* // Check subscription status
|
|
453
|
-
* const isSubbed = jobsCollection.isSubscribed('record_id_123');
|
|
454
|
-
*
|
|
455
|
-
* // Manually unsubscribe
|
|
456
|
-
* jobsCollection.unsubscribe('record_id_123');
|
|
457
|
-
* ```
|
|
458
|
-
*/
|
|
459
|
-
create<C extends keyof Schema & string, E extends string | undefined = undefined>(collection: C, options?: CreateCollectionOptions<Schema, C, E>): Collection<WithExpand<Schema, C, E>> & SubscribableCollection<WithExpand<Schema, C, E>> & JoinHelper<Schema, C, WithExpand<Schema, C, E>>;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
declare const SUBSCRIPTION_CONFIG: {
|
|
463
|
-
readonly MAX_RECONNECT_ATTEMPTS: 5;
|
|
464
|
-
readonly BASE_RECONNECT_DELAY_MS: 1000;
|
|
465
|
-
readonly DEFAULT_WAIT_TIMEOUT_MS: 5000;
|
|
466
|
-
readonly CLEANUP_DELAY_MS: 5000;
|
|
467
|
-
};
|
|
468
|
-
/**
|
|
469
|
-
* Manages real-time subscriptions to PocketBase collections.
|
|
470
|
-
* Handles subscription lifecycle, reconnection with exponential backoff,
|
|
471
|
-
* and automatic synchronization with TanStack DB collections.
|
|
472
473
|
*
|
|
473
|
-
*
|
|
474
|
-
* -
|
|
475
|
-
*
|
|
474
|
+
* @example
|
|
475
|
+
* With auto-expand collections:
|
|
476
|
+
* ```tsx
|
|
477
|
+
* const c = createCollection<Schema>(pb, queryClient);
|
|
478
|
+
* const authors = c('authors', {});
|
|
479
|
+
* const books = c('books', {
|
|
480
|
+
* expand: {
|
|
481
|
+
* author: authors
|
|
482
|
+
* }
|
|
483
|
+
* });
|
|
484
|
+
*
|
|
485
|
+
* const { Provider, useStore } = createReactProvider({ authors, books });
|
|
486
|
+
*
|
|
487
|
+
* function BooksWithExpandedAuthors() {
|
|
488
|
+
* const [books] = useStore('books');
|
|
489
|
+
* const { data } = useLiveQuery((q) => q.from({ books }));
|
|
490
|
+
*
|
|
491
|
+
* return (
|
|
492
|
+
* <ul>
|
|
493
|
+
* {data?.map(book => (
|
|
494
|
+
* <li key={book.id}>
|
|
495
|
+
* {book.title} by {book.expand?.author?.name}
|
|
496
|
+
* </li>
|
|
497
|
+
* ))}
|
|
498
|
+
* </ul>
|
|
499
|
+
* );
|
|
500
|
+
* }
|
|
501
|
+
* ```
|
|
476
502
|
*/
|
|
477
|
-
declare
|
|
478
|
-
private pocketbase;
|
|
479
|
-
private subscriptions;
|
|
480
|
-
private subscriptionPromises;
|
|
481
|
-
private cleanupTimers;
|
|
482
|
-
private subscriberCounts;
|
|
483
|
-
constructor(pocketbase: PocketBase);
|
|
484
|
-
private setupSubscription;
|
|
485
|
-
private handleReconnection;
|
|
486
|
-
/**
|
|
487
|
-
* Subscribe to real-time updates for a collection.
|
|
488
|
-
* Returns a promise that resolves when the subscription is fully established.
|
|
489
|
-
*
|
|
490
|
-
* @param collectionName - The PocketBase collection name
|
|
491
|
-
* @param collection - The TanStack DB collection to sync with
|
|
492
|
-
* @param recordId - Optional: Subscribe to specific record, or omit for collection-wide updates
|
|
493
|
-
*/
|
|
494
|
-
subscribe<T extends object>(collectionName: string, collection: Collection<T>, recordId?: string): Promise<void>;
|
|
495
|
-
/**
|
|
496
|
-
* Unsubscribe from real-time updates.
|
|
497
|
-
*
|
|
498
|
-
* @param collectionName - The PocketBase collection name
|
|
499
|
-
* @param recordId - Optional: Unsubscribe from specific record, or omit for collection-wide
|
|
500
|
-
*/
|
|
501
|
-
unsubscribe(collectionName: string, recordId?: string): void;
|
|
502
|
-
/**
|
|
503
|
-
* Unsubscribe from all subscriptions for a collection.
|
|
504
|
-
*
|
|
505
|
-
* @param collectionName - The PocketBase collection name
|
|
506
|
-
*/
|
|
507
|
-
unsubscribeAll(collectionName: string): void;
|
|
508
|
-
/**
|
|
509
|
-
* Check if subscribed to a collection.
|
|
510
|
-
*
|
|
511
|
-
* @param collectionName - The PocketBase collection name
|
|
512
|
-
* @param recordId - Optional: Check specific record subscription, or omit for collection-wide
|
|
513
|
-
*/
|
|
514
|
-
isSubscribed(collectionName: string, recordId?: string): boolean;
|
|
515
|
-
/**
|
|
516
|
-
* Wait for a subscription to be fully established (useful for testing).
|
|
517
|
-
*
|
|
518
|
-
* @param collectionName - The collection name
|
|
519
|
-
* @param recordId - Optional specific record ID
|
|
520
|
-
* @param timeoutMs - Timeout in milliseconds
|
|
521
|
-
*/
|
|
522
|
-
waitForSubscription(collectionName: string, recordId?: string, timeoutMs?: number): Promise<void>;
|
|
523
|
-
/**
|
|
524
|
-
* Track subscriber addition for a collection.
|
|
525
|
-
* Automatically subscribes when first subscriber is added.
|
|
526
|
-
*
|
|
527
|
-
* @param collectionName - The PocketBase collection name
|
|
528
|
-
* @param collection - The TanStack DB collection to sync with
|
|
529
|
-
*/
|
|
530
|
-
addSubscriber<T extends object>(collectionName: string, collection: Collection<T>): Promise<void>;
|
|
531
|
-
/**
|
|
532
|
-
* Track subscriber removal for a collection.
|
|
533
|
-
* Automatically unsubscribes (with delay) when last subscriber is removed.
|
|
534
|
-
*
|
|
535
|
-
* @param collectionName - The PocketBase collection name
|
|
536
|
-
*/
|
|
537
|
-
removeSubscriber(collectionName: string): void;
|
|
538
|
-
/**
|
|
539
|
-
* Get the current subscriber count for a collection.
|
|
540
|
-
* Useful for debugging and testing.
|
|
541
|
-
*
|
|
542
|
-
* @param collectionName - The PocketBase collection name
|
|
543
|
-
* @returns Current subscriber count
|
|
544
|
-
*/
|
|
545
|
-
getSubscriberCount(collectionName: string): number;
|
|
546
|
-
}
|
|
503
|
+
declare function createReactProvider<CollectionsMap extends Record<string, any>>(collections: CollectionsMap): ReactProviderResult<CollectionsMap>;
|
|
547
504
|
|
|
548
505
|
/**
|
|
549
506
|
* Logger interface for subscription events and internal operations.
|
|
@@ -556,6 +513,12 @@ interface Logger {
|
|
|
556
513
|
* @param context - Optional context object with additional information
|
|
557
514
|
*/
|
|
558
515
|
debug: (msg: string, context?: object) => void;
|
|
516
|
+
/**
|
|
517
|
+
* Log info-level messages.
|
|
518
|
+
* @param msg - The message to log
|
|
519
|
+
* @param context - Optional context object with additional information
|
|
520
|
+
*/
|
|
521
|
+
info: (msg: string, context?: object) => void;
|
|
559
522
|
/**
|
|
560
523
|
* Log warning-level messages.
|
|
561
524
|
* @param msg - The message to log
|
|
@@ -577,19 +540,14 @@ interface Logger {
|
|
|
577
540
|
*
|
|
578
541
|
* @example
|
|
579
542
|
* ```ts
|
|
580
|
-
* import { setLogger } from '
|
|
543
|
+
* import { setLogger } from 'pbtsdb';
|
|
581
544
|
*
|
|
582
|
-
* //
|
|
545
|
+
* // Integration with a custom logging service
|
|
583
546
|
* setLogger({
|
|
584
|
-
* debug: (msg, context) =>
|
|
585
|
-
*
|
|
586
|
-
* },
|
|
587
|
-
* warn: (msg, context) => {
|
|
588
|
-
* myLogger.warn(msg, context);
|
|
589
|
-
* },
|
|
547
|
+
* debug: (msg, context) => myLogger.debug(msg, context),
|
|
548
|
+
* warn: (msg, context) => myLogger.warn(msg, context),
|
|
590
549
|
* error: (msg, context) => {
|
|
591
550
|
* myLogger.error(msg, context);
|
|
592
|
-
* // Also send to error tracking service
|
|
593
551
|
* Sentry.captureMessage(msg, { level: 'error', extra: context });
|
|
594
552
|
* },
|
|
595
553
|
* });
|
|
@@ -597,7 +555,7 @@ interface Logger {
|
|
|
597
555
|
*
|
|
598
556
|
* @example
|
|
599
557
|
* ```ts
|
|
600
|
-
* //
|
|
558
|
+
* // Disable all logging
|
|
601
559
|
* setLogger({
|
|
602
560
|
* debug: () => {},
|
|
603
561
|
* warn: () => {},
|
|
@@ -611,4 +569,19 @@ declare function setLogger(customLogger: Logger): void;
|
|
|
611
569
|
*/
|
|
612
570
|
declare function resetLogger(): void;
|
|
613
571
|
|
|
614
|
-
|
|
572
|
+
/**
|
|
573
|
+
* Generates a new PocketBase-compatible record ID.
|
|
574
|
+
* Returns a 15-character alphanumeric string (lowercase letters and numbers).
|
|
575
|
+
*
|
|
576
|
+
* PocketBase uses 15-character IDs for records, formatted as lowercase alphanumeric.
|
|
577
|
+
*
|
|
578
|
+
* @returns A 15-character alphanumeric string suitable for use as a PocketBase record ID
|
|
579
|
+
*
|
|
580
|
+
* @example
|
|
581
|
+
* ```ts
|
|
582
|
+
* const id = newRecordId(); // "a1b2c3d4e5f6g7h"
|
|
583
|
+
* ```
|
|
584
|
+
*/
|
|
585
|
+
declare function newRecordId(): string;
|
|
586
|
+
|
|
587
|
+
export { type CreateCollectionOptions, type ExcludeUndefined, type ExtractRecordType, type ExtractRelations, type Logger, type OmittableFields, type ParseExpandFields, type ReactProviderResult, type RelationAsCollection, type SchemaDeclaration, type WithExpand, createCollection, createReactProvider, newRecordId, resetLogger, setLogger };
|