@dhruv2mars/offdex 0.0.2 → 0.0.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.
@@ -136,6 +136,18 @@ export function parseChecksumForAsset(text, asset) {
136
136
  return null;
137
137
  }
138
138
 
139
+ export function shouldReportProgress({ receivedBytes, totalBytes, lastPercent }) {
140
+ if (!totalBytes || totalBytes <= 0) {
141
+ return false;
142
+ }
143
+
144
+ const percent = Math.floor((receivedBytes / totalBytes) * 100);
145
+ if (lastPercent < 0) {
146
+ return true;
147
+ }
148
+ return percent === 100 || percent >= lastPercent + 10;
149
+ }
150
+
139
151
  function requestProtocolFor(url) {
140
152
  return new URL(url).protocol;
141
153
  }
@@ -183,7 +195,7 @@ export function requestText(url, redirects = 0) {
183
195
  });
184
196
  }
185
197
 
186
- export function download(url, outputPath, redirects = 0) {
198
+ export function download(url, outputPath, redirects = 0, options = {}) {
187
199
  if (redirects > 5) {
188
200
  throw new Error("too_many_redirects");
189
201
  }
@@ -207,7 +219,7 @@ export function download(url, outputPath, redirects = 0) {
207
219
  response.headers.location
208
220
  ) {
209
221
  response.resume();
210
- download(response.headers.location, outputPath, redirects + 1).then(resolve, reject);
222
+ download(response.headers.location, outputPath, redirects + 1, options).then(resolve, reject);
211
223
  return;
212
224
  }
213
225
  if (response.statusCode !== 200) {
@@ -215,6 +227,12 @@ export function download(url, outputPath, redirects = 0) {
215
227
  reject(new Error(`http ${response.statusCode}`));
216
228
  return;
217
229
  }
230
+ const totalBytes = Number(response.headers["content-length"] || 0);
231
+ let receivedBytes = 0;
232
+ response.on("data", (chunk) => {
233
+ receivedBytes += chunk.length;
234
+ options.onProgress?.({ receivedBytes, totalBytes });
235
+ });
218
236
  const file = createWriteStream(partPath);
219
237
  file.on("error", async (error) => {
220
238
  await rm(partPath, { force: true });
@@ -238,6 +256,9 @@ export function download(url, outputPath, redirects = 0) {
238
256
  });
239
257
  }
240
258
  );
259
+ request.setTimeout(options.timeoutMs ?? 30_000, () => {
260
+ request.destroy(new Error("download_timeout"));
261
+ });
241
262
  request.on("error", async (error) => {
242
263
  await rm(partPath, { force: true });
243
264
  reject(error);
@@ -252,7 +273,8 @@ export async function installRuntime({
252
273
  arch = process.arch,
253
274
  home = homedir(),
254
275
  downloadFn = download,
255
- requestTextFn = requestText
276
+ requestTextFn = requestText,
277
+ onProgress
256
278
  }) {
257
279
  assertSupportedPlatform(platform, arch);
258
280
  const installRoot = resolveInstallRoot(env, home);
@@ -279,7 +301,7 @@ export async function installRuntime({
279
301
  const tempPath = `${installBin}.download`;
280
302
  try {
281
303
  try {
282
- await downloadFn(`${baseUrl}/${asset}`, tempPath);
304
+ await downloadFn(`${baseUrl}/${asset}`, tempPath, 0, { onProgress });
283
305
  } catch {
284
306
  throw new Error(`failed_download:${asset}`);
285
307
  }
package/bin/install.js CHANGED
@@ -4,6 +4,7 @@ import { dirname, join } from "node:path";
4
4
  import {
5
5
  installRuntime,
6
6
  resolvePackageVersion,
7
+ shouldReportProgress,
7
8
  shouldSkipPackageInstall,
8
9
  supportedPlatformList
9
10
  } from "./install-lib.js";
@@ -17,7 +18,21 @@ if (shouldSkipPackageInstall({ env: process.env, packageRoot })) {
17
18
  process.exit(0);
18
19
  }
19
20
 
20
- installRuntime({ version: packageVersion })
21
+ let lastPercent = -10;
22
+
23
+ installRuntime({
24
+ version: packageVersion,
25
+ onProgress({ receivedBytes, totalBytes }) {
26
+ if (!shouldReportProgress({ receivedBytes, totalBytes, lastPercent })) {
27
+ return;
28
+ }
29
+
30
+ lastPercent = Math.floor((receivedBytes / totalBytes) * 100);
31
+ console.error(
32
+ `offdex: downloading native runtime ${lastPercent}% (${Math.round(receivedBytes / 1024 / 1024)}MB/${Math.round(totalBytes / 1024 / 1024)}MB)`
33
+ );
34
+ },
35
+ })
21
36
  .then(({ installBin }) => {
22
37
  console.log(`offdex: installed ${installBin}`);
23
38
  })
package/bin/offdex-lib.js CHANGED
@@ -1,7 +1,12 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { dirname, join } from "node:path";
4
- import { readInstalledVersion, resolveInstalledBin, shouldInstallBinary } from "./install-lib.js";
4
+ import {
5
+ isWorkspaceCheckout,
6
+ readInstalledVersion,
7
+ resolveInstalledBin,
8
+ shouldInstallBinary
9
+ } from "./install-lib.js";
5
10
 
6
11
  export function resolvePackageBinDir(moduleUrl = import.meta.url) {
7
12
  return dirname(fileURLToPath(moduleUrl));
@@ -18,4 +23,16 @@ export function installedVersion(env = process.env) {
18
23
  return readInstalledVersion(env);
19
24
  }
20
25
 
26
+ export function resolveWorkspaceBridgeCli(moduleUrl = import.meta.url) {
27
+ const binDir = resolvePackageBinDir(moduleUrl);
28
+ const packageRoot = join(binDir, "..");
29
+ const workspaceRootPackageJson = join(packageRoot, "..", "..", "package.json");
30
+ if (!isWorkspaceCheckout(workspaceRootPackageJson)) {
31
+ return null;
32
+ }
33
+
34
+ const bridgeCli = join(packageRoot, "..", "bridge", "src", "cli.ts");
35
+ return existsSync(bridgeCli) ? bridgeCli : null;
36
+ }
37
+
21
38
  export { resolveInstalledBin, shouldInstallBinary };
package/bin/offdex.js CHANGED
@@ -8,13 +8,50 @@ import {
8
8
  readPackageVersion,
9
9
  resolveInstalledBin,
10
10
  resolvePackageBinDir,
11
+ resolveWorkspaceBridgeCli,
11
12
  shouldInstallBinary
12
13
  } from "./offdex-lib.js";
13
14
 
14
15
  const args = process.argv.slice(2);
16
+ const HELP_TEXT = `Offdex CLI
17
+
18
+ Usage:
19
+ offdex bridge [options]
20
+ offdex help
21
+
22
+ Options:
23
+ --host <host> Bridge host. Default: 0.0.0.0
24
+ --port <port> Bridge port. Default: 42420
25
+ --mode <codex|demo> Bridge runtime mode. Default: codex
26
+ --control-plane-url <url> Managed remote control plane URL
27
+ -h, --help Show help
28
+
29
+ Environment fallbacks:
30
+ OFFDEX_BRIDGE_HOST
31
+ OFFDEX_BRIDGE_PORT
32
+ OFFDEX_BRIDGE_MODE
33
+ OFFDEX_CONTROL_PLANE_URL
34
+ `;
15
35
  const installedBin = resolveInstalledBin(process.env, process.platform);
16
36
  const packageVersion = readPackageVersion();
17
37
  const currentInstalledVersion = installedVersion(process.env);
38
+ const workspaceBridgeCli = resolveWorkspaceBridgeCli();
39
+
40
+ if (
41
+ !existsSync(installedBin) &&
42
+ (args.length === 0 || args[0] === "help" || args[0] === "--help" || args[0] === "-h")
43
+ ) {
44
+ console.log(HELP_TEXT);
45
+ process.exit(0);
46
+ }
47
+
48
+ if (workspaceBridgeCli && !existsSync(installedBin)) {
49
+ const result = spawnSync("bun", [workspaceBridgeCli, ...args], {
50
+ stdio: "inherit",
51
+ env: process.env
52
+ });
53
+ process.exit(result.status ?? 1);
54
+ }
18
55
 
19
56
  if (
20
57
  shouldInstallBinary({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhruv2mars/offdex",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Codex mobile bridge CLI for Offdex",
5
5
  "type": "module",
6
6
  "bin": {