@steambrew/ttc 2.6.3 → 2.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,25 +4,26 @@ import path, { dirname } from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { readFile } from 'fs/promises';
6
6
  import fs, { existsSync, readFile as readFile$1 } from 'fs';
7
- import { rollup } from 'rollup';
8
- import json from '@rollup/plugin-json';
7
+ import babel from '@rollup/plugin-babel';
9
8
  import commonjs from '@rollup/plugin-commonjs';
10
- import replace from '@rollup/plugin-replace';
11
- import typescript from '@rollup/plugin-typescript';
9
+ import json from '@rollup/plugin-json';
12
10
  import resolve, { nodeResolve } from '@rollup/plugin-node-resolve';
11
+ import replace from '@rollup/plugin-replace';
13
12
  import terser from '@rollup/plugin-terser';
14
- import babel from '@rollup/plugin-babel';
15
- import nodePolyfills from 'rollup-plugin-polyfill-node';
13
+ import typescript from '@rollup/plugin-typescript';
16
14
  import url from '@rollup/plugin-url';
15
+ import { rollup } from 'rollup';
16
+ import nodePolyfills from 'rollup-plugin-polyfill-node';
17
+ import { minify_sync } from 'terser';
17
18
  import scss from 'rollup-plugin-scss';
18
19
  import * as sass from 'sass';
19
- import injectProcessEnv from 'rollup-plugin-inject-process-env';
20
20
  import dotenv from 'dotenv';
21
- import { createFilter } from '@rollup/pluginutils';
22
- import MagicString from 'magic-string';
21
+ import injectProcessEnv from 'rollup-plugin-inject-process-env';
23
22
  import * as parser from '@babel/parser';
24
- import traverse from '@babel/traverse';
23
+ import { createFilter } from '@rollup/pluginutils';
25
24
  import * as glob from 'glob';
25
+ import MagicString from 'magic-string';
26
+ import _traverse from '@babel/traverse';
26
27
  import { performance as performance$1 } from 'perf_hooks';
27
28
 
28
29
  const Logger = {
@@ -83,7 +84,7 @@ var BuildType;
83
84
  BuildType[BuildType["ProdBuild"] = 1] = "ProdBuild";
84
85
  })(BuildType || (BuildType = {}));
85
86
  const ValidateParameters = (args) => {
86
- let typeProp = BuildType.DevBuild, targetProp = process.cwd();
87
+ let typeProp = BuildType.DevBuild, targetProp = process.cwd(), isMillennium = false;
87
88
  if (args.includes('--help')) {
88
89
  PrintParamHelp();
89
90
  process.exit();
@@ -117,10 +118,14 @@ const ValidateParameters = (args) => {
117
118
  }
118
119
  targetProp = args[i + 1];
119
120
  }
121
+ if (args[i] == '--millennium-internal') {
122
+ isMillennium = true;
123
+ }
120
124
  }
121
125
  return {
122
126
  type: typeProp,
123
127
  targetPlugin: targetProp,
128
+ isMillennium: isMillennium,
124
129
  };
125
130
  };
126
131
 
@@ -149,13 +154,24 @@ const CheckForUpdates = async () => {
149
154
  });
150
155
  };
151
156
 
152
- const ValidatePlugin = (target) => {
157
+ const ValidatePlugin = (bIsMillennium, target) => {
153
158
  return new Promise((resolve, reject) => {
154
159
  if (!existsSync(target)) {
155
160
  console.error(chalk.red.bold(`\n[-] --target [${target}] `) + chalk.red('is not a valid system path'));
156
161
  reject();
157
162
  return;
158
163
  }
164
+ if (bIsMillennium) {
165
+ console.log(chalk.green.bold('\n[+] Using Millennium internal build configuration'));
166
+ resolve({
167
+ name: 'core',
168
+ common_name: 'Millennium',
169
+ description: 'An integrated plugin that provides core platform functionality.',
170
+ useBackend: false,
171
+ frontend: '.',
172
+ });
173
+ return;
174
+ }
159
175
  const pluginModule = path.join(target, 'plugin.json');
160
176
  if (!existsSync(pluginModule)) {
161
177
  console.error(chalk.red.bold(`\n[-] --target [${target}] `) + chalk.red('is not a valid plugin (missing plugin.json)'));
@@ -200,7 +216,7 @@ function ExecutePluginModule() {
200
216
  }
201
217
  /** Expose the OnPluginConfigChange so it can be called externally */
202
218
  MillenniumStore.OnPluginConfigChange = OnPluginConfigChange;
203
- MILLENNIUM_BACKEND_IPC.postMessage(0, { pluginName: pluginName, methodName: '__builtins__.__millennium_plugin_settings_parser__' }).then((response) => {
219
+ MILLENNIUM_BACKEND_IPC.postMessage(0, { pluginName: pluginName, methodName: '__builtins__.__millennium_plugin_settings_parser__' }).then(async (response) => {
204
220
  /**
205
221
  * __millennium_plugin_settings_parser__ will return false if the plugin has no settings.
206
222
  * If the plugin has settings, it will return a base64 encoded string.
@@ -220,7 +236,7 @@ function ExecutePluginModule() {
220
236
  __millennium_internal_plugin_name_do_not_use_or_change__: pluginName,
221
237
  });
222
238
  /** Run the rolled up plugins default exported function */
223
- let pluginProps = PluginModule.default();
239
+ let pluginProps = await PluginModule.default();
224
240
  function isValidSidebarNavComponent(obj) {
225
241
  return obj && obj.title !== undefined && obj.icon !== undefined && obj.content !== undefined;
226
242
  }
@@ -293,16 +309,33 @@ function InitializePlugins() {
293
309
  MillenniumStore.ignoreProxyFlag = false;
294
310
  });
295
311
  }
296
- function WebkitInitializeIPC() {
297
- SteamClient?.BrowserView?.RegisterForMessageFromParent((messageId, data) => {
298
- if (messageId !== IPCMessageId) {
312
+ async function WebkitInitializeIPC() {
313
+ let intervalId = null;
314
+ const maxWaitTime = 10000; // 10 seconds
315
+ intervalId = setInterval(() => {
316
+ if (typeof SteamClient === 'undefined') {
299
317
  return;
300
318
  }
301
- const payload = JSON.parse(data);
302
- MillenniumStore.ignoreProxyFlag = true;
303
- MillenniumStore.settingsStore[payload.name] = payload.value;
304
- MillenniumStore.ignoreProxyFlag = false;
305
- });
319
+ if (intervalId) {
320
+ clearInterval(intervalId);
321
+ intervalId = null;
322
+ }
323
+ SteamClient.BrowserView?.RegisterForMessageFromParent((messageId, data) => {
324
+ if (messageId !== IPCMessageId) {
325
+ return;
326
+ }
327
+ const payload = JSON.parse(data);
328
+ MillenniumStore.ignoreProxyFlag = true;
329
+ MillenniumStore.settingsStore[payload.name] = payload.value;
330
+ MillenniumStore.ignoreProxyFlag = false;
331
+ });
332
+ }, 100);
333
+ setTimeout(() => {
334
+ if (intervalId) {
335
+ clearInterval(intervalId);
336
+ console.warn('%c Millennium %c Failed to find SteamClient after 10000ms', 'background:rgb(37, 105, 184); color: white;', 'background: transparent;');
337
+ }
338
+ }, maxWaitTime);
306
339
  }
307
340
  isClientModule ? ClientInitializeIPC() : WebkitInitializeIPC();
308
341
  const StartSettingPropagation = (name, value) => {
@@ -362,6 +395,7 @@ function InitializePlugins() {
362
395
  MillenniumStore.settingsStore = DefinePluginSetting({});
363
396
  }
364
397
 
398
+ const traverse = _traverse.default;
365
399
  const Log = (...message) => {
366
400
  console.log(chalk.blueBright.bold('constSysfsExpr'), ...message);
367
401
  };
@@ -629,7 +663,7 @@ function InsertMillennium(type, props) {
629
663
  continue;
630
664
  }
631
665
  Logger.Info('millenniumAPI', 'Bundling into ' + ComponentType[type] + ' module... ' + chalk.green.bold('okay'));
632
- bundle[fileName].code = ConstructFunctions([
666
+ let code = ConstructFunctions([
633
667
  `const MILLENNIUM_IS_CLIENT_MODULE = ${type === ComponentType.Plugin ? 'true' : 'false'};`,
634
668
  `const pluginName = "${props.strPluginInternalName}";`,
635
669
  InitializePlugins.toString(),
@@ -640,6 +674,10 @@ function InsertMillennium(type, props) {
640
674
  ExecutePluginModule.toString(),
641
675
  ExecutePluginModule.name + '()',
642
676
  ]);
677
+ if (props.bTersePlugin) {
678
+ code = minify_sync(code).code ?? code;
679
+ }
680
+ bundle[fileName].code = code;
643
681
  }
644
682
  };
645
683
  return { name: String(), generateBundle };
@@ -660,9 +698,9 @@ async function MergePluginList(plugins) {
660
698
  // Merge input plugins with the filtered custom plugins
661
699
  return [...plugins, ...filteredCustomPlugins];
662
700
  }
663
- async function GetPluginComponents(props) {
701
+ async function GetPluginComponents(pluginJson, props) {
664
702
  let tsConfigPath = '';
665
- const frontendDir = GetFrontEndDirectory();
703
+ const frontendDir = GetFrontEndDirectory(pluginJson);
666
704
  if (frontendDir === '.' || frontendDir === './') {
667
705
  tsConfigPath = './tsconfig.json';
668
706
  }
@@ -674,21 +712,23 @@ async function GetPluginComponents(props) {
674
712
  }
675
713
  Logger.Info('millenniumAPI', 'Loading tsconfig from ' + chalk.cyan.bold(tsConfigPath) + '... ' + chalk.green.bold('okay'));
676
714
  let pluginList = [
715
+ typescript({
716
+ tsconfig: tsConfigPath,
717
+ compilerOptions: {
718
+ outDir: undefined,
719
+ },
720
+ }),
677
721
  url({
678
722
  include: ['**/*.gif', '**/*.webm', '**/*.svg'], // Add all non-JS assets you use
679
723
  limit: 0, // Set to 0 to always copy the file instead of inlining as base64
680
724
  fileName: '[hash][extname]', // Optional: custom output naming
681
725
  }),
682
726
  InsertMillennium(ComponentType.Plugin, props),
683
- commonjs(),
684
- nodePolyfills(),
685
727
  nodeResolve({
686
728
  browser: true,
687
729
  }),
688
- typescript({
689
- include: ['**/*.ts', '**/*.tsx', 'src/**/*.ts', 'src/**/*.tsx'],
690
- tsconfig: tsConfigPath,
691
- }),
730
+ commonjs(),
731
+ nodePolyfills(),
692
732
  scss({
693
733
  output: false,
694
734
  outputStyle: 'compressed',
@@ -696,10 +736,8 @@ async function GetPluginComponents(props) {
696
736
  watch: 'src/styles',
697
737
  sass: sass,
698
738
  }),
699
- resolve(),
700
739
  json(),
701
740
  constSysfsExpr(),
702
- injectProcessEnv(envVars),
703
741
  replace({
704
742
  delimiters: ['', ''],
705
743
  preventAssignment: true,
@@ -711,6 +749,9 @@ async function GetPluginComponents(props) {
711
749
  'client.BindPluginSettings()': 'client.BindPluginSettings(pluginName)',
712
750
  }),
713
751
  ];
752
+ if (envVars.length > 0) {
753
+ pluginList.push(injectProcessEnv(envVars));
754
+ }
714
755
  if (props.bTersePlugin) {
715
756
  pluginList.push(terser());
716
757
  }
@@ -732,7 +773,6 @@ async function GetWebkitPluginComponents(props) {
732
773
  commonjs(),
733
774
  json(),
734
775
  constSysfsExpr(),
735
- injectProcessEnv(envVars),
736
776
  replace({
737
777
  delimiters: ['', ''],
738
778
  preventAssignment: true,
@@ -745,23 +785,37 @@ async function GetWebkitPluginComponents(props) {
745
785
  babelHelpers: 'bundled',
746
786
  }),
747
787
  ];
788
+ if (envVars.length > 0) {
789
+ pluginList.push(injectProcessEnv(envVars));
790
+ }
748
791
  pluginList = await MergePluginList(pluginList);
749
792
  props.bTersePlugin && pluginList.push(terser());
750
793
  return pluginList;
751
794
  }
752
- const GetFrontEndDirectory = () => {
753
- const pluginJsonPath = './plugin.json';
795
+ const GetFrontEndDirectory = (pluginJson) => {
754
796
  try {
755
- return JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'))?.frontend ?? 'frontend';
797
+ return pluginJson?.frontend ?? 'frontend';
756
798
  }
757
799
  catch (error) {
758
800
  return 'frontend';
759
801
  }
760
802
  };
761
- const TranspilerPluginComponent = async (props) => {
803
+ const TranspilerPluginComponent = async (bIsMillennium, pluginJson, props) => {
804
+ const frontendDir = GetFrontEndDirectory(pluginJson);
805
+ console.log(chalk.greenBright.bold('config'), 'Frontend directory set to:', chalk.cyan.bold(frontendDir));
806
+ const frontendPlugins = await GetPluginComponents(pluginJson, props);
807
+ // Fix entry file path construction
808
+ let entryFile = '';
809
+ if (frontendDir === '.' || frontendDir === './' || frontendDir === '') {
810
+ entryFile = './index.tsx';
811
+ }
812
+ else {
813
+ entryFile = `./${frontendDir}/index.tsx`;
814
+ }
815
+ console.log(chalk.greenBright.bold('config'), 'Entry file set to:', chalk.cyan.bold(entryFile));
762
816
  const frontendRollupConfig = {
763
- input: `./${GetFrontEndDirectory()}/index.tsx`,
764
- plugins: await GetPluginComponents(props),
817
+ input: entryFile,
818
+ plugins: frontendPlugins,
765
819
  context: 'window',
766
820
  external: (id) => {
767
821
  if (id === '@steambrew/webkit') {
@@ -772,7 +826,7 @@ const TranspilerPluginComponent = async (props) => {
772
826
  },
773
827
  output: {
774
828
  name: 'millennium_main',
775
- file: '.millennium/Dist/index.js',
829
+ file: bIsMillennium ? '../../build/frontend.bin' : '.millennium/Dist/index.js',
776
830
  globals: {
777
831
  react: 'window.SP_REACT',
778
832
  'react-dom': 'window.SP_REACTDOM',
@@ -827,15 +881,16 @@ const CheckModuleUpdates = async () => {
827
881
  };
828
882
  const StartCompilerModule = () => {
829
883
  const parameters = ValidateParameters(process.argv.slice(2));
884
+ const bIsMillennium = parameters.isMillennium || false;
830
885
  const bTersePlugin = parameters.type == BuildType.ProdBuild;
831
886
  console.log(chalk.greenBright.bold('config'), 'Building target:', parameters.targetPlugin, 'with type:', BuildType[parameters.type], 'minify:', bTersePlugin, '...');
832
- ValidatePlugin(parameters.targetPlugin)
887
+ ValidatePlugin(bIsMillennium, parameters.targetPlugin)
833
888
  .then((json) => {
834
889
  const props = {
835
890
  bTersePlugin: bTersePlugin,
836
891
  strPluginInternalName: json?.name,
837
892
  };
838
- TranspilerPluginComponent(props);
893
+ TranspilerPluginComponent(bIsMillennium, json, props);
839
894
  })
840
895
  /**
841
896
  * plugin is invalid, we close the proccess as it has already been handled
package/package.json CHANGED
@@ -1,53 +1,54 @@
1
- {
2
- "name": "@steambrew/ttc",
3
- "version": "2.6.3",
4
- "type": "module",
5
- "main": "dist/index.js",
6
- "module": "dist/index.js",
7
- "bin": {
8
- "millennium-ttc": "dist/index.js"
9
- },
10
- "scripts": {
11
- "build": "rollup -c",
12
- "prepare": "npm run build"
13
- },
14
- "publishConfig": {
15
- "access": "public"
16
- },
17
- "keywords": [],
18
- "author": "SteamClientHomebrew",
19
- "license": "MIT",
20
- "description": "A tiny typescript compiler for Millennium plugins.",
21
- "dependencies": {
22
- "@babel/parser": "^7.27.5",
23
- "@babel/preset-env": "^7.27.2",
24
- "@babel/preset-react": "^7.27.1",
25
- "@babel/preset-typescript": "^7.27.1",
26
- "@babel/traverse": "^7.27.4",
27
- "@rollup/plugin-babel": "^6.0.4",
28
- "@rollup/plugin-commonjs": "^28.0.3",
29
- "@rollup/plugin-json": "^6.1.0",
30
- "@rollup/plugin-node-resolve": "^15.3.1",
31
- "@rollup/plugin-replace": "^6.0.2",
32
- "@rollup/plugin-terser": "^0.4.4",
33
- "@rollup/plugin-typescript": "^12.1.2",
34
- "@rollup/plugin-url": "^8.0.2",
35
- "@rollup/pluginutils": "^5.1.4",
36
- "chalk": "^5.4.1",
37
- "dotenv": "^16.5.0",
38
- "fs": "0.0.1-security",
39
- "glob": "^11.0.2",
40
- "magic-string": "^0.30.17",
41
- "rollup": "^4.42.0",
42
- "rollup-plugin-inject-process-env": "^1.3.1",
43
- "rollup-plugin-polyfill-node": "^0.13.0",
44
- "rollup-plugin-scss": "^4.0.1",
45
- "sass": "^1.89.1",
46
- "tslib": "^2.8.1"
47
- },
48
- "devDependencies": {
49
- "@types/babel__traverse": "^7.20.7",
50
- "@types/glob": "^8.1.0",
51
- "@types/node": "^22.15.30"
52
- }
53
- }
1
+ {
2
+ "name": "@steambrew/ttc",
3
+ "version": "2.7.4",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "bin": {
8
+ "millennium-ttc": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "rollup -c",
12
+ "prepare": "npm run build"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "keywords": [],
18
+ "author": "SteamClientHomebrew",
19
+ "license": "MIT",
20
+ "description": "A tiny typescript compiler for Millennium plugins.",
21
+ "dependencies": {
22
+ "@babel/parser": "^7.27.5",
23
+ "@babel/preset-env": "^7.27.2",
24
+ "@babel/preset-react": "^7.27.1",
25
+ "@babel/preset-typescript": "^7.27.1",
26
+ "@babel/traverse": "^7.27.4",
27
+ "@rollup/plugin-babel": "^6.0.4",
28
+ "@rollup/plugin-commonjs": "^28.0.3",
29
+ "@rollup/plugin-json": "^6.1.0",
30
+ "@rollup/plugin-node-resolve": "^15.3.1",
31
+ "@rollup/plugin-replace": "^6.0.2",
32
+ "@rollup/plugin-terser": "^0.4.4",
33
+ "@rollup/plugin-typescript": "^12.1.2",
34
+ "@rollup/plugin-url": "^8.0.2",
35
+ "@rollup/pluginutils": "^5.1.4",
36
+ "chalk": "^5.4.1",
37
+ "dotenv": "^16.5.0",
38
+ "fs": "0.0.1-security",
39
+ "glob": "^11.0.2",
40
+ "magic-string": "^0.30.17",
41
+ "rollup": "^4.42.0",
42
+ "rollup-plugin-inject-process-env": "^1.3.1",
43
+ "rollup-plugin-polyfill-node": "^0.13.0",
44
+ "rollup-plugin-scss": "^4.0.1",
45
+ "sass": "^1.89.1",
46
+ "terser": "^5.43.1",
47
+ "tslib": "^2.8.1"
48
+ },
49
+ "devDependencies": {
50
+ "@types/babel__traverse": "^7.20.7",
51
+ "@types/glob": "^8.1.0",
52
+ "@types/node": "^22.15.30"
53
+ }
54
+ }
@@ -0,0 +1,2 @@
1
+ onlyBuiltDependencies:
2
+ - '@parcel/watcher'
@@ -2,7 +2,7 @@ import chalk from 'chalk';
2
2
  import path from 'path';
3
3
  import { existsSync, readFile } from 'fs';
4
4
 
5
- export const ValidatePlugin = (target: string): Promise<any> => {
5
+ export const ValidatePlugin = (bIsMillennium: boolean, target: string): Promise<any> => {
6
6
  return new Promise<any>((resolve, reject) => {
7
7
  if (!existsSync(target)) {
8
8
  console.error(chalk.red.bold(`\n[-] --target [${target}] `) + chalk.red('is not a valid system path'));
@@ -10,6 +10,19 @@ export const ValidatePlugin = (target: string): Promise<any> => {
10
10
  return;
11
11
  }
12
12
 
13
+ if (bIsMillennium) {
14
+ console.log(chalk.green.bold('\n[+] Using Millennium internal build configuration'));
15
+
16
+ resolve({
17
+ name: 'core',
18
+ common_name: 'Millennium',
19
+ description: 'An integrated plugin that provides core platform functionality.',
20
+ useBackend: false,
21
+ frontend: '.',
22
+ });
23
+ return;
24
+ }
25
+
13
26
  const pluginModule = path.join(target, 'plugin.json');
14
27
 
15
28
  if (!existsSync(pluginModule)) {
package/src/index.ts CHANGED
@@ -23,18 +23,19 @@ const CheckModuleUpdates = async () => {
23
23
 
24
24
  const StartCompilerModule = () => {
25
25
  const parameters = ValidateParameters(process.argv.slice(2));
26
+ const bIsMillennium = parameters.isMillennium || false;
26
27
  const bTersePlugin = parameters.type == BuildType.ProdBuild;
27
28
 
28
29
  console.log(chalk.greenBright.bold('config'), 'Building target:', parameters.targetPlugin, 'with type:', BuildType[parameters.type], 'minify:', bTersePlugin, '...');
29
30
 
30
- ValidatePlugin(parameters.targetPlugin)
31
+ ValidatePlugin(bIsMillennium, parameters.targetPlugin)
31
32
  .then((json: any) => {
32
33
  const props: TranspilerProps = {
33
34
  bTersePlugin: bTersePlugin,
34
35
  strPluginInternalName: json?.name,
35
36
  };
36
37
 
37
- TranspilerPluginComponent(props);
38
+ TranspilerPluginComponent(bIsMillennium, json, props);
38
39
  })
39
40
 
40
41
  /**
package/src/plugin-api.ts CHANGED
@@ -74,7 +74,7 @@ function ExecutePluginModule() {
74
74
  /** Expose the OnPluginConfigChange so it can be called externally */
75
75
  MillenniumStore.OnPluginConfigChange = OnPluginConfigChange;
76
76
 
77
- MILLENNIUM_BACKEND_IPC.postMessage(0, { pluginName: pluginName, methodName: '__builtins__.__millennium_plugin_settings_parser__' }).then((response: any) => {
77
+ MILLENNIUM_BACKEND_IPC.postMessage(0, { pluginName: pluginName, methodName: '__builtins__.__millennium_plugin_settings_parser__' }).then(async (response: any) => {
78
78
  /**
79
79
  * __millennium_plugin_settings_parser__ will return false if the plugin has no settings.
80
80
  * If the plugin has settings, it will return a base64 encoded string.
@@ -101,7 +101,7 @@ function ExecutePluginModule() {
101
101
  });
102
102
 
103
103
  /** Run the rolled up plugins default exported function */
104
- let pluginProps = PluginModule.default();
104
+ let pluginProps = await PluginModule.default();
105
105
 
106
106
  function isValidSidebarNavComponent(obj: any) {
107
107
  return obj && obj.title !== undefined && obj.icon !== undefined && obj.content !== undefined;
@@ -188,17 +188,38 @@ function InitializePlugins() {
188
188
  });
189
189
  }
190
190
 
191
- function WebkitInitializeIPC() {
192
- SteamClient?.BrowserView?.RegisterForMessageFromParent((messageId: string, data: string) => {
193
- if (messageId !== IPCMessageId) {
191
+ async function WebkitInitializeIPC() {
192
+ let intervalId: NodeJS.Timeout | null = null;
193
+ const maxWaitTime = 10000; // 10 seconds
194
+
195
+ intervalId = setInterval(() => {
196
+ if (typeof SteamClient === 'undefined') {
194
197
  return;
195
198
  }
196
199
 
197
- const payload = JSON.parse(data);
198
- MillenniumStore.ignoreProxyFlag = true;
199
- MillenniumStore.settingsStore[payload.name] = payload.value;
200
- MillenniumStore.ignoreProxyFlag = false;
201
- });
200
+ if (intervalId) {
201
+ clearInterval(intervalId);
202
+ intervalId = null;
203
+ }
204
+
205
+ SteamClient.BrowserView?.RegisterForMessageFromParent((messageId: string, data: string) => {
206
+ if (messageId !== IPCMessageId) {
207
+ return;
208
+ }
209
+
210
+ const payload = JSON.parse(data);
211
+ MillenniumStore.ignoreProxyFlag = true;
212
+ MillenniumStore.settingsStore[payload.name] = payload.value;
213
+ MillenniumStore.ignoreProxyFlag = false;
214
+ });
215
+ }, 100);
216
+
217
+ setTimeout(() => {
218
+ if (intervalId) {
219
+ clearInterval(intervalId);
220
+ console.warn('%c Millennium %c Failed to find SteamClient after 10000ms', 'background:rgb(37, 105, 184); color: white;', 'background: transparent;');
221
+ }
222
+ }, maxWaitTime);
202
223
  }
203
224
 
204
225
  isClientModule ? ClientInitializeIPC() : WebkitInitializeIPC();
@@ -271,3 +292,4 @@ function InitializePlugins() {
271
292
  }
272
293
 
273
294
  export { ExecutePluginModule, InitializePlugins };
295
+
@@ -29,11 +29,13 @@ export enum BuildType {
29
29
  export interface ParameterProps {
30
30
  type: BuildType;
31
31
  targetPlugin: string; // path
32
+ isMillennium?: boolean;
32
33
  }
33
34
 
34
35
  export const ValidateParameters = (args: Array<string>): ParameterProps => {
35
36
  let typeProp: BuildType = BuildType.DevBuild,
36
- targetProp: string = process.cwd();
37
+ targetProp: string = process.cwd(),
38
+ isMillennium: boolean = false;
37
39
 
38
40
  if (args.includes('--help')) {
39
41
  PrintParamHelp();
@@ -73,10 +75,15 @@ export const ValidateParameters = (args: Array<string>): ParameterProps => {
73
75
 
74
76
  targetProp = args[i + 1];
75
77
  }
78
+
79
+ if (args[i] == '--millennium-internal') {
80
+ isMillennium = true;
81
+ }
76
82
  }
77
83
 
78
84
  return {
79
85
  type: typeProp,
80
86
  targetPlugin: targetProp,
87
+ isMillennium: isMillennium,
81
88
  };
82
89
  };
@@ -1,12 +1,15 @@
1
- import { Plugin, SourceDescription, TransformPluginContext } from 'rollup';
2
- import fs from 'fs';
3
- import path from 'path';
4
- import { createFilter } from '@rollup/pluginutils';
5
- import MagicString from 'magic-string';
6
1
  import * as parser from '@babel/parser';
7
- import traverse from '@babel/traverse';
8
- import * as glob from 'glob';
2
+ import { createFilter } from '@rollup/pluginutils';
9
3
  import chalk from 'chalk';
4
+ import fs from 'fs';
5
+ import * as glob from 'glob';
6
+ import MagicString from 'magic-string';
7
+ import path from 'path';
8
+ import { Plugin, SourceDescription, TransformPluginContext } from 'rollup';
9
+
10
+ // Stupid fix because @babel/traverse exports a CommonJS module
11
+ import _traverse from '@babel/traverse';
12
+ const traverse = (_traverse as any).default as typeof _traverse;
10
13
 
11
14
  interface EmbedPluginOptions {
12
15
  include?: string | RegExp | (string | RegExp)[];
package/src/transpiler.ts CHANGED
@@ -1,23 +1,24 @@
1
- import { OutputOptions, RollupOptions, rollup } from 'rollup';
2
- import json from '@rollup/plugin-json';
1
+ import babel from '@rollup/plugin-babel';
3
2
  import commonjs from '@rollup/plugin-commonjs';
4
- import replace from '@rollup/plugin-replace';
5
- import typescript from '@rollup/plugin-typescript';
3
+ import json from '@rollup/plugin-json';
6
4
  import resolve, { nodeResolve } from '@rollup/plugin-node-resolve';
5
+ import replace from '@rollup/plugin-replace';
7
6
  import terser from '@rollup/plugin-terser';
8
- import babel from '@rollup/plugin-babel';
9
- import nodePolyfills from 'rollup-plugin-polyfill-node';
7
+ import typescript from '@rollup/plugin-typescript';
10
8
  import url from '@rollup/plugin-url';
9
+ import { InputPluginOption, OutputBundle, OutputOptions, RollupOptions, rollup } from 'rollup';
10
+ import nodePolyfills from 'rollup-plugin-polyfill-node';
11
+ import { minify_sync } from 'terser';
11
12
 
12
13
  import scss from 'rollup-plugin-scss';
13
14
  import * as sass from 'sass';
14
15
 
15
16
  import chalk from 'chalk';
16
- import { Logger } from './logger';
17
17
  import fs from 'fs';
18
+ import { Logger } from './logger';
18
19
 
19
- import injectProcessEnv from 'rollup-plugin-inject-process-env';
20
20
  import dotenv from 'dotenv';
21
+ import injectProcessEnv from 'rollup-plugin-inject-process-env';
21
22
  import { ExecutePluginModule, InitializePlugins } from './plugin-api';
22
23
  import constSysfsExpr from './static-embed';
23
24
 
@@ -54,7 +55,7 @@ export interface TranspilerProps {
54
55
  const WrappedCallServerMethod = 'const __call_server_method__ = (methodName, kwargs) => Millennium.callServerMethod(pluginName, methodName, kwargs)';
55
56
  const WrappedCallable = 'const __wrapped_callable__ = (route) => MILLENNIUM_API.callable(__call_server_method__, route)';
56
57
 
57
- const ConstructFunctions = (parts: any) => {
58
+ const ConstructFunctions = (parts: string[]): string => {
58
59
  return parts.join('\n');
59
60
  };
60
61
 
@@ -63,8 +64,8 @@ function generate(code: string) {
63
64
  return `let PluginEntryPointMain = function() { ${code} return millennium_main; };`;
64
65
  }
65
66
 
66
- function InsertMillennium(type: ComponentType, props: TranspilerProps) {
67
- const generateBundle = (_: unknown, bundle: any) => {
67
+ function InsertMillennium(type: ComponentType, props: TranspilerProps): InputPluginOption {
68
+ const generateBundle = (_: unknown, bundle: OutputBundle) => {
68
69
  for (const fileName in bundle) {
69
70
  if (bundle[fileName].type != 'chunk') {
70
71
  continue;
@@ -72,7 +73,7 @@ function InsertMillennium(type: ComponentType, props: TranspilerProps) {
72
73
 
73
74
  Logger.Info('millenniumAPI', 'Bundling into ' + ComponentType[type] + ' module... ' + chalk.green.bold('okay'));
74
75
 
75
- bundle[fileName].code = ConstructFunctions([
76
+ let code = ConstructFunctions([
76
77
  `const MILLENNIUM_IS_CLIENT_MODULE = ${type === ComponentType.Plugin ? 'true' : 'false'};`,
77
78
  `const pluginName = "${props.strPluginInternalName}";`,
78
79
  InitializePlugins.toString(),
@@ -83,6 +84,12 @@ function InsertMillennium(type: ComponentType, props: TranspilerProps) {
83
84
  ExecutePluginModule.toString(),
84
85
  ExecutePluginModule.name + '()',
85
86
  ]);
87
+
88
+ if (props.bTersePlugin) {
89
+ code = minify_sync(code).code ?? code;
90
+ }
91
+
92
+ bundle[fileName].code = code;
86
93
  }
87
94
  };
88
95
 
@@ -112,9 +119,9 @@ async function MergePluginList(plugins: any[]) {
112
119
  return [...plugins, ...filteredCustomPlugins];
113
120
  }
114
121
 
115
- async function GetPluginComponents(props: TranspilerProps) {
122
+ async function GetPluginComponents(pluginJson: any, props: TranspilerProps): Promise<InputPluginOption[]> {
116
123
  let tsConfigPath = '';
117
- const frontendDir = GetFrontEndDirectory();
124
+ const frontendDir = GetFrontEndDirectory(pluginJson);
118
125
 
119
126
  if (frontendDir === '.' || frontendDir === './') {
120
127
  tsConfigPath = './tsconfig.json';
@@ -129,21 +136,23 @@ async function GetPluginComponents(props: TranspilerProps) {
129
136
  Logger.Info('millenniumAPI', 'Loading tsconfig from ' + chalk.cyan.bold(tsConfigPath) + '... ' + chalk.green.bold('okay'));
130
137
 
131
138
  let pluginList = [
139
+ typescript({
140
+ tsconfig: tsConfigPath,
141
+ compilerOptions: {
142
+ outDir: undefined,
143
+ },
144
+ }),
132
145
  url({
133
146
  include: ['**/*.gif', '**/*.webm', '**/*.svg'], // Add all non-JS assets you use
134
147
  limit: 0, // Set to 0 to always copy the file instead of inlining as base64
135
148
  fileName: '[hash][extname]', // Optional: custom output naming
136
149
  }),
137
150
  InsertMillennium(ComponentType.Plugin, props),
138
- commonjs(),
139
- nodePolyfills(),
140
151
  nodeResolve({
141
152
  browser: true,
142
153
  }),
143
- typescript({
144
- include: ['**/*.ts', '**/*.tsx', 'src/**/*.ts', 'src/**/*.tsx'],
145
- tsconfig: tsConfigPath,
146
- }),
154
+ commonjs(),
155
+ nodePolyfills(),
147
156
  scss({
148
157
  output: false,
149
158
  outputStyle: 'compressed',
@@ -151,10 +160,8 @@ async function GetPluginComponents(props: TranspilerProps) {
151
160
  watch: 'src/styles',
152
161
  sass: sass,
153
162
  }),
154
- resolve(),
155
163
  json(),
156
164
  constSysfsExpr(),
157
- injectProcessEnv(envVars),
158
165
  replace({
159
166
  delimiters: ['', ''],
160
167
  preventAssignment: true,
@@ -167,9 +174,14 @@ async function GetPluginComponents(props: TranspilerProps) {
167
174
  }),
168
175
  ];
169
176
 
177
+ if (envVars.length > 0) {
178
+ pluginList.push(injectProcessEnv(envVars));
179
+ }
180
+
170
181
  if (props.bTersePlugin) {
171
182
  pluginList.push(terser());
172
183
  }
184
+
173
185
  return pluginList;
174
186
  }
175
187
 
@@ -189,7 +201,6 @@ async function GetWebkitPluginComponents(props: TranspilerProps) {
189
201
  commonjs(),
190
202
  json(),
191
203
  constSysfsExpr(),
192
- injectProcessEnv(envVars),
193
204
  replace({
194
205
  delimiters: ['', ''],
195
206
  preventAssignment: true,
@@ -203,25 +214,43 @@ async function GetWebkitPluginComponents(props: TranspilerProps) {
203
214
  }),
204
215
  ];
205
216
 
217
+ if (envVars.length > 0) {
218
+ pluginList.push(injectProcessEnv(envVars));
219
+ }
220
+
206
221
  pluginList = await MergePluginList(pluginList);
207
222
 
208
223
  props.bTersePlugin && pluginList.push(terser());
209
224
  return pluginList;
210
225
  }
211
226
 
212
- const GetFrontEndDirectory = () => {
213
- const pluginJsonPath = './plugin.json';
227
+ const GetFrontEndDirectory = (pluginJson: any) => {
214
228
  try {
215
- return JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'))?.frontend ?? 'frontend';
229
+ return pluginJson?.frontend ?? 'frontend';
216
230
  } catch (error) {
217
231
  return 'frontend';
218
232
  }
219
233
  };
220
234
 
221
- export const TranspilerPluginComponent = async (props: TranspilerProps) => {
235
+ export const TranspilerPluginComponent = async (bIsMillennium: boolean, pluginJson: any, props: TranspilerProps) => {
236
+ const frontendDir = GetFrontEndDirectory(pluginJson);
237
+ console.log(chalk.greenBright.bold('config'), 'Frontend directory set to:', chalk.cyan.bold(frontendDir));
238
+
239
+ const frontendPlugins = await GetPluginComponents(pluginJson, props);
240
+
241
+ // Fix entry file path construction
242
+ let entryFile = '';
243
+ if (frontendDir === '.' || frontendDir === './' || frontendDir === '') {
244
+ entryFile = './index.tsx';
245
+ } else {
246
+ entryFile = `./${frontendDir}/index.tsx`;
247
+ }
248
+
249
+ console.log(chalk.greenBright.bold('config'), 'Entry file set to:', chalk.cyan.bold(entryFile));
250
+
222
251
  const frontendRollupConfig: RollupOptions = {
223
- input: `./${GetFrontEndDirectory()}/index.tsx`,
224
- plugins: await GetPluginComponents(props),
252
+ input: entryFile,
253
+ plugins: frontendPlugins,
225
254
  context: 'window',
226
255
  external: (id) => {
227
256
  if (id === '@steambrew/webkit') {
@@ -235,7 +264,7 @@ export const TranspilerPluginComponent = async (props: TranspilerProps) => {
235
264
  },
236
265
  output: {
237
266
  name: 'millennium_main',
238
- file: '.millennium/Dist/index.js',
267
+ file: bIsMillennium ? '../../build/frontend.bin' : '.millennium/Dist/index.js',
239
268
  globals: {
240
269
  react: 'window.SP_REACT',
241
270
  'react-dom': 'window.SP_REACTDOM',