@dangayle/rustlike 0.1.0
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/LICENSE +22 -0
- package/README.md +864 -0
- package/dist/async-iter-1OXm1ncF.d.mts +468 -0
- package/dist/async-iter-1OXm1ncF.d.mts.map +1 -0
- package/dist/async-iter-3iu4aRtf.cjs +1129 -0
- package/dist/async-iter-3iu4aRtf.cjs.map +1 -0
- package/dist/async-iter-D7Pj6knS.d.cts +468 -0
- package/dist/async-iter-D7Pj6knS.d.cts.map +1 -0
- package/dist/async-iter-aLdg-qp2.mjs +1009 -0
- package/dist/async-iter-aLdg-qp2.mjs.map +1 -0
- package/dist/index.cjs +477 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +342 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +342 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +443 -0
- package/dist/index.mjs.map +1 -0
- package/dist/node.cjs +118 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +46 -0
- package/dist/node.d.cts.map +1 -0
- package/dist/node.d.mts +46 -0
- package/dist/node.d.mts.map +1 -0
- package/dist/node.mjs +87 -0
- package/dist/node.mjs.map +1 -0
- package/package.json +80 -0
package/dist/node.d.mts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { g as Result, s as Iter, t as AsyncIter } from "./async-iter-1OXm1ncF.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/node.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Create an Iter that lazily reads lines from a file.
|
|
6
|
+
* Uses Node.js fs.readFileSync but yields lines lazily via generator.
|
|
7
|
+
*
|
|
8
|
+
* Note: This reads the entire file into memory but yields lines lazily.
|
|
9
|
+
* For truly streaming line-by-line reading, use asyncIterLines.
|
|
10
|
+
*
|
|
11
|
+
* @param filepath - Path to the file to read
|
|
12
|
+
* @returns Result with Iter<string> on success, error message on failure
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const lines = iterLinesSync('data.txt');
|
|
16
|
+
* lines.match({
|
|
17
|
+
* ok: (iter) => iter.skip(1).map(parseLine).collect(),
|
|
18
|
+
* err: (e) => console.error(e)
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
declare function iterLinesSync(filepath: string): Result<Iter<string>, string>;
|
|
22
|
+
/**
|
|
23
|
+
* Create an AsyncIter that reads lines from a file using streaming.
|
|
24
|
+
* Truly memory-efficient - reads lines on-demand without loading entire file.
|
|
25
|
+
*
|
|
26
|
+
* Uses Node.js readline with createReadStream for efficient streaming.
|
|
27
|
+
*
|
|
28
|
+
* @param filepath - Path to the file to read
|
|
29
|
+
* @returns Promise of Result with AsyncIter<string> on success, error message on failure
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const result = await asyncIterLines('large-log.txt');
|
|
33
|
+
* result.match({
|
|
34
|
+
* ok: async (iter) => {
|
|
35
|
+
* const errors = await iter
|
|
36
|
+
* .filter(line => line.includes('ERROR'))
|
|
37
|
+
* .take(100)
|
|
38
|
+
* .collect();
|
|
39
|
+
* },
|
|
40
|
+
* err: (e) => console.error(e)
|
|
41
|
+
* });
|
|
42
|
+
*/
|
|
43
|
+
declare function asyncIterLines(filepath: string): Promise<Result<AsyncIter<string>, string>>;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { asyncIterLines, iterLinesSync };
|
|
46
|
+
//# sourceMappingURL=node.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.mts","names":[],"sources":["../src/node.ts"],"mappings":";;;AAiFA;;;;;;;;;;;;;;;;;AAAA,iBA1CgB,aAAA,CAAc,QAAA,WAAmB,MAAA,CAAO,IAAA;;;;;;;;;;;;;;;;;;;;;;iBA0ClC,cAAA,CAAe,QAAA,WAAmB,OAAA,CAAQ,MAAA,CAAO,SAAA"}
|
package/dist/node.mjs
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { f as Ok, n as asyncIter, s as iter, u as Err } from "./async-iter-aLdg-qp2.mjs";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as readline from "readline";
|
|
4
|
+
|
|
5
|
+
//#region src/node.ts
|
|
6
|
+
/**
|
|
7
|
+
* Node.js-specific utilities for rustlike.
|
|
8
|
+
*
|
|
9
|
+
* This module contains functions that depend on Node.js built-in modules
|
|
10
|
+
* (fs, readline) and should only be imported in Node.js environments.
|
|
11
|
+
* Browser and edge runtime consumers should use the main 'rustlike' entry point.
|
|
12
|
+
*
|
|
13
|
+
* Import from 'rustlike/node' to access these functions.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Create an Iter that lazily reads lines from a file.
|
|
17
|
+
* Uses Node.js fs.readFileSync but yields lines lazily via generator.
|
|
18
|
+
*
|
|
19
|
+
* Note: This reads the entire file into memory but yields lines lazily.
|
|
20
|
+
* For truly streaming line-by-line reading, use asyncIterLines.
|
|
21
|
+
*
|
|
22
|
+
* @param filepath - Path to the file to read
|
|
23
|
+
* @returns Result with Iter<string> on success, error message on failure
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const lines = iterLinesSync('data.txt');
|
|
27
|
+
* lines.match({
|
|
28
|
+
* ok: (iter) => iter.skip(1).map(parseLine).collect(),
|
|
29
|
+
* err: (e) => console.error(e)
|
|
30
|
+
* });
|
|
31
|
+
*/
|
|
32
|
+
function iterLinesSync(filepath) {
|
|
33
|
+
try {
|
|
34
|
+
const lines = fs.readFileSync(filepath, "utf-8").split("\n");
|
|
35
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
36
|
+
return Ok(iter(lines));
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (error instanceof Error) return Err(`Failed to read file '${filepath}': ${error.message}`);
|
|
39
|
+
return Err(`Failed to read file '${filepath}': ${String(error)}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Create an AsyncIter that reads lines from a file using streaming.
|
|
44
|
+
* Truly memory-efficient - reads lines on-demand without loading entire file.
|
|
45
|
+
*
|
|
46
|
+
* Uses Node.js readline with createReadStream for efficient streaming.
|
|
47
|
+
*
|
|
48
|
+
* @param filepath - Path to the file to read
|
|
49
|
+
* @returns Promise of Result with AsyncIter<string> on success, error message on failure
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const result = await asyncIterLines('large-log.txt');
|
|
53
|
+
* result.match({
|
|
54
|
+
* ok: async (iter) => {
|
|
55
|
+
* const errors = await iter
|
|
56
|
+
* .filter(line => line.includes('ERROR'))
|
|
57
|
+
* .take(100)
|
|
58
|
+
* .collect();
|
|
59
|
+
* },
|
|
60
|
+
* err: (e) => console.error(e)
|
|
61
|
+
* });
|
|
62
|
+
*/
|
|
63
|
+
async function asyncIterLines(filepath) {
|
|
64
|
+
try {
|
|
65
|
+
await fs.promises.access(filepath, fs.constants.R_OK);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (error instanceof Error) return Err(`Failed to access file '${filepath}': ${error.message}`);
|
|
68
|
+
return Err(`Failed to access file '${filepath}': ${String(error)}`);
|
|
69
|
+
}
|
|
70
|
+
return Ok(asyncIter((async function* () {
|
|
71
|
+
const fileStream = fs.createReadStream(filepath, { encoding: "utf-8" });
|
|
72
|
+
const rl = readline.createInterface({
|
|
73
|
+
input: fileStream,
|
|
74
|
+
crlfDelay: Infinity
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
for await (const line of rl) yield line;
|
|
78
|
+
} finally {
|
|
79
|
+
rl.close();
|
|
80
|
+
fileStream.destroy();
|
|
81
|
+
}
|
|
82
|
+
})()));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { asyncIterLines, iterLinesSync };
|
|
87
|
+
//# sourceMappingURL=node.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.mjs","names":[],"sources":["../src/node.ts"],"sourcesContent":["/**\n * Node.js-specific utilities for rustlike.\n *\n * This module contains functions that depend on Node.js built-in modules\n * (fs, readline) and should only be imported in Node.js environments.\n * Browser and edge runtime consumers should use the main 'rustlike' entry point.\n *\n * Import from 'rustlike/node' to access these functions.\n */\n\nimport * as fs from \"fs\";\nimport * as readline from \"readline\";\nimport { Result, Ok, Err } from \"./core\";\nimport { iter } from \"./iter\";\nimport { asyncIter } from \"./async-iter\";\nimport type { Iter } from \"./iter\";\nimport type { AsyncIter } from \"./async-iter\";\n\n// ============================================================================\n// File Reading (Sync)\n// ============================================================================\n\n/**\n * Create an Iter that lazily reads lines from a file.\n * Uses Node.js fs.readFileSync but yields lines lazily via generator.\n *\n * Note: This reads the entire file into memory but yields lines lazily.\n * For truly streaming line-by-line reading, use asyncIterLines.\n *\n * @param filepath - Path to the file to read\n * @returns Result with Iter<string> on success, error message on failure\n *\n * @example\n * const lines = iterLinesSync('data.txt');\n * lines.match({\n * ok: (iter) => iter.skip(1).map(parseLine).collect(),\n * err: (e) => console.error(e)\n * });\n */\nexport function iterLinesSync(filepath: string): Result<Iter<string>, string> {\n try {\n const content = fs.readFileSync(filepath, \"utf-8\");\n const lines = content.split(\"\\n\");\n // Remove trailing empty line if file ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n return Ok(iter(lines));\n } catch (error) {\n if (error instanceof Error) {\n return Err(`Failed to read file '${filepath}': ${error.message}`);\n }\n return Err(`Failed to read file '${filepath}': ${String(error)}`);\n }\n}\n\n// ============================================================================\n// File Reading (Async)\n// ============================================================================\n\n/**\n * Create an AsyncIter that reads lines from a file using streaming.\n * Truly memory-efficient - reads lines on-demand without loading entire file.\n *\n * Uses Node.js readline with createReadStream for efficient streaming.\n *\n * @param filepath - Path to the file to read\n * @returns Promise of Result with AsyncIter<string> on success, error message on failure\n *\n * @example\n * const result = await asyncIterLines('large-log.txt');\n * result.match({\n * ok: async (iter) => {\n * const errors = await iter\n * .filter(line => line.includes('ERROR'))\n * .take(100)\n * .collect();\n * },\n * err: (e) => console.error(e)\n * });\n */\nexport async function asyncIterLines(filepath: string): Promise<Result<AsyncIter<string>, string>> {\n // Check if file exists first\n try {\n await fs.promises.access(filepath, fs.constants.R_OK);\n } catch (error) {\n if (error instanceof Error) {\n return Err(`Failed to access file '${filepath}': ${error.message}`);\n }\n return Err(`Failed to access file '${filepath}': ${String(error)}`);\n }\n\n // Create the async iterator using readline\n const asyncIterator = (async function* () {\n const fileStream = fs.createReadStream(filepath, { encoding: \"utf-8\" });\n const rl = readline.createInterface({\n input: fileStream,\n crlfDelay: Infinity, // Handle both \\n and \\r\\n\n });\n\n try {\n for await (const line of rl) {\n yield line;\n }\n } finally {\n rl.close();\n fileStream.destroy();\n }\n })();\n\n return Ok(asyncIter(asyncIterator));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,SAAgB,cAAc,UAAgD;AAC5E,KAAI;EAEF,MAAM,QADU,GAAG,aAAa,UAAU,QAAQ,CAC5B,MAAM,KAAK;AAEjC,MAAI,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,OAAO,GAClD,OAAM,KAAK;AAEb,SAAO,GAAG,KAAK,MAAM,CAAC;UACf,OAAO;AACd,MAAI,iBAAiB,MACnB,QAAO,IAAI,wBAAwB,SAAS,KAAK,MAAM,UAAU;AAEnE,SAAO,IAAI,wBAAwB,SAAS,KAAK,OAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;AA6BrE,eAAsB,eAAe,UAA8D;AAEjG,KAAI;AACF,QAAM,GAAG,SAAS,OAAO,UAAU,GAAG,UAAU,KAAK;UAC9C,OAAO;AACd,MAAI,iBAAiB,MACnB,QAAO,IAAI,0BAA0B,SAAS,KAAK,MAAM,UAAU;AAErE,SAAO,IAAI,0BAA0B,SAAS,KAAK,OAAO,MAAM,GAAG;;AAqBrE,QAAO,GAAG,WAjBa,mBAAmB;EACxC,MAAM,aAAa,GAAG,iBAAiB,UAAU,EAAE,UAAU,SAAS,CAAC;EACvE,MAAM,KAAK,SAAS,gBAAgB;GAClC,OAAO;GACP,WAAW;GACZ,CAAC;AAEF,MAAI;AACF,cAAW,MAAM,QAAQ,GACvB,OAAM;YAEA;AACR,MAAG,OAAO;AACV,cAAW,SAAS;;KAEpB,CAE8B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dangayle/rustlike",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/dangayle/rustlike.git"
|
|
7
|
+
},
|
|
8
|
+
"homepage": "https://github.com/dangayle/rustlike#readme",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/dangayle/rustlike/issues"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"description": "TypeScript utilities for writing Rust-like code: Result, Option, exhaustive matching, and immutability helpers",
|
|
16
|
+
"keywords": [
|
|
17
|
+
"functional",
|
|
18
|
+
"immutable",
|
|
19
|
+
"option",
|
|
20
|
+
"pattern-matching",
|
|
21
|
+
"result",
|
|
22
|
+
"rust",
|
|
23
|
+
"typescript"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"author": "Dan Gayle <dangayle@gmail.com>",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"type": "module",
|
|
31
|
+
"main": "./dist/index.cjs",
|
|
32
|
+
"module": "./dist/index.mjs",
|
|
33
|
+
"types": "./dist/index.d.mts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/index.d.mts",
|
|
38
|
+
"default": "./dist/index.mjs"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/index.d.cts",
|
|
42
|
+
"default": "./dist/index.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./node": {
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/node.d.mts",
|
|
48
|
+
"default": "./dist/node.mjs"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/node.d.cts",
|
|
52
|
+
"default": "./dist/node.cjs"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^25.3.3",
|
|
58
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
59
|
+
"oxfmt": "^0.36.0",
|
|
60
|
+
"oxlint": "^1.51.0",
|
|
61
|
+
"oxlint-tsgolint": "^0.16.0",
|
|
62
|
+
"tsdown": "^0.20.3",
|
|
63
|
+
"typescript": "^5.3.0",
|
|
64
|
+
"vitest": "^4.0.18"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "tsdown && pnpm -C packages/eslint-plugin-rustlike build",
|
|
68
|
+
"build:lib": "tsdown",
|
|
69
|
+
"build:plugin": "pnpm -C packages/eslint-plugin-rustlike build",
|
|
70
|
+
"dev": "tsdown --watch",
|
|
71
|
+
"test": "vitest",
|
|
72
|
+
"test:run": "vitest run && pnpm -C packages/eslint-plugin-rustlike test",
|
|
73
|
+
"test:coverage": "vitest run --coverage",
|
|
74
|
+
"lint": "oxlint src/ examples/",
|
|
75
|
+
"lint:fix": "oxlint --fix src/ examples/",
|
|
76
|
+
"typecheck": "tsc --noEmit",
|
|
77
|
+
"fmt": "oxfmt",
|
|
78
|
+
"fmt:check": "oxfmt --check"
|
|
79
|
+
}
|
|
80
|
+
}
|