lazypock 0.1.1 → 0.1.2
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 +48 -1
- package/dist/cli.cjs +33 -19
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.global.js +33 -19
- package/dist/cli.global.js.map +1 -1
- package/dist/cli.js +33 -19
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +98 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +111 -66
- package/dist/index.d.ts +111 -66
- package/dist/index.global.js +98 -6
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +98 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/cli.ts +52 -24
- package/src/collection.ts +124 -12
- package/src/index.ts +1 -0
- package/src/lazypock.ts +10 -1
- package/src/realtime.ts +38 -0
package/dist/index.d.cts
CHANGED
|
@@ -183,6 +183,96 @@ declare class HttpClient {
|
|
|
183
183
|
delete<T = unknown>(path: string, options?: RequestOptions): Promise<T | null>;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
interface RealtimeEvent {
|
|
187
|
+
event: string;
|
|
188
|
+
topic: string;
|
|
189
|
+
payload: Record<string, unknown>;
|
|
190
|
+
}
|
|
191
|
+
type RealtimeConnectOpts = {
|
|
192
|
+
/** WebSocket URL (e.g. ws://localhost:4000/socket/websocket) */
|
|
193
|
+
url: string;
|
|
194
|
+
/** Auth token to pass as query param */
|
|
195
|
+
token?: string;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Derive a WebSocket URL from an HTTP base URL.
|
|
199
|
+
* http://localhost:4000/api → ws://localhost:4000/socket/websocket
|
|
200
|
+
*/
|
|
201
|
+
declare function wsUrlFromBaseUrl(baseUrl: string): string;
|
|
202
|
+
/**
|
|
203
|
+
* Phoenix Channel client for real-time collection subscriptions.
|
|
204
|
+
*
|
|
205
|
+
* Connects via WebSocket and subscribes to collection topics.
|
|
206
|
+
* Includes automatic reconnection with exponential backoff.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* const rt = new RealtimeService();
|
|
211
|
+
* rt.connect({ url: wsUrlFromBaseUrl('http://localhost:4000/api') });
|
|
212
|
+
* rt.subscribe('collection:posts', (e) => console.log(e));
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
declare class RealtimeService {
|
|
216
|
+
private ws;
|
|
217
|
+
private refCounter;
|
|
218
|
+
private subscriptions;
|
|
219
|
+
private reconnectTimer;
|
|
220
|
+
private reconnectAttempt;
|
|
221
|
+
private maxReconnectDelay;
|
|
222
|
+
onReconnect?: () => void;
|
|
223
|
+
onDisconnect?: () => void;
|
|
224
|
+
onError?: (err: Event) => void;
|
|
225
|
+
private url;
|
|
226
|
+
private token;
|
|
227
|
+
/** Whether the WebSocket is currently open. */
|
|
228
|
+
get isOpen(): boolean;
|
|
229
|
+
/**
|
|
230
|
+
* The most recently used WebSocket URL (set on {@link connect}).
|
|
231
|
+
* Useful for SDK convenience methods that auto-connect before subscribing.
|
|
232
|
+
*/
|
|
233
|
+
get lastUrl(): string;
|
|
234
|
+
/** The auth token configured for this connection (set on connect). */
|
|
235
|
+
get lastToken(): string | undefined;
|
|
236
|
+
/**
|
|
237
|
+
* Set the socket URL. Useful before subscribing so the SDK can
|
|
238
|
+
* auto-connect on the first {@link subscribe}.
|
|
239
|
+
*/
|
|
240
|
+
setUrl(url: string): void;
|
|
241
|
+
ensureConnected(): void;
|
|
242
|
+
connect(opts: RealtimeConnectOpts): void;
|
|
243
|
+
disconnect(): void;
|
|
244
|
+
/**
|
|
245
|
+
* Subscribe to a topic (e.g. "collection:posts" or "collection:posts:*").
|
|
246
|
+
* The backend Channel authorizes via listRule on join.
|
|
247
|
+
*/
|
|
248
|
+
subscribe(topic: string, callback: (e: RealtimeEvent) => void): void;
|
|
249
|
+
/**
|
|
250
|
+
* Unsubscribe a specific callback from a topic.
|
|
251
|
+
*/
|
|
252
|
+
unsubscribe(topic: string, callback?: (e: RealtimeEvent) => void): void;
|
|
253
|
+
private resubscribeAll;
|
|
254
|
+
private doConnect;
|
|
255
|
+
private handleMessage;
|
|
256
|
+
private joinTopic;
|
|
257
|
+
private nextRef;
|
|
258
|
+
private heartbeatInterval;
|
|
259
|
+
private startHeartbeat;
|
|
260
|
+
private stopHeartbeat;
|
|
261
|
+
private scheduleReconnect;
|
|
262
|
+
private clearReconnectTimer;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* A realtime record-change event delivered to subscription callbacks.
|
|
267
|
+
* Mirrors PocketBase's RealtimeService result shape (`action` + `record`).
|
|
268
|
+
*/
|
|
269
|
+
interface RealtimeMessage {
|
|
270
|
+
action: "create" | "update" | "delete";
|
|
271
|
+
record: Record<string, unknown>;
|
|
272
|
+
topic?: string;
|
|
273
|
+
}
|
|
274
|
+
/** Subscription callback for a collection's realtime events. */
|
|
275
|
+
type RealtimeCallback = (e: RealtimeMessage) => void;
|
|
186
276
|
/**
|
|
187
277
|
* Typed CRUD service for a single dynamic collection.
|
|
188
278
|
* Get an instance via {@link LazypockClient.collection}.
|
|
@@ -193,8 +283,9 @@ declare class CollectionService<T = ApiRecord> {
|
|
|
193
283
|
private http;
|
|
194
284
|
private collectionName;
|
|
195
285
|
private authStore?;
|
|
286
|
+
private realtime?;
|
|
196
287
|
/** @internal */
|
|
197
|
-
constructor(http: HttpClient, collectionName: string, authStore?: AuthStore);
|
|
288
|
+
constructor(http: HttpClient, collectionName: string, authStore?: AuthStore, realtime?: RealtimeService);
|
|
198
289
|
private encodeId;
|
|
199
290
|
/**
|
|
200
291
|
* List records with optional filter/sort/pagination.
|
|
@@ -255,6 +346,24 @@ declare class CollectionService<T = ApiRecord> {
|
|
|
255
346
|
* ```
|
|
256
347
|
*/
|
|
257
348
|
typed<TRecord = ApiRecord>(): CollectionService<TRecord>;
|
|
349
|
+
/**
|
|
350
|
+
* Subscribe to realtime changes for this collection.
|
|
351
|
+
* The event's `action` is one of `"create" | "update" | "delete"`.
|
|
352
|
+
*
|
|
353
|
+
* Access is governed by the collection's `listRule` (PocketBase semantics):
|
|
354
|
+
* public collections allow anonymous subscriptions; other collections
|
|
355
|
+
* require a matching logged-in user or superuser.
|
|
356
|
+
*
|
|
357
|
+
* @param callback Received on every record change.
|
|
358
|
+
* @param recordId Optional — subscribe to a single record instead of `*`.
|
|
359
|
+
* @returns A function that unsubscribes this callback.
|
|
360
|
+
*/
|
|
361
|
+
subscribe(callback: RealtimeCallback, recordId?: string): () => void;
|
|
362
|
+
/**
|
|
363
|
+
* Unsubscribe all callbacks from this collection (or a specific record).
|
|
364
|
+
* @param recordId Optional record id; omitting it unsubs everything.
|
|
365
|
+
*/
|
|
366
|
+
unsubscribe(recordId?: string): void;
|
|
258
367
|
/**
|
|
259
368
|
* Authenticate with email/password against this auth collection.
|
|
260
369
|
* Stores the returned token and user model in the auth store.
|
|
@@ -277,70 +386,6 @@ declare class CollectionService<T = ApiRecord> {
|
|
|
277
386
|
authMethods(options?: RequestOptions): Promise<Record<string, unknown> | null>;
|
|
278
387
|
}
|
|
279
388
|
|
|
280
|
-
interface RealtimeEvent {
|
|
281
|
-
event: string;
|
|
282
|
-
topic: string;
|
|
283
|
-
payload: Record<string, unknown>;
|
|
284
|
-
}
|
|
285
|
-
type RealtimeConnectOpts = {
|
|
286
|
-
/** WebSocket URL (e.g. ws://localhost:4000/socket/websocket) */
|
|
287
|
-
url: string;
|
|
288
|
-
/** Auth token to pass as query param */
|
|
289
|
-
token?: string;
|
|
290
|
-
};
|
|
291
|
-
/**
|
|
292
|
-
* Derive a WebSocket URL from an HTTP base URL.
|
|
293
|
-
* http://localhost:4000/api → ws://localhost:4000/socket/websocket
|
|
294
|
-
*/
|
|
295
|
-
declare function wsUrlFromBaseUrl(baseUrl: string): string;
|
|
296
|
-
/**
|
|
297
|
-
* Phoenix Channel client for real-time collection subscriptions.
|
|
298
|
-
*
|
|
299
|
-
* Connects via WebSocket and subscribes to collection topics.
|
|
300
|
-
* Includes automatic reconnection with exponential backoff.
|
|
301
|
-
*
|
|
302
|
-
* @example
|
|
303
|
-
* ```ts
|
|
304
|
-
* const rt = new RealtimeService();
|
|
305
|
-
* rt.connect({ url: wsUrlFromBaseUrl('http://localhost:4000/api') });
|
|
306
|
-
* rt.subscribe('collection:posts', (e) => console.log(e));
|
|
307
|
-
* ```
|
|
308
|
-
*/
|
|
309
|
-
declare class RealtimeService {
|
|
310
|
-
private ws;
|
|
311
|
-
private refCounter;
|
|
312
|
-
private subscriptions;
|
|
313
|
-
private reconnectTimer;
|
|
314
|
-
private reconnectAttempt;
|
|
315
|
-
private maxReconnectDelay;
|
|
316
|
-
onReconnect?: () => void;
|
|
317
|
-
onDisconnect?: () => void;
|
|
318
|
-
onError?: (err: Event) => void;
|
|
319
|
-
private url;
|
|
320
|
-
private token;
|
|
321
|
-
connect(opts: RealtimeConnectOpts): void;
|
|
322
|
-
disconnect(): void;
|
|
323
|
-
/**
|
|
324
|
-
* Subscribe to a topic (e.g. "collection:posts" or "collection:posts:*").
|
|
325
|
-
* The backend Channel authorizes via listRule on join.
|
|
326
|
-
*/
|
|
327
|
-
subscribe(topic: string, callback: (e: RealtimeEvent) => void): void;
|
|
328
|
-
/**
|
|
329
|
-
* Unsubscribe a specific callback from a topic.
|
|
330
|
-
*/
|
|
331
|
-
unsubscribe(topic: string, callback?: (e: RealtimeEvent) => void): void;
|
|
332
|
-
private resubscribeAll;
|
|
333
|
-
private doConnect;
|
|
334
|
-
private handleMessage;
|
|
335
|
-
private joinTopic;
|
|
336
|
-
private nextRef;
|
|
337
|
-
private heartbeatInterval;
|
|
338
|
-
private startHeartbeat;
|
|
339
|
-
private stopHeartbeat;
|
|
340
|
-
private scheduleReconnect;
|
|
341
|
-
private clearReconnectTimer;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
389
|
/** Response shape from the server file endpoints */
|
|
345
390
|
interface FileRecord {
|
|
346
391
|
id: string;
|
|
@@ -693,4 +738,4 @@ declare class TypedClient<TCollections extends LazypockCollections = LazypockCol
|
|
|
693
738
|
*/
|
|
694
739
|
declare function createClient<TCollections extends LazypockCollections = LazypockCollections>(options: LazypockClientOptions): TypedClient<TCollections>;
|
|
695
740
|
|
|
696
|
-
export { ApiError, type ApiRecord, type AuthModel, AuthStore, type CollectionSchema, CollectionService, type CreateData, type FileRecord, FilesService, LazypockClient, type LazypockClientOptions, type LazypockCollections, type ListResult, RealtimeService, type RecordShape, type RequestOptions, type SchemaField, type StorageAdapter, type SystemFields, TypedClient, type UpdateData, collectionTypeName, createClient, fieldTypeKind, fieldTypeScriptType, generateTypes, getFileUrl, schemaFieldType, wsUrlFromBaseUrl };
|
|
741
|
+
export { ApiError, type ApiRecord, type AuthModel, AuthStore, type CollectionSchema, CollectionService, type CreateData, type FileRecord, FilesService, LazypockClient, type LazypockClientOptions, type LazypockCollections, type ListResult, type RealtimeCallback, type RealtimeMessage, RealtimeService, type RecordShape, type RequestOptions, type SchemaField, type StorageAdapter, type SystemFields, TypedClient, type UpdateData, collectionTypeName, createClient, fieldTypeKind, fieldTypeScriptType, generateTypes, getFileUrl, schemaFieldType, wsUrlFromBaseUrl };
|
package/dist/index.d.ts
CHANGED
|
@@ -183,6 +183,96 @@ declare class HttpClient {
|
|
|
183
183
|
delete<T = unknown>(path: string, options?: RequestOptions): Promise<T | null>;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
interface RealtimeEvent {
|
|
187
|
+
event: string;
|
|
188
|
+
topic: string;
|
|
189
|
+
payload: Record<string, unknown>;
|
|
190
|
+
}
|
|
191
|
+
type RealtimeConnectOpts = {
|
|
192
|
+
/** WebSocket URL (e.g. ws://localhost:4000/socket/websocket) */
|
|
193
|
+
url: string;
|
|
194
|
+
/** Auth token to pass as query param */
|
|
195
|
+
token?: string;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Derive a WebSocket URL from an HTTP base URL.
|
|
199
|
+
* http://localhost:4000/api → ws://localhost:4000/socket/websocket
|
|
200
|
+
*/
|
|
201
|
+
declare function wsUrlFromBaseUrl(baseUrl: string): string;
|
|
202
|
+
/**
|
|
203
|
+
* Phoenix Channel client for real-time collection subscriptions.
|
|
204
|
+
*
|
|
205
|
+
* Connects via WebSocket and subscribes to collection topics.
|
|
206
|
+
* Includes automatic reconnection with exponential backoff.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* const rt = new RealtimeService();
|
|
211
|
+
* rt.connect({ url: wsUrlFromBaseUrl('http://localhost:4000/api') });
|
|
212
|
+
* rt.subscribe('collection:posts', (e) => console.log(e));
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
declare class RealtimeService {
|
|
216
|
+
private ws;
|
|
217
|
+
private refCounter;
|
|
218
|
+
private subscriptions;
|
|
219
|
+
private reconnectTimer;
|
|
220
|
+
private reconnectAttempt;
|
|
221
|
+
private maxReconnectDelay;
|
|
222
|
+
onReconnect?: () => void;
|
|
223
|
+
onDisconnect?: () => void;
|
|
224
|
+
onError?: (err: Event) => void;
|
|
225
|
+
private url;
|
|
226
|
+
private token;
|
|
227
|
+
/** Whether the WebSocket is currently open. */
|
|
228
|
+
get isOpen(): boolean;
|
|
229
|
+
/**
|
|
230
|
+
* The most recently used WebSocket URL (set on {@link connect}).
|
|
231
|
+
* Useful for SDK convenience methods that auto-connect before subscribing.
|
|
232
|
+
*/
|
|
233
|
+
get lastUrl(): string;
|
|
234
|
+
/** The auth token configured for this connection (set on connect). */
|
|
235
|
+
get lastToken(): string | undefined;
|
|
236
|
+
/**
|
|
237
|
+
* Set the socket URL. Useful before subscribing so the SDK can
|
|
238
|
+
* auto-connect on the first {@link subscribe}.
|
|
239
|
+
*/
|
|
240
|
+
setUrl(url: string): void;
|
|
241
|
+
ensureConnected(): void;
|
|
242
|
+
connect(opts: RealtimeConnectOpts): void;
|
|
243
|
+
disconnect(): void;
|
|
244
|
+
/**
|
|
245
|
+
* Subscribe to a topic (e.g. "collection:posts" or "collection:posts:*").
|
|
246
|
+
* The backend Channel authorizes via listRule on join.
|
|
247
|
+
*/
|
|
248
|
+
subscribe(topic: string, callback: (e: RealtimeEvent) => void): void;
|
|
249
|
+
/**
|
|
250
|
+
* Unsubscribe a specific callback from a topic.
|
|
251
|
+
*/
|
|
252
|
+
unsubscribe(topic: string, callback?: (e: RealtimeEvent) => void): void;
|
|
253
|
+
private resubscribeAll;
|
|
254
|
+
private doConnect;
|
|
255
|
+
private handleMessage;
|
|
256
|
+
private joinTopic;
|
|
257
|
+
private nextRef;
|
|
258
|
+
private heartbeatInterval;
|
|
259
|
+
private startHeartbeat;
|
|
260
|
+
private stopHeartbeat;
|
|
261
|
+
private scheduleReconnect;
|
|
262
|
+
private clearReconnectTimer;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* A realtime record-change event delivered to subscription callbacks.
|
|
267
|
+
* Mirrors PocketBase's RealtimeService result shape (`action` + `record`).
|
|
268
|
+
*/
|
|
269
|
+
interface RealtimeMessage {
|
|
270
|
+
action: "create" | "update" | "delete";
|
|
271
|
+
record: Record<string, unknown>;
|
|
272
|
+
topic?: string;
|
|
273
|
+
}
|
|
274
|
+
/** Subscription callback for a collection's realtime events. */
|
|
275
|
+
type RealtimeCallback = (e: RealtimeMessage) => void;
|
|
186
276
|
/**
|
|
187
277
|
* Typed CRUD service for a single dynamic collection.
|
|
188
278
|
* Get an instance via {@link LazypockClient.collection}.
|
|
@@ -193,8 +283,9 @@ declare class CollectionService<T = ApiRecord> {
|
|
|
193
283
|
private http;
|
|
194
284
|
private collectionName;
|
|
195
285
|
private authStore?;
|
|
286
|
+
private realtime?;
|
|
196
287
|
/** @internal */
|
|
197
|
-
constructor(http: HttpClient, collectionName: string, authStore?: AuthStore);
|
|
288
|
+
constructor(http: HttpClient, collectionName: string, authStore?: AuthStore, realtime?: RealtimeService);
|
|
198
289
|
private encodeId;
|
|
199
290
|
/**
|
|
200
291
|
* List records with optional filter/sort/pagination.
|
|
@@ -255,6 +346,24 @@ declare class CollectionService<T = ApiRecord> {
|
|
|
255
346
|
* ```
|
|
256
347
|
*/
|
|
257
348
|
typed<TRecord = ApiRecord>(): CollectionService<TRecord>;
|
|
349
|
+
/**
|
|
350
|
+
* Subscribe to realtime changes for this collection.
|
|
351
|
+
* The event's `action` is one of `"create" | "update" | "delete"`.
|
|
352
|
+
*
|
|
353
|
+
* Access is governed by the collection's `listRule` (PocketBase semantics):
|
|
354
|
+
* public collections allow anonymous subscriptions; other collections
|
|
355
|
+
* require a matching logged-in user or superuser.
|
|
356
|
+
*
|
|
357
|
+
* @param callback Received on every record change.
|
|
358
|
+
* @param recordId Optional — subscribe to a single record instead of `*`.
|
|
359
|
+
* @returns A function that unsubscribes this callback.
|
|
360
|
+
*/
|
|
361
|
+
subscribe(callback: RealtimeCallback, recordId?: string): () => void;
|
|
362
|
+
/**
|
|
363
|
+
* Unsubscribe all callbacks from this collection (or a specific record).
|
|
364
|
+
* @param recordId Optional record id; omitting it unsubs everything.
|
|
365
|
+
*/
|
|
366
|
+
unsubscribe(recordId?: string): void;
|
|
258
367
|
/**
|
|
259
368
|
* Authenticate with email/password against this auth collection.
|
|
260
369
|
* Stores the returned token and user model in the auth store.
|
|
@@ -277,70 +386,6 @@ declare class CollectionService<T = ApiRecord> {
|
|
|
277
386
|
authMethods(options?: RequestOptions): Promise<Record<string, unknown> | null>;
|
|
278
387
|
}
|
|
279
388
|
|
|
280
|
-
interface RealtimeEvent {
|
|
281
|
-
event: string;
|
|
282
|
-
topic: string;
|
|
283
|
-
payload: Record<string, unknown>;
|
|
284
|
-
}
|
|
285
|
-
type RealtimeConnectOpts = {
|
|
286
|
-
/** WebSocket URL (e.g. ws://localhost:4000/socket/websocket) */
|
|
287
|
-
url: string;
|
|
288
|
-
/** Auth token to pass as query param */
|
|
289
|
-
token?: string;
|
|
290
|
-
};
|
|
291
|
-
/**
|
|
292
|
-
* Derive a WebSocket URL from an HTTP base URL.
|
|
293
|
-
* http://localhost:4000/api → ws://localhost:4000/socket/websocket
|
|
294
|
-
*/
|
|
295
|
-
declare function wsUrlFromBaseUrl(baseUrl: string): string;
|
|
296
|
-
/**
|
|
297
|
-
* Phoenix Channel client for real-time collection subscriptions.
|
|
298
|
-
*
|
|
299
|
-
* Connects via WebSocket and subscribes to collection topics.
|
|
300
|
-
* Includes automatic reconnection with exponential backoff.
|
|
301
|
-
*
|
|
302
|
-
* @example
|
|
303
|
-
* ```ts
|
|
304
|
-
* const rt = new RealtimeService();
|
|
305
|
-
* rt.connect({ url: wsUrlFromBaseUrl('http://localhost:4000/api') });
|
|
306
|
-
* rt.subscribe('collection:posts', (e) => console.log(e));
|
|
307
|
-
* ```
|
|
308
|
-
*/
|
|
309
|
-
declare class RealtimeService {
|
|
310
|
-
private ws;
|
|
311
|
-
private refCounter;
|
|
312
|
-
private subscriptions;
|
|
313
|
-
private reconnectTimer;
|
|
314
|
-
private reconnectAttempt;
|
|
315
|
-
private maxReconnectDelay;
|
|
316
|
-
onReconnect?: () => void;
|
|
317
|
-
onDisconnect?: () => void;
|
|
318
|
-
onError?: (err: Event) => void;
|
|
319
|
-
private url;
|
|
320
|
-
private token;
|
|
321
|
-
connect(opts: RealtimeConnectOpts): void;
|
|
322
|
-
disconnect(): void;
|
|
323
|
-
/**
|
|
324
|
-
* Subscribe to a topic (e.g. "collection:posts" or "collection:posts:*").
|
|
325
|
-
* The backend Channel authorizes via listRule on join.
|
|
326
|
-
*/
|
|
327
|
-
subscribe(topic: string, callback: (e: RealtimeEvent) => void): void;
|
|
328
|
-
/**
|
|
329
|
-
* Unsubscribe a specific callback from a topic.
|
|
330
|
-
*/
|
|
331
|
-
unsubscribe(topic: string, callback?: (e: RealtimeEvent) => void): void;
|
|
332
|
-
private resubscribeAll;
|
|
333
|
-
private doConnect;
|
|
334
|
-
private handleMessage;
|
|
335
|
-
private joinTopic;
|
|
336
|
-
private nextRef;
|
|
337
|
-
private heartbeatInterval;
|
|
338
|
-
private startHeartbeat;
|
|
339
|
-
private stopHeartbeat;
|
|
340
|
-
private scheduleReconnect;
|
|
341
|
-
private clearReconnectTimer;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
389
|
/** Response shape from the server file endpoints */
|
|
345
390
|
interface FileRecord {
|
|
346
391
|
id: string;
|
|
@@ -693,4 +738,4 @@ declare class TypedClient<TCollections extends LazypockCollections = LazypockCol
|
|
|
693
738
|
*/
|
|
694
739
|
declare function createClient<TCollections extends LazypockCollections = LazypockCollections>(options: LazypockClientOptions): TypedClient<TCollections>;
|
|
695
740
|
|
|
696
|
-
export { ApiError, type ApiRecord, type AuthModel, AuthStore, type CollectionSchema, CollectionService, type CreateData, type FileRecord, FilesService, LazypockClient, type LazypockClientOptions, type LazypockCollections, type ListResult, RealtimeService, type RecordShape, type RequestOptions, type SchemaField, type StorageAdapter, type SystemFields, TypedClient, type UpdateData, collectionTypeName, createClient, fieldTypeKind, fieldTypeScriptType, generateTypes, getFileUrl, schemaFieldType, wsUrlFromBaseUrl };
|
|
741
|
+
export { ApiError, type ApiRecord, type AuthModel, AuthStore, type CollectionSchema, CollectionService, type CreateData, type FileRecord, FilesService, LazypockClient, type LazypockClientOptions, type LazypockCollections, type ListResult, type RealtimeCallback, type RealtimeMessage, RealtimeService, type RecordShape, type RequestOptions, type SchemaField, type StorageAdapter, type SystemFields, TypedClient, type UpdateData, collectionTypeName, createClient, fieldTypeKind, fieldTypeScriptType, generateTypes, getFileUrl, schemaFieldType, wsUrlFromBaseUrl };
|
package/dist/index.global.js
CHANGED
|
@@ -329,12 +329,25 @@ var Lazypock = (() => {
|
|
|
329
329
|
};
|
|
330
330
|
|
|
331
331
|
// src/collection.ts
|
|
332
|
+
function normalizeAction(event, rawAction) {
|
|
333
|
+
if (typeof rawAction === "string") {
|
|
334
|
+
const a = rawAction.toLowerCase();
|
|
335
|
+
if (a === "create" || a === "update" || a === "delete") {
|
|
336
|
+
return a;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (event === "record_change") return "update";
|
|
340
|
+
if (event === "create" || event === "record_create") return "create";
|
|
341
|
+
if (event === "delete" || event === "record_delete") return "delete";
|
|
342
|
+
return "update";
|
|
343
|
+
}
|
|
332
344
|
var CollectionService = class {
|
|
333
345
|
/** @internal */
|
|
334
|
-
constructor(http, collectionName, authStore) {
|
|
346
|
+
constructor(http, collectionName, authStore, realtime) {
|
|
335
347
|
this.http = http;
|
|
336
348
|
this.collectionName = collectionName;
|
|
337
349
|
this.authStore = authStore;
|
|
350
|
+
this.realtime = realtime;
|
|
338
351
|
}
|
|
339
352
|
encodeId(id) {
|
|
340
353
|
return encodeURIComponent(id);
|
|
@@ -406,10 +419,7 @@ var Lazypock = (() => {
|
|
|
406
419
|
* Useful for constructing `expand` query parameters.
|
|
407
420
|
*/
|
|
408
421
|
async expandFields(options) {
|
|
409
|
-
const data = await this.http.get(
|
|
410
|
-
"/collections/" + this.encodeId(this.collectionName),
|
|
411
|
-
options
|
|
412
|
-
);
|
|
422
|
+
const data = await this.http.get("/collections/" + this.encodeId(this.collectionName), options);
|
|
413
423
|
if (!data?.fields) return null;
|
|
414
424
|
return data.fields.filter((f) => f.type === "relation" && f.options?.collection).map((f) => ({
|
|
415
425
|
field: f.name,
|
|
@@ -436,6 +446,46 @@ var Lazypock = (() => {
|
|
|
436
446
|
typed() {
|
|
437
447
|
return this;
|
|
438
448
|
}
|
|
449
|
+
// ── Realtime Subscriptions (PocketBase-style) ──
|
|
450
|
+
/**
|
|
451
|
+
* Subscribe to realtime changes for this collection.
|
|
452
|
+
* The event's `action` is one of `"create" | "update" | "delete"`.
|
|
453
|
+
*
|
|
454
|
+
* Access is governed by the collection's `listRule` (PocketBase semantics):
|
|
455
|
+
* public collections allow anonymous subscriptions; other collections
|
|
456
|
+
* require a matching logged-in user or superuser.
|
|
457
|
+
*
|
|
458
|
+
* @param callback Received on every record change.
|
|
459
|
+
* @param recordId Optional — subscribe to a single record instead of `*`.
|
|
460
|
+
* @returns A function that unsubscribes this callback.
|
|
461
|
+
*/
|
|
462
|
+
subscribe(callback, recordId) {
|
|
463
|
+
if (!this.realtime) {
|
|
464
|
+
console.warn("[lazypock] No realtime service configured.");
|
|
465
|
+
return () => {
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
const topic = "collection:" + this.collectionName + (recordId ? ":" + recordId : "");
|
|
469
|
+
const handler = (raw) => {
|
|
470
|
+
const record = raw.payload?.["record"] ?? {};
|
|
471
|
+
callback({
|
|
472
|
+
action: normalizeAction(raw.event, raw.payload?.["action"]),
|
|
473
|
+
record,
|
|
474
|
+
topic: raw.topic
|
|
475
|
+
});
|
|
476
|
+
};
|
|
477
|
+
this.realtime.ensureConnected();
|
|
478
|
+
this.realtime.subscribe(topic, handler);
|
|
479
|
+
return () => this.realtime?.unsubscribe(topic, handler);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Unsubscribe all callbacks from this collection (or a specific record).
|
|
483
|
+
* @param recordId Optional record id; omitting it unsubs everything.
|
|
484
|
+
*/
|
|
485
|
+
unsubscribe(recordId) {
|
|
486
|
+
const topic = "collection:" + this.collectionName + (recordId ? ":" + recordId : "");
|
|
487
|
+
this.realtime?.unsubscribe(topic);
|
|
488
|
+
}
|
|
439
489
|
// ── Auth Collection Methods ──
|
|
440
490
|
/**
|
|
441
491
|
* Authenticate with email/password against this auth collection.
|
|
@@ -472,6 +522,7 @@ var Lazypock = (() => {
|
|
|
472
522
|
/**
|
|
473
523
|
* Get available auth methods for this collection.
|
|
474
524
|
*/
|
|
525
|
+
// ── end Realtime ──
|
|
475
526
|
async authMethods(options) {
|
|
476
527
|
return this.http.get(
|
|
477
528
|
"/" + this.encodeId(this.collectionName) + "/auth-methods",
|
|
@@ -502,6 +553,39 @@ var Lazypock = (() => {
|
|
|
502
553
|
// ── Heartbeat ──
|
|
503
554
|
this.heartbeatInterval = null;
|
|
504
555
|
}
|
|
556
|
+
/** Whether the WebSocket is currently open. */
|
|
557
|
+
get isOpen() {
|
|
558
|
+
return this.ws?.readyState === WebSocket.OPEN;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* The most recently used WebSocket URL (set on {@link connect}).
|
|
562
|
+
* Useful for SDK convenience methods that auto-connect before subscribing.
|
|
563
|
+
*/
|
|
564
|
+
get lastUrl() {
|
|
565
|
+
return this.url;
|
|
566
|
+
}
|
|
567
|
+
/** The auth token configured for this connection (set on connect). */
|
|
568
|
+
get lastToken() {
|
|
569
|
+
return this.token;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Set the socket URL. Useful before subscribing so the SDK can
|
|
573
|
+
* auto-connect on the first {@link subscribe}.
|
|
574
|
+
*/
|
|
575
|
+
setUrl(url) {
|
|
576
|
+
this.url = url;
|
|
577
|
+
}
|
|
578
|
+
/*
|
|
579
|
+
* Ensure the socket is connected, then subscribe.
|
|
580
|
+
* Used by collection-level convenience wrappers so a connection is opened
|
|
581
|
+
* automatically on the first subscribe (matching PocketBase behaviour —
|
|
582
|
+
* works for anonymous/public collections too).
|
|
583
|
+
*/
|
|
584
|
+
ensureConnected() {
|
|
585
|
+
if (this.isOpen || !this.url) return;
|
|
586
|
+
if (typeof WebSocket === "undefined") return;
|
|
587
|
+
this.doConnect();
|
|
588
|
+
}
|
|
505
589
|
connect(opts) {
|
|
506
590
|
this.url = opts.url;
|
|
507
591
|
this.token = opts.token;
|
|
@@ -918,6 +1002,9 @@ ${opts.body}
|
|
|
918
1002
|
this.authStore = options.authStore ?? new AuthStore(options.storage ?? memoryStorage);
|
|
919
1003
|
this.http = new HttpClient(baseUrl, this.authStore);
|
|
920
1004
|
this.realtime = options.realtime ?? new RealtimeService();
|
|
1005
|
+
if (!options.realtime) {
|
|
1006
|
+
this.realtime.setUrl(wsUrlFromBaseUrl(baseUrl));
|
|
1007
|
+
}
|
|
921
1008
|
this.files = new FilesService(this.http);
|
|
922
1009
|
if (options.types?.schemas) {
|
|
923
1010
|
this.schemaByName = new Map(
|
|
@@ -939,7 +1026,12 @@ ${opts.body}
|
|
|
939
1026
|
collection(name) {
|
|
940
1027
|
let svc = this.collectionCache.get(name);
|
|
941
1028
|
if (!svc) {
|
|
942
|
-
svc = new CollectionService(
|
|
1029
|
+
svc = new CollectionService(
|
|
1030
|
+
this.http,
|
|
1031
|
+
name,
|
|
1032
|
+
this.authStore,
|
|
1033
|
+
this.realtime
|
|
1034
|
+
);
|
|
943
1035
|
this.collectionCache.set(name, svc);
|
|
944
1036
|
}
|
|
945
1037
|
return svc;
|