@file-viewer/vite-plugin 2.1.0 → 2.1.2

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.en.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @file-viewer/vite-plugin
2
2
 
3
- Vite plugin for Flyfish File Viewer on-demand renderer assembly. It generates `virtual:file-viewer-renderers` from the formats your application declares, imports only the matching renderer packages, and provides renderer-oriented chunk planning plus offline worker/WASM/font asset copying. The extension mapping is verified against the full `@file-viewer/core` format matrix in repository gates, so new formats cannot silently drift away from automatic assembly.
3
+ Vite plugin for Flyfish File Viewer on-demand renderer assembly. It can auto-discover installed `@file-viewer/preset-*` packages and inject them into the page, so Vue, React, Svelte, jQuery, and Vanilla JS components receive matching preview capability without application code passing `renderers` manually. It can also generate `virtual:file-viewer-renderers` from declared formats, import only matching renderer packages, and provide renderer-oriented chunk planning plus offline worker/WASM/font asset copying.
4
4
 
5
5
  ## Install
6
6
 
@@ -50,22 +50,26 @@ fileViewerRenderers({
50
50
  })
51
51
  ```
52
52
 
53
- `scan: true` inspects common source folders for lightweight hints and merges them with `formats`:
53
+ `inject` is enabled by default. The plugin injects `virtual:file-viewer-renderers` into Vite HTML entrypoints, preset imports register themselves in core, and framework components consume them through `autoRenderers`.
54
54
 
55
55
  ```ts
56
- export const fileViewerFormats = ['pdf', 'docx', 'xlsx']
56
+ const options = {
57
+ // Defaults to true; set false when a product needs total manual control.
58
+ autoRenderers: true
59
+ }
57
60
  ```
58
61
 
59
- ```html
60
- <input accept=".pdf,.docx" data-file-viewer-formats="dwg,xmind" />
61
- ```
62
+ For strict registry control, disable injection and pass the virtual module explicitly:
62
63
 
63
- This is useful when upload accept lists, sample matrices, or attachment allow-lists already live in source code: dev and production builds can generate the renderer assembly module without a second hand-written import list.
64
-
65
- ## Application Code
64
+ ```ts
65
+ fileViewerRenderers({
66
+ preset: 'office',
67
+ inject: false,
68
+ copyAssets: true
69
+ })
70
+ ```
66
71
 
67
72
  ```ts
68
- import FileViewer from '@file-viewer/vue3'
69
73
  import { configuredFileViewerRenderers } from 'virtual:file-viewer-renderers'
70
74
 
71
75
  const options = {
@@ -74,9 +78,27 @@ const options = {
74
78
  }
75
79
  ```
76
80
 
81
+ You can also use `preset: 'auto'` to discover installed preset packages. When `preset-all` is installed, it wins to avoid importing narrower presets twice.
82
+
83
+ `scan: true` inspects common source folders for lightweight hints and merges them with `formats`:
84
+
85
+ ```ts
86
+ export const fileViewerFormats = ['pdf', 'docx', 'xlsx']
87
+ ```
88
+
89
+ ```html
90
+ <input accept=".pdf,.docx" data-file-viewer-formats="dwg,xmind" />
91
+ ```
92
+
93
+ This is useful when upload accept lists, sample matrices, or attachment allow-lists already live in source code: dev and production builds can generate the renderer assembly module without a second hand-written import list.
94
+
95
+ ## Missing Renderer Guidance
96
+
97
+ When a file extension is in the supported matrix but the current project has not assembled its renderer, core now shows an install-oriented “renderer assembly required” state with the recommended preset / renderer package. For example, `.pdf` points to `@file-viewer/preset-office` or `@file-viewer/renderer-pdf`. Only truly unknown extensions show an unsupported-format state.
98
+
77
99
  ## Current Boundary
78
100
 
79
- The plugin currently generates imports for extracted renderer packages: Word, Spreadsheet, PDF, OFD, Presentation, CAD, Draw.io/Excalidraw/Mermaid/PlantUML, 3D, Data, EDA, Typst, archives, email, EPUB, code/Markdown/Patch/Git Bundle, image, media, XMind, and Geo. Declare them explicitly with `formats`, or let `scan: true` discover source hints automatically; core-supported extensions such as `.zipx`, `.cbz`, `.tiff`, `.mjs`, `.gv`, `.patch`, `.bundle`, `.mermaid`, `.puml`, and `.mpeg` also resolve to their renderer packages. With `copyAssets:true`, the plugin also copies the Typst compiler / renderer WASM files and the `wasm/typst/fonts/` default-font directory. `preset: 'lite' | 'office' | 'engineering' | 'all'` imports the matching `@file-viewer/preset-*` package; when `formats` are also present, the plugin adds extra renderers outside the preset.
101
+ The plugin currently generates imports for extracted renderer packages: Word, Spreadsheet, PDF, OFD, Presentation, CAD, Draw.io/Excalidraw/Mermaid/PlantUML, 3D, Data, EDA, Typst, archives, email, EPUB, code/Markdown/Patch/Git Bundle, image, media, XMind, and Geo. Declare them explicitly with `formats`, or let `scan: true` discover source hints automatically; core-supported extensions such as `.zipx`, `.cbz`, `.tiff`, `.mjs`, `.gv`, `.patch`, `.bundle`, `.mermaid`, `.puml`, and `.mpeg` also resolve to their renderer packages. With `copyAssets:true`, the plugin also copies the Typst compiler / renderer WASM files and the `wasm/typst/fonts/` default-font directory. `preset: 'auto' | 'lite' | 'office' | 'engineering' | 'all'` imports matching `@file-viewer/preset-*` packages; when `formats` are also present, the plugin adds extra renderers outside the preset.
80
102
 
81
103
  ## Documentation
82
104
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @file-viewer/vite-plugin
2
2
 
3
- Flyfish File Viewer 的 Vite 按需 renderer 自动装配插件。它根据业务声明的文件格式生成 `virtual:file-viewer-renderers`,只 import 命中的 renderer 包,并提供 chunk 分组和离线 worker/WASM/字体资源复制能力。插件的扩展名映射会在仓库门禁中对照 `@file-viewer/core` 的完整格式矩阵验证,避免新增格式后自动装配能力漂移。
3
+ Flyfish File Viewer 的 Vite 按需 renderer 自动装配插件。它可以自动发现已安装的 `@file-viewer/preset-*` 包并注入到页面,让 Vue、React、Svelte、jQuery 和 Vanilla JS 组件无需手动传 `renderers` 就获得对应预览能力;也可以根据业务声明的文件格式生成 `virtual:file-viewer-renderers`,只 import 命中的 renderer 包,并提供 chunk 分组和离线 worker/WASM/字体资源复制能力。
4
4
 
5
5
  ## 安装
6
6
 
@@ -50,22 +50,26 @@ fileViewerRenderers({
50
50
  })
51
51
  ```
52
52
 
53
- `scan: true` 会扫描常见源码目录里的轻量 hint,并把它们合并到 `formats`:
53
+ `inject` 默认开启,插件会把 `virtual:file-viewer-renderers` 注入 Vite HTML 入口,preset 导入后会自动注册到 core。常规业务只需要安装组件包和对应 preset,组件会通过 `autoRenderers` 默认读取这些能力。
54
54
 
55
55
  ```ts
56
- export const fileViewerFormats = ['pdf', 'docx', 'xlsx']
56
+ const options = {
57
+ // 默认 true;需要完全手动控制时设为 false。
58
+ autoRenderers: true
59
+ }
57
60
  ```
58
61
 
59
- ```html
60
- <input accept=".pdf,.docx" data-file-viewer-formats="dwg,xmind" />
61
- ```
62
+ 如果你需要严格控制 registry,可以关闭注入并手动传入:
62
63
 
63
- 这适合业务把上传入口、示例矩阵或附件白名单维护在源码中时使用:开发和构建阶段插件会自动生成 renderer 装配模块,少写一份手工 import 清单。
64
-
65
- ## 业务代码
64
+ ```ts
65
+ fileViewerRenderers({
66
+ preset: 'office',
67
+ inject: false,
68
+ copyAssets: true
69
+ })
70
+ ```
66
71
 
67
72
  ```ts
68
- import FileViewer from '@file-viewer/vue3'
69
73
  import { configuredFileViewerRenderers } from 'virtual:file-viewer-renderers'
70
74
 
71
75
  const options = {
@@ -74,9 +78,27 @@ const options = {
74
78
  }
75
79
  ```
76
80
 
81
+ 也可以使用 `preset: 'auto'` 发现项目中已安装的 preset 包;当 `preset-all` 存在时会优先使用它,避免重复导入其它 preset。
82
+
83
+ `scan: true` 会扫描常见源码目录里的轻量 hint,并把它们合并到 `formats`:
84
+
85
+ ```ts
86
+ export const fileViewerFormats = ['pdf', 'docx', 'xlsx']
87
+ ```
88
+
89
+ ```html
90
+ <input accept=".pdf,.docx" data-file-viewer-formats="dwg,xmind" />
91
+ ```
92
+
93
+ 这适合业务把上传入口、示例矩阵或附件白名单维护在源码中时使用:开发和构建阶段插件会自动生成 renderer 装配模块,少写一份手工 import 清单。
94
+
95
+ ## 缺失 renderer 提示
96
+
97
+ 如果用户打开的是支持矩阵内的格式,但项目没有安装或装配对应 renderer,core 会显示“需要装配预览能力”,并提示推荐安装的 preset / renderer 包,例如 `.pdf` 会引导安装 `@file-viewer/preset-office` 或 `@file-viewer/renderer-pdf`。只有真正不在支持矩阵中的扩展名才显示“不支持在线预览”。
98
+
77
99
  ## 当前边界
78
100
 
79
- 当前插件会为已经拆出的 renderer 包生成导入:Word、Spreadsheet、PDF、OFD、Presentation、CAD、Draw.io/Excalidraw/Mermaid/PlantUML、3D、Data、EDA、Typst、压缩包、邮件、EPUB、代码/Markdown/Patch/Git Bundle、图片、媒体、XMind 和 Geo。可以通过 `formats` 显式声明,也可以通过 `scan: true` 从源码 hint 自动发现;`.zipx`、`.cbz`、`.tiff`、`.mjs`、`.gv`、`.patch`、`.bundle`、`.mermaid`、`.puml`、`.mpeg` 等 core 支持的扩展也会映射到对应 renderer。开启 `copyAssets:true` 时会同时复制 Typst compiler / renderer WASM 与 `wasm/typst/fonts/` 默认字体目录。`preset: 'lite' | 'office' | 'engineering' | 'all'` 会导入对应 `@file-viewer/preset-*` 包;如果同时声明 `formats`,插件会在 preset 之外补充额外 renderer。
101
+ 当前插件会为已经拆出的 renderer 包生成导入:Word、Spreadsheet、PDF、OFD、Presentation、CAD、Draw.io/Excalidraw/Mermaid/PlantUML、3D、Data、EDA、Typst、压缩包、邮件、EPUB、代码/Markdown/Patch/Git Bundle、图片、媒体、XMind 和 Geo。可以通过 `formats` 显式声明,也可以通过 `scan: true` 从源码 hint 自动发现;`.zipx`、`.cbz`、`.tiff`、`.mjs`、`.gv`、`.patch`、`.bundle`、`.mermaid`、`.puml`、`.mpeg` 等 core 支持的扩展也会映射到对应 renderer。开启 `copyAssets:true` 时会同时复制 Typst compiler / renderer WASM 与 `wasm/typst/fonts/` 默认字体目录。`preset: 'auto' | 'lite' | 'office' | 'engineering' | 'all'` 会导入对应 `@file-viewer/preset-*` 包;如果同时声明 `formats`,插件会在 preset 之外补充额外 renderer。
80
102
 
81
103
  ## 文档
82
104
 
package/client.d.ts CHANGED
@@ -9,6 +9,7 @@ declare module 'virtual:file-viewer-renderers' {
9
9
 
10
10
  export interface ConfiguredFileViewerRendererPlan {
11
11
  preset: string | null;
12
+ autoPresets: string[];
12
13
  formats: string[];
13
14
  rendererIds: string[];
14
15
  packages: string[];
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Plugin } from 'vite';
2
2
  export type FileViewerVitePreset = 'all' | 'lite' | 'office' | 'engineering';
3
+ export type FileViewerVitePresetMode = FileViewerVitePreset | 'auto';
3
4
  export type FileViewerMissingRendererMode = 'error' | 'warn' | 'ignore';
4
5
  export type FileViewerChunkStrategy = 'renderer' | 'none';
5
6
  export interface FileViewerRendererScanOptions {
@@ -45,10 +46,23 @@ export interface FileViewerRenderersPluginOptions {
45
46
  */
46
47
  renderers?: readonly string[];
47
48
  /**
48
- * Presets import their dedicated @file-viewer/preset-* package. Add
49
- * `formats` / `renderers` when you need to extend a preset with extra lines.
49
+ * Presets import their dedicated @file-viewer/preset-* package. Use `auto`
50
+ * to discover installed preset packages, and add `formats` / `renderers`
51
+ * when you need to extend a preset with extra lines.
50
52
  */
51
- preset?: FileViewerVitePreset;
53
+ preset?: FileViewerVitePresetMode;
54
+ /**
55
+ * Auto-discovers installed `@file-viewer/preset-*` packages and registers
56
+ * them globally for framework components. Defaults to true only when no
57
+ * explicit preset/formats/renderers are configured, or when `preset: 'auto'`.
58
+ */
59
+ autoPresets?: boolean | readonly FileViewerVitePreset[];
60
+ /**
61
+ * Injects the virtual renderer module into Vite HTML entrypoints so
62
+ * framework components can consume auto-registered renderers without
63
+ * application code importing `virtual:file-viewer-renderers`.
64
+ */
65
+ inject?: boolean;
52
66
  /**
53
67
  * Virtual module id consumed by application code.
54
68
  */
@@ -85,6 +99,8 @@ export declare function createFileViewerManualChunks(options?: FileViewerRendere
85
99
  export declare function resolveFileViewerRendererSelection(options?: FileViewerRenderersPluginOptions, projectRoot?: string): {
86
100
  preset: FileViewerVitePreset | null;
87
101
  presetPackage: string | null;
102
+ autoPresets: FileViewerVitePreset[];
103
+ autoPresetPackages: string[];
88
104
  formats: string[];
89
105
  packages: string[];
90
106
  rendererIds: string[];
package/dist/index.js CHANGED
@@ -557,8 +557,11 @@ export function collectFileViewerRendererScanTokens(projectRoot, scan) {
557
557
  });
558
558
  return unique(tokens);
559
559
  }
560
+ function resolveManualPreset(preset) {
561
+ return preset && preset !== 'auto' ? preset : null;
562
+ }
560
563
  function selectRenderers(options) {
561
- const preset = options.preset ?? null;
564
+ const preset = resolveManualPreset(options.preset);
562
565
  const presetCoveredIds = new Set(preset ? presetRendererIds[preset] : []);
563
566
  const selected = new Map();
564
567
  const missing = [];
@@ -606,37 +609,55 @@ function expandDescriptorRendererIds(ids) {
606
609
  return descriptor ? [...descriptor.rendererIds] : [id];
607
610
  }));
608
611
  }
609
- function renderVirtualModule(selection, formats) {
612
+ function renderVirtualModule(selection, formats, autoPresetIds = []) {
610
613
  const presetModule = selection.preset ? presetModules[selection.preset] : null;
614
+ const autoPresetModules = autoPresetIds
615
+ .filter((id) => id !== selection.preset)
616
+ .map((id) => presetModules[id]);
611
617
  const presetImport = presetModule
612
618
  ? `import { ${presetModule.exportName} as presetRenderers } from '${presetModule.packageName}';`
613
619
  : null;
620
+ const autoPresetImports = autoPresetModules.map((preset, index) => `import { ${preset.exportName} as autoPresetRenderers${index} } from '${preset.packageName}';`);
614
621
  const rendererImports = selection.descriptors.map((descriptor, index) => `import { ${descriptor.exportName} as renderer${index} } from '${descriptor.packageName}';`);
615
622
  const rendererNames = [
616
623
  ...(presetModule ? ['presetRenderers'] : []),
624
+ ...autoPresetModules.map((_preset, index) => `autoPresetRenderers${index}`),
617
625
  ...selection.descriptors.map((_descriptor, index) => `renderer${index}`)
618
626
  ];
619
627
  const rendererIds = unique([
620
628
  ...(presetModule ? expandDescriptorRendererIds(presetModule.rendererIds) : []),
629
+ ...autoPresetModules.flatMap((preset) => expandDescriptorRendererIds(preset.rendererIds)),
621
630
  ...selection.descriptors.flatMap((descriptor) => descriptor.rendererIds)
622
631
  ]);
623
632
  const packages = unique([
624
633
  ...(presetModule ? [presetModule.packageName] : []),
634
+ ...autoPresetModules.map((preset) => preset.packageName),
625
635
  ...selection.descriptors.map((descriptor) => descriptor.packageName)
626
636
  ]);
627
637
  const plan = {
628
638
  preset: selection.preset,
639
+ autoPresets: autoPresetModules.map((preset) => preset.id),
629
640
  formats,
630
641
  rendererIds,
631
642
  packages,
632
643
  generatedBy: '@file-viewer/vite-plugin'
633
644
  };
645
+ const autoRegistrationId = selection.descriptors.length
646
+ ? '@file-viewer/vite-plugin:configured'
647
+ : selection.preset && !autoPresetModules.length
648
+ ? selection.preset
649
+ : !selection.preset && autoPresetModules.length === 1
650
+ ? autoPresetModules[0].id
651
+ : '@file-viewer/vite-plugin:configured';
634
652
  return [
653
+ `import { registerFileViewerAutoRendererPreset } from '@file-viewer/core';`,
635
654
  ...[presetImport].filter(Boolean),
655
+ ...autoPresetImports,
636
656
  ...rendererImports,
637
657
  '',
638
658
  `export const configuredFileViewerRenderers = [${rendererNames.join(', ')}];`,
639
659
  `export const fileViewerRendererPlan = ${JSON.stringify(plan, null, 2)};`,
660
+ `registerFileViewerAutoRendererPreset(configuredFileViewerRenderers, { id: ${JSON.stringify(autoRegistrationId)} });`,
640
661
  'export default configuredFileViewerRenderers;',
641
662
  ''
642
663
  ].join('\n');
@@ -648,10 +669,14 @@ function hasManualChunks(config) {
648
669
  }
649
670
  return Boolean(output?.manualChunks);
650
671
  }
651
- function createManualChunks(selection) {
672
+ function createManualChunks(selection, autoPresetIds = []) {
652
673
  const packageToChunk = new Map();
653
- if (selection.preset) {
654
- const presetModule = presetModules[selection.preset];
674
+ const presetIds = unique([
675
+ ...(selection.preset ? [selection.preset] : []),
676
+ ...autoPresetIds
677
+ ]);
678
+ presetIds.forEach((presetId) => {
679
+ const presetModule = presetModules[presetId];
655
680
  packageToChunk.set(presetModule.packageName, presetModule.chunkName);
656
681
  presetModule.rendererIds
657
682
  .map((id) => descriptorsById.get(id))
@@ -659,7 +684,7 @@ function createManualChunks(selection) {
659
684
  .forEach((descriptor) => {
660
685
  packageToChunk.set(descriptor.packageName, descriptor.chunkName);
661
686
  });
662
- }
687
+ });
663
688
  selection.descriptors.forEach((descriptor) => {
664
689
  packageToChunk.set(descriptor.packageName, descriptor.chunkName);
665
690
  });
@@ -763,6 +788,39 @@ function resolvePackageJson(packageName, anchorPackages = []) {
763
788
  }
764
789
  return resolveWorkspacePackageJson(packageName);
765
790
  }
791
+ function hasExplicitRendererSelection(options) {
792
+ return Boolean(resolveManualPreset(options.preset) ||
793
+ options.formats?.length ||
794
+ options.renderers?.length ||
795
+ options.scan);
796
+ }
797
+ function shouldAutoDiscoverPresets(options) {
798
+ if (Array.isArray(options.autoPresets)) {
799
+ return true;
800
+ }
801
+ if (typeof options.autoPresets === 'boolean') {
802
+ return options.autoPresets;
803
+ }
804
+ return options.preset === 'auto' || !hasExplicitRendererSelection(options);
805
+ }
806
+ function resolveAutoPresetIds(options) {
807
+ if (!shouldAutoDiscoverPresets(options)) {
808
+ return [];
809
+ }
810
+ const candidates = Array.isArray(options.autoPresets)
811
+ ? options.autoPresets
812
+ : Object.keys(presetModules);
813
+ const installed = unique(candidates).filter((presetId) => Boolean(resolvePackageJson(presetModules[presetId].packageName)));
814
+ return installed.includes('all') ? ['all'] : installed;
815
+ }
816
+ function collectSelectedPackages(selection, autoPresetIds = []) {
817
+ const presetModule = selection.preset ? presetModules[selection.preset] : null;
818
+ return unique([
819
+ ...(presetModule ? [presetModule.packageName] : []),
820
+ ...autoPresetIds.map((presetId) => presetModules[presetId].packageName),
821
+ ...selection.descriptors.map((descriptor) => descriptor.packageName)
822
+ ]);
823
+ }
766
824
  function resolvePackageRoot(packageName, anchorPackages = []) {
767
825
  const packageJson = resolvePackageJson(packageName, anchorPackages);
768
826
  return packageJson ? dirname(packageJson) : null;
@@ -849,10 +907,11 @@ function resolveTargetDir(value, fallback) {
849
907
  function copyOptions(value) {
850
908
  return typeof value === 'object' ? value : {};
851
909
  }
852
- function collectAssetRendererIds(selection) {
853
- const presetIds = selection.preset
854
- ? expandDescriptorRendererIds(presetModules[selection.preset].rendererIds)
855
- : [];
910
+ function collectAssetRendererIds(selection, autoPresetIds = []) {
911
+ const presetIds = [
912
+ ...(selection.preset ? expandDescriptorRendererIds(presetModules[selection.preset].rendererIds) : []),
913
+ ...autoPresetIds.flatMap((presetId) => expandDescriptorRendererIds(presetModules[presetId].rendererIds))
914
+ ];
856
915
  return unique([
857
916
  ...presetIds,
858
917
  ...selection.descriptors.flatMap((descriptor) => descriptor.rendererIds)
@@ -890,6 +949,7 @@ export function fileViewerRenderers(options = {}) {
890
949
  ...options,
891
950
  formats: [...(options.formats || []), ...scanFormats]
892
951
  });
952
+ let autoPresetIds = resolveAutoPresetIds(options);
893
953
  let resolvedConfig = null;
894
954
  const refreshSelection = (projectRoot) => {
895
955
  if (projectRoot) {
@@ -900,7 +960,9 @@ export function fileViewerRenderers(options = {}) {
900
960
  ...options,
901
961
  formats: [...(options.formats || []), ...scanFormats]
902
962
  });
963
+ autoPresetIds = resolveAutoPresetIds(options);
903
964
  };
965
+ const hasConfiguredRenderers = () => Boolean(selection.preset || selection.descriptors.length || autoPresetIds.length);
904
966
  return {
905
967
  name: 'file-viewer-renderers',
906
968
  enforce: 'pre',
@@ -914,7 +976,7 @@ export function fileViewerRenderers(options = {}) {
914
976
  build: {
915
977
  rollupOptions: {
916
978
  output: {
917
- manualChunks: createManualChunks(selection)
979
+ manualChunks: createManualChunks(selection, autoPresetIds)
918
980
  }
919
981
  }
920
982
  }
@@ -926,10 +988,7 @@ export function fileViewerRenderers(options = {}) {
926
988
  },
927
989
  buildStart() {
928
990
  assertMissingRendererPolicy(selection, missingMode);
929
- const packages = unique([
930
- ...(selection.preset ? [presetModules[selection.preset].packageName] : []),
931
- ...selection.descriptors.map((descriptor) => descriptor.packageName)
932
- ]);
991
+ const packages = collectSelectedPackages(selection, autoPresetIds);
933
992
  const missingPackages = packages.filter((packageName) => !resolvePackageJson(packageName));
934
993
  if (missingPackages.length && missingMode !== 'ignore') {
935
994
  const message = `Missing File Viewer preset/renderer package(s): ${missingPackages.join(', ')}. Install them or remove the matching preset/formats from @file-viewer/vite-plugin.`;
@@ -946,9 +1005,22 @@ export function fileViewerRenderers(options = {}) {
946
1005
  return;
947
1006
  }
948
1007
  const targetRoot = resolveTargetDir(copyOptions(options.copyAssets).publicDir, resolvedConfig?.publicDir || 'public');
949
- const results = await copyKnownRendererAssets(targetRoot, collectAssetRendererIds(selection));
1008
+ const results = await copyKnownRendererAssets(targetRoot, collectAssetRendererIds(selection, autoPresetIds));
950
1009
  reportAssetCopy(results, targetRoot, missingMode);
951
1010
  },
1011
+ transformIndexHtml() {
1012
+ if (options.inject === false || !hasConfiguredRenderers()) {
1013
+ return undefined;
1014
+ }
1015
+ return [
1016
+ {
1017
+ tag: 'script',
1018
+ attrs: { type: 'module' },
1019
+ children: `import ${JSON.stringify(moduleId)};`,
1020
+ injectTo: 'head'
1021
+ }
1022
+ ];
1023
+ },
952
1024
  handleHotUpdate(context) {
953
1025
  if (!options.scan || !resolvedConfig) {
954
1026
  return undefined;
@@ -978,7 +1050,7 @@ export function fileViewerRenderers(options = {}) {
978
1050
  }
979
1051
  const outDir = resolvedConfig?.build.outDir || 'dist';
980
1052
  const targetRoot = resolveTargetDir(copyOptions(options.copyAssets).outDir, outDir);
981
- const results = await copyKnownRendererAssets(targetRoot, collectAssetRendererIds(selection));
1053
+ const results = await copyKnownRendererAssets(targetRoot, collectAssetRendererIds(selection, autoPresetIds));
982
1054
  reportAssetCopy(results, targetRoot, missingMode);
983
1055
  },
984
1056
  resolveId(id) {
@@ -989,14 +1061,14 @@ export function fileViewerRenderers(options = {}) {
989
1061
  },
990
1062
  load(id) {
991
1063
  if (id === resolvedModuleId || id === resolvedVirtualModuleId) {
992
- return renderVirtualModule(selection, requestedFormats);
1064
+ return renderVirtualModule(selection, requestedFormats, autoPresetIds);
993
1065
  }
994
1066
  return undefined;
995
1067
  }
996
1068
  };
997
1069
  }
998
1070
  export function createFileViewerManualChunks(options = {}) {
999
- return createManualChunks(selectRenderers(options));
1071
+ return createManualChunks(selectRenderers(options), resolveAutoPresetIds(options));
1000
1072
  }
1001
1073
  export function resolveFileViewerRendererSelection(options = {}, projectRoot = process.cwd()) {
1002
1074
  const scanFormats = collectFileViewerRendererScanTokens(projectRoot, options.scan);
@@ -1010,17 +1082,19 @@ export function resolveFileViewerRendererSelection(options = {}, projectRoot = p
1010
1082
  formats: [...(options.formats || []), ...scanFormats]
1011
1083
  });
1012
1084
  const presetModule = selection.preset ? presetModules[selection.preset] : null;
1013
- const packages = unique([
1014
- ...(presetModule ? [presetModule.packageName] : []),
1015
- ...selection.descriptors.map((descriptor) => descriptor.packageName)
1016
- ]);
1085
+ const autoPresetIds = resolveAutoPresetIds(options);
1086
+ const autoPresetModules = autoPresetIds.map((presetId) => presetModules[presetId]);
1087
+ const packages = collectSelectedPackages(selection, autoPresetIds);
1017
1088
  return {
1018
1089
  preset: selection.preset,
1019
1090
  presetPackage: presetModule?.packageName ?? null,
1091
+ autoPresets: autoPresetModules.map((preset) => preset.id),
1092
+ autoPresetPackages: autoPresetModules.map((preset) => preset.packageName),
1020
1093
  formats: requestedFormats,
1021
1094
  packages,
1022
1095
  rendererIds: unique([
1023
1096
  ...(presetModule ? expandDescriptorRendererIds(presetModule.rendererIds) : []),
1097
+ ...autoPresetModules.flatMap((preset) => expandDescriptorRendererIds(preset.rendererIds)),
1024
1098
  ...selection.descriptors.flatMap((descriptor) => descriptor.rendererIds)
1025
1099
  ]),
1026
1100
  renderers: selection.descriptors.map((descriptor) => ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/vite-plugin",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Vite plugin for Flyfish File Viewer on-demand renderer assembly, chunk planning, and offline asset deployment.",