@frybynite/image-cloud 0.5.2 → 0.6.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 (89) hide show
  1. package/README.md +46 -13
  2. package/dist/composite-CtUxtN2l.js +96 -0
  3. package/dist/composite-CtUxtN2l.js.map +1 -0
  4. package/dist/google-drive-CC-qFSV1.js +260 -0
  5. package/dist/google-drive-CC-qFSV1.js.map +1 -0
  6. package/dist/image-cloud-auto-init.js +345 -759
  7. package/dist/image-cloud-auto-init.js.map +1 -1
  8. package/dist/image-cloud.js +1248 -1204
  9. package/dist/image-cloud.js.map +1 -1
  10. package/dist/image-cloud.umd.js +5 -5
  11. package/dist/image-cloud.umd.js.map +1 -1
  12. package/dist/index.d.ts +1654 -23
  13. package/dist/loaders/all.d.ts +1654 -0
  14. package/dist/loaders/all.js +496 -0
  15. package/dist/loaders/all.js.map +1 -0
  16. package/dist/loaders/composite.d.ts +1654 -0
  17. package/dist/loaders/composite.js +96 -0
  18. package/dist/loaders/composite.js.map +1 -0
  19. package/dist/loaders/google-drive.d.ts +1654 -0
  20. package/dist/loaders/google-drive.js +260 -0
  21. package/dist/loaders/google-drive.js.map +1 -0
  22. package/dist/loaders/static.d.ts +1654 -0
  23. package/dist/loaders/static.js +219 -0
  24. package/dist/loaders/static.js.map +1 -0
  25. package/dist/react.d.ts +1654 -1
  26. package/dist/react.js +434 -848
  27. package/dist/react.js.map +1 -1
  28. package/dist/static-ejylHtQ4.js +219 -0
  29. package/dist/static-ejylHtQ4.js.map +1 -0
  30. package/dist/vue.d.ts +1654 -1
  31. package/dist/vue.js +442 -856
  32. package/dist/vue.js.map +1 -1
  33. package/dist/web-component.d.ts +1654 -1
  34. package/dist/web-component.js +429 -843
  35. package/dist/web-component.js.map +1 -1
  36. package/package.json +28 -15
  37. package/dist/ImageCloud.d.ts +0 -99
  38. package/dist/ImageCloud.d.ts.map +0 -1
  39. package/dist/config/adapter.d.ts +0 -50
  40. package/dist/config/adapter.d.ts.map +0 -1
  41. package/dist/config/defaults.d.ts +0 -118
  42. package/dist/config/defaults.d.ts.map +0 -1
  43. package/dist/config/types.d.ts +0 -599
  44. package/dist/config/types.d.ts.map +0 -1
  45. package/dist/engines/AnimationEngine.d.ts +0 -82
  46. package/dist/engines/AnimationEngine.d.ts.map +0 -1
  47. package/dist/engines/EntryAnimationEngine.d.ts +0 -161
  48. package/dist/engines/EntryAnimationEngine.d.ts.map +0 -1
  49. package/dist/engines/LayoutEngine.d.ts +0 -68
  50. package/dist/engines/LayoutEngine.d.ts.map +0 -1
  51. package/dist/engines/PathAnimator.d.ts +0 -50
  52. package/dist/engines/PathAnimator.d.ts.map +0 -1
  53. package/dist/engines/SwipeEngine.d.ts +0 -53
  54. package/dist/engines/SwipeEngine.d.ts.map +0 -1
  55. package/dist/engines/ZoomEngine.d.ts +0 -139
  56. package/dist/engines/ZoomEngine.d.ts.map +0 -1
  57. package/dist/image-cloud-auto-init.d.ts +0 -14
  58. package/dist/image-cloud-auto-init.d.ts.map +0 -1
  59. package/dist/index.d.ts.map +0 -1
  60. package/dist/layouts/ClusterPlacementLayout.d.ts +0 -40
  61. package/dist/layouts/ClusterPlacementLayout.d.ts.map +0 -1
  62. package/dist/layouts/GridPlacementLayout.d.ts +0 -27
  63. package/dist/layouts/GridPlacementLayout.d.ts.map +0 -1
  64. package/dist/layouts/RadialPlacementLayout.d.ts +0 -33
  65. package/dist/layouts/RadialPlacementLayout.d.ts.map +0 -1
  66. package/dist/layouts/RandomPlacementLayout.d.ts +0 -26
  67. package/dist/layouts/RandomPlacementLayout.d.ts.map +0 -1
  68. package/dist/layouts/SpiralPlacementLayout.d.ts +0 -43
  69. package/dist/layouts/SpiralPlacementLayout.d.ts.map +0 -1
  70. package/dist/layouts/WavePlacementLayout.d.ts +0 -48
  71. package/dist/layouts/WavePlacementLayout.d.ts.map +0 -1
  72. package/dist/loaders/CompositeLoader.d.ts +0 -37
  73. package/dist/loaders/CompositeLoader.d.ts.map +0 -1
  74. package/dist/loaders/GoogleDriveLoader.d.ts +0 -90
  75. package/dist/loaders/GoogleDriveLoader.d.ts.map +0 -1
  76. package/dist/loaders/ImageFilter.d.ts +0 -26
  77. package/dist/loaders/ImageFilter.d.ts.map +0 -1
  78. package/dist/loaders/StaticImageLoader.d.ts +0 -85
  79. package/dist/loaders/StaticImageLoader.d.ts.map +0 -1
  80. package/dist/react/index.d.ts +0 -16
  81. package/dist/react/index.d.ts.map +0 -1
  82. package/dist/styles/functionalStyles.d.ts +0 -11
  83. package/dist/styles/functionalStyles.d.ts.map +0 -1
  84. package/dist/utils/styleUtils.d.ts +0 -54
  85. package/dist/utils/styleUtils.d.ts.map +0 -1
  86. package/dist/vue/index.d.ts +0 -18
  87. package/dist/vue/index.d.ts.map +0 -1
  88. package/dist/web-component/index.d.ts +0 -15
  89. package/dist/web-component/index.d.ts.map +0 -1
package/README.md CHANGED
@@ -32,21 +32,29 @@ No install needed — load directly from a CDN:
32
32
 
33
33
  **jsDelivr**
34
34
  ```
35
- https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/image-cloud.js (ESM)
36
- https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/image-cloud.umd.js (UMD)
37
- https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/image-cloud-auto-init.js
35
+ https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/image-cloud.js (Main - ESM)
36
+ https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/image-cloud.umd.js (Main - UMD)
37
+ https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/image-cloud-auto-init.js (Auto-init)
38
+ https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/loaders/static.js (Static loader)
39
+ https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/loaders/google-drive.js (Google Drive loader)
40
+ https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/loaders/all.js (All loaders)
38
41
  https://cdn.jsdelivr.net/npm/@frybynite/image-cloud@latest/dist/style.css
39
42
  ```
40
43
 
41
44
  **unpkg**
42
45
  ```
43
- https://unpkg.com/@frybynite/image-cloud@latest/dist/image-cloud.js (ESM)
44
- https://unpkg.com/@frybynite/image-cloud@latest/dist/image-cloud.umd.js (UMD)
45
- https://unpkg.com/@frybynite/image-cloud@latest/dist/image-cloud-auto-init.js
46
+ https://unpkg.com/@frybynite/image-cloud@latest/dist/image-cloud.js (Main - ESM)
47
+ https://unpkg.com/@frybynite/image-cloud@latest/dist/image-cloud.umd.js (Main - UMD)
48
+ https://unpkg.com/@frybynite/image-cloud@latest/dist/image-cloud-auto-init.js (Auto-init)
49
+ https://unpkg.com/@frybynite/image-cloud@latest/dist/loaders/static.js (Static loader)
50
+ https://unpkg.com/@frybynite/image-cloud@latest/dist/loaders/google-drive.js (Google Drive loader)
51
+ https://unpkg.com/@frybynite/image-cloud@latest/dist/loaders/all.js (All loaders)
46
52
  https://unpkg.com/@frybynite/image-cloud@latest/dist/style.css
47
53
  ```
48
54
 
49
- Replace `@latest` with a specific version (e.g., `@0.2.1`) to pin to that release.
55
+ Replace `@latest` with a specific version (e.g., `@0.5.1`) to pin to that release.
56
+
57
+ **Note:** Loaders are imported as separate bundles to reduce bundle size. Import only the loaders you need.
50
58
 
51
59
  ## Quick Start
52
60
 
@@ -54,15 +62,22 @@ Replace `@latest` with a specific version (e.g., `@0.2.1`) to pin to that releas
54
62
 
55
63
  ```typescript
56
64
  import { ImageCloud } from '@frybynite/image-cloud';
65
+ import '@frybynite/image-cloud/loaders/static'; // Import loaders separately for optimal bundle size
57
66
  import '@frybynite/image-cloud/style.css';
58
67
 
59
68
  const cloud = new ImageCloud({
60
69
  container: 'myCloud',
61
- images: [
62
- 'https://images.pexels.com/photos/1261728/pexels-photo-1261728.jpeg?auto=compress&w=600',
63
- 'https://images.pexels.com/photos/3225517/pexels-photo-3225517.jpeg?auto=compress&w=600',
64
- 'https://images.pexels.com/photos/1402787/pexels-photo-1402787.jpeg?auto=compress&w=600'
65
- ],
70
+ loaders: [{
71
+ static: {
72
+ sources: [{
73
+ urls: [
74
+ 'https://images.pexels.com/photos/1261728/pexels-photo-1261728.jpeg?auto=compress&w=600',
75
+ 'https://images.pexels.com/photos/3225517/pexels-photo-3225517.jpeg?auto=compress&w=600',
76
+ 'https://images.pexels.com/photos/1402787/pexels-photo-1402787.jpeg?auto=compress&w=600'
77
+ ]
78
+ }]
79
+ }
80
+ }],
66
81
  layout: {
67
82
  algorithm: 'radial'
68
83
  }
@@ -71,6 +86,11 @@ const cloud = new ImageCloud({
71
86
  await cloud.init();
72
87
  ```
73
88
 
89
+ **Tip:** If you're using multiple loaders or want to include all of them, import the all-in-one bundle:
90
+ ```typescript
91
+ import '@frybynite/image-cloud/loaders/all'; // Includes static, google-drive, and composite loaders
92
+ ```
93
+
74
94
  ### HTML (Auto-initialization)
75
95
 
76
96
  ```html
@@ -103,12 +123,25 @@ await cloud.init();
103
123
 
104
124
  For detailed configuration, see the documentation in the `docs/` folder:
105
125
 
106
- 1. **[Loaders](docs/LOADERS.md)** — Configure image sources (static URLs, JSON endpoints, local paths, Google Drive folders)
126
+ 1. **[Loaders](docs/LOADERS.md)** — Configure image sources (static URLs, JSON endpoints, local paths, Google Drive folders). Loaders are imported as separate bundles to reduce bundle size.
107
127
  2. **[Layouts](docs/LAYOUTS.md)** — Choose and customize layout algorithms (radial, grid, spiral, cluster, random, wave)
108
128
  3. **[Image Sizing](docs/IMAGE_SIZING.md)** — Control base sizes, variance, and responsive/adaptive behavior
109
129
  4. **[Full Parameter Reference](docs/PARAMETERS.md)** — Complete configuration options for animation, interaction, styling, and more
110
130
  5. **[API Reference](docs/api/README.md)** — TypeScript API documentation for the ImageCloud class, types, loaders, and layouts
111
131
 
132
+ ### Bundle Size Optimization
133
+
134
+ Image Cloud uses a **loader registry pattern** to optimize bundle size:
135
+ - The **main bundle** contains the core ImageCloud class (~30KB gzipped)
136
+ - **Loader bundles** (static, google-drive, composite) are imported separately and auto-register when loaded
137
+ - **Import only the loaders you need** to minimize bundle size
138
+
139
+ Example: Using only the static loader
140
+ ```typescript
141
+ import { ImageCloud } from '@frybynite/image-cloud';
142
+ import '@frybynite/image-cloud/loaders/static'; // ~2.3KB gzipped
143
+ ```
144
+
112
145
  ### Using the Configurator
113
146
 
114
147
  The easiest way to create a custom configuration is with the interactive Configurator tool:
@@ -0,0 +1,96 @@
1
+ const i = class t {
2
+ /**
3
+ * Register a loader implementation with the registry
4
+ * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')
5
+ * @param Loader - Loader class constructor to register
6
+ */
7
+ static registerLoader(e, r) {
8
+ t.registry.set(e, r);
9
+ }
10
+ /**
11
+ * Get a registered loader implementation
12
+ * @param name - Loader identifier
13
+ * @returns Loader class constructor
14
+ * @throws Error if loader is not registered
15
+ */
16
+ static getLoader(e) {
17
+ const r = t.registry.get(e);
18
+ if (!r)
19
+ throw new Error(
20
+ `Loader "${e}" is not registered. Import "@frybynite/image-cloud/loaders/${e}" or "@frybynite/image-cloud/loaders/all".`
21
+ );
22
+ return r;
23
+ }
24
+ /**
25
+ * Check if a loader is registered
26
+ * @param name - Loader identifier
27
+ * @returns True if the loader is registered, false otherwise
28
+ */
29
+ static isRegistered(e) {
30
+ return t.registry.has(e);
31
+ }
32
+ };
33
+ i.registry = /* @__PURE__ */ new Map();
34
+ let d = i;
35
+ class l {
36
+ constructor(e) {
37
+ if (this._prepared = !1, this._discoveredUrls = [], this.loaders = e.loaders, this.debugLogging = e.debugLogging ?? !1, !this.loaders || this.loaders.length === 0)
38
+ throw new Error("CompositeLoader requires at least one loader to be configured");
39
+ this.log(`CompositeLoader initialized with ${this.loaders.length} loader(s)`);
40
+ }
41
+ /**
42
+ * Prepare all loaders in parallel and combine their results
43
+ * @param filter - Filter to apply to discovered images
44
+ */
45
+ async prepare(e) {
46
+ this._discoveredUrls = [], this.log(`Preparing ${this.loaders.length} loader(s) in parallel`);
47
+ const r = this.loaders.map((s, o) => s.prepare(e).then(() => {
48
+ this.log(`Loader ${o} prepared with ${s.imagesLength()} images`);
49
+ }).catch((a) => {
50
+ console.warn(`Loader ${o} failed to prepare:`, a);
51
+ }));
52
+ await Promise.all(r);
53
+ for (const s of this.loaders)
54
+ if (s.isPrepared()) {
55
+ const o = s.imageURLs();
56
+ this._discoveredUrls.push(...o);
57
+ }
58
+ this._prepared = !0, this.log(`CompositeLoader prepared with ${this._discoveredUrls.length} total images`);
59
+ }
60
+ /**
61
+ * Get the combined number of discovered images
62
+ * @throws Error if called before prepare()
63
+ */
64
+ imagesLength() {
65
+ if (!this._prepared)
66
+ throw new Error("CompositeLoader.imagesLength() called before prepare()");
67
+ return this._discoveredUrls.length;
68
+ }
69
+ /**
70
+ * Get the combined ordered list of image URLs
71
+ * @throws Error if called before prepare()
72
+ */
73
+ imageURLs() {
74
+ if (!this._prepared)
75
+ throw new Error("CompositeLoader.imageURLs() called before prepare()");
76
+ return [...this._discoveredUrls];
77
+ }
78
+ /**
79
+ * Check if the loader has been prepared
80
+ */
81
+ isPrepared() {
82
+ return this._prepared;
83
+ }
84
+ /**
85
+ * Debug logging helper
86
+ * @param args - Arguments to log
87
+ */
88
+ log(...e) {
89
+ this.debugLogging && typeof console < "u" && console.log("[CompositeLoader]", ...e);
90
+ }
91
+ }
92
+ d.registerLoader("composite", l);
93
+ export {
94
+ l as CompositeLoader
95
+ };
96
+ //# sourceMappingURL=composite-CtUxtN2l.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite-CtUxtN2l.js","sources":["loaders/composite.js"],"sourcesContent":["const s = class s {\n /**\n * Register a loader implementation with the registry\n * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')\n * @param Loader - Loader class constructor to register\n */\n static registerLoader(e, r) {\n s.registry.set(e, r);\n }\n /**\n * Get a registered loader implementation\n * @param name - Loader identifier\n * @returns Loader class constructor\n * @throws Error if loader is not registered\n */\n static getLoader(e) {\n const r = s.registry.get(e);\n if (!r)\n throw new Error(\n `Loader \"${e}\" is not registered. Import \"@frybynite/image-cloud/loaders/${e}\" or \"@frybynite/image-cloud/loaders/all\".`\n );\n return r;\n }\n /**\n * Check if a loader is registered\n * @param name - Loader identifier\n * @returns True if the loader is registered, false otherwise\n */\n static isRegistered(e) {\n return s.registry.has(e);\n }\n};\ns.registry = /* @__PURE__ */ new Map();\nlet i = s;\nclass d {\n constructor(e) {\n if (this._prepared = !1, this._discoveredUrls = [], this.loaders = e.loaders, this.debugLogging = e.debugLogging ?? !1, !this.loaders || this.loaders.length === 0)\n throw new Error(\"CompositeLoader requires at least one loader to be configured\");\n this.log(`CompositeLoader initialized with ${this.loaders.length} loader(s)`);\n }\n /**\n * Prepare all loaders in parallel and combine their results\n * @param filter - Filter to apply to discovered images\n */\n async prepare(e) {\n this._discoveredUrls = [], this.log(`Preparing ${this.loaders.length} loader(s) in parallel`);\n const r = this.loaders.map((t, o) => t.prepare(e).then(() => {\n this.log(`Loader ${o} prepared with ${t.imagesLength()} images`);\n }).catch((a) => {\n console.warn(`Loader ${o} failed to prepare:`, a);\n }));\n await Promise.all(r);\n for (const t of this.loaders)\n if (t.isPrepared()) {\n const o = t.imageURLs();\n this._discoveredUrls.push(...o);\n }\n this._prepared = !0, this.log(`CompositeLoader prepared with ${this._discoveredUrls.length} total images`);\n }\n /**\n * Get the combined number of discovered images\n * @throws Error if called before prepare()\n */\n imagesLength() {\n if (!this._prepared)\n throw new Error(\"CompositeLoader.imagesLength() called before prepare()\");\n return this._discoveredUrls.length;\n }\n /**\n * Get the combined ordered list of image URLs\n * @throws Error if called before prepare()\n */\n imageURLs() {\n if (!this._prepared)\n throw new Error(\"CompositeLoader.imageURLs() called before prepare()\");\n return [...this._discoveredUrls];\n }\n /**\n * Check if the loader has been prepared\n */\n isPrepared() {\n return this._prepared;\n }\n /**\n * Debug logging helper\n * @param args - Arguments to log\n */\n log(...e) {\n this.debugLogging && typeof console < \"u\" && console.log(\"[CompositeLoader]\", ...e);\n }\n}\ni.registerLoader(\"composite\", d);\nexport {\n d as CompositeLoader\n};\n//# sourceMappingURL=composite.js.map\n"],"names":["s","i","d","t"],"mappings":"AAAA,MAAMA,IAAI,MAAMA,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,OAAO,eAAe,GAAG,GAAG;AAC1B,IAAAA,EAAE,SAAS,IAAI,GAAG,CAAC;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,UAAU,GAAG;AAClB,UAAM,IAAIA,EAAE,SAAS,IAAI,CAAC;AAC1B,QAAI,CAAC;AACH,YAAM,IAAI;AAAA,QACR,WAAW,CAAC,+DAA+D,CAAC;AAAA,MACpF;AACI,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,aAAa,GAAG;AACrB,WAAOA,EAAE,SAAS,IAAI,CAAC;AAAA,EACzB;AACF;AACAA,EAAE,WAA2B,oBAAI,IAAG;AACpC,IAAIC,IAAID;AACR,MAAME,EAAE;AAAA,EACN,YAAY,GAAG;AACb,QAAI,KAAK,YAAY,IAAI,KAAK,kBAAkB,CAAA,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,eAAe,EAAE,gBAAgB,IAAI,CAAC,KAAK,WAAW,KAAK,QAAQ,WAAW;AAC/J,YAAM,IAAI,MAAM,+DAA+D;AACjF,SAAK,IAAI,oCAAoC,KAAK,QAAQ,MAAM,YAAY;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,GAAG;AACf,SAAK,kBAAkB,IAAI,KAAK,IAAI,aAAa,KAAK,QAAQ,MAAM,wBAAwB;AAC5F,UAAM,IAAI,KAAK,QAAQ,IAAI,CAACC,GAAG,MAAMA,EAAE,QAAQ,CAAC,EAAE,KAAK,MAAM;AAC3D,WAAK,IAAI,UAAU,CAAC,kBAAkBA,EAAE,cAAc,SAAS;AAAA,IACjE,CAAC,EAAE,MAAM,CAAC,MAAM;AACd,cAAQ,KAAK,UAAU,CAAC,uBAAuB,CAAC;AAAA,IAClD,CAAC,CAAC;AACF,UAAM,QAAQ,IAAI,CAAC;AACnB,eAAWA,KAAK,KAAK;AACnB,UAAIA,EAAE,cAAc;AAClB,cAAM,IAAIA,EAAE,UAAS;AACrB,aAAK,gBAAgB,KAAK,GAAG,CAAC;AAAA,MAChC;AACF,SAAK,YAAY,IAAI,KAAK,IAAI,iCAAiC,KAAK,gBAAgB,MAAM,eAAe;AAAA,EAC3G;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACb,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,wDAAwD;AAC1E,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACV,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,qDAAqD;AACvE,WAAO,CAAC,GAAG,KAAK,eAAe;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAIA,aAAa;AACX,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAG;AACR,SAAK,gBAAgB,OAAO,UAAU,OAAO,QAAQ,IAAI,qBAAqB,GAAG,CAAC;AAAA,EACpF;AACF;AACAF,EAAE,eAAe,aAAaC,CAAC;"}
@@ -0,0 +1,260 @@
1
+ const h = class d {
2
+ /**
3
+ * Register a loader implementation with the registry
4
+ * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')
5
+ * @param Loader - Loader class constructor to register
6
+ */
7
+ static registerLoader(e, t) {
8
+ d.registry.set(e, t);
9
+ }
10
+ /**
11
+ * Get a registered loader implementation
12
+ * @param name - Loader identifier
13
+ * @returns Loader class constructor
14
+ * @throws Error if loader is not registered
15
+ */
16
+ static getLoader(e) {
17
+ const t = d.registry.get(e);
18
+ if (!t)
19
+ throw new Error(
20
+ `Loader "${e}" is not registered. Import "@frybynite/image-cloud/loaders/${e}" or "@frybynite/image-cloud/loaders/all".`
21
+ );
22
+ return t;
23
+ }
24
+ /**
25
+ * Check if a loader is registered
26
+ * @param name - Loader identifier
27
+ * @returns True if the loader is registered, false otherwise
28
+ */
29
+ static isRegistered(e) {
30
+ return d.registry.has(e);
31
+ }
32
+ };
33
+ h.registry = /* @__PURE__ */ new Map();
34
+ let f = h;
35
+ class m {
36
+ constructor(e) {
37
+ if (this._prepared = !1, this._discoveredUrls = [], this.apiKey = e.apiKey ?? "", this.apiEndpoint = e.apiEndpoint ?? "https://www.googleapis.com/drive/v3/files", this.debugLogging = e.debugLogging ?? !1, this.sources = e.sources ?? [], !this.sources || this.sources.length === 0)
38
+ throw new Error("GoogleDriveLoader requires at least one source to be configured");
39
+ }
40
+ /**
41
+ * Prepare the loader by discovering all images from configured sources
42
+ * @param filter - Filter to apply to discovered images
43
+ */
44
+ async prepare(e) {
45
+ this._discoveredUrls = [];
46
+ for (const t of this.sources)
47
+ if ("folders" in t)
48
+ for (const r of t.folders) {
49
+ const i = t.recursive !== void 0 ? t.recursive : !0, s = await this.loadFromFolder(r, e, i);
50
+ this._discoveredUrls.push(...s);
51
+ }
52
+ else if ("files" in t) {
53
+ const r = await this.loadFiles(t.files, e);
54
+ this._discoveredUrls.push(...r);
55
+ }
56
+ this._prepared = !0;
57
+ }
58
+ /**
59
+ * Get the number of discovered images
60
+ * @throws Error if called before prepare()
61
+ */
62
+ imagesLength() {
63
+ if (!this._prepared)
64
+ throw new Error("GoogleDriveLoader.imagesLength() called before prepare()");
65
+ return this._discoveredUrls.length;
66
+ }
67
+ /**
68
+ * Get the ordered list of image URLs
69
+ * @throws Error if called before prepare()
70
+ */
71
+ imageURLs() {
72
+ if (!this._prepared)
73
+ throw new Error("GoogleDriveLoader.imageURLs() called before prepare()");
74
+ return [...this._discoveredUrls];
75
+ }
76
+ /**
77
+ * Check if the loader has been prepared
78
+ */
79
+ isPrepared() {
80
+ return this._prepared;
81
+ }
82
+ /**
83
+ * Extract folder ID from various Google Drive URL formats
84
+ * @param folderUrl - Google Drive folder URL
85
+ * @returns Folder ID or null if invalid
86
+ */
87
+ extractFolderId(e) {
88
+ const t = [
89
+ /\/folders\/([a-zA-Z0-9_-]+)/,
90
+ // Standard format
91
+ /id=([a-zA-Z0-9_-]+)/
92
+ // Alternative format
93
+ ];
94
+ for (const r of t) {
95
+ const i = e.match(r);
96
+ if (i && i[1])
97
+ return i[1];
98
+ }
99
+ return null;
100
+ }
101
+ /**
102
+ * Load images from a Google Drive folder
103
+ * @param folderUrl - Google Drive folder URL
104
+ * @param filter - Filter to apply to discovered images
105
+ * @param recursive - Whether to include images from subfolders
106
+ * @returns Promise resolving to array of image URLs
107
+ */
108
+ async loadFromFolder(e, t, r = !0) {
109
+ const i = this.extractFolderId(e);
110
+ if (!i)
111
+ throw new Error("Invalid Google Drive folder URL. Please check the URL format.");
112
+ if (!this.apiKey || this.apiKey === "YOUR_API_KEY_HERE")
113
+ return this.loadImagesDirectly(i, t);
114
+ try {
115
+ return r ? await this.loadImagesRecursively(i, t) : await this.loadImagesFromSingleFolder(i, t);
116
+ } catch (s) {
117
+ return console.error("Error loading from Google Drive API:", s), this.loadImagesDirectly(i, t);
118
+ }
119
+ }
120
+ /**
121
+ * Load images from a single folder (non-recursive)
122
+ * @param folderId - Google Drive folder ID
123
+ * @param filter - Filter to apply to discovered images
124
+ * @returns Promise resolving to array of image URLs
125
+ */
126
+ async loadImagesFromSingleFolder(e, t) {
127
+ const r = [], i = `'${e}' in parents and trashed=false`, s = `${this.apiEndpoint}?q=${encodeURIComponent(i)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(s);
128
+ if (!a.ok)
129
+ throw new Error(`API request failed: ${a.status} ${a.statusText}`);
130
+ const l = (await a.json()).files.filter(
131
+ (o) => o.mimeType.startsWith("image/") && t.isAllowed(o.name)
132
+ );
133
+ return this.log(`Found ${l.length} images in folder ${e} (non-recursive)`), l.forEach((o) => {
134
+ r.push(`https://lh3.googleusercontent.com/d/${o.id}=s1600`), this.log(`Added file: ${o.name}`);
135
+ }), r;
136
+ }
137
+ /**
138
+ * Load specific files by their URLs or IDs
139
+ * @param fileUrls - Array of Google Drive file URLs or IDs
140
+ * @param filter - Filter to apply to discovered images
141
+ * @returns Promise resolving to array of image URLs
142
+ */
143
+ async loadFiles(e, t) {
144
+ const r = [];
145
+ for (const i of e) {
146
+ const s = this.extractFileId(i);
147
+ if (!s) {
148
+ this.log(`Skipping invalid file URL: ${i}`);
149
+ continue;
150
+ }
151
+ if (this.apiKey && this.apiKey !== "YOUR_API_KEY_HERE")
152
+ try {
153
+ const a = `${this.apiEndpoint}/${s}?fields=name,mimeType&key=${this.apiKey}`, l = await fetch(a);
154
+ if (l.ok) {
155
+ const o = await l.json();
156
+ o.mimeType.startsWith("image/") && t.isAllowed(o.name) ? (r.push(`https://lh3.googleusercontent.com/d/${s}=s1600`), this.log(`Added file: ${o.name}`)) : this.log(`Skipping non-image file: ${o.name} (${o.mimeType})`);
157
+ } else
158
+ this.log(`Failed to fetch metadata for file ${s}: ${l.status}`);
159
+ } catch (a) {
160
+ this.log(`Error fetching metadata for file ${s}:`, a);
161
+ }
162
+ else
163
+ r.push(`https://lh3.googleusercontent.com/d/${s}=s1600`);
164
+ }
165
+ return r;
166
+ }
167
+ /**
168
+ * Extract file ID from Google Drive file URL
169
+ * @param fileUrl - Google Drive file URL or file ID
170
+ * @returns File ID or null if invalid
171
+ */
172
+ extractFileId(e) {
173
+ if (!/[/:.]/.test(e))
174
+ return e;
175
+ const t = [
176
+ /\/file\/d\/([a-zA-Z0-9_-]+)/,
177
+ // Standard file format
178
+ /\/open\?id=([a-zA-Z0-9_-]+)/,
179
+ // Alternative format
180
+ /id=([a-zA-Z0-9_-]+)/
181
+ // Generic id parameter
182
+ ];
183
+ for (const r of t) {
184
+ const i = e.match(r);
185
+ if (i && i[1])
186
+ return i[1];
187
+ }
188
+ return null;
189
+ }
190
+ /**
191
+ * Recursively load images from a folder and all its subfolders
192
+ * @param folderId - Google Drive folder ID
193
+ * @param filter - Filter to apply to discovered images
194
+ * @returns Promise resolving to array of image URLs
195
+ */
196
+ async loadImagesRecursively(e, t) {
197
+ const r = [], i = `'${e}' in parents and trashed=false`, s = `${this.apiEndpoint}?q=${encodeURIComponent(i)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(s);
198
+ if (!a.ok)
199
+ throw new Error(`API request failed: ${a.status} ${a.statusText}`);
200
+ const l = await a.json(), o = l.files.filter(
201
+ (n) => n.mimeType.startsWith("image/") && t.isAllowed(n.name)
202
+ ), c = l.files.filter(
203
+ (n) => n.mimeType === "application/vnd.google-apps.folder"
204
+ );
205
+ this.log(`Found ${l.files.length} total items in folder ${e}`), l.files.forEach((n) => this.log(` - File: ${n.name} (${n.mimeType})`)), this.log(`- ${o.length} valid files (images only)`), this.log(`- ${c.length} subfolders`), o.forEach((n) => {
206
+ r.push(`https://lh3.googleusercontent.com/d/${n.id}=s1600`), this.log(`Added file: ${n.name}`);
207
+ });
208
+ for (const n of c) {
209
+ this.log(`Loading images from subfolder: ${n.name}`);
210
+ const g = await this.loadImagesRecursively(n.id, t);
211
+ r.push(...g);
212
+ }
213
+ return r;
214
+ }
215
+ /**
216
+ * Direct loading method (no API key required, but less reliable)
217
+ * Uses embedded folder view to scrape image IDs
218
+ * @param folderId - Google Drive folder ID
219
+ * @param filter - Filter to apply (not used in fallback mode)
220
+ * @returns Promise resolving to array of image URLs
221
+ */
222
+ async loadImagesDirectly(e, t) {
223
+ try {
224
+ const r = `https://drive.google.com/embeddedfolderview?id=${e}`, i = await fetch(r, { mode: "cors" });
225
+ if (!i.ok)
226
+ throw new Error("Cannot access folder directly (CORS or permissions issue)");
227
+ const s = await i.text(), a = /\/file\/d\/([a-zA-Z0-9_-]+)/g, l = [...s.matchAll(a)];
228
+ return [...new Set(l.map((o) => o[1]))].map(
229
+ (o) => `https://drive.google.com/uc?export=view&id=${o}`
230
+ );
231
+ } catch (r) {
232
+ throw console.error("Direct loading failed:", r), new Error(
233
+ `Unable to load images. Please ensure:
234
+ 1. The folder is shared publicly (Anyone with the link can view)
235
+ 2. The folder contains image files
236
+ 3. Consider adding a Google Drive API key in config.js for better reliability`
237
+ );
238
+ }
239
+ }
240
+ /**
241
+ * Manually add image URLs (for testing or when auto-loading fails)
242
+ * @param imageIds - Array of Google Drive file IDs
243
+ * @returns Array of direct image URLs
244
+ */
245
+ manualImageUrls(e) {
246
+ return e.map((t) => `https://drive.google.com/uc?export=view&id=${t}`);
247
+ }
248
+ /**
249
+ * Debug logging helper
250
+ * @param args - Arguments to log
251
+ */
252
+ log(...e) {
253
+ this.debugLogging && typeof console < "u" && console.log(...e);
254
+ }
255
+ }
256
+ f.registerLoader("google-drive", m);
257
+ export {
258
+ m as GoogleDriveLoader
259
+ };
260
+ //# sourceMappingURL=google-drive-CC-qFSV1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-drive-CC-qFSV1.js","sources":["loaders/google-drive.js"],"sourcesContent":["const h = class h {\n /**\n * Register a loader implementation with the registry\n * @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')\n * @param Loader - Loader class constructor to register\n */\n static registerLoader(e, s) {\n h.registry.set(e, s);\n }\n /**\n * Get a registered loader implementation\n * @param name - Loader identifier\n * @returns Loader class constructor\n * @throws Error if loader is not registered\n */\n static getLoader(e) {\n const s = h.registry.get(e);\n if (!s)\n throw new Error(\n `Loader \"${e}\" is not registered. Import \"@frybynite/image-cloud/loaders/${e}\" or \"@frybynite/image-cloud/loaders/all\".`\n );\n return s;\n }\n /**\n * Check if a loader is registered\n * @param name - Loader identifier\n * @returns True if the loader is registered, false otherwise\n */\n static isRegistered(e) {\n return h.registry.has(e);\n }\n};\nh.registry = /* @__PURE__ */ new Map();\nlet g = h;\nclass f {\n constructor(e) {\n if (this._prepared = !1, this._discoveredUrls = [], this.apiKey = e.apiKey ?? \"\", this.apiEndpoint = e.apiEndpoint ?? \"https://www.googleapis.com/drive/v3/files\", this.debugLogging = e.debugLogging ?? !1, this.sources = e.sources ?? [], !this.sources || this.sources.length === 0)\n throw new Error(\"GoogleDriveLoader requires at least one source to be configured\");\n }\n /**\n * Prepare the loader by discovering all images from configured sources\n * @param filter - Filter to apply to discovered images\n */\n async prepare(e) {\n this._discoveredUrls = [];\n for (const s of this.sources)\n if (\"folders\" in s)\n for (const r of s.folders) {\n const t = s.recursive !== void 0 ? s.recursive : !0, o = await this.loadFromFolder(r, e, t);\n this._discoveredUrls.push(...o);\n }\n else if (\"files\" in s) {\n const r = await this.loadFiles(s.files, e);\n this._discoveredUrls.push(...r);\n }\n this._prepared = !0;\n }\n /**\n * Get the number of discovered images\n * @throws Error if called before prepare()\n */\n imagesLength() {\n if (!this._prepared)\n throw new Error(\"GoogleDriveLoader.imagesLength() called before prepare()\");\n return this._discoveredUrls.length;\n }\n /**\n * Get the ordered list of image URLs\n * @throws Error if called before prepare()\n */\n imageURLs() {\n if (!this._prepared)\n throw new Error(\"GoogleDriveLoader.imageURLs() called before prepare()\");\n return [...this._discoveredUrls];\n }\n /**\n * Check if the loader has been prepared\n */\n isPrepared() {\n return this._prepared;\n }\n /**\n * Extract folder ID from various Google Drive URL formats\n * @param folderUrl - Google Drive folder URL\n * @returns Folder ID or null if invalid\n */\n extractFolderId(e) {\n const s = [\n /\\/folders\\/([a-zA-Z0-9_-]+)/,\n // Standard format\n /id=([a-zA-Z0-9_-]+)/\n // Alternative format\n ];\n for (const r of s) {\n const t = e.match(r);\n if (t && t[1])\n return t[1];\n }\n return null;\n }\n /**\n * Load images from a Google Drive folder\n * @param folderUrl - Google Drive folder URL\n * @param filter - Filter to apply to discovered images\n * @param recursive - Whether to include images from subfolders\n * @returns Promise resolving to array of image URLs\n */\n async loadFromFolder(e, s, r = !0) {\n const t = this.extractFolderId(e);\n if (!t)\n throw new Error(\"Invalid Google Drive folder URL. Please check the URL format.\");\n if (!this.apiKey || this.apiKey === \"YOUR_API_KEY_HERE\")\n return this.loadImagesDirectly(t, s);\n try {\n return r ? await this.loadImagesRecursively(t, s) : await this.loadImagesFromSingleFolder(t, s);\n } catch (o) {\n return console.error(\"Error loading from Google Drive API:\", o), this.loadImagesDirectly(t, s);\n }\n }\n /**\n * Load images from a single folder (non-recursive)\n * @param folderId - Google Drive folder ID\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of image URLs\n */\n async loadImagesFromSingleFolder(e, s) {\n const r = [], t = `'${e}' in parents and trashed=false`, d = `${this.apiEndpoint}?q=${encodeURIComponent(t)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, i = await fetch(d);\n if (!i.ok)\n throw new Error(`API request failed: ${i.status} ${i.statusText}`);\n const c = (await i.json()).files.filter(\n (l) => l.mimeType.startsWith(\"image/\") && s.isAllowed(l.name)\n );\n return this.log(`Found ${c.length} images in folder ${e} (non-recursive)`), c.forEach((l) => {\n r.push(`https://lh3.googleusercontent.com/d/${l.id}=s1600`), this.log(`Added file: ${l.name}`);\n }), r;\n }\n /**\n * Load specific files by their URLs or IDs\n * @param fileUrls - Array of Google Drive file URLs or IDs\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of image URLs\n */\n async loadFiles(e, s) {\n const r = [];\n for (const t of e) {\n const o = this.extractFileId(t);\n if (!o) {\n this.log(`Skipping invalid file URL: ${t}`);\n continue;\n }\n if (this.apiKey && this.apiKey !== \"YOUR_API_KEY_HERE\")\n try {\n const d = `${this.apiEndpoint}/${o}?fields=name,mimeType&key=${this.apiKey}`, i = await fetch(d);\n if (i.ok) {\n const n = await i.json();\n n.mimeType.startsWith(\"image/\") && s.isAllowed(n.name) ? (r.push(`https://lh3.googleusercontent.com/d/${o}=s1600`), this.log(`Added file: ${n.name}`)) : this.log(`Skipping non-image file: ${n.name} (${n.mimeType})`);\n } else\n this.log(`Failed to fetch metadata for file ${o}: ${i.status}`);\n } catch (d) {\n this.log(`Error fetching metadata for file ${o}:`, d);\n }\n else\n r.push(`https://lh3.googleusercontent.com/d/${o}=s1600`);\n }\n return r;\n }\n /**\n * Extract file ID from Google Drive file URL\n * @param fileUrl - Google Drive file URL or file ID\n * @returns File ID or null if invalid\n */\n extractFileId(e) {\n if (!/[/:.]/.test(e))\n return e;\n const s = [\n /\\/file\\/d\\/([a-zA-Z0-9_-]+)/,\n // Standard file format\n /\\/open\\?id=([a-zA-Z0-9_-]+)/,\n // Alternative format\n /id=([a-zA-Z0-9_-]+)/\n // Generic id parameter\n ];\n for (const r of s) {\n const t = e.match(r);\n if (t && t[1])\n return t[1];\n }\n return null;\n }\n /**\n * Recursively load images from a folder and all its subfolders\n * @param folderId - Google Drive folder ID\n * @param filter - Filter to apply to discovered images\n * @returns Promise resolving to array of image URLs\n */\n async loadImagesRecursively(e, s) {\n const r = [], t = `'${e}' in parents and trashed=false`, d = `${this.apiEndpoint}?q=${encodeURIComponent(t)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, i = await fetch(d);\n if (!i.ok)\n throw new Error(`API request failed: ${i.status} ${i.statusText}`);\n const n = await i.json(), c = n.files.filter(\n (a) => a.mimeType.startsWith(\"image/\") && s.isAllowed(a.name)\n ), l = n.files.filter(\n (a) => a.mimeType === \"application/vnd.google-apps.folder\"\n );\n this.log(`Found ${n.files.length} total items in folder ${e}`), n.files.forEach((a) => this.log(` - File: ${a.name} (${a.mimeType})`)), this.log(`- ${c.length} valid files (images only)`), this.log(`- ${l.length} subfolders`), c.forEach((a) => {\n r.push(`https://lh3.googleusercontent.com/d/${a.id}=s1600`), this.log(`Added file: ${a.name}`);\n });\n for (const a of l) {\n this.log(`Loading images from subfolder: ${a.name}`);\n const m = await this.loadImagesRecursively(a.id, s);\n r.push(...m);\n }\n return r;\n }\n /**\n * Direct loading method (no API key required, but less reliable)\n * Uses embedded folder view to scrape image IDs\n * @param folderId - Google Drive folder ID\n * @param filter - Filter to apply (not used in fallback mode)\n * @returns Promise resolving to array of image URLs\n */\n async loadImagesDirectly(e, s) {\n try {\n const r = `https://drive.google.com/embeddedfolderview?id=${e}`, t = await fetch(r, { mode: \"cors\" });\n if (!t.ok)\n throw new Error(\"Cannot access folder directly (CORS or permissions issue)\");\n const o = await t.text(), d = /\\/file\\/d\\/([a-zA-Z0-9_-]+)/g, i = [...o.matchAll(d)];\n return [...new Set(i.map((l) => l[1]))].map(\n (l) => `https://drive.google.com/uc?export=view&id=${l}`\n );\n } catch (r) {\n throw console.error(\"Direct loading failed:\", r), new Error(\n `Unable to load images. Please ensure:\n1. The folder is shared publicly (Anyone with the link can view)\n2. The folder contains image files\n3. Consider adding a Google Drive API key in config.js for better reliability`\n );\n }\n }\n /**\n * Manually add image URLs (for testing or when auto-loading fails)\n * @param imageIds - Array of Google Drive file IDs\n * @returns Array of direct image URLs\n */\n manualImageUrls(e) {\n return e.map((s) => `https://drive.google.com/uc?export=view&id=${s}`);\n }\n /**\n * Debug logging helper\n * @param args - Arguments to log\n */\n log(...e) {\n this.debugLogging && typeof console < \"u\" && console.log(...e);\n }\n}\ng.registerLoader(\"google-drive\", f);\nexport {\n f as GoogleDriveLoader\n};\n//# sourceMappingURL=google-drive.js.map\n"],"names":["h","s","g","f","t","o","d","i","c","l","n","a","m"],"mappings":"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"}