@cannyminds/dms-file-viewers 0.1.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.
Files changed (65) hide show
  1. package/dist/chunk-3STHCDAC.js +1402 -0
  2. package/dist/chunk-3STHCDAC.js.map +1 -0
  3. package/dist/chunk-4RL77HKO.js +196 -0
  4. package/dist/chunk-4RL77HKO.js.map +1 -0
  5. package/dist/chunk-73ZIFR3P.mjs +1402 -0
  6. package/dist/chunk-73ZIFR3P.mjs.map +1 -0
  7. package/dist/chunk-7JTIG6OU.js +177 -0
  8. package/dist/chunk-7JTIG6OU.js.map +1 -0
  9. package/dist/chunk-BNHQYEZ7.js +448 -0
  10. package/dist/chunk-BNHQYEZ7.js.map +1 -0
  11. package/dist/chunk-EMP7RZM2.js +159 -0
  12. package/dist/chunk-EMP7RZM2.js.map +1 -0
  13. package/dist/chunk-FZYMVHF6.mjs +159 -0
  14. package/dist/chunk-FZYMVHF6.mjs.map +1 -0
  15. package/dist/chunk-GNWU6XHH.js +288 -0
  16. package/dist/chunk-GNWU6XHH.js.map +1 -0
  17. package/dist/chunk-LKBM4O47.mjs +177 -0
  18. package/dist/chunk-LKBM4O47.mjs.map +1 -0
  19. package/dist/chunk-NOLXOOIP.mjs +448 -0
  20. package/dist/chunk-NOLXOOIP.mjs.map +1 -0
  21. package/dist/chunk-QLJKOQTP.mjs +78 -0
  22. package/dist/chunk-QLJKOQTP.mjs.map +1 -0
  23. package/dist/chunk-QQDQJ7TS.mjs +263 -0
  24. package/dist/chunk-QQDQJ7TS.mjs.map +1 -0
  25. package/dist/chunk-QRYIHDRT.mjs +196 -0
  26. package/dist/chunk-QRYIHDRT.mjs.map +1 -0
  27. package/dist/chunk-RE4XRGSV.js +263 -0
  28. package/dist/chunk-RE4XRGSV.js.map +1 -0
  29. package/dist/chunk-XQBXRMB7.mjs +288 -0
  30. package/dist/chunk-XQBXRMB7.mjs.map +1 -0
  31. package/dist/chunk-Z7FUO5RX.js +78 -0
  32. package/dist/chunk-Z7FUO5RX.js.map +1 -0
  33. package/dist/components/viewers/AudioViewer.js +9 -0
  34. package/dist/components/viewers/AudioViewer.js.map +1 -0
  35. package/dist/components/viewers/AudioViewer.mjs +9 -0
  36. package/dist/components/viewers/AudioViewer.mjs.map +1 -0
  37. package/dist/components/viewers/DefaultViewer.js +8 -0
  38. package/dist/components/viewers/DefaultViewer.js.map +1 -0
  39. package/dist/components/viewers/DefaultViewer.mjs +8 -0
  40. package/dist/components/viewers/DefaultViewer.mjs.map +1 -0
  41. package/dist/components/viewers/ImageViewer.js +10 -0
  42. package/dist/components/viewers/ImageViewer.js.map +1 -0
  43. package/dist/components/viewers/ImageViewer.mjs +10 -0
  44. package/dist/components/viewers/ImageViewer.mjs.map +1 -0
  45. package/dist/components/viewers/PDFViewer.js +9 -0
  46. package/dist/components/viewers/PDFViewer.js.map +1 -0
  47. package/dist/components/viewers/PDFViewer.mjs +9 -0
  48. package/dist/components/viewers/PDFViewer.mjs.map +1 -0
  49. package/dist/components/viewers/TIFFViewer.js +9 -0
  50. package/dist/components/viewers/TIFFViewer.js.map +1 -0
  51. package/dist/components/viewers/TIFFViewer.mjs +9 -0
  52. package/dist/components/viewers/TIFFViewer.mjs.map +1 -0
  53. package/dist/components/viewers/TextViewer.js +9 -0
  54. package/dist/components/viewers/TextViewer.js.map +1 -0
  55. package/dist/components/viewers/TextViewer.mjs +9 -0
  56. package/dist/components/viewers/TextViewer.mjs.map +1 -0
  57. package/dist/components/viewers/VideoViewer.js +9 -0
  58. package/dist/components/viewers/VideoViewer.js.map +1 -0
  59. package/dist/components/viewers/VideoViewer.mjs +9 -0
  60. package/dist/components/viewers/VideoViewer.mjs.map +1 -0
  61. package/dist/index.js +284 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/index.mjs +284 -0
  64. package/dist/index.mjs.map +1 -0
  65. package/package.json +46 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,284 @@
1
+ "use client";
2
+ import {
3
+ AudioViewer
4
+ } from "./chunk-FZYMVHF6.mjs";
5
+ import {
6
+ DefaultViewer
7
+ } from "./chunk-QLJKOQTP.mjs";
8
+ import {
9
+ ImageViewer
10
+ } from "./chunk-XQBXRMB7.mjs";
11
+ import {
12
+ PDFViewer
13
+ } from "./chunk-73ZIFR3P.mjs";
14
+ import {
15
+ TextViewer
16
+ } from "./chunk-LKBM4O47.mjs";
17
+ import {
18
+ TIFFViewer
19
+ } from "./chunk-NOLXOOIP.mjs";
20
+ import {
21
+ VideoViewer
22
+ } from "./chunk-QRYIHDRT.mjs";
23
+ import {
24
+ FileIcon_default,
25
+ getFileExtension,
26
+ getMimeTypeFromExtension
27
+ } from "./chunk-QQDQJ7TS.mjs";
28
+
29
+ // src/components/FileViewer.tsx
30
+ import { useState, useEffect, useMemo } from "react";
31
+
32
+ // src/registry.ts
33
+ var loadTextViewer = () => import("./components/viewers/TextViewer.mjs").then((m) => ({ default: m.TextViewer }));
34
+ var loadImageViewer = () => import("./components/viewers/ImageViewer.mjs").then((m) => ({ default: m.ImageViewer }));
35
+ var loadPDFViewer = () => import("./components/viewers/PDFViewer.mjs").then((m) => ({ default: m.PDFViewer }));
36
+ var loadVideoViewer = () => import("./components/viewers/VideoViewer.mjs").then((m) => ({ default: m.VideoViewer }));
37
+ var loadAudioViewer = () => import("./components/viewers/AudioViewer.mjs").then((m) => ({ default: m.AudioViewer }));
38
+ var loadTIFFViewer = () => import("./components/viewers/TIFFViewer.mjs").then((m) => ({ default: m.TIFFViewer }));
39
+ var loadDefaultViewer = () => import("./components/viewers/DefaultViewer.mjs").then((m) => ({ default: m.DefaultViewer }));
40
+ var dynamicViewerRegistry = {
41
+ // Text files
42
+ "txt": { type: "text", loader: loadTextViewer },
43
+ "json": { type: "text", loader: loadTextViewer },
44
+ "xml": { type: "text", loader: loadTextViewer },
45
+ "csv": { type: "text", loader: loadTextViewer },
46
+ "md": { type: "text", loader: loadTextViewer },
47
+ "js": { type: "text", loader: loadTextViewer },
48
+ "jsx": { type: "text", loader: loadTextViewer },
49
+ "ts": { type: "text", loader: loadTextViewer },
50
+ "tsx": { type: "text", loader: loadTextViewer },
51
+ "css": { type: "text", loader: loadTextViewer },
52
+ "scss": { type: "text", loader: loadTextViewer },
53
+ "html": { type: "text", loader: loadTextViewer },
54
+ "py": { type: "text", loader: loadTextViewer },
55
+ "java": { type: "text", loader: loadTextViewer },
56
+ "cpp": { type: "text", loader: loadTextViewer },
57
+ "c": { type: "text", loader: loadTextViewer },
58
+ "php": { type: "text", loader: loadTextViewer },
59
+ "rb": { type: "text", loader: loadTextViewer },
60
+ "go": { type: "text", loader: loadTextViewer },
61
+ "rs": { type: "text", loader: loadTextViewer },
62
+ "sql": { type: "text", loader: loadTextViewer },
63
+ "yaml": { type: "text", loader: loadTextViewer },
64
+ "yml": { type: "text", loader: loadTextViewer },
65
+ // Images
66
+ "jpg": { type: "image", loader: loadImageViewer },
67
+ "jpeg": { type: "image", loader: loadImageViewer },
68
+ "png": { type: "image", loader: loadImageViewer },
69
+ "gif": { type: "image", loader: loadImageViewer },
70
+ "svg": { type: "image", loader: loadImageViewer },
71
+ "webp": { type: "image", loader: loadImageViewer },
72
+ "bmp": { type: "image", loader: loadImageViewer },
73
+ "ico": { type: "image", loader: loadImageViewer },
74
+ "tif": { type: "tiff", loader: loadTIFFViewer },
75
+ "tiff": { type: "tiff", loader: loadTIFFViewer },
76
+ // PDF
77
+ "pdf": { type: "pdf", loader: loadPDFViewer },
78
+ // Videos
79
+ "mp4": { type: "video", loader: loadVideoViewer },
80
+ "webm": { type: "video", loader: loadVideoViewer },
81
+ "ogg": { type: "video", loader: loadVideoViewer },
82
+ "avi": { type: "video", loader: loadVideoViewer },
83
+ "mov": { type: "video", loader: loadVideoViewer },
84
+ "wmv": { type: "video", loader: loadVideoViewer },
85
+ "flv": { type: "video", loader: loadVideoViewer },
86
+ "mkv": { type: "video", loader: loadVideoViewer },
87
+ // Audio
88
+ "mp3": { type: "audio", loader: loadAudioViewer },
89
+ "wav": { type: "audio", loader: loadAudioViewer },
90
+ "m4a": { type: "audio", loader: loadAudioViewer },
91
+ "flac": { type: "audio", loader: loadAudioViewer },
92
+ "aac": { type: "audio", loader: loadAudioViewer },
93
+ "oga": { type: "audio", loader: loadAudioViewer }
94
+ };
95
+ var componentCache = /* @__PURE__ */ new Map();
96
+ var getViewerInfo = (extension) => {
97
+ const ext = extension.toLowerCase();
98
+ return dynamicViewerRegistry[ext] || { type: "default", loader: loadDefaultViewer };
99
+ };
100
+ var getViewerComponent = async (extension, customRegistry) => {
101
+ const ext = extension.toLowerCase();
102
+ if (componentCache.has(ext)) {
103
+ return componentCache.get(ext);
104
+ }
105
+ const registry = { ...dynamicViewerRegistry, ...customRegistry };
106
+ const viewerInfo = registry[ext] || { type: "default", loader: loadDefaultViewer };
107
+ try {
108
+ const { default: Component } = await viewerInfo.loader();
109
+ componentCache.set(ext, Component);
110
+ return Component;
111
+ } catch (error) {
112
+ if (!componentCache.has("default")) {
113
+ const { default: DefaultComponent } = await loadDefaultViewer();
114
+ componentCache.set("default", DefaultComponent);
115
+ }
116
+ return componentCache.get("default");
117
+ }
118
+ };
119
+
120
+ // src/components/FileViewer.tsx
121
+ import { jsx, jsxs } from "react/jsx-runtime";
122
+ if (typeof document !== "undefined") {
123
+ const style = document.createElement("style");
124
+ style.textContent = `
125
+ @keyframes dms-file-viewer-spin {
126
+ 0% { transform: rotate(0deg); }
127
+ 100% { transform: rotate(360deg); }
128
+ }
129
+ `;
130
+ document.head.appendChild(style);
131
+ }
132
+ var DefaultLoadingComponent = ({ fileName, type }) => /* @__PURE__ */ jsx("div", { style: {
133
+ display: "flex",
134
+ alignItems: "center",
135
+ justifyContent: "center",
136
+ padding: "40px",
137
+ border: "1px solid #ddd",
138
+ borderRadius: "4px",
139
+ backgroundColor: "#f9f9f9"
140
+ }, children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
141
+ /* @__PURE__ */ jsx("div", { style: {
142
+ width: "24px",
143
+ height: "24px",
144
+ border: "2px solid #ccc",
145
+ borderTop: "2px solid #007bff",
146
+ borderRadius: "50%",
147
+ animation: "dms-file-viewer-spin 1s linear infinite",
148
+ margin: "0 auto 16px"
149
+ } }),
150
+ /* @__PURE__ */ jsxs("p", { children: [
151
+ "Loading ",
152
+ type,
153
+ " viewer..."
154
+ ] }),
155
+ fileName && /* @__PURE__ */ jsxs("p", { style: { fontSize: "12px", color: "#666" }, children: [
156
+ "File: ",
157
+ fileName
158
+ ] })
159
+ ] }) });
160
+ var DefaultErrorComponent = ({ error, retry }) => /* @__PURE__ */ jsx("div", { style: {
161
+ display: "flex",
162
+ alignItems: "center",
163
+ justifyContent: "center",
164
+ padding: "40px",
165
+ border: "1px solid #ddd",
166
+ borderRadius: "4px",
167
+ backgroundColor: "#fff2f2"
168
+ }, children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
169
+ /* @__PURE__ */ jsx("p", { style: { color: "#d32f2f", marginBottom: "16px" }, children: "Failed to load file viewer" }),
170
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: "#666", marginBottom: "16px" }, children: error.message }),
171
+ /* @__PURE__ */ jsx(
172
+ "button",
173
+ {
174
+ onClick: retry,
175
+ style: {
176
+ padding: "8px 16px",
177
+ border: "1px solid #007bff",
178
+ borderRadius: "4px",
179
+ backgroundColor: "#007bff",
180
+ color: "#fff",
181
+ cursor: "pointer"
182
+ },
183
+ children: "Retry"
184
+ }
185
+ )
186
+ ] }) });
187
+ var FileViewer = ({
188
+ file,
189
+ url,
190
+ fileName,
191
+ mimeType,
192
+ customRegistry,
193
+ loadingComponent: LoadingComponent = DefaultLoadingComponent,
194
+ errorComponent: ErrorComponent = DefaultErrorComponent,
195
+ ...props
196
+ }) => {
197
+ const [ViewerComponent, setViewerComponent] = useState(null);
198
+ const [loading, setLoading] = useState(false);
199
+ const [error, setError] = useState(null);
200
+ const resolvedFileInfo = useMemo(() => {
201
+ let resolvedFileName = fileName;
202
+ if (!resolvedFileName && file) {
203
+ resolvedFileName = file.name;
204
+ }
205
+ if (!resolvedFileName && url) {
206
+ resolvedFileName = url.split("/").pop() || "unknown";
207
+ }
208
+ const extension = resolvedFileName ? getFileExtension(resolvedFileName) : "";
209
+ let resolvedMimeType = mimeType;
210
+ if (!resolvedMimeType && file) {
211
+ resolvedMimeType = file.type;
212
+ }
213
+ if (!resolvedMimeType && extension) {
214
+ resolvedMimeType = getMimeTypeFromExtension(extension);
215
+ }
216
+ const viewerInfo = getViewerInfo(extension);
217
+ return {
218
+ fileName: resolvedFileName,
219
+ extension,
220
+ mimeType: resolvedMimeType,
221
+ viewerInfo
222
+ };
223
+ }, [file, url, fileName, mimeType]);
224
+ const loadViewer = async () => {
225
+ if (loading) return;
226
+ setLoading(true);
227
+ setError(null);
228
+ try {
229
+ const component = await getViewerComponent(resolvedFileInfo.extension, customRegistry);
230
+ setViewerComponent(() => component);
231
+ } catch (err) {
232
+ setError(err instanceof Error ? err : new Error("Failed to load viewer"));
233
+ } finally {
234
+ setLoading(false);
235
+ }
236
+ };
237
+ useEffect(() => {
238
+ loadViewer();
239
+ }, [resolvedFileInfo.extension]);
240
+ const viewerProps = useMemo(() => ({
241
+ file,
242
+ url,
243
+ fileName: resolvedFileInfo.fileName,
244
+ mimeType: resolvedFileInfo.mimeType,
245
+ fileSize: file?.size,
246
+ ...props
247
+ }), [file, url, resolvedFileInfo.fileName, resolvedFileInfo.mimeType, props]);
248
+ if (loading || !ViewerComponent) {
249
+ return /* @__PURE__ */ jsx(
250
+ LoadingComponent,
251
+ {
252
+ fileName: resolvedFileInfo.fileName,
253
+ type: resolvedFileInfo.viewerInfo.type
254
+ }
255
+ );
256
+ }
257
+ if (error) {
258
+ return /* @__PURE__ */ jsx(
259
+ ErrorComponent,
260
+ {
261
+ error,
262
+ retry: loadViewer
263
+ }
264
+ );
265
+ }
266
+ return /* @__PURE__ */ jsx(ViewerComponent, { ...viewerProps });
267
+ };
268
+ export {
269
+ AudioViewer,
270
+ DefaultViewer,
271
+ FileIcon_default as FileIcon,
272
+ FileViewer,
273
+ ImageViewer,
274
+ PDFViewer,
275
+ TIFFViewer,
276
+ TextViewer,
277
+ VideoViewer,
278
+ dynamicViewerRegistry,
279
+ getFileExtension,
280
+ getMimeTypeFromExtension,
281
+ getViewerComponent,
282
+ getViewerInfo
283
+ };
284
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/FileViewer.tsx","../src/registry.ts"],"sourcesContent":["import React, { useState, useEffect, useMemo } from 'react';\r\nimport { FileViewerProps, ViewerInfo, FileViewerComponent } from '../types';\r\nimport { getFileExtension, getMimeTypeFromExtension } from '../utils/fileUtils';\r\nimport { getViewerComponent, getViewerInfo } from '../registry';\r\n\r\n// Inject CSS for spinner animation\r\nif (typeof document !== 'undefined') {\r\n const style = document.createElement('style');\r\n style.textContent = `\r\n @keyframes dms-file-viewer-spin {\r\n 0% { transform: rotate(0deg); }\r\n 100% { transform: rotate(360deg); }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n}\r\n\r\nexport interface FileViewerComponentProps extends Partial<FileViewerProps> {\r\n customRegistry?: Record<string, ViewerInfo>;\r\n loadingComponent?: React.ComponentType<{ fileName?: string; type?: string }>;\r\n errorComponent?: React.ComponentType<{ error: Error; retry: () => void }>;\r\n}\r\n\r\n// Default loading component\r\nconst DefaultLoadingComponent: React.FC<{ fileName?: string; type?: string }> = ({ fileName, type }) => (\r\n <div style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '40px',\r\n border: '1px solid #ddd',\r\n borderRadius: '4px',\r\n backgroundColor: '#f9f9f9'\r\n }}>\r\n <div style={{ textAlign: 'center' }}>\r\n <div style={{\r\n width: '24px',\r\n height: '24px',\r\n border: '2px solid #ccc',\r\n borderTop: '2px solid #007bff',\r\n borderRadius: '50%',\r\n animation: 'dms-file-viewer-spin 1s linear infinite',\r\n margin: '0 auto 16px'\r\n }} />\r\n <p>Loading {type} viewer...</p>\r\n {fileName && <p style={{ fontSize: '12px', color: '#666' }}>File: {fileName}</p>}\r\n </div>\r\n </div>\r\n);\r\n\r\n// Default error component\r\nconst DefaultErrorComponent: React.FC<{ error: Error; retry: () => void }> = ({ error, retry }) => (\r\n <div style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '40px',\r\n border: '1px solid #ddd',\r\n borderRadius: '4px',\r\n backgroundColor: '#fff2f2'\r\n }}>\r\n <div style={{ textAlign: 'center' }}>\r\n <p style={{ color: '#d32f2f', marginBottom: '16px' }}>\r\n Failed to load file viewer\r\n </p>\r\n <p style={{ fontSize: '12px', color: '#666', marginBottom: '16px' }}>\r\n {error.message}\r\n </p>\r\n <button\r\n onClick={retry}\r\n style={{\r\n padding: '8px 16px',\r\n border: '1px solid #007bff',\r\n borderRadius: '4px',\r\n backgroundColor: '#007bff',\r\n color: '#fff',\r\n cursor: 'pointer'\r\n }}\r\n >\r\n Retry\r\n </button>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport const FileViewer: React.FC<FileViewerComponentProps> = ({\r\n file,\r\n url,\r\n fileName,\r\n mimeType,\r\n customRegistry,\r\n loadingComponent: LoadingComponent = DefaultLoadingComponent,\r\n errorComponent: ErrorComponent = DefaultErrorComponent,\r\n ...props\r\n}) => {\r\n const [ViewerComponent, setViewerComponent] = useState<FileViewerComponent | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n // Resolve file information\r\n const resolvedFileInfo = useMemo(() => {\r\n // Determine file name\r\n let resolvedFileName = fileName;\r\n if (!resolvedFileName && file) {\r\n resolvedFileName = file.name;\r\n }\r\n if (!resolvedFileName && url) {\r\n resolvedFileName = url.split('/').pop() || 'unknown';\r\n }\r\n\r\n // Determine file extension\r\n const extension = resolvedFileName ? getFileExtension(resolvedFileName) : '';\r\n\r\n // Determine mime type\r\n let resolvedMimeType = mimeType;\r\n if (!resolvedMimeType && file) {\r\n resolvedMimeType = file.type;\r\n }\r\n if (!resolvedMimeType && extension) {\r\n resolvedMimeType = getMimeTypeFromExtension(extension);\r\n }\r\n\r\n // Get viewer info\r\n const viewerInfo = getViewerInfo(extension);\r\n\r\n return {\r\n fileName: resolvedFileName,\r\n extension,\r\n mimeType: resolvedMimeType,\r\n viewerInfo\r\n };\r\n }, [file, url, fileName, mimeType]);\r\n\r\n // Load viewer component dynamically\r\n const loadViewer = async () => {\r\n if (loading) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const component = await getViewerComponent(resolvedFileInfo.extension, customRegistry);\r\n setViewerComponent(() => component);\r\n } catch (err) {\r\n setError(err instanceof Error ? err : new Error('Failed to load viewer'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n // Load viewer when file info changes\r\n useEffect(() => {\r\n loadViewer();\r\n }, [resolvedFileInfo.extension]);\r\n\r\n // Prepare props for the viewer\r\n const viewerProps = useMemo(() => ({\r\n file,\r\n url,\r\n fileName: resolvedFileInfo.fileName,\r\n mimeType: resolvedFileInfo.mimeType,\r\n fileSize: file?.size,\r\n ...props\r\n }), [file, url, resolvedFileInfo.fileName, resolvedFileInfo.mimeType, props]);\r\n\r\n // Show loading state\r\n if (loading || !ViewerComponent) {\r\n return (\r\n <LoadingComponent\r\n fileName={resolvedFileInfo.fileName}\r\n type={resolvedFileInfo.viewerInfo.type}\r\n />\r\n );\r\n }\r\n\r\n // Show error state\r\n if (error) {\r\n return (\r\n <ErrorComponent\r\n error={error}\r\n retry={loadViewer}\r\n />\r\n );\r\n }\r\n\r\n // Render the loaded viewer component\r\n return <ViewerComponent {...viewerProps} />;\r\n};","import { DynamicViewerRegistry, ViewerInfo, FileViewerComponent } from './types';\r\n\r\n// Dynamic import functions for each viewer type\r\nconst loadTextViewer = () => import('./components/viewers/TextViewer').then(m => ({ default: m.TextViewer }));\r\nconst loadImageViewer = () => import('./components/viewers/ImageViewer').then(m => ({ default: m.ImageViewer }));\r\nconst loadPDFViewer = () => import('./components/viewers/PDFViewer').then(m => ({ default: m.PDFViewer }));\r\nconst loadVideoViewer = () => import('./components/viewers/VideoViewer').then(m => ({ default: m.VideoViewer }));\r\nconst loadAudioViewer = () => import('./components/viewers/AudioViewer').then(m => ({ default: m.AudioViewer }));\r\nconst loadTIFFViewer = () => import('./components/viewers/TIFFViewer').then(m => ({ default: m.TIFFViewer }));\r\nconst loadDefaultViewer = () => import('./components/viewers/DefaultViewer').then(m => ({ default: m.DefaultViewer }));\r\n\r\n// Registry mapping file extensions to viewer info\r\nexport const dynamicViewerRegistry: Record<string, ViewerInfo> = {\r\n // Text files\r\n 'txt': { type: 'text', loader: loadTextViewer },\r\n 'json': { type: 'text', loader: loadTextViewer },\r\n 'xml': { type: 'text', loader: loadTextViewer },\r\n 'csv': { type: 'text', loader: loadTextViewer },\r\n 'md': { type: 'text', loader: loadTextViewer },\r\n 'js': { type: 'text', loader: loadTextViewer },\r\n 'jsx': { type: 'text', loader: loadTextViewer },\r\n 'ts': { type: 'text', loader: loadTextViewer },\r\n 'tsx': { type: 'text', loader: loadTextViewer },\r\n 'css': { type: 'text', loader: loadTextViewer },\r\n 'scss': { type: 'text', loader: loadTextViewer },\r\n 'html': { type: 'text', loader: loadTextViewer },\r\n 'py': { type: 'text', loader: loadTextViewer },\r\n 'java': { type: 'text', loader: loadTextViewer },\r\n 'cpp': { type: 'text', loader: loadTextViewer },\r\n 'c': { type: 'text', loader: loadTextViewer },\r\n 'php': { type: 'text', loader: loadTextViewer },\r\n 'rb': { type: 'text', loader: loadTextViewer },\r\n 'go': { type: 'text', loader: loadTextViewer },\r\n 'rs': { type: 'text', loader: loadTextViewer },\r\n 'sql': { type: 'text', loader: loadTextViewer },\r\n 'yaml': { type: 'text', loader: loadTextViewer },\r\n 'yml': { type: 'text', loader: loadTextViewer },\r\n\r\n // Images\r\n 'jpg': { type: 'image', loader: loadImageViewer },\r\n 'jpeg': { type: 'image', loader: loadImageViewer },\r\n 'png': { type: 'image', loader: loadImageViewer },\r\n 'gif': { type: 'image', loader: loadImageViewer },\r\n 'svg': { type: 'image', loader: loadImageViewer },\r\n 'webp': { type: 'image', loader: loadImageViewer },\r\n 'bmp': { type: 'image', loader: loadImageViewer },\r\n 'ico': { type: 'image', loader: loadImageViewer },\r\n 'tif': { type: 'tiff', loader: loadTIFFViewer },\r\n 'tiff': { type: 'tiff', loader: loadTIFFViewer },\r\n\r\n // PDF\r\n 'pdf': { type: 'pdf', loader: loadPDFViewer },\r\n\r\n // Videos\r\n 'mp4': { type: 'video', loader: loadVideoViewer },\r\n 'webm': { type: 'video', loader: loadVideoViewer },\r\n 'ogg': { type: 'video', loader: loadVideoViewer },\r\n 'avi': { type: 'video', loader: loadVideoViewer },\r\n 'mov': { type: 'video', loader: loadVideoViewer },\r\n 'wmv': { type: 'video', loader: loadVideoViewer },\r\n 'flv': { type: 'video', loader: loadVideoViewer },\r\n 'mkv': { type: 'video', loader: loadVideoViewer },\r\n\r\n // Audio\r\n 'mp3': { type: 'audio', loader: loadAudioViewer },\r\n 'wav': { type: 'audio', loader: loadAudioViewer },\r\n 'm4a': { type: 'audio', loader: loadAudioViewer },\r\n 'flac': { type: 'audio', loader: loadAudioViewer },\r\n 'aac': { type: 'audio', loader: loadAudioViewer },\r\n 'oga': { type: 'audio', loader: loadAudioViewer },\r\n};\r\n\r\n// Cache to store loaded components\r\nconst componentCache = new Map<string, FileViewerComponent>();\r\n\r\nexport const getViewerInfo = (extension: string): ViewerInfo => {\r\n const ext = extension.toLowerCase();\r\n return dynamicViewerRegistry[ext] || { type: 'default', loader: loadDefaultViewer };\r\n};\r\n\r\nexport const getViewerComponent = async (\r\n extension: string,\r\n customRegistry?: Record<string, ViewerInfo>\r\n): Promise<FileViewerComponent> => {\r\n const ext = extension.toLowerCase();\r\n\r\n // Check cache first\r\n if (componentCache.has(ext)) {\r\n return componentCache.get(ext)!;\r\n }\r\n\r\n // Get viewer info from registry\r\n const registry = { ...dynamicViewerRegistry, ...customRegistry };\r\n const viewerInfo = registry[ext] || { type: 'default', loader: loadDefaultViewer };\r\n\r\n try {\r\n // Dynamically import the component\r\n const { default: Component } = await viewerInfo.loader();\r\n\r\n // Cache the loaded component\r\n componentCache.set(ext, Component);\r\n\r\n return Component;\r\n } catch (error) {\r\n // Fallback to default viewer on error\r\n if (!componentCache.has('default')) {\r\n const { default: DefaultComponent } = await loadDefaultViewer();\r\n componentCache.set('default', DefaultComponent);\r\n }\r\n\r\n return componentCache.get('default')!;\r\n }\r\n};"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@cannyminds/dms-file-viewers",
3
+ "version": "0.1.0",
4
+ "description": "File viewer components library with dynamic loading",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch"
21
+ },
22
+ "dependencies": {
23
+ "@cannyminds/pdf-viewer": "0.3.0",
24
+ "pdf-lib": "^1.17.1",
25
+ "react-window": "^1.8.10",
26
+ "utif": "^3.1.0"
27
+ },
28
+ "peerDependencies": {
29
+ "@emotion/react": "^11.14.0",
30
+ "@emotion/styled": "^11.14.0",
31
+ "@mui/icons-material": "^7.3.4",
32
+ "@mui/material": "^7.3.4",
33
+ "react": "^18.0.0 || ^19.0.0",
34
+ "react-dom": "^18.0.0 || ^19.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/react": "^19.0.0",
38
+ "@types/react-dom": "^19.0.0",
39
+ "@types/react-window": "^2.0.0",
40
+ "tsup": "^8.0.0",
41
+ "typescript": "^5.0.0"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ }
46
+ }