@zuzjs/flare 0.2.25 → 0.2.27

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
@@ -473,6 +473,98 @@ export function RoomMessages({ roomId }: { roomId: string }) {
473
473
  }
474
474
  ```
475
475
 
476
+ #### React Storage Queue Hook (Start/Pause)
477
+
478
+ ```tsx
479
+ import { useMemo } from 'react';
480
+ import { connectApp } from '@zuzjs/flare';
481
+ import { useStorage, Status } from '@zuzjs/flare/react';
482
+
483
+ const app = connectApp({
484
+ endpoint: 'http://localhost:8080',
485
+ appId: 'my-app',
486
+ });
487
+
488
+ export function StorageUploader() {
489
+ const storage = useMemo(() => app.storage(), []);
490
+
491
+ const upload = useStorage(storage, {
492
+ onItemComplete: (item, result) => {
493
+ console.log('uploaded', item.objectKey, result.url);
494
+ },
495
+ onItemError: (item, err) => {
496
+ console.error('upload failed', item.objectKey, err.message);
497
+ },
498
+ });
499
+
500
+ const onSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
501
+ const files = Array.from(event.target.files ?? []);
502
+ if (!files.length) return;
503
+
504
+ upload.addToQueue(
505
+ files.map((file) => ({
506
+ file,
507
+ bucket: 'attachments',
508
+ key: `uploads/${Date.now()}-${file.name}`,
509
+ contentType: file.type || 'application/octet-stream',
510
+ access: 'public',
511
+ })),
512
+ );
513
+ };
514
+
515
+ return (
516
+ <div>
517
+ <input type='file' multiple onChange={onSelect} />
518
+
519
+ <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>
520
+ <button onClick={() => void upload.start()} disabled={!upload.hasPending || upload.running}>
521
+ Start
522
+ </button>
523
+ <button onClick={upload.pause} disabled={!upload.running}>
524
+ Pause
525
+ </button>
526
+ </div>
527
+
528
+ <ul>
529
+ {upload.que.map((item) => (
530
+ <li key={item.id}>
531
+ {item.objectKey} - {item.progress}% - {Status[item.status]}
532
+ </li>
533
+ ))}
534
+ </ul>
535
+ </div>
536
+ );
537
+ }
538
+ ```
539
+
540
+ `addToQueue(...)` auto-starts uploads by default.
541
+
542
+ Manual mode example (only upload when `start()` is clicked):
543
+
544
+ ```tsx
545
+ const upload = useStorage(storage, {
546
+ autoStartOnAdd: false,
547
+ });
548
+
549
+ upload.addToQueue([
550
+ {
551
+ file,
552
+ bucket: 'attachments',
553
+ key: `uploads/${Date.now()}-${file.name}`,
554
+ },
555
+ ]);
556
+
557
+ await upload.start();
558
+ ```
559
+
560
+ Notes:
561
+
562
+ - Queue items expose `item.objectKey` (not `item.key`) to avoid React prop-name conflicts.
563
+ - `addToQueue(...)` input still uses `key` because it maps directly to `putObject({ key })`.
564
+ - `addToQueue(...)` starts processing immediately unless `autoStartOnAdd: false` or the queue is paused.
565
+ - `pause()` stops scheduling new uploads; it does not cancel an already in-flight request.
566
+ - Call `start()` again to continue with remaining queued items.
567
+
476
568
  #### Next.js Example (Client Component)
477
569
 
478
570
  ```tsx
package/dist/grpc.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { F as FlareConfig, aR as StructuredQuery } from './index-18tMqAtM.cjs';
1
+ import { F as FlareConfig, aR as StructuredQuery } from './index-J1xVXysN.cjs';
2
2
  import '@zuzjs/auth';
3
3
 
4
4
  declare function runGrpcQuery<T = Record<string, unknown>>(config: FlareConfig, collection: string, query: StructuredQuery): Promise<T[] | null>;
package/dist/grpc.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { F as FlareConfig, aR as StructuredQuery } from './index-18tMqAtM.js';
1
+ import { F as FlareConfig, aR as StructuredQuery } from './index-J1xVXysN.js';
2
2
  import '@zuzjs/auth';
3
3
 
4
4
  declare function runGrpcQuery<T = Record<string, unknown>>(config: FlareConfig, collection: string, query: StructuredQuery): Promise<T[] | null>;
@@ -1,4 +1,4 @@
1
- import { b0 as WhereCondition, aT as SubscriptionCallback, aw as QueryConfig, J as DocUpdatedCallback, I as DocDeletedCallback, H as DocChangedCallback, ay as QueryPresetMap, az as QueryPresetParams, aA as QueryPresetRow, a as AggregateSpec, ae as HavingClause, ah as JoinClause, a_ as VectorSearchClause, aR as StructuredQuery, aX as SubscriptionHandle, u as CollectionStreamOptions, r as CollectionStream, q as CollectionExternalStore, G as DocAddedCallback, m as BulkWriteOptions, o as BulkWriteResult, aY as UpdateManyItem, F as FlareConfig, aS as SubscribeOptions, aW as SubscriptionErrorCallback, aV as SubscriptionError, v as ConnectionState, ap as PresenceCallback, aq as PresenceJoinCallback, ar as PresenceLeaveCallback, aZ as VectorFieldConfig, aB as QueryPresetSpec, a8 as FlareStorageTransferManagerConfig, aN as StorageProgress, aL as StorageBucketInput, aK as StorageBucket, k as BucketPolicyInput, a1 as FlareStorageRulesPolicy, j as BucketCorsRule, a0 as FlareStorageRulesHistoryResult, au as PutObjectInput, av as PutObjectResult, aa as GetObjectInput, ab as GetObjectResult, ac as GetObjectUrlInput, L as DownloadObjectInput, M as DownloadObjectResult, af as HeadObjectInput, aM as StorageObjectMeta, ag as HeadObjectsInput, aj as ListObjectsInput, ak as ListObjectsResult, w as CopyObjectInput, z as DeleteObjectInput, E as DeleteObjectsInput, aO as StorageSignedUrlInput, a7 as FlareStorageSignedUrlResult, P as FlareAuthConfig, f as AuthStateListener, d as AuthConfigListener, U as FlareAuthSession, V as FlareAuthUser, Q as FlareAuthHydrationInput, R as FlareAuthHydrationOptions, i as BrowserPushTokenOptions, B as BrowserPushRegistrationOptions, aD as RegisterPushTokenInput, aI as SendPushNotificationInput, at as PushSendResult, e as AuthResult } from './index-18tMqAtM.cjs';
1
+ import { b0 as WhereCondition, aT as SubscriptionCallback, aw as QueryConfig, J as DocUpdatedCallback, I as DocDeletedCallback, H as DocChangedCallback, ay as QueryPresetMap, az as QueryPresetParams, aA as QueryPresetRow, a as AggregateSpec, ae as HavingClause, ah as JoinClause, a_ as VectorSearchClause, aR as StructuredQuery, aX as SubscriptionHandle, u as CollectionStreamOptions, r as CollectionStream, q as CollectionExternalStore, G as DocAddedCallback, m as BulkWriteOptions, o as BulkWriteResult, aY as UpdateManyItem, F as FlareConfig, aS as SubscribeOptions, aW as SubscriptionErrorCallback, aV as SubscriptionError, v as ConnectionState, ap as PresenceCallback, aq as PresenceJoinCallback, ar as PresenceLeaveCallback, aZ as VectorFieldConfig, aB as QueryPresetSpec, a8 as FlareStorageTransferManagerConfig, aN as StorageProgress, aL as StorageBucketInput, aK as StorageBucket, k as BucketPolicyInput, a1 as FlareStorageRulesPolicy, j as BucketCorsRule, a0 as FlareStorageRulesHistoryResult, au as PutObjectInput, av as PutObjectResult, aa as GetObjectInput, ab as GetObjectResult, ac as GetObjectUrlInput, L as DownloadObjectInput, M as DownloadObjectResult, af as HeadObjectInput, aM as StorageObjectMeta, ag as HeadObjectsInput, aj as ListObjectsInput, ak as ListObjectsResult, w as CopyObjectInput, z as DeleteObjectInput, E as DeleteObjectsInput, aO as StorageSignedUrlInput, a7 as FlareStorageSignedUrlResult, P as FlareAuthConfig, f as AuthStateListener, d as AuthConfigListener, U as FlareAuthSession, V as FlareAuthUser, Q as FlareAuthHydrationInput, R as FlareAuthHydrationOptions, i as BrowserPushTokenOptions, B as BrowserPushRegistrationOptions, aD as RegisterPushTokenInput, aI as SendPushNotificationInput, at as PushSendResult, e as AuthResult } from './index-J1xVXysN.cjs';
2
2
  import { AuthGuard, AuthToken, ProviderId } from '@zuzjs/auth';
3
3
 
4
4
  /**
@@ -554,6 +554,7 @@ declare class FlareBase<TPresetMap extends QueryPresetMap = {}> {
554
554
 
555
555
  interface FlareStorageTransport {
556
556
  readonly appId: string;
557
+ readonly storageRulesHomeBucket?: string;
557
558
  readonly transferManager?: FlareStorageTransferManagerConfig;
558
559
  call(topic: string, payload?: Record<string, unknown>): Promise<Record<string, unknown>>;
559
560
  subscribe(subId: string, collection: string, docId: string | undefined, query: unknown, callback: (event: any) => void, options?: {
@@ -582,6 +583,10 @@ declare class FlareStorage {
582
583
  constructor(transport: FlareStorageTransport);
583
584
  private _scheduleUpload;
584
585
  private _scheduleDownload;
586
+ private _normalizeBucketName;
587
+ private _storageHomeBucket;
588
+ private _resolveStorageBucketName;
589
+ private _storageObjectPath;
585
590
  private _ensureBuckets;
586
591
  private _loadBuckets;
587
592
  private _invalidateBucketCache;
@@ -1,4 +1,4 @@
1
- import { b0 as WhereCondition, aT as SubscriptionCallback, aw as QueryConfig, J as DocUpdatedCallback, I as DocDeletedCallback, H as DocChangedCallback, ay as QueryPresetMap, az as QueryPresetParams, aA as QueryPresetRow, a as AggregateSpec, ae as HavingClause, ah as JoinClause, a_ as VectorSearchClause, aR as StructuredQuery, aX as SubscriptionHandle, u as CollectionStreamOptions, r as CollectionStream, q as CollectionExternalStore, G as DocAddedCallback, m as BulkWriteOptions, o as BulkWriteResult, aY as UpdateManyItem, F as FlareConfig, aS as SubscribeOptions, aW as SubscriptionErrorCallback, aV as SubscriptionError, v as ConnectionState, ap as PresenceCallback, aq as PresenceJoinCallback, ar as PresenceLeaveCallback, aZ as VectorFieldConfig, aB as QueryPresetSpec, a8 as FlareStorageTransferManagerConfig, aN as StorageProgress, aL as StorageBucketInput, aK as StorageBucket, k as BucketPolicyInput, a1 as FlareStorageRulesPolicy, j as BucketCorsRule, a0 as FlareStorageRulesHistoryResult, au as PutObjectInput, av as PutObjectResult, aa as GetObjectInput, ab as GetObjectResult, ac as GetObjectUrlInput, L as DownloadObjectInput, M as DownloadObjectResult, af as HeadObjectInput, aM as StorageObjectMeta, ag as HeadObjectsInput, aj as ListObjectsInput, ak as ListObjectsResult, w as CopyObjectInput, z as DeleteObjectInput, E as DeleteObjectsInput, aO as StorageSignedUrlInput, a7 as FlareStorageSignedUrlResult, P as FlareAuthConfig, f as AuthStateListener, d as AuthConfigListener, U as FlareAuthSession, V as FlareAuthUser, Q as FlareAuthHydrationInput, R as FlareAuthHydrationOptions, i as BrowserPushTokenOptions, B as BrowserPushRegistrationOptions, aD as RegisterPushTokenInput, aI as SendPushNotificationInput, at as PushSendResult, e as AuthResult } from './index-18tMqAtM.js';
1
+ import { b0 as WhereCondition, aT as SubscriptionCallback, aw as QueryConfig, J as DocUpdatedCallback, I as DocDeletedCallback, H as DocChangedCallback, ay as QueryPresetMap, az as QueryPresetParams, aA as QueryPresetRow, a as AggregateSpec, ae as HavingClause, ah as JoinClause, a_ as VectorSearchClause, aR as StructuredQuery, aX as SubscriptionHandle, u as CollectionStreamOptions, r as CollectionStream, q as CollectionExternalStore, G as DocAddedCallback, m as BulkWriteOptions, o as BulkWriteResult, aY as UpdateManyItem, F as FlareConfig, aS as SubscribeOptions, aW as SubscriptionErrorCallback, aV as SubscriptionError, v as ConnectionState, ap as PresenceCallback, aq as PresenceJoinCallback, ar as PresenceLeaveCallback, aZ as VectorFieldConfig, aB as QueryPresetSpec, a8 as FlareStorageTransferManagerConfig, aN as StorageProgress, aL as StorageBucketInput, aK as StorageBucket, k as BucketPolicyInput, a1 as FlareStorageRulesPolicy, j as BucketCorsRule, a0 as FlareStorageRulesHistoryResult, au as PutObjectInput, av as PutObjectResult, aa as GetObjectInput, ab as GetObjectResult, ac as GetObjectUrlInput, L as DownloadObjectInput, M as DownloadObjectResult, af as HeadObjectInput, aM as StorageObjectMeta, ag as HeadObjectsInput, aj as ListObjectsInput, ak as ListObjectsResult, w as CopyObjectInput, z as DeleteObjectInput, E as DeleteObjectsInput, aO as StorageSignedUrlInput, a7 as FlareStorageSignedUrlResult, P as FlareAuthConfig, f as AuthStateListener, d as AuthConfigListener, U as FlareAuthSession, V as FlareAuthUser, Q as FlareAuthHydrationInput, R as FlareAuthHydrationOptions, i as BrowserPushTokenOptions, B as BrowserPushRegistrationOptions, aD as RegisterPushTokenInput, aI as SendPushNotificationInput, at as PushSendResult, e as AuthResult } from './index-J1xVXysN.js';
2
2
  import { AuthGuard, AuthToken, ProviderId } from '@zuzjs/auth';
3
3
 
4
4
  /**
@@ -554,6 +554,7 @@ declare class FlareBase<TPresetMap extends QueryPresetMap = {}> {
554
554
 
555
555
  interface FlareStorageTransport {
556
556
  readonly appId: string;
557
+ readonly storageRulesHomeBucket?: string;
557
558
  readonly transferManager?: FlareStorageTransferManagerConfig;
558
559
  call(topic: string, payload?: Record<string, unknown>): Promise<Record<string, unknown>>;
559
560
  subscribe(subId: string, collection: string, docId: string | undefined, query: unknown, callback: (event: any) => void, options?: {
@@ -582,6 +583,10 @@ declare class FlareStorage {
582
583
  constructor(transport: FlareStorageTransport);
583
584
  private _scheduleUpload;
584
585
  private _scheduleDownload;
586
+ private _normalizeBucketName;
587
+ private _storageHomeBucket;
588
+ private _resolveStorageBucketName;
589
+ private _storageObjectPath;
585
590
  private _ensureBuckets;
586
591
  private _loadBuckets;
587
592
  private _invalidateBucketCache;
@@ -110,6 +110,7 @@ interface FlareAuthConfig {
110
110
  needsEmailVerification?: boolean;
111
111
  autoSendVerificationEmail?: boolean;
112
112
  redirectUri?: string;
113
+ storageRulesHomeBucket?: string | null;
113
114
  csrfToken?: string;
114
115
  cookie?: {
115
116
  accessTokenName?: string;
@@ -419,6 +420,9 @@ interface PutObjectResult {
419
420
  bucket: string;
420
421
  key: string;
421
422
  access: "public" | "private";
423
+ /** Alias of contentType for compatibility with legacy callers. */
424
+ type?: string;
425
+ contentType?: string;
422
426
  url?: string;
423
427
  size: number;
424
428
  encrypted: boolean;
@@ -110,6 +110,7 @@ interface FlareAuthConfig {
110
110
  needsEmailVerification?: boolean;
111
111
  autoSendVerificationEmail?: boolean;
112
112
  redirectUri?: string;
113
+ storageRulesHomeBucket?: string | null;
113
114
  csrfToken?: string;
114
115
  cookie?: {
115
116
  accessTokenName?: string;
@@ -419,6 +420,9 @@ interface PutObjectResult {
419
420
  bucket: string;
420
421
  key: string;
421
422
  access: "public" | "private";
423
+ /** Alias of contentType for compatibility with legacy callers. */
424
+ type?: string;
425
+ contentType?: string;
422
426
  url?: string;
423
427
  size: number;
424
428
  encrypted: boolean;