@plugable-io/react 0.0.3 → 0.0.4

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.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React, { ReactNode, CSSProperties } from 'react';
3
- import { BucketClient, FileObject } from '@plugable-io/js';
3
+ import { BucketClient, FileObject, ListResponse } from '@plugable-io/js';
4
4
  export { FileObject, SearchOptions, UpdateOptions } from '@plugable-io/js';
5
5
 
6
6
  type AuthProvider = 'clerk' | 'supabase' | 'firebase';
@@ -11,9 +11,15 @@ interface PlugableProviderProps {
11
11
  authProvider?: AuthProvider;
12
12
  clerkJWTTemplate?: string;
13
13
  baseUrl?: string;
14
+ staleTime?: number;
14
15
  }
15
16
  type PlugableEventType = 'file.uploaded' | 'file.deleted';
16
17
  type EventHandler = (data?: any) => void;
18
+ interface CacheEntry {
19
+ files: FileObject[];
20
+ paging: ListResponse['paging'];
21
+ timestamp: number;
22
+ }
17
23
  interface PlugableContextValue {
18
24
  client: BucketClient;
19
25
  bucketId: string;
@@ -21,8 +27,12 @@ interface PlugableContextValue {
21
27
  emit: (event: PlugableEventType, data?: any) => void;
22
28
  getToken: () => Promise<string> | string;
23
29
  baseUrl?: string;
30
+ staleTime: number;
31
+ getCache: (key: string) => CacheEntry | undefined;
32
+ setCache: (key: string, entry: CacheEntry) => void;
33
+ invalidateCache: (pattern?: string) => void;
24
34
  }
25
- declare function PlugableProvider({ bucketId, children, getToken, authProvider, clerkJWTTemplate, baseUrl, }: PlugableProviderProps): react_jsx_runtime.JSX.Element;
35
+ declare function PlugableProvider({ bucketId, children, getToken, authProvider, clerkJWTTemplate, baseUrl, staleTime, }: PlugableProviderProps): react_jsx_runtime.JSX.Element;
26
36
  declare function usePlugable(): PlugableContextValue;
27
37
 
28
38
  interface DropzoneProps {
@@ -106,6 +116,7 @@ interface UseFilesOptions {
106
116
  autoLoad?: boolean;
107
117
  orderBy?: 'created_at' | 'name' | 'byte_size';
108
118
  orderDirection?: 'asc' | 'desc';
119
+ staleTime?: number;
109
120
  }
110
121
  interface UseFilesResult {
111
122
  files: FileObject[];
@@ -120,6 +131,6 @@ interface UseFilesResult {
120
131
  setPage: (page: number) => void;
121
132
  refresh: () => Promise<void>;
122
133
  }
123
- declare function useFiles({ metadata, startPage, perPage, mediaType, autoLoad, orderBy, orderDirection, }?: UseFilesOptions): UseFilesResult;
134
+ declare function useFiles({ metadata, startPage, perPage, mediaType, autoLoad, orderBy, orderDirection, staleTime, }?: UseFilesOptions): UseFilesResult;
124
135
 
125
136
  export { type AuthProvider, Dropzone, type DropzoneProps, type DropzoneRenderProps, FileImage, type FileImageProps, FileList, type FileListProps, type FileListRenderProps, FilePreview, type FilePreviewProps, PlugableProvider, type PlugableProviderProps, type UseFilesOptions, type UseFilesResult, clearImageCache, useFiles, usePlugable };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React, { ReactNode, CSSProperties } from 'react';
3
- import { BucketClient, FileObject } from '@plugable-io/js';
3
+ import { BucketClient, FileObject, ListResponse } from '@plugable-io/js';
4
4
  export { FileObject, SearchOptions, UpdateOptions } from '@plugable-io/js';
5
5
 
6
6
  type AuthProvider = 'clerk' | 'supabase' | 'firebase';
@@ -11,9 +11,15 @@ interface PlugableProviderProps {
11
11
  authProvider?: AuthProvider;
12
12
  clerkJWTTemplate?: string;
13
13
  baseUrl?: string;
14
+ staleTime?: number;
14
15
  }
15
16
  type PlugableEventType = 'file.uploaded' | 'file.deleted';
16
17
  type EventHandler = (data?: any) => void;
18
+ interface CacheEntry {
19
+ files: FileObject[];
20
+ paging: ListResponse['paging'];
21
+ timestamp: number;
22
+ }
17
23
  interface PlugableContextValue {
18
24
  client: BucketClient;
19
25
  bucketId: string;
@@ -21,8 +27,12 @@ interface PlugableContextValue {
21
27
  emit: (event: PlugableEventType, data?: any) => void;
22
28
  getToken: () => Promise<string> | string;
23
29
  baseUrl?: string;
30
+ staleTime: number;
31
+ getCache: (key: string) => CacheEntry | undefined;
32
+ setCache: (key: string, entry: CacheEntry) => void;
33
+ invalidateCache: (pattern?: string) => void;
24
34
  }
25
- declare function PlugableProvider({ bucketId, children, getToken, authProvider, clerkJWTTemplate, baseUrl, }: PlugableProviderProps): react_jsx_runtime.JSX.Element;
35
+ declare function PlugableProvider({ bucketId, children, getToken, authProvider, clerkJWTTemplate, baseUrl, staleTime, }: PlugableProviderProps): react_jsx_runtime.JSX.Element;
26
36
  declare function usePlugable(): PlugableContextValue;
27
37
 
28
38
  interface DropzoneProps {
@@ -106,6 +116,7 @@ interface UseFilesOptions {
106
116
  autoLoad?: boolean;
107
117
  orderBy?: 'created_at' | 'name' | 'byte_size';
108
118
  orderDirection?: 'asc' | 'desc';
119
+ staleTime?: number;
109
120
  }
110
121
  interface UseFilesResult {
111
122
  files: FileObject[];
@@ -120,6 +131,6 @@ interface UseFilesResult {
120
131
  setPage: (page: number) => void;
121
132
  refresh: () => Promise<void>;
122
133
  }
123
- declare function useFiles({ metadata, startPage, perPage, mediaType, autoLoad, orderBy, orderDirection, }?: UseFilesOptions): UseFilesResult;
134
+ declare function useFiles({ metadata, startPage, perPage, mediaType, autoLoad, orderBy, orderDirection, staleTime, }?: UseFilesOptions): UseFilesResult;
124
135
 
125
136
  export { type AuthProvider, Dropzone, type DropzoneProps, type DropzoneRenderProps, FileImage, type FileImageProps, FileList, type FileListProps, type FileListRenderProps, FilePreview, type FilePreviewProps, PlugableProvider, type PlugableProviderProps, type UseFilesOptions, type UseFilesResult, clearImageCache, useFiles, usePlugable };
package/dist/index.js CHANGED
@@ -100,9 +100,12 @@ function PlugableProvider({
100
100
  getToken,
101
101
  authProvider,
102
102
  clerkJWTTemplate,
103
- baseUrl
103
+ baseUrl,
104
+ staleTime = 5 * 60 * 1e3
105
+ // Default 5 minutes
104
106
  }) {
105
107
  const listenersRef = (0, import_react.useRef)({});
108
+ const [cache, setCacheState] = (0, import_react.useState)(/* @__PURE__ */ new Map());
106
109
  const client = (0, import_react.useMemo)(() => {
107
110
  if (!getToken && !authProvider) {
108
111
  throw new Error(
@@ -128,6 +131,34 @@ function PlugableProvider({
128
131
  }, []);
129
132
  const emit = (0, import_react.useCallback)((event, data) => {
130
133
  listenersRef.current[event]?.forEach((handler) => handler(data));
134
+ if (event === "file.uploaded" || event === "file.deleted") {
135
+ setCacheState(/* @__PURE__ */ new Map());
136
+ }
137
+ }, []);
138
+ const getCache = (0, import_react.useCallback)((key) => {
139
+ return cache.get(key);
140
+ }, [cache]);
141
+ const setCache = (0, import_react.useCallback)((key, entry) => {
142
+ setCacheState((prev) => {
143
+ const next = new Map(prev);
144
+ next.set(key, entry);
145
+ return next;
146
+ });
147
+ }, []);
148
+ const invalidateCache = (0, import_react.useCallback)((pattern) => {
149
+ if (!pattern) {
150
+ setCacheState(/* @__PURE__ */ new Map());
151
+ return;
152
+ }
153
+ setCacheState((prev) => {
154
+ const next = new Map(prev);
155
+ for (const key of prev.keys()) {
156
+ if (key.includes(pattern)) {
157
+ next.delete(key);
158
+ }
159
+ }
160
+ return next;
161
+ });
131
162
  }, []);
132
163
  const value = (0, import_react.useMemo)(
133
164
  () => ({
@@ -136,9 +167,13 @@ function PlugableProvider({
136
167
  on,
137
168
  emit,
138
169
  getToken: client.tokenGetter,
139
- baseUrl
170
+ baseUrl,
171
+ staleTime,
172
+ getCache,
173
+ setCache,
174
+ invalidateCache
140
175
  }),
141
- [client, bucketId, on, emit, baseUrl]
176
+ [client, bucketId, on, emit, baseUrl, staleTime, getCache, setCache, invalidateCache]
142
177
  );
143
178
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlugableContext.Provider, { value, children });
144
179
  }
@@ -371,16 +406,17 @@ function useFiles({
371
406
  mediaType,
372
407
  autoLoad = true,
373
408
  orderBy,
374
- orderDirection
409
+ orderDirection,
410
+ staleTime
375
411
  } = {}) {
376
- const { client, on } = usePlugable();
412
+ const { client, on, getCache, setCache, staleTime: providerStaleTime } = usePlugable();
377
413
  const [files, setFiles] = (0, import_react3.useState)([]);
378
414
  const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
379
415
  const [page, setPage] = (0, import_react3.useState)(startPage);
380
416
  const [hasNext, setHasNext] = (0, import_react3.useState)(false);
417
+ const effectiveStaleTime = staleTime ?? providerStaleTime;
381
418
  const metadataKey = JSON.stringify(metadata);
382
419
  const stableMetadata = (0, import_react3.useMemo)(() => metadata, [metadataKey]);
383
- const loadedParamsRef = (0, import_react3.useRef)(null);
384
420
  const paramsKeyWithPage = (0, import_react3.useMemo)(() => JSON.stringify({
385
421
  metadata: stableMetadata,
386
422
  mediaType,
@@ -389,7 +425,27 @@ function useFiles({
389
425
  orderDirection,
390
426
  page
391
427
  }), [stableMetadata, mediaType, perPage, orderBy, orderDirection, page]);
392
- const fetchFiles = (0, import_react3.useCallback)(async (pageNum) => {
428
+ const fetchFiles = (0, import_react3.useCallback)(async (pageNum, skipCache = false) => {
429
+ if (!skipCache) {
430
+ const cacheKey = JSON.stringify({
431
+ metadata: stableMetadata,
432
+ mediaType,
433
+ perPage,
434
+ orderBy,
435
+ orderDirection,
436
+ page: pageNum
437
+ });
438
+ const cachedEntry = getCache(cacheKey);
439
+ if (cachedEntry) {
440
+ const age = Date.now() - cachedEntry.timestamp;
441
+ const isStale = age > effectiveStaleTime;
442
+ if (!isStale) {
443
+ setFiles(cachedEntry.files);
444
+ setHasNext(cachedEntry.paging.has_next_page);
445
+ return;
446
+ }
447
+ }
448
+ }
393
449
  setIsLoading(true);
394
450
  try {
395
451
  const options = {
@@ -398,13 +454,11 @@ function useFiles({
398
454
  page: pageNum,
399
455
  per_page: perPage,
400
456
  with_download_url: true,
401
- order_by: orderBy,
402
- order_direction: orderDirection
457
+ ...orderBy && { order_by: orderBy },
458
+ ...orderDirection && { order_direction: orderDirection }
403
459
  };
404
460
  const response = await client.list(options);
405
- setFiles(response.files);
406
- setHasNext(response.paging.has_next_page);
407
- const currentParamsKey = JSON.stringify({
461
+ const cacheKey = JSON.stringify({
408
462
  metadata: stableMetadata,
409
463
  mediaType,
410
464
  perPage,
@@ -412,7 +466,13 @@ function useFiles({
412
466
  orderDirection,
413
467
  page: pageNum
414
468
  });
415
- loadedParamsRef.current = currentParamsKey;
469
+ setCache(cacheKey, {
470
+ files: response.files,
471
+ paging: response.paging,
472
+ timestamp: Date.now()
473
+ });
474
+ setFiles(response.files);
475
+ setHasNext(response.paging.has_next_page);
416
476
  } catch (err) {
417
477
  console.error("Failed to load files:", err);
418
478
  setFiles([]);
@@ -420,17 +480,24 @@ function useFiles({
420
480
  } finally {
421
481
  setIsLoading(false);
422
482
  }
423
- }, [client, stableMetadata, mediaType, perPage, orderBy, orderDirection]);
483
+ }, [client, stableMetadata, mediaType, perPage, orderBy, orderDirection, getCache, setCache, effectiveStaleTime]);
424
484
  (0, import_react3.useEffect)(() => {
425
- const hasLoadedForParams = loadedParamsRef.current === paramsKeyWithPage;
426
- const shouldLoad = autoLoad || !hasLoadedForParams && files.length === 0 && !isLoading;
427
- if (shouldLoad) {
428
- fetchFiles(page);
485
+ const cachedEntry = getCache(paramsKeyWithPage);
486
+ if (cachedEntry) {
487
+ const age = Date.now() - cachedEntry.timestamp;
488
+ const isStale = age > effectiveStaleTime;
489
+ setFiles(cachedEntry.files);
490
+ setHasNext(cachedEntry.paging.has_next_page);
491
+ if (isStale && autoLoad) {
492
+ fetchFiles(page, true);
493
+ }
494
+ } else if (autoLoad) {
495
+ fetchFiles(page, true);
429
496
  }
430
- }, [fetchFiles, page, autoLoad, paramsKeyWithPage, isLoading]);
497
+ }, [paramsKeyWithPage, autoLoad, getCache, effectiveStaleTime, fetchFiles, page]);
431
498
  (0, import_react3.useEffect)(() => {
432
499
  const unsubscribe = on("file.uploaded", () => {
433
- fetchFiles(page);
500
+ fetchFiles(page, true);
434
501
  });
435
502
  return unsubscribe;
436
503
  }, [on, fetchFiles, page]);
@@ -443,7 +510,7 @@ function useFiles({
443
510
  setPage((p) => Math.max(1, p - 1));
444
511
  }, []);
445
512
  const refresh = (0, import_react3.useCallback)(async () => {
446
- await fetchFiles(page);
513
+ await fetchFiles(page, true);
447
514
  }, [fetchFiles, page]);
448
515
  return {
449
516
  files,
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/PlugableProvider.tsx
2
- import { createContext, useContext, useMemo, useCallback, useRef } from "react";
2
+ import { createContext, useContext, useMemo, useCallback, useRef, useState } from "react";
3
3
  import { BucketClient } from "@plugable-io/js";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  var PlugableContext = createContext(null);
@@ -57,9 +57,12 @@ function PlugableProvider({
57
57
  getToken,
58
58
  authProvider,
59
59
  clerkJWTTemplate,
60
- baseUrl
60
+ baseUrl,
61
+ staleTime = 5 * 60 * 1e3
62
+ // Default 5 minutes
61
63
  }) {
62
64
  const listenersRef = useRef({});
65
+ const [cache, setCacheState] = useState(/* @__PURE__ */ new Map());
63
66
  const client = useMemo(() => {
64
67
  if (!getToken && !authProvider) {
65
68
  throw new Error(
@@ -85,6 +88,34 @@ function PlugableProvider({
85
88
  }, []);
86
89
  const emit = useCallback((event, data) => {
87
90
  listenersRef.current[event]?.forEach((handler) => handler(data));
91
+ if (event === "file.uploaded" || event === "file.deleted") {
92
+ setCacheState(/* @__PURE__ */ new Map());
93
+ }
94
+ }, []);
95
+ const getCache = useCallback((key) => {
96
+ return cache.get(key);
97
+ }, [cache]);
98
+ const setCache = useCallback((key, entry) => {
99
+ setCacheState((prev) => {
100
+ const next = new Map(prev);
101
+ next.set(key, entry);
102
+ return next;
103
+ });
104
+ }, []);
105
+ const invalidateCache = useCallback((pattern) => {
106
+ if (!pattern) {
107
+ setCacheState(/* @__PURE__ */ new Map());
108
+ return;
109
+ }
110
+ setCacheState((prev) => {
111
+ const next = new Map(prev);
112
+ for (const key of prev.keys()) {
113
+ if (key.includes(pattern)) {
114
+ next.delete(key);
115
+ }
116
+ }
117
+ return next;
118
+ });
88
119
  }, []);
89
120
  const value = useMemo(
90
121
  () => ({
@@ -93,9 +124,13 @@ function PlugableProvider({
93
124
  on,
94
125
  emit,
95
126
  getToken: client.tokenGetter,
96
- baseUrl
127
+ baseUrl,
128
+ staleTime,
129
+ getCache,
130
+ setCache,
131
+ invalidateCache
97
132
  }),
98
- [client, bucketId, on, emit, baseUrl]
133
+ [client, bucketId, on, emit, baseUrl, staleTime, getCache, setCache, invalidateCache]
99
134
  );
100
135
  return /* @__PURE__ */ jsx(PlugableContext.Provider, { value, children });
101
136
  }
@@ -108,7 +143,7 @@ function usePlugable() {
108
143
  }
109
144
 
110
145
  // src/components/Dropzone.tsx
111
- import React, { useCallback as useCallback2, useState } from "react";
146
+ import React, { useCallback as useCallback2, useState as useState2 } from "react";
112
147
  import { BucketClient as BucketClient2 } from "@plugable-io/js";
113
148
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
114
149
  function Dropzone({
@@ -134,10 +169,10 @@ function Dropzone({
134
169
  }
135
170
  return defaultClient;
136
171
  }, [_bucketId, defaultClient, getToken, baseUrl]);
137
- const [isDragActive, setIsDragActive] = useState(false);
138
- const [isUploading, setIsUploading] = useState(false);
139
- const [uploadProgress, setUploadProgress] = useState({});
140
- const [uploadedFiles, setUploadedFiles] = useState([]);
172
+ const [isDragActive, setIsDragActive] = useState2(false);
173
+ const [isUploading, setIsUploading] = useState2(false);
174
+ const [uploadProgress, setUploadProgress] = useState2({});
175
+ const [uploadedFiles, setUploadedFiles] = useState2([]);
141
176
  const fileInputRef = React.useRef(null);
142
177
  const uploadFiles = useCallback2(
143
178
  async (files) => {
@@ -320,7 +355,7 @@ function Dropzone({
320
355
  }
321
356
 
322
357
  // src/hooks/useFiles.ts
323
- import { useState as useState2, useCallback as useCallback3, useEffect, useMemo as useMemo2, useRef as useRef2 } from "react";
358
+ import { useState as useState3, useCallback as useCallback3, useEffect, useMemo as useMemo2 } from "react";
324
359
  function useFiles({
325
360
  metadata,
326
361
  startPage = 1,
@@ -328,16 +363,17 @@ function useFiles({
328
363
  mediaType,
329
364
  autoLoad = true,
330
365
  orderBy,
331
- orderDirection
366
+ orderDirection,
367
+ staleTime
332
368
  } = {}) {
333
- const { client, on } = usePlugable();
334
- const [files, setFiles] = useState2([]);
335
- const [isLoading, setIsLoading] = useState2(false);
336
- const [page, setPage] = useState2(startPage);
337
- const [hasNext, setHasNext] = useState2(false);
369
+ const { client, on, getCache, setCache, staleTime: providerStaleTime } = usePlugable();
370
+ const [files, setFiles] = useState3([]);
371
+ const [isLoading, setIsLoading] = useState3(false);
372
+ const [page, setPage] = useState3(startPage);
373
+ const [hasNext, setHasNext] = useState3(false);
374
+ const effectiveStaleTime = staleTime ?? providerStaleTime;
338
375
  const metadataKey = JSON.stringify(metadata);
339
376
  const stableMetadata = useMemo2(() => metadata, [metadataKey]);
340
- const loadedParamsRef = useRef2(null);
341
377
  const paramsKeyWithPage = useMemo2(() => JSON.stringify({
342
378
  metadata: stableMetadata,
343
379
  mediaType,
@@ -346,7 +382,27 @@ function useFiles({
346
382
  orderDirection,
347
383
  page
348
384
  }), [stableMetadata, mediaType, perPage, orderBy, orderDirection, page]);
349
- const fetchFiles = useCallback3(async (pageNum) => {
385
+ const fetchFiles = useCallback3(async (pageNum, skipCache = false) => {
386
+ if (!skipCache) {
387
+ const cacheKey = JSON.stringify({
388
+ metadata: stableMetadata,
389
+ mediaType,
390
+ perPage,
391
+ orderBy,
392
+ orderDirection,
393
+ page: pageNum
394
+ });
395
+ const cachedEntry = getCache(cacheKey);
396
+ if (cachedEntry) {
397
+ const age = Date.now() - cachedEntry.timestamp;
398
+ const isStale = age > effectiveStaleTime;
399
+ if (!isStale) {
400
+ setFiles(cachedEntry.files);
401
+ setHasNext(cachedEntry.paging.has_next_page);
402
+ return;
403
+ }
404
+ }
405
+ }
350
406
  setIsLoading(true);
351
407
  try {
352
408
  const options = {
@@ -355,13 +411,11 @@ function useFiles({
355
411
  page: pageNum,
356
412
  per_page: perPage,
357
413
  with_download_url: true,
358
- order_by: orderBy,
359
- order_direction: orderDirection
414
+ ...orderBy && { order_by: orderBy },
415
+ ...orderDirection && { order_direction: orderDirection }
360
416
  };
361
417
  const response = await client.list(options);
362
- setFiles(response.files);
363
- setHasNext(response.paging.has_next_page);
364
- const currentParamsKey = JSON.stringify({
418
+ const cacheKey = JSON.stringify({
365
419
  metadata: stableMetadata,
366
420
  mediaType,
367
421
  perPage,
@@ -369,7 +423,13 @@ function useFiles({
369
423
  orderDirection,
370
424
  page: pageNum
371
425
  });
372
- loadedParamsRef.current = currentParamsKey;
426
+ setCache(cacheKey, {
427
+ files: response.files,
428
+ paging: response.paging,
429
+ timestamp: Date.now()
430
+ });
431
+ setFiles(response.files);
432
+ setHasNext(response.paging.has_next_page);
373
433
  } catch (err) {
374
434
  console.error("Failed to load files:", err);
375
435
  setFiles([]);
@@ -377,17 +437,24 @@ function useFiles({
377
437
  } finally {
378
438
  setIsLoading(false);
379
439
  }
380
- }, [client, stableMetadata, mediaType, perPage, orderBy, orderDirection]);
440
+ }, [client, stableMetadata, mediaType, perPage, orderBy, orderDirection, getCache, setCache, effectiveStaleTime]);
381
441
  useEffect(() => {
382
- const hasLoadedForParams = loadedParamsRef.current === paramsKeyWithPage;
383
- const shouldLoad = autoLoad || !hasLoadedForParams && files.length === 0 && !isLoading;
384
- if (shouldLoad) {
385
- fetchFiles(page);
442
+ const cachedEntry = getCache(paramsKeyWithPage);
443
+ if (cachedEntry) {
444
+ const age = Date.now() - cachedEntry.timestamp;
445
+ const isStale = age > effectiveStaleTime;
446
+ setFiles(cachedEntry.files);
447
+ setHasNext(cachedEntry.paging.has_next_page);
448
+ if (isStale && autoLoad) {
449
+ fetchFiles(page, true);
450
+ }
451
+ } else if (autoLoad) {
452
+ fetchFiles(page, true);
386
453
  }
387
- }, [fetchFiles, page, autoLoad, paramsKeyWithPage, isLoading]);
454
+ }, [paramsKeyWithPage, autoLoad, getCache, effectiveStaleTime, fetchFiles, page]);
388
455
  useEffect(() => {
389
456
  const unsubscribe = on("file.uploaded", () => {
390
- fetchFiles(page);
457
+ fetchFiles(page, true);
391
458
  });
392
459
  return unsubscribe;
393
460
  }, [on, fetchFiles, page]);
@@ -400,7 +467,7 @@ function useFiles({
400
467
  setPage((p) => Math.max(1, p - 1));
401
468
  }, []);
402
469
  const refresh = useCallback3(async () => {
403
- await fetchFiles(page);
470
+ await fetchFiles(page, true);
404
471
  }, [fetchFiles, page]);
405
472
  return {
406
473
  files,
@@ -447,7 +514,7 @@ function FileList({
447
514
  }
448
515
 
449
516
  // src/components/FileImage.tsx
450
- import { useEffect as useEffect2, useState as useState3 } from "react";
517
+ import { useEffect as useEffect2, useState as useState4 } from "react";
451
518
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
452
519
  var imageCache = /* @__PURE__ */ new Map();
453
520
  function FileImage({
@@ -462,9 +529,9 @@ function FileImage({
462
529
  onLoad,
463
530
  onError
464
531
  }) {
465
- const [imageSrc, setImageSrc] = useState3(null);
466
- const [isLoading, setIsLoading] = useState3(true);
467
- const [error, setError] = useState3(null);
532
+ const [imageSrc, setImageSrc] = useState4(null);
533
+ const [isLoading, setIsLoading] = useState4(true);
534
+ const [error, setError] = useState4(null);
468
535
  useEffect2(() => {
469
536
  let isMounted = true;
470
537
  let objectUrl = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plugable-io/react",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "React components and hooks for Plugable File Management API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",