@eiva/protoc-gen-fletcher 0.1.2-alpha → 0.3.0-alpha

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/README.md CHANGED
@@ -17,14 +17,14 @@ npm install --save-dev @protobuf-ts/protoc
17
17
  ```
18
18
 
19
19
  ```bash
20
- npm install --save-dev fletcher-gateway-client@npm:@eiva/fletcher-gateway-client
20
+ npm install --save-dev @eiva/fletcher-gateway-client
21
21
  ```
22
22
 
23
23
  Three pieces:
24
24
 
25
25
  - **`@eiva/protoc-gen-fletcher`** — this plugin shim.
26
26
  - **`@protobuf-ts/protoc`** — ships the `protoc` compiler binary itself. Declared as a peer dependency; npm 7+ auto-installs it, older npm versions print a warning. Install explicitly above to be safe.
27
- - **`fletcher-gateway-client`** under the bare alias `npm:@eiva/fletcher-gateway-client` the generated `.fletcher.ts` files import `WireTypeId` and the `TypedSchema` type from a **bare** `'fletcher-gateway-client'` specifier. Installing under that alias makes the published `@eiva/fletcher-gateway-client` resolve at runtime via standard Node resolution (no tsconfig path-alias trickery needed).
27
+ - **`@eiva/fletcher-gateway-client`** the gateway runtime. The generated `.fletcher.ts` files import `WireTypeId` and the `TypedSchema` type from `'@eiva/fletcher-gateway-client'`, so a plain install resolves them via standard Node resolution no bare-alias or tsconfig path trickery needed.
28
28
 
29
29
  ## Usage
30
30
 
@@ -53,13 +53,15 @@ function followRedirects(url, depth) {
53
53
  return resolve(followRedirects(res.headers.location, depth + 1));
54
54
  }
55
55
  if (res.statusCode !== 200) {
56
- return reject(
57
- new Error(
58
- `Download failed (${res.statusCode}): ${url}\n` +
59
- `Check that the release exists at ` +
60
- `https://github.com/eivacom/Fletcher/releases/tag/protoc-v${VERSION}`,
61
- ),
56
+ // 5xx / 429 are transient (gateway timeouts, rate limiting); tag
57
+ // them retryable. 4xx (e.g. 404 missing release) is fatal.
58
+ const err = new Error(
59
+ `Download failed (${res.statusCode}): ${url}\n` +
60
+ `Check that the release exists at ` +
61
+ `https://github.com/eivacom/Fletcher/releases/tag/protoc-v${VERSION}`,
62
62
  );
63
+ err.retryable = res.statusCode >= 500 || res.statusCode === 429;
64
+ return reject(err);
63
65
  }
64
66
  const chunks = [];
65
67
  res.on('data', (chunk) => chunks.push(chunk));
@@ -70,6 +72,39 @@ function followRedirects(url, depth) {
70
72
  });
71
73
  }
72
74
 
75
+ // GitHub Releases occasionally returns a transient 5xx (e.g. a 504 gateway
76
+ // timeout) or drops the connection. Retry a few times with exponential
77
+ // backoff so a blip doesn't fail codegen for a user; non-retryable (4xx)
78
+ // errors and the final attempt propagate immediately.
79
+ const MAX_DOWNLOAD_ATTEMPTS = 6;
80
+
81
+ function isRetryable(err) {
82
+ // Untagged errors (socket resets, timeouts) are transient; only errors
83
+ // explicitly tagged retryable=false (4xx responses) are fatal.
84
+ return !(err && err.retryable === false);
85
+ }
86
+
87
+ async function downloadWithRetry(url) {
88
+ let lastErr;
89
+ for (let attempt = 1; attempt <= MAX_DOWNLOAD_ATTEMPTS; ++attempt) {
90
+ try {
91
+ return await followRedirects(url, 0);
92
+ } catch (err) {
93
+ lastErr = err;
94
+ if (!isRetryable(err) || attempt === MAX_DOWNLOAD_ATTEMPTS) {
95
+ break;
96
+ }
97
+ const delayMs = Math.min(1000 * 2 ** (attempt - 1), 8000); // 1,2,4,8,8s
98
+ process.stderr.write(
99
+ `protoc-gen-fletcher: download attempt ${attempt}/${MAX_DOWNLOAD_ATTEMPTS} failed ` +
100
+ `(${err.message}); retrying in ${delayMs}ms\n`,
101
+ );
102
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
103
+ }
104
+ }
105
+ throw lastErr;
106
+ }
107
+
73
108
  async function ensureBinary() {
74
109
  const asset = platformAssetName();
75
110
  const cacheBin = path.join(cacheDir(), asset);
@@ -81,7 +116,7 @@ async function ensureBinary() {
81
116
  process.stderr.write(`protoc-gen-fletcher: downloading ${url}\n`);
82
117
 
83
118
  fs.mkdirSync(cacheDir(), { recursive: true });
84
- const buf = await followRedirects(url, 0);
119
+ const buf = await downloadWithRetry(url);
85
120
 
86
121
  // Atomic write: write to a unique tmp file in the same dir, then rename.
87
122
  // Multiple npm scripts may invoke the shim in parallel; rename within the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eiva/protoc-gen-fletcher",
3
- "version": "0.1.2-alpha",
3
+ "version": "0.3.0-alpha",
4
4
  "description": "protoc plugin that generates typed TypeScript schema descriptors for Fletcher's positional wire format. Downloads the platform-matching native plugin binary from GitHub Releases on first invocation.",
5
5
  "license": "LGPL-3.0-or-later",
6
6
  "homepage": "https://github.com/eivacom/Fletcher/tree/main/protoc",