@playcraft/build 0.0.13 → 0.0.15

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 (82) hide show
  1. package/dist/analyzers/scene-asset-collector.js +99 -9
  2. package/dist/base-builder.d.ts +15 -78
  3. package/dist/base-builder.js +34 -741
  4. package/dist/engines/engine-detector.d.ts +38 -0
  5. package/dist/engines/engine-detector.js +201 -0
  6. package/dist/engines/generic-adapter.d.ts +71 -0
  7. package/dist/engines/generic-adapter.js +378 -0
  8. package/dist/engines/index.d.ts +7 -0
  9. package/dist/engines/index.js +7 -0
  10. package/dist/engines/playcanvas-adapter.d.ts +85 -0
  11. package/dist/engines/playcanvas-adapter.js +813 -0
  12. package/dist/generators/config-generator.js +59 -1
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.js +4 -0
  15. package/dist/loaders/playcraft-loader.js +240 -5
  16. package/dist/platforms/adikteev.d.ts +1 -1
  17. package/dist/platforms/adikteev.js +30 -36
  18. package/dist/platforms/applovin.d.ts +1 -1
  19. package/dist/platforms/applovin.js +31 -36
  20. package/dist/platforms/base.d.ts +27 -5
  21. package/dist/platforms/base.js +79 -181
  22. package/dist/platforms/bigo.d.ts +1 -1
  23. package/dist/platforms/bigo.js +28 -28
  24. package/dist/platforms/facebook.d.ts +1 -1
  25. package/dist/platforms/facebook.js +21 -10
  26. package/dist/platforms/google.d.ts +1 -1
  27. package/dist/platforms/google.js +28 -21
  28. package/dist/platforms/index.d.ts +1 -0
  29. package/dist/platforms/index.js +4 -0
  30. package/dist/platforms/inmobi.d.ts +1 -1
  31. package/dist/platforms/inmobi.js +27 -34
  32. package/dist/platforms/ironsource.d.ts +1 -1
  33. package/dist/platforms/ironsource.js +37 -40
  34. package/dist/platforms/liftoff.d.ts +1 -1
  35. package/dist/platforms/liftoff.js +22 -30
  36. package/dist/platforms/mintegral.d.ts +10 -0
  37. package/dist/platforms/mintegral.js +65 -0
  38. package/dist/platforms/moloco.d.ts +1 -1
  39. package/dist/platforms/moloco.js +18 -20
  40. package/dist/platforms/playcraft.d.ts +1 -1
  41. package/dist/platforms/playcraft.js +2 -2
  42. package/dist/platforms/remerge.d.ts +1 -1
  43. package/dist/platforms/remerge.js +19 -20
  44. package/dist/platforms/snapchat.d.ts +1 -1
  45. package/dist/platforms/snapchat.js +32 -26
  46. package/dist/platforms/tiktok.d.ts +1 -1
  47. package/dist/platforms/tiktok.js +28 -24
  48. package/dist/platforms/unity.d.ts +1 -1
  49. package/dist/platforms/unity.js +30 -36
  50. package/dist/playable-builder.d.ts +1 -0
  51. package/dist/playable-builder.js +16 -2
  52. package/dist/types.d.ts +113 -1
  53. package/dist/types.js +77 -1
  54. package/dist/utils/ammo-detector.d.ts +9 -0
  55. package/dist/utils/ammo-detector.js +76 -0
  56. package/dist/utils/build-mode-detector.js +2 -0
  57. package/dist/utils/minify.d.ts +32 -0
  58. package/dist/utils/minify.js +82 -0
  59. package/dist/utils/obfuscate.d.ts +42 -0
  60. package/dist/utils/obfuscate.js +216 -0
  61. package/dist/vite/config-builder-generic.d.ts +70 -0
  62. package/dist/vite/config-builder-generic.js +251 -0
  63. package/dist/vite/config-builder.d.ts +8 -0
  64. package/dist/vite/config-builder.js +53 -16
  65. package/dist/vite/platform-configs.js +29 -1
  66. package/dist/vite/plugin-compress-js.d.ts +21 -0
  67. package/dist/vite/plugin-compress-js.js +213 -0
  68. package/dist/vite/plugin-esm-html-generator.js +5 -1
  69. package/dist/vite/plugin-obfuscate.d.ts +22 -0
  70. package/dist/vite/plugin-obfuscate.js +52 -0
  71. package/dist/vite/plugin-platform.d.ts +5 -0
  72. package/dist/vite/plugin-platform.js +499 -35
  73. package/dist/vite/plugin-playcanvas.js +21 -68
  74. package/dist/vite/plugin-source-builder.js +102 -21
  75. package/dist/vite-builder.d.ts +25 -7
  76. package/dist/vite-builder.js +141 -52
  77. package/package.json +4 -2
  78. package/physics/cannon-rigidbody-adapter.js +243 -22
  79. package/templates/__loading__.js +0 -12
  80. package/templates/index.esm.mjs +0 -11
  81. package/templates/patches/playcraft-cta-adapter.js +129 -31
  82. package/templates/patches/scene-physics-defaults.js +49 -0
@@ -71,6 +71,7 @@ export declare class PlayableBuilder {
71
71
  private extractPreloadModules;
72
72
  private stripAmmoAssets;
73
73
  private injectPhysicsLibrary;
74
+ private injectScenePhysicsPatch;
74
75
  private isAmmoModule;
75
76
  private readPatchFile;
76
77
  /**
@@ -2,6 +2,7 @@ import fs from 'fs/promises';
2
2
  import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { createPlatformAdapter } from './platforms/index.js';
5
+ import { minifyPatchCode } from './utils/minify.js';
5
6
  /**
6
7
  * Playable Ads 打包器 - 将多文件版本转换为单HTML
7
8
  *
@@ -31,8 +32,8 @@ export class PlayableBuilder {
31
32
  await this.validateBaseBuild();
32
33
  // 2. 转换为单HTML
33
34
  const html = await this.convertToSingleHTML();
34
- // 3. 应用渠道配置
35
- const finalHtml = this.platformAdapter.modifyHTML(html, []);
35
+ // 3. 应用渠道配置(现在是异步的)
36
+ const finalHtml = await this.platformAdapter.modifyHTML(html, []);
36
37
  // 4. 验证大小限制
37
38
  const htmlSize = Buffer.from(finalHtml, 'utf-8').length;
38
39
  this.sizeReport.total = htmlSize;
@@ -87,6 +88,8 @@ export class PlayableBuilder {
87
88
  if (this.options.ammoReplacement) {
88
89
  html = await this.injectPhysicsLibrary(html);
89
90
  }
91
+ // 4.2 注入 Scene applySettings 补丁,避免 settings.physics 缺失导致 gravity 报错
92
+ html = await this.injectScenePhysicsPatch(html);
90
93
  // 5. 内联 __settings__.js,并转换资源URL为data URLs
91
94
  html = await this.inlineSettings(html);
92
95
  // 6. 内联 __modules__.js
@@ -478,6 +481,17 @@ window.PRELOAD_MODULES = ${JSON.stringify(preloadModules)};
478
481
  }
479
482
  return `${tag}\n${html}`;
480
483
  }
484
+ async injectScenePhysicsPatch(html) {
485
+ const patchCode = await this.readPatchFile('scene-physics-defaults.js');
486
+ if (!patchCode)
487
+ return html;
488
+ const minified = await minifyPatchCode(patchCode, 'scene-physics-defaults.js');
489
+ const tag = `<script>${minified}</script>`;
490
+ if (html.includes('</head>')) {
491
+ return html.replace('</head>', `${tag}\n</head>`);
492
+ }
493
+ return `${tag}\n${html}`;
494
+ }
481
495
  isAmmoModule(module) {
482
496
  const moduleName = module.moduleName?.toLowerCase() ?? '';
483
497
  const glueUrl = module.glueUrl?.toLowerCase() ?? '';
package/dist/types.d.ts CHANGED
@@ -1,5 +1,12 @@
1
- export type Platform = 'playcraft' | 'facebook' | 'snapchat' | 'ironsource' | 'applovin' | 'google' | 'tiktok' | 'unity' | 'liftoff' | 'moloco' | 'bigo' | 'inmobi' | 'adikteev' | 'remerge';
1
+ export type Platform = 'playcraft' | 'facebook' | 'snapchat' | 'ironsource' | 'applovin' | 'google' | 'tiktok' | 'unity' | 'liftoff' | 'moloco' | 'bigo' | 'inmobi' | 'adikteev' | 'remerge' | 'mintegral';
2
2
  export type OutputFormat = 'html' | 'zip';
3
+ /**
4
+ * 商店跳转地址(CTA 按钮目标)
5
+ */
6
+ export interface StoreUrls {
7
+ ios?: string;
8
+ android?: string;
9
+ }
3
10
  export type BuildMode = 'classic' | 'esm';
4
11
  export type ESMMode = 'auto' | 'enabled' | 'disabled';
5
12
  export interface BuildOptions {
@@ -8,6 +15,7 @@ export interface BuildOptions {
8
15
  outputDir?: string;
9
16
  compressEngine?: boolean;
10
17
  compressConfigJson?: boolean;
18
+ compressJS?: boolean;
11
19
  analyze?: boolean;
12
20
  analyzeReportPath?: string;
13
21
  patchXhrOut?: boolean;
@@ -39,6 +47,7 @@ export interface BuildOptions {
39
47
  esmMode?: ESMMode;
40
48
  preserveESM?: boolean;
41
49
  forceIIFE?: boolean;
50
+ storeUrls?: StoreUrls;
42
51
  }
43
52
  export interface BaseBuildMetadata {
44
53
  mode: BuildMode;
@@ -103,3 +112,106 @@ export interface SizeReport {
103
112
  total: number;
104
113
  limit: number;
105
114
  }
115
+ /**
116
+ * 支持的引擎类型
117
+ */
118
+ export type EngineType = 'playcanvas' | 'phaser' | 'pixijs' | 'threejs' | 'cocos' | 'babylonjs' | 'layaair' | 'egret' | 'generic';
119
+ /**
120
+ * 引擎能力集,驱动前端 UI 和 CLI 的条件逻辑
121
+ */
122
+ export interface EngineCapabilities {
123
+ supportsSceneSelection: boolean;
124
+ supportsESMMode: boolean;
125
+ supportsEngineCompression: boolean;
126
+ supportsAmmoReplacement: boolean;
127
+ supportsModelCompression: boolean;
128
+ requiresNpmBuild: boolean;
129
+ }
130
+ /**
131
+ * 各引擎的能力定义
132
+ */
133
+ export declare const ENGINE_CAPABILITIES: Record<EngineType, EngineCapabilities>;
134
+ /**
135
+ * 基础构建选项
136
+ */
137
+ export interface BaseBuildOptions {
138
+ outputDir: string;
139
+ selectedScenes?: string[];
140
+ analyze?: boolean;
141
+ analyzeReportPath?: string;
142
+ clean?: boolean;
143
+ engine?: EngineType;
144
+ }
145
+ /**
146
+ * 基础构建输出
147
+ */
148
+ export interface BaseBuildOutput {
149
+ outputDir: string;
150
+ metadata: BaseBuildMetadata;
151
+ files: {
152
+ html: string;
153
+ engine: string | null;
154
+ config: string;
155
+ settings: string | null;
156
+ modules: string | null;
157
+ start: string;
158
+ scenes: string[];
159
+ assets: string[];
160
+ };
161
+ }
162
+ /**
163
+ * 扩展 BaseBuildMetadata,增加引擎类型
164
+ */
165
+ export interface BaseBuildMetadata {
166
+ mode: BuildMode;
167
+ engine: EngineType;
168
+ importMap?: {
169
+ id: string;
170
+ imports: Record<string, string>;
171
+ };
172
+ entryPoint?: string;
173
+ buildOutputDir?: string;
174
+ }
175
+ /**
176
+ * 扩展 BuildOptions,增加引擎类型
177
+ */
178
+ export interface BuildOptions {
179
+ platform: Platform;
180
+ format?: OutputFormat;
181
+ outputDir?: string;
182
+ compressEngine?: boolean;
183
+ compressConfigJson?: boolean;
184
+ analyze?: boolean;
185
+ analyzeReportPath?: string;
186
+ patchXhrOut?: boolean;
187
+ inlineGameScripts?: boolean;
188
+ externFiles?: boolean | ExternFilesConfig;
189
+ mraidSupport?: boolean;
190
+ snapchatCta?: boolean;
191
+ ammoReplacement?: 'p2' | 'cannon';
192
+ snapchat?: {
193
+ folderName?: string;
194
+ externalUrlPrefix?: string;
195
+ };
196
+ engineVersion?: string;
197
+ engineUrl?: string;
198
+ enginePath?: string;
199
+ useGitHubEngine?: boolean;
200
+ autoBuild?: boolean;
201
+ skipBuild?: boolean;
202
+ buildOptions?: LocalBuildOptions;
203
+ useVite?: boolean;
204
+ selectedScenes?: string[];
205
+ cssMinify?: boolean;
206
+ jsMinify?: boolean;
207
+ compressImages?: boolean;
208
+ imageQuality?: number;
209
+ convertToWebP?: boolean;
210
+ compressModels?: boolean;
211
+ modelCompression?: 'draco' | 'meshopt';
212
+ esmMode?: ESMMode;
213
+ preserveESM?: boolean;
214
+ forceIIFE?: boolean;
215
+ engine?: EngineType;
216
+ storeUrls?: StoreUrls;
217
+ }
package/dist/types.js CHANGED
@@ -1 +1,77 @@
1
- export {};
1
+ /**
2
+ * 各引擎的能力定义
3
+ */
4
+ export const ENGINE_CAPABILITIES = {
5
+ playcanvas: {
6
+ supportsSceneSelection: true,
7
+ supportsESMMode: true,
8
+ supportsEngineCompression: true,
9
+ supportsAmmoReplacement: true,
10
+ supportsModelCompression: true,
11
+ requiresNpmBuild: false,
12
+ },
13
+ phaser: {
14
+ supportsSceneSelection: false,
15
+ supportsESMMode: false,
16
+ supportsEngineCompression: false,
17
+ supportsAmmoReplacement: false,
18
+ supportsModelCompression: false,
19
+ requiresNpmBuild: true,
20
+ },
21
+ pixijs: {
22
+ supportsSceneSelection: false,
23
+ supportsESMMode: false,
24
+ supportsEngineCompression: false,
25
+ supportsAmmoReplacement: false,
26
+ supportsModelCompression: false,
27
+ requiresNpmBuild: true,
28
+ },
29
+ threejs: {
30
+ supportsSceneSelection: false,
31
+ supportsESMMode: false,
32
+ supportsEngineCompression: false,
33
+ supportsAmmoReplacement: false,
34
+ supportsModelCompression: true, // Three.js 支持 3D 模型
35
+ requiresNpmBuild: true,
36
+ },
37
+ cocos: {
38
+ supportsSceneSelection: false,
39
+ supportsESMMode: false,
40
+ supportsEngineCompression: false,
41
+ supportsAmmoReplacement: false,
42
+ supportsModelCompression: false,
43
+ requiresNpmBuild: true,
44
+ },
45
+ babylonjs: {
46
+ supportsSceneSelection: false,
47
+ supportsESMMode: false,
48
+ supportsEngineCompression: false,
49
+ supportsAmmoReplacement: false,
50
+ supportsModelCompression: true, // Babylon.js 支持 3D 模型
51
+ requiresNpmBuild: true,
52
+ },
53
+ layaair: {
54
+ supportsSceneSelection: false,
55
+ supportsESMMode: false,
56
+ supportsEngineCompression: false,
57
+ supportsAmmoReplacement: false,
58
+ supportsModelCompression: false,
59
+ requiresNpmBuild: true,
60
+ },
61
+ egret: {
62
+ supportsSceneSelection: false,
63
+ supportsESMMode: false,
64
+ supportsEngineCompression: false,
65
+ supportsAmmoReplacement: false,
66
+ supportsModelCompression: false,
67
+ requiresNpmBuild: true,
68
+ },
69
+ generic: {
70
+ supportsSceneSelection: false,
71
+ supportsESMMode: false,
72
+ supportsEngineCompression: false,
73
+ supportsAmmoReplacement: false,
74
+ supportsModelCompression: false,
75
+ requiresNpmBuild: true,
76
+ },
77
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 检测 Base Build 是否使用 Ammo.js 及建议的替换引擎
3
+ * 与 CLI 的 detectAmmoUsage 逻辑一致
4
+ */
5
+ export declare function detectAmmoUsage(baseBuildDir: string): Promise<{
6
+ hasAmmo: boolean;
7
+ suggestedEngine: 'p2' | 'cannon';
8
+ use3dPhysics: boolean;
9
+ }>;
@@ -0,0 +1,76 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ function resolveSuggestedPhysicsEngine(use3dPhysics) {
4
+ return use3dPhysics ? 'cannon' : 'p2';
5
+ }
6
+ /**
7
+ * 检测 Base Build 是否使用 Ammo.js 及建议的替换引擎
8
+ * 与 CLI 的 detectAmmoUsage 逻辑一致
9
+ */
10
+ export async function detectAmmoUsage(baseBuildDir) {
11
+ const configPath = path.join(baseBuildDir, 'config.json');
12
+ let hasAmmo = false;
13
+ let use3dPhysics = false;
14
+ try {
15
+ const configContent = await fs.readFile(configPath, 'utf-8');
16
+ const configJson = JSON.parse(configContent);
17
+ // 检查 application_properties.use3dPhysics
18
+ use3dPhysics = Boolean(configJson.application_properties?.use3dPhysics);
19
+ // 如果 use3dPhysics 未设置,通过检查场景内容来推断
20
+ if (!use3dPhysics) {
21
+ try {
22
+ const files = await fs.readdir(baseBuildDir);
23
+ for (const file of files) {
24
+ if (file.endsWith('.json') && !['config.json', 'manifest.json'].includes(file)) {
25
+ try {
26
+ const sceneContent = await fs.readFile(path.join(baseBuildDir, file), 'utf-8');
27
+ if (sceneContent.includes('"rigidbody"') ||
28
+ sceneContent.includes('"collision"') ||
29
+ sceneContent.includes('"joint"')) {
30
+ use3dPhysics = true;
31
+ break;
32
+ }
33
+ }
34
+ catch {
35
+ /* 忽略 */
36
+ }
37
+ }
38
+ }
39
+ }
40
+ catch {
41
+ /* 忽略 */
42
+ }
43
+ }
44
+ if (configJson.assets) {
45
+ for (const asset of Object.values(configJson.assets)) {
46
+ const assetData = asset;
47
+ const moduleName = String(assetData?.data?.moduleName ?? '').toLowerCase();
48
+ const fileUrl = String(assetData?.file?.url ?? '').toLowerCase();
49
+ if (moduleName.includes('ammo') || fileUrl.includes('ammo')) {
50
+ hasAmmo = true;
51
+ break;
52
+ }
53
+ }
54
+ }
55
+ }
56
+ catch {
57
+ /* 忽略解析失败 */
58
+ }
59
+ if (!hasAmmo) {
60
+ try {
61
+ const settingsPath = path.join(baseBuildDir, '__settings__.js');
62
+ const settingsContent = await fs.readFile(settingsPath, 'utf-8');
63
+ if (settingsContent.toLowerCase().includes('ammo')) {
64
+ hasAmmo = true;
65
+ }
66
+ }
67
+ catch {
68
+ /* 忽略读取失败 */
69
+ }
70
+ }
71
+ return {
72
+ hasAmmo,
73
+ suggestedEngine: resolveSuggestedPhysicsEngine(use3dPhysics),
74
+ use3dPhysics,
75
+ };
76
+ }
@@ -15,6 +15,7 @@ export async function detectBuildMode(baseBuildDir) {
15
15
  const importMapContent = importMapMatch ? JSON.parse(importMapMatch[1]) : { imports: {} };
16
16
  return {
17
17
  mode: 'esm',
18
+ engine: 'playcanvas', // 默认 PlayCanvas,从元数据文件读取时会覆盖
18
19
  importMap: {
19
20
  id: 'detected',
20
21
  imports: importMapContent.imports || {},
@@ -25,6 +26,7 @@ export async function detectBuildMode(baseBuildDir) {
25
26
  // Classic 模式
26
27
  return {
27
28
  mode: 'classic',
29
+ engine: 'playcanvas', // 默认 PlayCanvas,从元数据文件读取时会覆盖
28
30
  };
29
31
  }
30
32
  /**
@@ -0,0 +1,32 @@
1
+ /**
2
+ * 压缩 JavaScript 代码
3
+ * @param code - 原始 JavaScript 代码
4
+ * @param options - 压缩选项
5
+ * @returns 压缩后的代码
6
+ */
7
+ export declare function minifyJS(code: string, options?: {
8
+ /** 是否移除注释,默认 true */
9
+ removeComments?: boolean;
10
+ /** 是否混淆变量名,默认 true */
11
+ mangle?: boolean;
12
+ /** 是否进行代码压缩优化,默认 true */
13
+ compress?: boolean;
14
+ /** 是否为 ESM 模块(含 import/export),默认 false */
15
+ module?: boolean;
16
+ }): Promise<string>;
17
+ /**
18
+ * 同步版本的压缩(使用预压缩的代码)
19
+ * 注意:这个函数用于需要同步返回的场景,实际压缩应在构建时完成
20
+ */
21
+ export declare function minifyJSSync(code: string): string;
22
+ /**
23
+ * 读取并压缩 patch 文件(带缓存)
24
+ * @param patchCode - patch 文件内容
25
+ * @param cacheKey - 缓存键(通常是文件名)
26
+ * @returns 压缩后的代码
27
+ */
28
+ export declare function minifyPatchCode(patchCode: string, cacheKey?: string): Promise<string>;
29
+ /**
30
+ * 清除压缩缓存
31
+ */
32
+ export declare function clearMinifyCache(): void;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * JavaScript 代码压缩工具
3
+ * 用于压缩 patch 脚本和内联代码
4
+ */
5
+ import { minify as terserMinify } from 'terser';
6
+ /**
7
+ * 压缩 JavaScript 代码
8
+ * @param code - 原始 JavaScript 代码
9
+ * @param options - 压缩选项
10
+ * @returns 压缩后的代码
11
+ */
12
+ export async function minifyJS(code, options) {
13
+ const { removeComments = true, mangle = true, compress = true, module: isModule = false, } = options || {};
14
+ try {
15
+ const result = await terserMinify(code, {
16
+ module: isModule,
17
+ compress: compress ? {
18
+ dead_code: true,
19
+ drop_console: false,
20
+ drop_debugger: true,
21
+ passes: 3,
22
+ } : false,
23
+ mangle: mangle ? {
24
+ toplevel: true,
25
+ } : false,
26
+ format: {
27
+ comments: removeComments ? false : 'some',
28
+ },
29
+ });
30
+ return result.code || code;
31
+ }
32
+ catch (error) {
33
+ console.warn('[minifyJS] 压缩失败,返回原始代码:', error);
34
+ return code;
35
+ }
36
+ }
37
+ /**
38
+ * 同步版本的压缩(使用预压缩的代码)
39
+ * 注意:这个函数用于需要同步返回的场景,实际压缩应在构建时完成
40
+ */
41
+ export function minifyJSSync(code) {
42
+ // 简单的压缩:移除多余空白和注释
43
+ return code
44
+ // 移除单行注释(但保留 URL 中的 //)
45
+ .replace(/(?<!:)\/\/.*$/gm, '')
46
+ // 移除多行注释
47
+ .replace(/\/\*[\s\S]*?\*\//g, '')
48
+ // 压缩空白
49
+ .replace(/\s+/g, ' ')
50
+ // 移除语句间多余空格
51
+ .replace(/\s*([{};,:])\s*/g, '$1')
52
+ // 移除括号周围空格
53
+ .replace(/\s*([()])\s*/g, '$1')
54
+ // 修复一些被过度压缩的地方
55
+ .replace(/}([a-zA-Z])/g, '} $1')
56
+ .replace(/;([a-zA-Z])/g, ';$1')
57
+ .trim();
58
+ }
59
+ // 缓存已压缩的 patch 文件
60
+ const minifiedCache = new Map();
61
+ /**
62
+ * 读取并压缩 patch 文件(带缓存)
63
+ * @param patchCode - patch 文件内容
64
+ * @param cacheKey - 缓存键(通常是文件名)
65
+ * @returns 压缩后的代码
66
+ */
67
+ export async function minifyPatchCode(patchCode, cacheKey) {
68
+ if (cacheKey && minifiedCache.has(cacheKey)) {
69
+ return minifiedCache.get(cacheKey);
70
+ }
71
+ const minified = await minifyJS(patchCode);
72
+ if (cacheKey) {
73
+ minifiedCache.set(cacheKey, minified);
74
+ }
75
+ return minified;
76
+ }
77
+ /**
78
+ * 清除压缩缓存
79
+ */
80
+ export function clearMinifyCache() {
81
+ minifiedCache.clear();
82
+ }
@@ -0,0 +1,42 @@
1
+ export type ObfuscateLevel = 'light' | 'medium' | 'heavy';
2
+ export declare function getFflateInflateRuntime(): string;
3
+ /**
4
+ * 对 JS 代码进行混淆 + fflate 压缩,生成自解压 bootstrap
5
+ */
6
+ export declare function obfuscateAndCompress(jsCode: string, level?: ObfuscateLevel): Promise<{
7
+ /** fflate inflate 运行时脚本(<script>标签) */
8
+ runtime: string;
9
+ /** 自解压 bootstrap 脚本(<script>标签) */
10
+ bootstrap: string;
11
+ /** 原始代码大小 */
12
+ originalSize: number;
13
+ /** 混淆后大小 */
14
+ obfuscatedSize: number;
15
+ /** 压缩后大小(binary) */
16
+ compressedSize: number;
17
+ /** 最终大小(base64 + bootstrap) */
18
+ finalSize: number;
19
+ }>;
20
+ /**
21
+ * 使用 fflate 压缩引擎代码(替换 LZ4)
22
+ * 不做混淆,只做压缩
23
+ */
24
+ export declare function compressWithFflate(code: string): {
25
+ runtime: string;
26
+ compressed: string;
27
+ originalSize: number;
28
+ compressedSize: number;
29
+ };
30
+ /**
31
+ * 使用 fflate 压缩 config.json(替换 LZ4)
32
+ */
33
+ export declare function compressConfigJsonWithFflate(jsonString: string): {
34
+ dataUrl: string;
35
+ originalSize: number;
36
+ compressedSize: number;
37
+ };
38
+ /**
39
+ * 构建 config.json 解压 patch(fflate 版本)
40
+ * 拦截 pc.Http.prototype.get,检测 fflate 压缩的 JSON 并解压
41
+ */
42
+ export declare function buildFflateConfigDecompressPatch(): string;