@rs-x/cli 2.0.0-next.21 → 2.0.0-next.22

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/bin/rsx.cjs CHANGED
@@ -3142,11 +3142,14 @@ function rsxBootstrapFilePath(entryFile) {
3142
3142
  }
3143
3143
 
3144
3144
  function ensureRsxBootstrapFile(bootstrapFile, dryRun) {
3145
- const content = `import { InjectionContainer } from '@rs-x/core';\nimport { RsXExpressionParserModule } from '@rs-x/expression-parser';\n\n// Generated by rsx init\nexport async function initRsx(): Promise<void> {\n await InjectionContainer.load(RsXExpressionParserModule);\n}\n`;
3145
+ const content = `import { InjectionContainer } from '@rs-x/core';\nimport { RsXExpressionParserModule } from '@rs-x/expression-parser';\n\n// Generated by rsx init top-level await ensures DI is ready before any expression module evaluates\nawait InjectionContainer.load(RsXExpressionParserModule);\n`;
3146
3146
 
3147
3147
  if (fs.existsSync(bootstrapFile)) {
3148
3148
  const existing = fs.readFileSync(bootstrapFile, 'utf8');
3149
- if (existing.includes('export async function initRsx')) {
3149
+ if (
3150
+ existing.includes('await InjectionContainer.load') ||
3151
+ existing.includes('export async function initRsx')
3152
+ ) {
3150
3153
  logInfo(`Bootstrap module already exists: ${bootstrapFile}`);
3151
3154
  return;
3152
3155
  }
@@ -3209,16 +3212,14 @@ function indentBlock(text, spaces) {
3209
3212
  }
3210
3213
 
3211
3214
  function wrapReactEntry(source) {
3215
+ // top-level await in rsx-bootstrap.ts ensures DI is loaded before any
3216
+ // expression module evaluates — no async wrapper needed here
3212
3217
  const reactStartPattern =
3213
3218
  /(ReactDOM\s*\.\s*)?createRoot\([\s\S]*?\)\s*\.\s*render\([\s\S]*?\);/mu;
3214
- const match = source.match(reactStartPattern);
3215
- if (!match) {
3219
+ if (!source.match(reactStartPattern)) {
3216
3220
  return null;
3217
3221
  }
3218
-
3219
- const renderCall = match[0].trim();
3220
- const replacement = `const __rsxStart = async () => {\n await initRsx();\n${indentBlock(renderCall, 2)}\n};\n\nvoid __rsxStart();`;
3221
- return source.replace(reactStartPattern, replacement);
3222
+ return source;
3222
3223
  }
3223
3224
 
3224
3225
  function wrapAngularEntry(source) {
@@ -3243,16 +3244,14 @@ function wrapAngularEntry(source) {
3243
3244
  }
3244
3245
 
3245
3246
  function wrapVueEntry(source) {
3247
+ // top-level await in rsx-bootstrap.ts ensures DI is loaded before any
3248
+ // expression module evaluates — no async wrapper needed here
3246
3249
  const vueStartPattern =
3247
3250
  /createApp\([\s\S]*?\)\s*\.\s*mount\([\s\S]*?\)\s*;/mu;
3248
- const match = source.match(vueStartPattern);
3249
- if (!match) {
3251
+ if (!source.match(vueStartPattern)) {
3250
3252
  return null;
3251
3253
  }
3252
-
3253
- const mountCall = match[0].trim();
3254
- const replacement = `const __rsxBootstrap = async () => {\n await initRsx();\n${indentBlock(mountCall, 2)}\n};\n\nvoid __rsxBootstrap();`;
3255
- return source.replace(vueStartPattern, replacement);
3254
+ return source;
3256
3255
  }
3257
3256
 
3258
3257
  function wrapGenericEntry(source) {
@@ -3448,13 +3447,19 @@ function patchNextEntryFile(entryFile, gateFile, dryRun) {
3448
3447
 
3449
3448
  function patchEntryFileForRsx(entryFile, bootstrapFile, context, dryRun) {
3450
3449
  const original = fs.readFileSync(entryFile, 'utf8');
3451
- if (original.includes('initRsx') && original.includes('rsx-bootstrap')) {
3450
+ if (original.includes('rsx-bootstrap')) {
3452
3451
  logInfo(`Entry already wired for RS-X bootstrap: ${entryFile}`);
3453
3452
  return true;
3454
3453
  }
3455
3454
 
3456
3455
  const importPath = toModuleImportPath(entryFile, bootstrapFile);
3457
- const importStatement = `import { initRsx } from '${importPath}';`;
3456
+ // For React/Vue: side-effect import only top-level await in bootstrap
3457
+ // ensures DI is ready before any expression module evaluates.
3458
+ // For Angular/generic: named import used by the async wrapper.
3459
+ const importStatement =
3460
+ context === 'react' || context === 'vuejs'
3461
+ ? `import '${importPath}';`
3462
+ : `import { initRsx } from '${importPath}';`;
3458
3463
 
3459
3464
  let updated = injectImport(original, importStatement);
3460
3465
 
@@ -3559,8 +3564,7 @@ function runInit(flags) {
3559
3564
 
3560
3565
  if (!patched) {
3561
3566
  logInfo('Manual fallback snippet:');
3562
- console.log(" import { initRsx } from './rsx-bootstrap';");
3563
- console.log(' await initRsx(); // before first rsx(...)');
3567
+ console.log(" import './rsx-bootstrap'; // must be the first import in your entry file");
3564
3568
  }
3565
3569
  }
3566
3570
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rs-x/cli",
3
- "version": "2.0.0-next.21",
3
+ "version": "2.0.0-next.22",
4
4
  "description": "CLI for installing RS-X compiler tooling and VS Code integration",
5
5
  "bin": {
6
6
  "rsx": "./bin/rsx.cjs"