lazypock 0.1.5 → 0.2.0

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/dist/index.d.cts CHANGED
@@ -50,11 +50,39 @@ interface RequestOptions {
50
50
  signal?: AbortSignal;
51
51
  /** Custom fetch implementation (for RN or test mocking) */
52
52
  fetch?: typeof globalThis.fetch;
53
+ /**
54
+ * Request identifier used by the auto-cancellation mechanism.
55
+ *
56
+ * Pending requests sharing the same key cancel each other — only the
57
+ * last one is executed (PocketBase `requestKey` semantics).
58
+ *
59
+ * - `string` — use this exact key instead of the default `METHOD + path`.
60
+ * - `null` — disable auto-cancellation for this request (never auto-cancelled).
61
+ *
62
+ * @default `${method} ${path}`
63
+ */
64
+ requestKey?: string | null;
65
+ /**
66
+ * Disable auto-cancellation for this request.
67
+ * Alias of `requestKey: null` (PocketBase `$autoCancel: false` compat).
68
+ */
69
+ autoCancel?: boolean;
70
+ /**
71
+ * Custom request key used for auto-cancellation.
72
+ * Alias of `requestKey` (PocketBase `$cancelKey` compat).
73
+ */
74
+ cancelKey?: string;
53
75
  }
54
76
  declare class ApiError extends Error {
55
77
  readonly data: unknown;
56
78
  readonly status: number;
57
- constructor(message: string, data: unknown, status: number);
79
+ /**
80
+ * `true` when this error was caused by an aborted/cancelled request
81
+ * (auto-cancelled duplicate, or manually via `cancelRequest()` /
82
+ * `cancelAllRequests()` / an external AbortSignal).
83
+ */
84
+ readonly isAbort: boolean;
85
+ constructor(message: string, data: unknown, status: number, isAbort?: boolean);
58
86
  }
59
87
 
60
88
  /**
@@ -130,29 +158,51 @@ declare class AuthStore {
130
158
  private notify;
131
159
  }
132
160
 
133
- /**
134
- * Low-level HTTP client wrapping `fetch` with automatic auth token injection.
135
- * Only relies on `globalThis.fetch` — works in browser, React Native, and Node 18+.
136
- */
137
161
  declare class HttpClient {
138
162
  private baseUrl;
139
163
  private authStore;
140
164
  private defaultFetch;
165
+ /**
166
+ * Abort controllers for in-flight requests, keyed by their cancellation key
167
+ * (default `METHOD path`). A new request with the same key aborts the
168
+ * previous one — PocketBase-style auto-cancellation of duplicated requests.
169
+ */
170
+ private cancelControllers;
171
+ /** Global toggle for the auto-cancellation behaviour (default: on). */
172
+ private enableAutoCancellation;
141
173
  /**
142
174
  * @param baseUrl The API base URL (e.g. `http://localhost:4000/api`). Trailing slash stripped.
143
175
  * @param authStore The auth store providing the token for Authorization headers.
144
176
  */
145
177
  constructor(baseUrl: string, authStore: AuthStore);
146
178
  private refreshAuth;
179
+ /**
180
+ * Globally enable or disable auto-cancellation of duplicated pending requests.
181
+ * Fluent — returns `this` for chaining.
182
+ */
183
+ autoCancellation(enable: boolean): this;
184
+ /**
185
+ * Abort a pending request identified by its cancellation key
186
+ * (default `METHOD path`, e.g. `"GET /api/posts"`). No-op if not pending.
187
+ */
188
+ cancelRequest(requestKey: string): this;
189
+ /** Abort all pending requests. */
190
+ cancelAllRequests(): this;
147
191
  /**
148
192
  * Make an HTTP request with automatic auth token injection and optional auto-refresh.
149
193
  *
194
+ * Auto-cancellation: a request keyed by `options.requestKey` (default
195
+ * `METHOD path`) aborts any previous pending request with the same key,
196
+ * so only the last duplicate executes. Set `requestKey: null` or
197
+ * `autoCancel: false` to opt out per request.
198
+ *
150
199
  * @param method HTTP method.
151
200
  * @param path URL path (appended to baseUrl).
152
201
  * @param body JSON-serializable body, or FormData for file uploads.
153
202
  * @param options Optional request options.
154
203
  * @returns Parsed JSON response, or null for 204 No Content.
155
- * @throws {ApiError} On non-2xx responses.
204
+ * @throws {ApiError} On non-2xx responses or when the request is aborted
205
+ * (aborted requests throw an `ApiError` with `isAbort === true`).
156
206
  */
157
207
  request<T = unknown>(method: Method, path: string, body?: unknown, options?: RequestOptions): Promise<T | null>;
158
208
  /**
@@ -409,12 +459,28 @@ interface FileRecord {
409
459
  mimeType: string;
410
460
  size: number;
411
461
  url: string;
462
+ /** Map of thumbnail size => URL, e.g. { "50x50": "/api/files/<id>/thumbs/50x50" } */
463
+ thumbs?: Record<string, string>;
412
464
  [key: string]: unknown;
413
465
  }
414
466
  /**
415
467
  * Construct a file URL from the API base URL and file ID.
416
468
  */
417
469
  declare function getFileUrl(baseUrl: string, fileId: string): string;
470
+ /**
471
+ * Construct a thumbnail URL from the API base URL, file ID, and thumb size.
472
+ * @param size e.g. "50x50"
473
+ */
474
+ declare function getThumbUrl(baseUrl: string, fileId: string, size: string): string;
475
+ /**
476
+ * Construct an on-demand scaled image URL from the API base URL, file ID, and size.
477
+ *
478
+ * The size is an ImageMagick geometry: "100" (width, keep aspect), "100x100"
479
+ * (fit within box), "100x100!" (exact crop), "x200" (height). The server
480
+ * generates and caches the scaled image on first request.
481
+ * @param size e.g. "100x100"
482
+ */
483
+ declare function getScaleUrl(baseUrl: string, fileId: string, size: string): string;
418
484
  /**
419
485
  * Service for file upload, retrieval, and deletion.
420
486
  * Access via {@link LazypockClient.files}.
@@ -435,6 +501,27 @@ declare class FilesService {
435
501
  recordId?: string;
436
502
  fieldName?: string;
437
503
  }): Promise<FileRecord | null>;
504
+ /**
505
+ * List uploaded files (newest first), with optional filters.
506
+ *
507
+ * @param options Filters and pagination.
508
+ */
509
+ list(options?: {
510
+ page?: number;
511
+ perPage?: number;
512
+ collectionName?: string;
513
+ fieldName?: string;
514
+ mime?: string;
515
+ }): Promise<{
516
+ items: FileRecord[];
517
+ page: number;
518
+ perPage: number;
519
+ total: number;
520
+ }>;
521
+ /**
522
+ * Fetch file metadata including URL.
523
+ * @param fileId The file ID.
524
+ */
438
525
  /**
439
526
  * Fetch file metadata including URL.
440
527
  * @param fileId The file ID.
@@ -670,6 +757,27 @@ declare class LazypockClient {
670
757
  generateTypes(options?: {
671
758
  packageName?: string;
672
759
  }): string;
760
+ /**
761
+ * Globally enable or disable auto-cancellation of duplicated pending requests.
762
+ *
763
+ * When enabled (default), a new request whose `requestKey` (default
764
+ * `HTTP_METHOD + path`) matches a still-pending request aborts the previous
765
+ * one — only the last duplicate executes.
766
+ *
767
+ * @example
768
+ * ```ts
769
+ * client.autoCancellation(false); // keep every request
770
+ * ```
771
+ */
772
+ autoCancellation(enable: boolean): this;
773
+ /**
774
+ * Abort a single pending request by its cancellation key
775
+ * (default `HTTP_METHOD + path`, e.g. `"GET /api/posts?page=1"`).
776
+ * The request rejects with an `ApiError` whose `isAbort` is `true`.
777
+ */
778
+ cancelRequest(requestKey: string): this;
779
+ /** Abort all pending requests. */
780
+ cancelAllRequests(): this;
673
781
  /** Check whether any superuser exists (for login vs setup screen routing). */
674
782
  checkSuperuser(): Promise<{
675
783
  has_superuser: boolean;
@@ -698,7 +806,11 @@ declare class LazypockClient {
698
806
  login(email: string, password: string, collection?: string): Promise<({
699
807
  token: string;
700
808
  } & Record<string, unknown>) | null>;
701
- /** Fetch the current superuser profile and refresh the auth model. */
809
+ /**
810
+ * Fetch the current authenticated identity (superuser OR auth collection user).
811
+ * Uses `GET /api/me` (PocketBase parity) — works with both superuser tokens
812
+ * and auth collection user tokens.
813
+ */
702
814
  me<T = ApiRecord>(options?: RequestOptions): Promise<T | null>;
703
815
  /**
704
816
  * Authenticate against an auth collection with email/password.
@@ -758,4 +870,4 @@ declare class TypedClient<TCollections extends LazypockCollections = LazypockCol
758
870
  */
759
871
  declare function createClient<TCollections extends LazypockCollections = LazypockCollections>(options: LazypockClientOptions): TypedClient<TCollections>;
760
872
 
761
- export { ApiError, type ApiRecord, type AuthModel, AuthStore, type CollectionSchema, CollectionService, type CollectionsMessage, CollectionsService, 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 };
873
+ export { ApiError, type ApiRecord, type AuthModel, AuthStore, type CollectionSchema, CollectionService, type CollectionsMessage, CollectionsService, type CreateData, type FileRecord, FilesService, HttpClient, 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, getScaleUrl, getThumbUrl, schemaFieldType, wsUrlFromBaseUrl };
package/dist/index.d.ts CHANGED
@@ -50,11 +50,39 @@ interface RequestOptions {
50
50
  signal?: AbortSignal;
51
51
  /** Custom fetch implementation (for RN or test mocking) */
52
52
  fetch?: typeof globalThis.fetch;
53
+ /**
54
+ * Request identifier used by the auto-cancellation mechanism.
55
+ *
56
+ * Pending requests sharing the same key cancel each other — only the
57
+ * last one is executed (PocketBase `requestKey` semantics).
58
+ *
59
+ * - `string` — use this exact key instead of the default `METHOD + path`.
60
+ * - `null` — disable auto-cancellation for this request (never auto-cancelled).
61
+ *
62
+ * @default `${method} ${path}`
63
+ */
64
+ requestKey?: string | null;
65
+ /**
66
+ * Disable auto-cancellation for this request.
67
+ * Alias of `requestKey: null` (PocketBase `$autoCancel: false` compat).
68
+ */
69
+ autoCancel?: boolean;
70
+ /**
71
+ * Custom request key used for auto-cancellation.
72
+ * Alias of `requestKey` (PocketBase `$cancelKey` compat).
73
+ */
74
+ cancelKey?: string;
53
75
  }
54
76
  declare class ApiError extends Error {
55
77
  readonly data: unknown;
56
78
  readonly status: number;
57
- constructor(message: string, data: unknown, status: number);
79
+ /**
80
+ * `true` when this error was caused by an aborted/cancelled request
81
+ * (auto-cancelled duplicate, or manually via `cancelRequest()` /
82
+ * `cancelAllRequests()` / an external AbortSignal).
83
+ */
84
+ readonly isAbort: boolean;
85
+ constructor(message: string, data: unknown, status: number, isAbort?: boolean);
58
86
  }
59
87
 
60
88
  /**
@@ -130,29 +158,51 @@ declare class AuthStore {
130
158
  private notify;
131
159
  }
132
160
 
133
- /**
134
- * Low-level HTTP client wrapping `fetch` with automatic auth token injection.
135
- * Only relies on `globalThis.fetch` — works in browser, React Native, and Node 18+.
136
- */
137
161
  declare class HttpClient {
138
162
  private baseUrl;
139
163
  private authStore;
140
164
  private defaultFetch;
165
+ /**
166
+ * Abort controllers for in-flight requests, keyed by their cancellation key
167
+ * (default `METHOD path`). A new request with the same key aborts the
168
+ * previous one — PocketBase-style auto-cancellation of duplicated requests.
169
+ */
170
+ private cancelControllers;
171
+ /** Global toggle for the auto-cancellation behaviour (default: on). */
172
+ private enableAutoCancellation;
141
173
  /**
142
174
  * @param baseUrl The API base URL (e.g. `http://localhost:4000/api`). Trailing slash stripped.
143
175
  * @param authStore The auth store providing the token for Authorization headers.
144
176
  */
145
177
  constructor(baseUrl: string, authStore: AuthStore);
146
178
  private refreshAuth;
179
+ /**
180
+ * Globally enable or disable auto-cancellation of duplicated pending requests.
181
+ * Fluent — returns `this` for chaining.
182
+ */
183
+ autoCancellation(enable: boolean): this;
184
+ /**
185
+ * Abort a pending request identified by its cancellation key
186
+ * (default `METHOD path`, e.g. `"GET /api/posts"`). No-op if not pending.
187
+ */
188
+ cancelRequest(requestKey: string): this;
189
+ /** Abort all pending requests. */
190
+ cancelAllRequests(): this;
147
191
  /**
148
192
  * Make an HTTP request with automatic auth token injection and optional auto-refresh.
149
193
  *
194
+ * Auto-cancellation: a request keyed by `options.requestKey` (default
195
+ * `METHOD path`) aborts any previous pending request with the same key,
196
+ * so only the last duplicate executes. Set `requestKey: null` or
197
+ * `autoCancel: false` to opt out per request.
198
+ *
150
199
  * @param method HTTP method.
151
200
  * @param path URL path (appended to baseUrl).
152
201
  * @param body JSON-serializable body, or FormData for file uploads.
153
202
  * @param options Optional request options.
154
203
  * @returns Parsed JSON response, or null for 204 No Content.
155
- * @throws {ApiError} On non-2xx responses.
204
+ * @throws {ApiError} On non-2xx responses or when the request is aborted
205
+ * (aborted requests throw an `ApiError` with `isAbort === true`).
156
206
  */
157
207
  request<T = unknown>(method: Method, path: string, body?: unknown, options?: RequestOptions): Promise<T | null>;
158
208
  /**
@@ -409,12 +459,28 @@ interface FileRecord {
409
459
  mimeType: string;
410
460
  size: number;
411
461
  url: string;
462
+ /** Map of thumbnail size => URL, e.g. { "50x50": "/api/files/<id>/thumbs/50x50" } */
463
+ thumbs?: Record<string, string>;
412
464
  [key: string]: unknown;
413
465
  }
414
466
  /**
415
467
  * Construct a file URL from the API base URL and file ID.
416
468
  */
417
469
  declare function getFileUrl(baseUrl: string, fileId: string): string;
470
+ /**
471
+ * Construct a thumbnail URL from the API base URL, file ID, and thumb size.
472
+ * @param size e.g. "50x50"
473
+ */
474
+ declare function getThumbUrl(baseUrl: string, fileId: string, size: string): string;
475
+ /**
476
+ * Construct an on-demand scaled image URL from the API base URL, file ID, and size.
477
+ *
478
+ * The size is an ImageMagick geometry: "100" (width, keep aspect), "100x100"
479
+ * (fit within box), "100x100!" (exact crop), "x200" (height). The server
480
+ * generates and caches the scaled image on first request.
481
+ * @param size e.g. "100x100"
482
+ */
483
+ declare function getScaleUrl(baseUrl: string, fileId: string, size: string): string;
418
484
  /**
419
485
  * Service for file upload, retrieval, and deletion.
420
486
  * Access via {@link LazypockClient.files}.
@@ -435,6 +501,27 @@ declare class FilesService {
435
501
  recordId?: string;
436
502
  fieldName?: string;
437
503
  }): Promise<FileRecord | null>;
504
+ /**
505
+ * List uploaded files (newest first), with optional filters.
506
+ *
507
+ * @param options Filters and pagination.
508
+ */
509
+ list(options?: {
510
+ page?: number;
511
+ perPage?: number;
512
+ collectionName?: string;
513
+ fieldName?: string;
514
+ mime?: string;
515
+ }): Promise<{
516
+ items: FileRecord[];
517
+ page: number;
518
+ perPage: number;
519
+ total: number;
520
+ }>;
521
+ /**
522
+ * Fetch file metadata including URL.
523
+ * @param fileId The file ID.
524
+ */
438
525
  /**
439
526
  * Fetch file metadata including URL.
440
527
  * @param fileId The file ID.
@@ -670,6 +757,27 @@ declare class LazypockClient {
670
757
  generateTypes(options?: {
671
758
  packageName?: string;
672
759
  }): string;
760
+ /**
761
+ * Globally enable or disable auto-cancellation of duplicated pending requests.
762
+ *
763
+ * When enabled (default), a new request whose `requestKey` (default
764
+ * `HTTP_METHOD + path`) matches a still-pending request aborts the previous
765
+ * one — only the last duplicate executes.
766
+ *
767
+ * @example
768
+ * ```ts
769
+ * client.autoCancellation(false); // keep every request
770
+ * ```
771
+ */
772
+ autoCancellation(enable: boolean): this;
773
+ /**
774
+ * Abort a single pending request by its cancellation key
775
+ * (default `HTTP_METHOD + path`, e.g. `"GET /api/posts?page=1"`).
776
+ * The request rejects with an `ApiError` whose `isAbort` is `true`.
777
+ */
778
+ cancelRequest(requestKey: string): this;
779
+ /** Abort all pending requests. */
780
+ cancelAllRequests(): this;
673
781
  /** Check whether any superuser exists (for login vs setup screen routing). */
674
782
  checkSuperuser(): Promise<{
675
783
  has_superuser: boolean;
@@ -698,7 +806,11 @@ declare class LazypockClient {
698
806
  login(email: string, password: string, collection?: string): Promise<({
699
807
  token: string;
700
808
  } & Record<string, unknown>) | null>;
701
- /** Fetch the current superuser profile and refresh the auth model. */
809
+ /**
810
+ * Fetch the current authenticated identity (superuser OR auth collection user).
811
+ * Uses `GET /api/me` (PocketBase parity) — works with both superuser tokens
812
+ * and auth collection user tokens.
813
+ */
702
814
  me<T = ApiRecord>(options?: RequestOptions): Promise<T | null>;
703
815
  /**
704
816
  * Authenticate against an auth collection with email/password.
@@ -758,4 +870,4 @@ declare class TypedClient<TCollections extends LazypockCollections = LazypockCol
758
870
  */
759
871
  declare function createClient<TCollections extends LazypockCollections = LazypockCollections>(options: LazypockClientOptions): TypedClient<TCollections>;
760
872
 
761
- export { ApiError, type ApiRecord, type AuthModel, AuthStore, type CollectionSchema, CollectionService, type CollectionsMessage, CollectionsService, 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 };
873
+ export { ApiError, type ApiRecord, type AuthModel, AuthStore, type CollectionSchema, CollectionService, type CollectionsMessage, CollectionsService, type CreateData, type FileRecord, FilesService, HttpClient, 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, getScaleUrl, getThumbUrl, schemaFieldType, wsUrlFromBaseUrl };