cpp.js 1.0.0-beta.6 → 1.0.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 (64) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +1 -1
  3. package/README.md +9 -26
  4. package/package.json +24 -14
  5. package/src/{functions/buildJS.js → actions/buildJs.js} +7 -6
  6. package/src/actions/buildWasm.js +68 -0
  7. package/src/actions/createInterface.js +128 -0
  8. package/src/actions/createLib.js +104 -0
  9. package/src/actions/createXCFramework.js +44 -0
  10. package/src/actions/getAllBridges.js +8 -0
  11. package/src/actions/getCmakeParameters.js +56 -0
  12. package/src/actions/getData.js +28 -0
  13. package/src/actions/getDependLibs.js +19 -0
  14. package/src/{functions → actions}/run.js +118 -64
  15. package/src/assets/CMakeLists.txt +14 -10
  16. package/src/assets/commonBridges.cpp +16 -0
  17. package/src/assets/dist.cmake +1 -1
  18. package/src/assets/ios.toolchain.cmake +4 -4
  19. package/src/bin.js +255 -96
  20. package/src/index.js +13 -63
  21. package/src/integration/getCppJsScript.js +91 -0
  22. package/src/integration/getDependFilePath.js +34 -0
  23. package/src/state/calculateDependencyParameters.js +64 -0
  24. package/src/state/index.js +81 -0
  25. package/src/state/loadConfig.js +104 -0
  26. package/src/utils/downloadAndExtractFile.js +36 -0
  27. package/src/utils/findFiles.js +5 -0
  28. package/src/utils/fixPackageName.js +7 -0
  29. package/src/utils/getAbsolutePath.js +14 -0
  30. package/src/utils/getCMakeListsFilePath.js +17 -0
  31. package/src/utils/getOsUserAndGroupId.js +1 -1
  32. package/src/utils/getParentPath.js +12 -0
  33. package/src/utils/hash.js +20 -0
  34. package/src/utils/loadJs.js +32 -0
  35. package/src/utils/loadJson.js +16 -0
  36. package/src/utils/pullDockerImage.js +2 -2
  37. package/src/utils/systemKeys.js +18 -0
  38. package/src/utils/writeJson.js +9 -0
  39. package/.mocharc.yaml +0 -3
  40. package/src/functions/createBridge.js +0 -37
  41. package/src/functions/createLib.js +0 -44
  42. package/src/functions/createWasm.js +0 -67
  43. package/src/functions/findOrCreateInterfaceFile.js +0 -68
  44. package/src/functions/finishBuild.js +0 -43
  45. package/src/functions/getCmakeParams.js +0 -106
  46. package/src/functions/getData.js +0 -36
  47. package/src/functions/getLibs.js +0 -33
  48. package/src/functions/specs/createBridge.spec.js +0 -51
  49. package/src/functions/specs/findOrCreateInterfaceFile.spec.js +0 -49
  50. package/src/utils/createTempDir.js +0 -15
  51. package/src/utils/findCMakeListsFile.js +0 -16
  52. package/src/utils/getBaseInfo.js +0 -15
  53. package/src/utils/getCliPath.js +0 -12
  54. package/src/utils/getConfig.js +0 -170
  55. package/src/utils/getDirName.js +0 -8
  56. package/src/utils/getPathInfo.js +0 -10
  57. package/src/utils/specs/findCMakeListsFile.spec.js +0 -34
  58. package/src/utils/specs/utils.spec.js +0 -81
  59. package/test/data/sample.cpp +0 -1
  60. package/test/data/sample.h +0 -10
  61. package/test/data/sample.i +0 -12
  62. package/test/data/sample2.ei +0 -12
  63. package/test/data/sample2.h +0 -10
  64. /package/{test/data/sample2.cpp → src/assets/cppjsEmptySource.cpp} +0 -0
package/src/bin.js CHANGED
@@ -1,12 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import fs from 'node:fs';
4
+ import { execFileSync } from 'node:child_process';
3
5
  import { Command, Option } from 'commander';
4
- import fs from 'fs';
5
- import glob from 'glob';
6
- import { createDir } from './utils/createTempDir.js';
7
- import getPathInfo from './utils/getPathInfo.js';
6
+ import replace from 'replace';
8
7
 
9
- import CppjsCompiler from './index.js';
8
+ import { state } from './index.js';
9
+ import createBridgeFile from './actions/createInterface.js';
10
+ import createLib from './actions/createLib.js';
11
+ import buildWasm from './actions/buildWasm.js';
12
+ import createXCFramework from './actions/createXCFramework.js';
13
+ import runCppjsApp from './actions/run.js';
14
+ import downloadAndExtractFile from './utils/downloadAndExtractFile.js';
15
+ import writeJson from './utils/writeJson.js';
16
+ import systemKeys from './utils/systemKeys.js';
17
+
18
+ import { getDockerImage } from './utils/pullDockerImage.js';
19
+ import { getContentHash } from './utils/hash.js';
20
+ import findFiles from './utils/findFiles.js';
10
21
 
11
22
  const packageJSON = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url)));
12
23
 
@@ -20,148 +31,296 @@ program
20
31
 
21
32
  const commandBuild = program.command('build')
22
33
  .description('compile the project that was set up using Cpp.js')
23
- .addOption(new Option('-p, --platform <platform>', 'target platform').default('all').choices(['all', 'wasm', 'android', 'ios']));
34
+ .addOption(new Option('-p, --platform <platform>', 'target platform').default('All').choices(['All', 'WebAssembly', 'Android', 'iOS']));
24
35
 
25
- const commandRun = program.command('run')
26
- .description('run docker application');
36
+ const commandDocker = program.command('docker')
37
+ .description('manage docker');
38
+ const commandRun = commandDocker.command('run').description('run docker application');
39
+ commandDocker.command('create').description('create docker container');
40
+ commandDocker.command('start').description('start docker container');
41
+ commandDocker.command('stop').description('stop docker container');
42
+ commandDocker.command('delete').description('delete docker container');
27
43
 
28
- const commandPostInstall = program.command('postinstall')
29
- .description('prepare the required packages for Cpp.js after installation');
44
+ const commandConfig = program.command('config')
45
+ .description('manage the Cpp.js configuration files');
46
+ commandConfig.command('get').description('get the Cpp.js system configuration');
47
+ commandConfig.command('set').description('set the Cpp.js system configuration');
48
+ commandConfig.command('delete').description('delete the Cpp.js system configuration');
49
+ const commandConfigList = commandConfig.command('list').description('list the Cpp.js configurations')
50
+ .addOption(new Option('-t, --type <type>', 'config type').default('system').choices(['all', 'system', 'project']));
51
+ commandConfig.command('keys').description('list all available system configuration keys for Cpp.js');
30
52
 
31
53
  program.parse(process.argv);
32
54
 
33
55
  switch (program.args[0]) {
34
56
  case 'build': {
35
57
  const { platform } = commandBuild.opts();
36
- build(platform);
58
+ if (state.config.build) {
59
+ buildExternal(platform);
60
+ } else {
61
+ build(platform);
62
+ }
37
63
  break;
38
64
  }
39
- case 'run': {
40
- const [programName, ...params] = commandRun.args;
41
- run(programName, params);
65
+ case 'docker': {
66
+ switch (program.args[1]) {
67
+ case 'run': {
68
+ const [programName, ...params] = commandRun.args;
69
+ run(programName, params);
70
+ break;
71
+ }
72
+ case 'create': {
73
+ const args = [
74
+ 'run',
75
+ '-dit',
76
+ '--name',
77
+ `${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-'),
78
+ '-v', `${state.config.paths.base}:/tmp/cppjs/live`,
79
+ getDockerImage(),
80
+ 'bash',
81
+ ];
82
+ try {
83
+ execFileSync('docker', args, { stdio: 'inherit' });
84
+ } catch (e) {
85
+ console.error('An error occurred while running the application. Please check the logs for more details.');
86
+ process.exit();
87
+ }
88
+ break;
89
+ }
90
+ case 'start': {
91
+ const args = [
92
+ 'start',
93
+ `${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-'),
94
+ ];
95
+ try {
96
+ execFileSync('docker', args, { stdio: 'inherit' });
97
+ } catch (e) {
98
+ console.error('An error occurred while running the application. Please check the logs for more details.');
99
+ process.exit();
100
+ }
101
+ break;
102
+ }
103
+ case 'stop': {
104
+ const args = [
105
+ 'stop',
106
+ `${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-'),
107
+ ];
108
+ try {
109
+ execFileSync('docker', args, { stdio: 'inherit' });
110
+ } catch (e) {
111
+ console.error('An error occurred while running the application. Please check the logs for more details.');
112
+ process.exit();
113
+ }
114
+ break;
115
+ }
116
+ case 'delete': {
117
+ const args = [
118
+ 'rm',
119
+ `${getDockerImage()}-${getContentHash(state.config.paths.base)}`.replace('/', '-').replace(':', '-'),
120
+ ];
121
+ try {
122
+ execFileSync('docker', args, { stdio: 'inherit' });
123
+ } catch (e) {
124
+ console.error('An error occurred while running the application. Please check the logs for more details.');
125
+ process.exit();
126
+ }
127
+ break;
128
+ }
129
+ default:
130
+ }
42
131
  break;
43
132
  }
44
- case 'postinstall': {
45
- postInstall();
133
+ case 'config': {
134
+ switch (program.args[1]) {
135
+ case 'get':
136
+ getSystemConfig(program.args[2]);
137
+ break;
138
+ case 'set':
139
+ setSystemConfig(program.args[2], program.args[3]);
140
+ break;
141
+ case 'delete':
142
+ deleteSystemConfig(program.args[2]);
143
+ break;
144
+ case 'list':
145
+ listSystemConfig(commandConfigList.opts().type);
146
+ break;
147
+ case 'keys':
148
+ listSystemKeys();
149
+ break;
150
+ default:
151
+ break;
152
+ }
46
153
  break;
47
154
  }
48
155
  default:
49
156
  break;
50
157
  }
51
158
 
52
- function postInstall() {
53
- const projectPath = process.env.PWD;
54
- const isDarwin = process.platform === 'darwin';
55
- if (
56
- !isDarwin
57
- || (
58
- !fs.existsSync(`${projectPath}/cppjs.config.js`)
59
- && !fs.existsSync(`${projectPath}/cppjs.config.cjs`)
60
- && !fs.existsSync(`${projectPath}/cppjs.config.mjs`)
61
- )
62
- ) {
159
+ function listSystemKeys() {
160
+ console.info('Available configurations:');
161
+ console.table(systemKeys);
162
+ }
163
+
164
+ function getSystemConfig(systemKey) {
165
+ if (!systemKey) {
166
+ listSystemConfig('system');
63
167
  return;
64
168
  }
169
+ const key = systemKey.toUpperCase();
170
+ const output = {};
171
+ if (key in state.config.system) {
172
+ output[key] = { value: state.config.system[key] || 'undefined', default: systemKeys[key].default };
173
+ }
174
+ Object.keys(systemKeys).filter((k) => k.includes(key)).forEach((k) => {
175
+ if (k in state.config.system) {
176
+ output[k] = { value: state.config.system[k] || 'undefined', default: systemKeys[k].default };
177
+ }
178
+ });
65
179
 
66
- const cppjs = new CppjsCompiler();
67
- const name = cppjs?.config?.general?.name;
68
- let dist = cppjs?.config?.paths?.output;
69
- dist = dist ? getPathInfo(dist, projectPath).relative : null;
180
+ console.table(output);
181
+ }
70
182
 
71
- if (!name || !dist) {
72
- return;
183
+ function setSystemConfig(key, value) {
184
+ if (!systemKeys[key]) {
185
+ throw new Error(`Configuration ${key} is not available. Please choose from the following available configurations: ${Object.keys(systemKeys).join(', ')}`);
186
+ }
187
+ if (systemKeys[key].options && !systemKeys[key].options.includes(value)) {
188
+ throw new Error(`Value ${value} is not available. Please choose from the following available values: ${systemKeys[key].options.join(', ')}`);
73
189
  }
74
190
 
75
- cppjs?.config?.export?.libName?.forEach((fileName) => {
76
- if (fs.existsSync(`${projectPath}/${fileName}.xcframework`) || !fs.existsSync(`${dist}/prebuilt/${fileName}.xcframework`)) {
77
- return;
78
- }
79
- fs.symlinkSync(`${dist}/prebuilt/${fileName}.xcframework`, `${projectPath}/${fileName}.xcframework`);
80
- });
191
+ state.config.system[key] = value;
192
+ writeJson(state.config.paths.systemConfig, state.config.system);
81
193
  }
82
194
 
83
- function run(programName, params) {
84
- const compiler = new CppjsCompiler();
85
- compiler.run(programName, params, { console: true });
195
+ function deleteSystemConfig(key) {
196
+ if (!systemKeys[key]) {
197
+ throw new Error(`Configuration ${key} is not available. Please choose from the following available configurations: ${Object.keys(systemKeys).join(', ')}`);
198
+ }
199
+ delete state.config.system[key];
200
+ writeJson(state.config.paths.systemConfig, state.config.system);
86
201
  }
87
202
 
88
- function build(platform) {
89
- const compiler2 = new CppjsCompiler();
203
+ function listSystemConfig(type) {
204
+ const { system: systemConfig, ...projectConfig } = state.config;
205
+ if (type === 'all' || type === 'system') {
206
+ console.log('System Configuration');
207
+ console.table(systemConfig);
208
+ }
90
209
 
91
- const modules = [];
92
- compiler2.config.paths.module.forEach((modulePath) => {
93
- modules.push(...glob.sync('**/*.i', { absolute: true, cwd: modulePath }));
94
- modules.push(...glob.sync('*.i', { absolute: true, cwd: modulePath }));
95
- });
210
+ if (type === 'all') {
211
+ console.log('');
212
+ }
96
213
 
97
- if (platform === 'all' || platform === 'wasm') {
98
- if (!fs.existsSync(`${compiler2.config.paths.output}/prebuilt/Emscripten-x86_64`)) {
99
- buildWasm();
100
- modules.forEach((modulePath) => {
101
- const fileName = modulePath.split('/').at(-1);
102
- createDir('prebuilt/Emscripten-x86_64/swig', compiler2.config.paths.output);
103
- fs.copyFileSync(modulePath, `${compiler2.config.paths.output}/prebuilt/Emscripten-x86_64/swig/${fileName}`);
214
+ if (type === 'all' || type === 'project') {
215
+ console.log('Project Configuration');
216
+ console.table(projectConfig);
217
+ }
218
+ }
219
+
220
+ function run(programName, params) {
221
+ runCppjsApp(programName, params, null, null, { console: true });
222
+ }
223
+
224
+ async function buildExternal(platform) {
225
+ const version = state.config.package.nativeVersion;
226
+ if (!version) {
227
+ console.error('no version found!');
228
+ return;
229
+ }
230
+
231
+ const { getURL, replaceList, copyToSource } = state.config.build;
232
+ const isNewlyCreated = await downloadAndExtractFile(getURL(version), state.config.paths.build);
233
+ const sourcePath = `${state.config.paths.build}/source`;
234
+ if (isNewlyCreated && replaceList) {
235
+ replaceList.forEach(({ regex, replacement, paths }) => {
236
+ replace({
237
+ regex, replacement, paths: paths.map((p) => `${sourcePath}/${p}`), recursive: false, silent: true,
104
238
  });
105
- }
239
+ });
106
240
  }
107
241
 
108
- if (platform === 'wasm') return;
109
- const platforms = {
110
- all: ['Android-arm64-v8a', 'iOS-iphoneos', 'iOS-iphonesimulator'],
111
- android: ['Android-arm64-v8a'],
112
- ios: ['iOS-iphoneos', 'iOS-iphonesimulator'],
113
- };
114
- platforms[platform].forEach((p) => {
115
- if (!fs.existsSync(`${compiler2.config.paths.output}/prebuilt/${p}`)) {
116
- const compiler = new CppjsCompiler(p);
117
- compiler.createLib();
242
+ if (isNewlyCreated && copyToSource) {
243
+ Object.entries(copyToSource).forEach(([key, value]) => {
244
+ fs.copyFileSync(`${state.config.paths.project}/${key}`, `${sourcePath}/${value}`);
245
+ });
246
+ }
247
+
248
+ buildLib(platform);
249
+ }
250
+
251
+ async function build(platform) {
252
+ buildLib(platform);
253
+ if (platform === 'WebAssembly' || platform === 'All') {
254
+ createWasmJs();
255
+ }
256
+ }
257
+
258
+ function buildLib(platform) {
259
+ state.platforms[platform].forEach((p) => {
260
+ if (!fs.existsSync(`${state.config.paths.output}/prebuilt/${p}/lib`)) {
261
+ createLib(p, 'Source', { isProd: true, buildSource: true });
262
+
263
+ const modules = [];
264
+ state.config.paths.module.forEach((modulePath) => {
265
+ modules.push(...findFiles('**/*.i', { cwd: modulePath }));
266
+ modules.push(...findFiles('*.i', { cwd: modulePath }));
267
+ });
268
+ if (modules.length > 0) {
269
+ fs.mkdirSync(`${state.config.paths.output}/prebuilt/${p}/swig`, { recursive: true });
270
+ }
118
271
  modules.forEach((modulePath) => {
119
272
  const fileName = modulePath.split('/').at(-1);
120
- createDir(`prebuilt/${p}/swig`, compiler2.config.paths.output);
121
- fs.copyFileSync(modulePath, `${compiler2.config.paths.output}/prebuilt/${p}/swig/${fileName}`);
273
+ fs.copyFileSync(modulePath, `${state.config.paths.output}/prebuilt/${p}/swig/${fileName}`);
122
274
  });
275
+ } else {
276
+ console.log(`${state.config.general.name} is already compiled to ${p} architecture.`);
123
277
  }
124
278
  });
125
- if (platform === 'all' || platform === 'ios') {
126
- compiler2.finishBuild();
127
- }
128
279
 
129
- const distCmakeContent = fs.readFileSync(`${compiler2.config.paths.cli}/assets/dist.cmake`, { encoding: 'utf8', flag: 'r' })
130
- .replace('___PROJECT_NAME___', compiler2.config.general.name).replace('___PROJECT_LIBS___', compiler2.config.export.libName.join(';'));
131
- fs.writeFileSync(`${compiler2.config.paths.output}/prebuilt/CMakeLists.txt`, distCmakeContent);
280
+ fs.cpSync(`${state.config.paths.build}/Source-Release/prebuilt`, `${state.config.paths.output}/prebuilt`, { recursive: true, dereference: true });
281
+
282
+ createXCFramework();
283
+
284
+ const distCmakeContent = fs.readFileSync(`${state.config.paths.cli}/assets/dist.cmake`, { encoding: 'utf8', flag: 'r' })
285
+ .replace('___PROJECT_NAME___', state.config.general.name).replace('___PROJECT_LIBS___', state.config.export.libName.join(';'));
286
+ fs.writeFileSync(`${state.config.paths.output}/prebuilt/CMakeLists.txt`, distCmakeContent);
132
287
  }
133
288
 
134
- async function buildWasm() {
289
+ async function createWasmJs() {
135
290
  let headers = [];
136
-
137
- const compiler = new CppjsCompiler();
138
- compiler.config.paths.header.forEach((headerPath) => {
139
- headers.push(glob.sync('**/*.h', { absolute: true, cwd: headerPath }));
291
+ state.config.paths.header.forEach((headerPath) => {
292
+ headers.push(findFiles('**/*.h', { cwd: headerPath }));
140
293
  });
141
294
  headers = headers.filter((path) => !!path.toString()).flat();
142
295
 
296
+ const bridges = [];
143
297
  headers.forEach((header) => {
144
- compiler.findOrCreateInterfaceFile(header);
298
+ const bridgePath = createBridgeFile(header);
299
+ bridges.push(bridgePath);
145
300
  });
146
301
 
147
- compiler.createBridge();
148
- await compiler.createWasm({ cc: ['-O3'] });
149
- createDir('prebuilt/Emscripten-x86_64/lib', compiler.config.paths.output);
302
+ const opt = {
303
+ isProd: true,
304
+ buildSource: false,
305
+ nativeGlob: [
306
+ `${state.config.paths.cli}/assets/commonBridges.cpp`,
307
+ ...bridges,
308
+ ],
309
+ };
310
+ createLib('Emscripten-x86_64', 'Bridge', opt);
150
311
 
151
- fs.renameSync(`${compiler.config.paths.temp}/lib/lib${compiler.config.general.name}.a`, `${compiler.config.paths.output}/prebuilt/Emscripten-x86_64/lib/lib${compiler.config.general.name}.a`);
152
- fs.renameSync(`${compiler.config.paths.temp}/include/`, `${compiler.config.paths.output}/prebuilt/Emscripten-x86_64/include`);
312
+ await buildWasm('browser', true);
313
+ await buildWasm('node', true);
153
314
 
154
- fs.rmSync(`${compiler.config.paths.output}/data`, { recursive: true, force: true });
155
- if (fs.existsSync(`${compiler.config.paths.temp}/data`)) {
156
- fs.renameSync(`${compiler.config.paths.temp}/data`, `${compiler.config.paths.output}/data`);
315
+ fs.rmSync(`${state.config.paths.output}/data`, { recursive: true, force: true });
316
+ if (fs.existsSync(`${state.config.paths.build}/data`)) {
317
+ fs.renameSync(`${state.config.paths.build}/data`, `${state.config.paths.output}/data`);
157
318
  }
158
319
 
159
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.node.js`, `${compiler.config.paths.output}/${compiler.config.general.name}.node.js`);
160
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.browser.js`, `${compiler.config.paths.output}/${compiler.config.general.name}.browser.js`);
161
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.wasm`, `${compiler.config.paths.output}/${compiler.config.general.name}.wasm`);
162
- if (fs.existsSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.data.txt`)) {
163
- fs.copyFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.data.txt`, `${compiler.config.paths.output}/${compiler.config.general.name}.data.txt`);
320
+ fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.node.js`, `${state.config.paths.output}/${state.config.general.name}.node.js`);
321
+ fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.browser.js`, `${state.config.paths.output}/${state.config.general.name}.browser.js`);
322
+ fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.wasm`, `${state.config.paths.output}/${state.config.general.name}.wasm`);
323
+ if (fs.existsSync(`${state.config.paths.build}/${state.config.general.name}.data.txt`)) {
324
+ fs.copyFileSync(`${state.config.paths.build}/${state.config.general.name}.data.txt`, `${state.config.paths.output}/${state.config.general.name}.data.txt`);
164
325
  }
165
-
166
- fs.rmSync(compiler.config.paths.temp, { recursive: true, force: true });
167
326
  }
package/src/index.js CHANGED
@@ -1,63 +1,13 @@
1
- import createBridge from './functions/createBridge.js';
2
- import findOrCreateInterfaceFile from './functions/findOrCreateInterfaceFile.js';
3
- import run from './functions/run.js';
4
- import finishBuild from './functions/finishBuild.js';
5
- import getCmakeParams from './functions/getCmakeParams.js';
6
- import getData from './functions/getData.js';
7
- import createWasm from './functions/createWasm.js';
8
- import createLib from './functions/createLib.js';
9
- import getConfig from './utils/getConfig.js';
10
-
11
- const platforms = ['Emscripten-x86_64', 'Android-arm64-v8a', 'iOS-iphoneos', 'iOS-iphonesimulator'];
12
- export default class CppjsCompiler {
13
- constructor(platform) {
14
- this.config = getConfig();
15
- this.interfaces = [];
16
- this.platform = platform;
17
- }
18
-
19
- findOrCreateInterfaceFile(path) {
20
- return findOrCreateInterfaceFile(this, path);
21
- }
22
-
23
- createBridge() {
24
- return createBridge(this);
25
- }
26
-
27
- createWasm(options) {
28
- return createWasm(this, options);
29
- }
30
-
31
- createLib() {
32
- return createLib(this);
33
- }
34
-
35
- getCmakeParams() {
36
- return getCmakeParams(this.config, null, true, true);
37
- }
38
-
39
- getData(field, prefixPath, subPlatform) {
40
- return getData(this.config, field, prefixPath, this.platform, subPlatform);
41
- }
42
-
43
- run(program, params, dockerOptions) {
44
- run(this, program, params, dockerOptions);
45
- }
46
-
47
- finishBuild() {
48
- finishBuild(this);
49
- }
50
-
51
- // eslint-disable-next-line class-methods-use-this
52
- getAllPlatforms() {
53
- return platforms;
54
- }
55
- }
56
-
57
- export function initCppJs() {
58
- return new Promise((resolve) => {
59
- resolve();
60
- });
61
- }
62
-
63
- export const Native = {};
1
+ // eslint-disable-next-line import/prefer-default-export
2
+ export { default as state } from './state/index.js';
3
+ export { default as getParentPath } from './utils/getParentPath.js';
4
+ export { default as createLib } from './actions/createLib.js';
5
+ export { default as createBridgeFile } from './actions/createInterface.js';
6
+ export { default as buildWasm } from './actions/buildWasm.js';
7
+ export { default as getData } from './actions/getData.js';
8
+ export { default as getCmakeParameters } from './actions/getCmakeParameters.js';
9
+ export { default as createXCFramework } from './actions/createXCFramework.js';
10
+ export { default as getAllBridges } from './actions/getAllBridges.js';
11
+ export { default as run } from './actions/run.js';
12
+ export { default as getCppJsScript } from './integration/getCppJsScript.js';
13
+ export { default as getDependFilePath } from './integration/getDependFilePath.js';
@@ -0,0 +1,91 @@
1
+ import getData from '../actions/getData.js';
2
+ import loadJson from '../utils/loadJson.js';
3
+ import state from '../state/index.js';
4
+
5
+ export default function getCppJsScript(platform, bridgePath = null) {
6
+ if (!platform || !state.platforms.All.includes(platform)) {
7
+ throw new Error('The platform is not available!');
8
+ }
9
+ const env = JSON.stringify(getData('env', platform));
10
+ const getPlatformScript = state.platforms.WebAssembly.includes(platform) ? getWebScript : getReactNativeScript;
11
+
12
+ const bridgeExportFile = `${bridgePath}.exports.json`;
13
+ let symbols = null;
14
+ if (bridgePath) {
15
+ symbols = loadJson(bridgeExportFile);
16
+ }
17
+
18
+ let symbolExportDefineString = '';
19
+ let symbolExportAssignString = '';
20
+ if (symbols && Array.isArray(symbols)) {
21
+ symbolExportDefineString = symbols.map((s) => `export let ${s} = null;`).join('\n');
22
+ symbolExportAssignString = symbols.map((s) => `${s} = m.${s};`).join('\n');
23
+ }
24
+
25
+ const scriptContent = `
26
+ AllSymbols = m;
27
+ ${symbolExportAssignString}
28
+ `;
29
+
30
+ return `
31
+ export let AllSymbols = {};
32
+ ${symbolExportDefineString}
33
+ ${getPlatformScript(env, scriptContent)}
34
+ `;
35
+ }
36
+
37
+ function getReactNativeScript(env, modulePrefix) {
38
+ return `
39
+ import { NativeModules } from 'react-native';
40
+ import Module from '@cpp.js/core-embind-jsi';
41
+
42
+ const { RNJsiLib } = NativeModules;
43
+
44
+ function setEnv() {
45
+ const env = JSON.parse('${env}');
46
+ const CPPJS_DATA_PATH = Module.CppJS.getEnv('CPPJS_DATA_PATH');
47
+
48
+ Object.entries(env).forEach(([key, value]) => {
49
+ Module.CppJS.setEnv(key, value.replace('_CPPJS_DATA_PATH_', CPPJS_DATA_PATH), true);
50
+ });
51
+ }
52
+
53
+ export function initCppJs(config = {}) {
54
+ return new Promise((resolve, reject) => {
55
+ if (RNJsiLib && RNJsiLib.start) {
56
+ RNJsiLib.start();
57
+ setEnv();
58
+ const m = Module;
59
+ ${modulePrefix}
60
+ resolve(Module);
61
+ } else {
62
+ reject('Module failed to initialise.');
63
+ }
64
+ });
65
+ }
66
+ `;
67
+ }
68
+
69
+ function getWebScript(env, modulePrefix) {
70
+ const params = `{
71
+ ...config,
72
+ env: {...${env}, ...config.env},
73
+ paths: {
74
+ wasm: 'cpp.wasm',
75
+ data: 'cpp.data.txt'
76
+ }
77
+ }`;
78
+
79
+ return `
80
+ export function initCppJs(config = {}) {
81
+ return new Promise((resolve, reject) => {
82
+ import(/* webpackIgnore: true */ '/cpp.js').then(n => {
83
+ return window.CppJs.initCppJs(${params});
84
+ }).then(m => {
85
+ ${modulePrefix}
86
+ resolve(m);
87
+ });
88
+ });
89
+ }
90
+ `;
91
+ }
@@ -0,0 +1,34 @@
1
+ import fs from 'node:fs';
2
+ import state from '../state/index.js';
3
+
4
+ export default function getDependFilePath(source, platform) {
5
+ const headerRegex = new RegExp(`\\.(${state.config.ext.header.join('|')})$`);
6
+ const moduleRegex = new RegExp(`\\.(${state.config.ext.module.join('|')})$`);
7
+
8
+ const dependPackage = state.config.allDependencies.find((d) => source.startsWith(d.package.name));
9
+ if (dependPackage) {
10
+ const depName = dependPackage.package.name;
11
+ const filePath = source.substring(depName.length + 1);
12
+
13
+ let path;
14
+ if (headerRegex.test(source)) {
15
+ path = `${dependPackage.paths.output}/prebuilt/${platform}/include`;
16
+ } else if (moduleRegex.test(source)) {
17
+ path = `${dependPackage.paths.output}/prebuilt/${platform}/swig`;
18
+ } else {
19
+ path = `${dependPackage.paths.output}/prebuilt/${platform}`;
20
+ }
21
+
22
+ if (fs.existsSync(`${path}/${depName}/${filePath}`)) {
23
+ path = `${path}/${depName}/${filePath}`;
24
+ } else if (fs.existsSync(`${path}/${filePath}`)) {
25
+ path = `${path}/${filePath}`;
26
+ } else {
27
+ throw new Error(`${source} not found in ${depName} package.`);
28
+ }
29
+
30
+ return path;
31
+ }
32
+
33
+ return null;
34
+ }