@scalebun/react-native 1.6.3 → 1.6.5

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/scalebun.js CHANGED
@@ -866,6 +866,73 @@ function resolveOtaCli() {
866
866
  }
867
867
  }
868
868
 
869
+ /**
870
+ * Run the bundled CLI, showing a loader until it produces its first output.
871
+ *
872
+ * `npx scalebun <cmd>` pays npx + two Node startups + module loading (~0.5–1s)
873
+ * before anything appears — a blank terminal that reads as "hung". This spins a
874
+ * dependency-free loader in this (fast, dep-free) process while the CLI child
875
+ * boots, then clears it the instant the child writes.
876
+ *
877
+ * Only stdout is piped (so we can detect that first byte); stdin and stderr stay
878
+ * inherited, so masked token input and the delete/rollback confirmations — all of
879
+ * which key off `process.stdin.isTTY` — keep working. FORCE_COLOR keeps the
880
+ * child's colours despite the pipe. On a non-TTY (CI, pipes) we skip the loader
881
+ * and inherit everything, exactly as before.
882
+ */
883
+ function runCli(cliEntry, args) {
884
+ const { spawn, spawnSync } = require('child_process');
885
+
886
+ if (!process.stdout.isTTY) {
887
+ const res = spawnSync(process.execPath, [cliEntry, ...args], { stdio: 'inherit' });
888
+ process.exit(res.status ?? 1);
889
+ return;
890
+ }
891
+
892
+ const env = { ...process.env };
893
+ if (!env.FORCE_COLOR) env.FORCE_COLOR = '1';
894
+
895
+ const child = spawn(process.execPath, [cliEntry, ...args], {
896
+ stdio: ['inherit', 'pipe', 'inherit'],
897
+ env,
898
+ });
899
+
900
+ const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
901
+ const label = ' Starting ScaleBun…';
902
+ let i = 0;
903
+ let spinning = true;
904
+ process.stdout.write('\x1b[?25l'); // hide cursor
905
+ const timer = setInterval(() => {
906
+ i = (i + 1) % frames.length;
907
+ process.stdout.write(`\r${paint(frames[i], C.cyan)}${label}`);
908
+ }, 80);
909
+ const stopSpinner = () => {
910
+ if (!spinning) return;
911
+ spinning = false;
912
+ clearInterval(timer);
913
+ // Erase the spinner line and restore the cursor.
914
+ process.stdout.write('\r' + ' '.repeat(label.length + 2) + '\r\x1b[?25h');
915
+ };
916
+
917
+ child.stdout.on('data', (chunk) => {
918
+ stopSpinner();
919
+ process.stdout.write(chunk);
920
+ });
921
+ child.on('error', () => {
922
+ stopSpinner();
923
+ process.exit(1);
924
+ });
925
+ child.on('exit', (code) => {
926
+ stopSpinner();
927
+ process.exit(code ?? 0);
928
+ });
929
+ // Defensive: never leave the terminal cursor hidden.
930
+ process.on('SIGINT', stopSpinner);
931
+ process.on('exit', () => {
932
+ if (spinning) process.stdout.write('\x1b[?25h');
933
+ });
934
+ }
935
+
869
936
  /**
870
937
  * Hand the invocation to @scalebun/cli, preserving argv and exit code.
871
938
  * Falls back to an actionable install instruction when it is not present.
@@ -891,46 +958,46 @@ function delegateToOtaCli(argv) {
891
958
  process.exit(2);
892
959
  }
893
960
 
894
- const { spawnSync } = require('child_process');
895
- const res = spawnSync(process.execPath, [cliEntry, ...argv], {
896
- stdio: 'inherit',
897
- });
898
- process.exit(res.status ?? 1);
961
+ runCli(cliEntry, argv);
899
962
  }
900
963
 
901
964
  /**
902
- * Print the full command surface: the SDK-setup commands this package handles
903
- * directly, followed by the complete @scalebun/cli command tree.
965
+ * Print the full, guided command surface.
904
966
  *
905
- * The CLI tree is rendered by delegating to `@scalebun/cli --help` rather than a
906
- * hardcoded list, so it is a single source of truth and cannot drift. When the
907
- * CLI cannot be resolved (should not happen it is a dependency) we fall back to
908
- * a prose note instead of an error, since this is a help screen.
967
+ * Delegates to the bundled @scalebun/cli's own banner (invoked with no args),
968
+ * which renders the "publish your first OTA update" getting-started flow,
969
+ * project setup (doctor + init ios/android), and every OTA subcommand a single
970
+ * source of truth that cannot drift. `--help` on the CLI would only list
971
+ * top-level groups (so `ota generate-key-pair` etc. would stay hidden), which is
972
+ * exactly the discoverability gap this avoids. When the CLI cannot be resolved
973
+ * (should not happen — it is a dependency) we fall back to a static list.
909
974
  */
910
975
  function printFullHelp() {
911
- console.log('');
912
- console.log(paint('ScaleBun SDK CLI', C.bold));
913
- console.log('');
914
- console.log(paint('SDK setup (bundled with @scalebun/react-native):', C.bold));
915
- console.log(' npx scalebun doctor Diagnose push-notification setup');
916
- console.log(' npx scalebun init ios Wire the iOS AppDelegate for Direct APNs + OTA');
917
- console.log(' npx scalebun init android Wire Android MainApplication for OTA bundle loading');
918
- console.log(paint(' add --check to verify (exit 1 if missing) or --dry-run to preview', C.dim));
919
- console.log('');
920
-
921
976
  const cliEntry = resolveOtaCli();
922
- if (!cliEntry) {
923
- console.log(paint('OTA & account commands:', C.bold));
924
- console.log(' Provided by @scalebun/cli (login, quickstart, apps, ota publish,');
925
- console.log(' releases, rollout…). It ships with this package but could not be');
926
- console.log(' resolved — run `npm install`, then `npx scalebun --help` again.');
927
- console.log('');
977
+ if (cliEntry) {
978
+ // No args the CLI prints its banner + status + full guided command list.
979
+ runCli(cliEntry, []);
928
980
  return;
929
981
  }
930
982
 
931
- console.log(paint('OTA & account commands (from @scalebun/cli):', C.bold));
932
- const { spawnSync } = require('child_process');
933
- spawnSync(process.execPath, [cliEntry, '--help'], { stdio: 'inherit' });
983
+ // Fallback: CLI unresolvable — show at least the setup commands + how to fix.
984
+ console.log('');
985
+ console.log(paint('ScaleBun CLI', C.bold));
986
+ console.log('');
987
+ console.log(paint('Publish your first OTA update:', C.bold));
988
+ console.log(' 1. npx scalebun login Authenticate (paste a token)');
989
+ console.log(' 2. npx scalebun apps Find your --app-id');
990
+ console.log(' 3. npx scalebun init android | init ios Wire the native app for OTA, then rebuild');
991
+ console.log(' 4. npx scalebun ota publish --app-id <id> --hermes');
992
+ console.log('');
993
+ console.log(paint('Project setup:', C.bold));
994
+ console.log(' npx scalebun doctor Check the project is OTA-ready');
995
+ console.log(' npx scalebun init ios Wire the iOS AppDelegate for OTA + Direct APNs');
996
+ console.log(' npx scalebun init android Wire the Android MainApplication for OTA');
997
+ console.log(paint(' add --check to verify (exit 1 if missing) or --dry-run to preview', C.dim));
998
+ console.log('');
999
+ console.log(paint('The OTA & account commands come from @scalebun/cli, which ships with this', C.dim));
1000
+ console.log(paint('package but could not be resolved — run `npm install`, then retry.', C.dim));
934
1001
  console.log('');
935
1002
  }
936
1003
 
@@ -489,7 +489,7 @@ var SDK_VERSION;
489
489
  var init_version = __esm({
490
490
  "lib/module/core/constants/version.js"() {
491
491
  "use strict";
492
- SDK_VERSION = "1.6.3";
492
+ SDK_VERSION = "1.6.5";
493
493
  }
494
494
  });
495
495
 
@@ -492,7 +492,7 @@ var SDK_VERSION;
492
492
  var init_version = __esm({
493
493
  "lib/module/core/constants/version.js"() {
494
494
  "use strict";
495
- SDK_VERSION = "1.6.3";
495
+ SDK_VERSION = "1.6.5";
496
496
  }
497
497
  });
498
498
 
@@ -9,5 +9,5 @@ exports.SDK_VERSION = void 0;
9
9
  * can attribute telemetry to the SDK build that produced it.
10
10
  * Keep in sync with package.json "version".
11
11
  */
12
- const SDK_VERSION = exports.SDK_VERSION = '1.6.3';
12
+ const SDK_VERSION = exports.SDK_VERSION = '1.6.5';
13
13
  //# sourceMappingURL=version.js.map
@@ -3,5 +3,5 @@
3
3
  * can attribute telemetry to the SDK build that produced it.
4
4
  * Keep in sync with package.json "version".
5
5
  */
6
- export const SDK_VERSION = '1.6.3';
6
+ export const SDK_VERSION = '1.6.5';
7
7
  //# sourceMappingURL=version.js.map
@@ -3,5 +3,5 @@
3
3
  * can attribute telemetry to the SDK build that produced it.
4
4
  * Keep in sync with package.json "version".
5
5
  */
6
- export declare const SDK_VERSION = "1.6.3";
6
+ export declare const SDK_VERSION = "1.6.5";
7
7
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalebun/react-native",
3
- "version": "1.6.3",
3
+ "version": "1.6.5",
4
4
  "description": "Production-grade React Native SDK for ScaleBun",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -105,7 +105,7 @@
105
105
  "@babel/runtime": "^7.25.0",
106
106
  "@jridgewell/sourcemap-codec": "1.5.5",
107
107
  "@jridgewell/trace-mapping": "0.3.31",
108
- "@scalebun/cli": "^1.6.3"
108
+ "@scalebun/cli": "^1.6.5"
109
109
  },
110
110
  "codegenConfig": {
111
111
  "name": "ScaleBunSpec",
@@ -3,4 +3,4 @@
3
3
  * can attribute telemetry to the SDK build that produced it.
4
4
  * Keep in sync with package.json "version".
5
5
  */
6
- export const SDK_VERSION = '1.6.3';
6
+ export const SDK_VERSION = '1.6.5';