writr 4.1.0 → 4.1.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.
package/README.md CHANGED
@@ -28,11 +28,12 @@
28
28
  * Github Flavor Markdown (remark-gfm).
29
29
  * Emoji Support (remark-emoji).
30
30
  * MDX Support (remark-mdx).
31
- * ESM and Node 20+
32
31
 
33
- ## Getting Started
32
+ ## ESM and Node Version Support
33
+
34
+ This package is ESM only and tested on the current lts version and its previous. Please don't open issues for questions regarding CommonJS / ESM or previous Nodejs versions. To learn more about using ESM please read this from `sindresorhus`: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
34
35
 
35
- ## Install Writr
36
+ ## Getting Started
36
37
 
37
38
  ```bash
38
39
  > npm install writr
package/package.json CHANGED
@@ -1,14 +1,12 @@
1
1
  {
2
2
  "name": "writr",
3
- "version": "4.1.0",
3
+ "version": "4.1.2",
4
4
  "description": "Markdown Rendering Simplified",
5
5
  "type": "module",
6
- "main": "./dist/writr.cjs",
7
- "module": "./dist/writr.js",
6
+ "main": "./dist/writr.js",
8
7
  "types": "./dist/writr.d.ts",
9
8
  "exports": {
10
9
  ".": {
11
- "require": "./dist/writr.cjs",
12
10
  "import": "./dist/writr.js"
13
11
  }
14
12
  },
@@ -48,19 +46,19 @@
48
46
  ],
49
47
  "scripts": {
50
48
  "clean": "rimraf ./dist ./coverage ./node_modules ./package-lock.json ./yarn.lock ./site/README.md ./site/dist",
51
- "build": "rimraf ./dist && tsup src/writr.ts --format cjs,esm --dts --clean",
49
+ "build": "rimraf ./dist && tsup src/writr.ts --format esm --dts --clean",
52
50
  "prepare": "npm run build",
53
51
  "test": "xo --fix && vitest run --coverage",
54
52
  "website:build": "rimraf ./site/README.md ./site/dist && npx docula build -s ./site -o ./site/dist",
55
53
  "website:serve": "rimraf ./site/README.md ./site/dist && npx docula serve -s ./site -o ./site/dist"
56
54
  },
57
55
  "dependencies": {
58
- "cacheable": "^1.7.1",
56
+ "cacheable": "^1.8.0",
59
57
  "crypto": "^1.0.1",
60
58
  "fs": "^0.0.1-security",
61
- "html-react-parser": "^5.1.16",
59
+ "html-react-parser": "^5.1.18",
62
60
  "js-yaml": "^4.1.0",
63
- "keyv": "^5.0.3",
61
+ "keyv": "^5.1.0",
64
62
  "react": "^18.3.1",
65
63
  "rehype-highlight": "^7.0.0",
66
64
  "rehype-katex": "^7.0.1",
@@ -78,15 +76,15 @@
78
76
  "devDependencies": {
79
77
  "@keyv/sqlite": "^4.0.1",
80
78
  "@types/js-yaml": "^4.0.9",
81
- "@types/node": "^22.7.4",
82
- "@types/react": "^18.3.10",
83
- "@vitest/coverage-v8": "^2.1.1",
79
+ "@types/node": "^22.7.5",
80
+ "@types/react": "^18.3.11",
81
+ "@vitest/coverage-v8": "^2.1.2",
84
82
  "docula": "^0.9.1",
85
83
  "rimraf": "^6.0.1",
86
84
  "ts-node": "^10.9.2",
87
85
  "tsup": "^8.3.0",
88
86
  "typescript": "^5.6.2",
89
- "vitest": "^2.1.1",
87
+ "vitest": "^2.1.2",
90
88
  "webpack": "^5.95.0",
91
89
  "xo": "^0.59.3"
92
90
  },
package/dist/writr.cjs DELETED
@@ -1,321 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/writr.ts
31
- var writr_exports = {};
32
- __export(writr_exports, {
33
- Writr: () => Writr
34
- });
35
- module.exports = __toCommonJS(writr_exports);
36
- var import_node_fs = __toESM(require("fs"), 1);
37
- var import_node_path = require("path");
38
- var import_unified = require("unified");
39
- var import_remark_parse = __toESM(require("remark-parse"), 1);
40
- var import_remark_rehype = __toESM(require("remark-rehype"), 1);
41
- var import_rehype_slug = __toESM(require("rehype-slug"), 1);
42
- var import_rehype_highlight = __toESM(require("rehype-highlight"), 1);
43
- var import_rehype_stringify = __toESM(require("rehype-stringify"), 1);
44
- var import_remark_toc = __toESM(require("remark-toc"), 1);
45
- var import_remark_math = __toESM(require("remark-math"), 1);
46
- var import_rehype_katex = __toESM(require("rehype-katex"), 1);
47
- var import_remark_gfm = __toESM(require("remark-gfm"), 1);
48
- var import_remark_emoji = __toESM(require("remark-emoji"), 1);
49
- var import_remark_mdx = __toESM(require("remark-mdx"), 1);
50
- var import_html_react_parser = __toESM(require("html-react-parser"), 1);
51
- var yaml = __toESM(require("js-yaml"), 1);
52
-
53
- // src/writr-cache.ts
54
- var import_node_crypto = require("crypto");
55
- var import_cacheable = require("cacheable");
56
- var WritrCache = class {
57
- _markdownStore = new import_cacheable.Cacheable();
58
- _markdownStoreSync = new import_cacheable.CacheableMemory();
59
- _hashStore = new import_cacheable.CacheableMemory();
60
- get markdownStore() {
61
- return this._markdownStore;
62
- }
63
- get markdownStoreSync() {
64
- return this._markdownStoreSync;
65
- }
66
- get hashStore() {
67
- return this._hashStore;
68
- }
69
- async getMarkdown(markdown, options) {
70
- const key = this.hash(markdown, options);
71
- return this.get(key);
72
- }
73
- getMarkdownSync(markdown, options) {
74
- const key = this.hash(markdown, options);
75
- return this.getSync(key);
76
- }
77
- async setMarkdown(markdown, value, options) {
78
- const key = this.hash(markdown, options);
79
- return this.set(key, value);
80
- }
81
- setMarkdownSync(markdown, value, options) {
82
- const key = this.hash(markdown, options);
83
- this.setSync(key, value);
84
- return true;
85
- }
86
- async get(key) {
87
- return this._markdownStore.get(key);
88
- }
89
- getSync(key) {
90
- return this._markdownStoreSync.get(key);
91
- }
92
- async set(key, value) {
93
- return this._markdownStore.set(key, value);
94
- }
95
- setSync(key, value) {
96
- this._markdownStoreSync.set(key, value);
97
- return true;
98
- }
99
- async clear() {
100
- await this._markdownStore.clear();
101
- this._markdownStoreSync.clear();
102
- this._hashStore.clear();
103
- }
104
- setStorageAdapter(adapter) {
105
- this._markdownStore = new import_cacheable.Cacheable({ primary: adapter });
106
- }
107
- hash(markdown, options) {
108
- const key = JSON.stringify({ markdown, options });
109
- let result = this._hashStore.get(key);
110
- if (result) {
111
- return result;
112
- }
113
- result = (0, import_node_crypto.createHash)("sha256").update(key).digest("hex");
114
- this._hashStore.set(key, result);
115
- return result;
116
- }
117
- };
118
-
119
- // src/writr.ts
120
- var Writr = class {
121
- engine = (0, import_unified.unified)().use(import_remark_parse.default).use(import_remark_gfm.default).use(import_remark_toc.default).use(import_remark_emoji.default).use(import_remark_rehype.default).use(import_rehype_slug.default).use(import_remark_math.default).use(import_rehype_katex.default).use(import_rehype_highlight.default).use(import_remark_mdx.default).use(import_rehype_stringify.default);
122
- // Stringify HTML
123
- _options = {
124
- openai: void 0,
125
- renderOptions: {
126
- emoji: true,
127
- toc: true,
128
- slug: true,
129
- highlight: true,
130
- gfm: true,
131
- math: true,
132
- mdx: true,
133
- caching: true
134
- }
135
- };
136
- _content = "";
137
- _cache = new WritrCache();
138
- constructor(arguments1, arguments2) {
139
- if (typeof arguments1 === "string") {
140
- this._content = arguments1;
141
- } else if (arguments1) {
142
- this._options = { ...this._options, ...arguments1 };
143
- if (this._options.renderOptions) {
144
- this.engine = this.createProcessor(this._options.renderOptions);
145
- }
146
- }
147
- if (arguments2) {
148
- this._options = { ...this._options, ...arguments2 };
149
- if (this._options.renderOptions) {
150
- this.engine = this.createProcessor(this._options.renderOptions);
151
- }
152
- }
153
- }
154
- get options() {
155
- return this._options;
156
- }
157
- get content() {
158
- return this._content;
159
- }
160
- set content(value) {
161
- this._content = value;
162
- }
163
- get cache() {
164
- return this._cache;
165
- }
166
- get frontMatterRaw() {
167
- const start = this._content.indexOf("---\n");
168
- if (start === -1) {
169
- return "";
170
- }
171
- const end = this._content.indexOf("\n---\n", start + 4);
172
- if (end === -1) {
173
- return "";
174
- }
175
- return this._content.slice(start, end + 5);
176
- }
177
- get body() {
178
- const start = this._content.indexOf("---\n");
179
- if (start === -1) {
180
- return this._content;
181
- }
182
- const end = this._content.indexOf("\n---\n", start + 4);
183
- if (end === -1) {
184
- return this._content;
185
- }
186
- return this._content.slice(Math.max(0, end + 5)).trim();
187
- }
188
- get markdown() {
189
- return this.body;
190
- }
191
- get frontMatter() {
192
- const frontMatter = this.frontMatterRaw;
193
- const match = /^---\s*([\s\S]*?)\s*---\s*/.exec(frontMatter);
194
- if (match) {
195
- return yaml.load(match[1].trim());
196
- }
197
- return {};
198
- }
199
- set frontMatter(data) {
200
- const frontMatter = this.frontMatterRaw;
201
- const yamlString = yaml.dump(data);
202
- const newFrontMatter = `---
203
- ${yamlString}---
204
- `;
205
- this._content = this._content.replace(frontMatter, newFrontMatter);
206
- }
207
- getFrontMatterValue(key) {
208
- return this.frontMatter[key];
209
- }
210
- async render(options) {
211
- try {
212
- let result = "";
213
- if (this.isCacheEnabled(options)) {
214
- const cached = await this._cache.getMarkdown(this._content, options);
215
- if (cached) {
216
- return cached;
217
- }
218
- }
219
- let { engine } = this;
220
- if (options) {
221
- options = { ...this._options.renderOptions, ...options };
222
- engine = this.createProcessor(options);
223
- }
224
- const file = await engine.process(this.body);
225
- result = String(file);
226
- if (this.isCacheEnabled(options)) {
227
- await this._cache.setMarkdown(this._content, result, options);
228
- }
229
- return result;
230
- } catch (error) {
231
- throw new Error(`Failed to render markdown: ${error.message}`);
232
- }
233
- }
234
- renderSync(options) {
235
- try {
236
- let result = "";
237
- if (this.isCacheEnabled(options)) {
238
- const cached = this._cache.getMarkdownSync(this._content, options);
239
- if (cached) {
240
- return cached;
241
- }
242
- }
243
- let { engine } = this;
244
- if (options) {
245
- options = { ...this._options.renderOptions, ...options };
246
- engine = this.createProcessor(options);
247
- }
248
- const file = engine.processSync(this.body);
249
- result = String(file);
250
- if (this.isCacheEnabled(options)) {
251
- this._cache.setMarkdownSync(this._content, result, options);
252
- }
253
- return result;
254
- } catch (error) {
255
- throw new Error(`Failed to render markdown: ${error.message}`);
256
- }
257
- }
258
- async renderReact(options, reactParseOptions) {
259
- const html = await this.render(options);
260
- return (0, import_html_react_parser.default)(html, reactParseOptions);
261
- }
262
- renderReactSync(options, reactParseOptions) {
263
- const html = this.renderSync(options);
264
- return (0, import_html_react_parser.default)(html, reactParseOptions);
265
- }
266
- async loadFromFile(filePath) {
267
- const { readFile } = import_node_fs.default.promises;
268
- this._content = await readFile(filePath, "utf8");
269
- }
270
- loadFromFileSync(filePath) {
271
- this._content = import_node_fs.default.readFileSync(filePath, "utf8");
272
- }
273
- async saveToFile(filePath) {
274
- const { writeFile, mkdir } = import_node_fs.default.promises;
275
- const directoryPath = (0, import_node_path.dirname)(filePath);
276
- await mkdir(directoryPath, { recursive: true });
277
- await writeFile(filePath, this._content, "utf8");
278
- }
279
- saveToFileSync(filePath) {
280
- const directoryPath = (0, import_node_path.dirname)(filePath);
281
- import_node_fs.default.mkdirSync(directoryPath, { recursive: true });
282
- import_node_fs.default.writeFileSync(filePath, this._content, "utf8");
283
- }
284
- isCacheEnabled(options) {
285
- if (options?.caching !== void 0) {
286
- return options.caching;
287
- }
288
- return this._options?.renderOptions?.caching ?? false;
289
- }
290
- createProcessor(options) {
291
- const processor = (0, import_unified.unified)().use(import_remark_parse.default);
292
- if (options.gfm) {
293
- processor.use(import_remark_gfm.default);
294
- }
295
- if (options.toc) {
296
- processor.use(import_remark_toc.default, { heading: "toc|table of contents" });
297
- }
298
- if (options.emoji) {
299
- processor.use(import_remark_emoji.default);
300
- }
301
- processor.use(import_remark_rehype.default);
302
- if (options.slug) {
303
- processor.use(import_rehype_slug.default);
304
- }
305
- if (options.highlight) {
306
- processor.use(import_rehype_highlight.default);
307
- }
308
- if (options.math) {
309
- processor.use(import_remark_math.default).use(import_rehype_katex.default);
310
- }
311
- if (options.mdx) {
312
- processor.use(import_remark_mdx.default);
313
- }
314
- processor.use(import_rehype_stringify.default);
315
- return processor;
316
- }
317
- };
318
- // Annotate the CommonJS export names for ESM import in node:
319
- 0 && (module.exports = {
320
- Writr
321
- });
package/dist/writr.d.cts DELETED
@@ -1,71 +0,0 @@
1
- import * as unified from 'unified';
2
- import * as hast from 'hast';
3
- import * as mdast from 'mdast';
4
- import React from 'react';
5
- import { HTMLReactParserOptions } from 'html-react-parser';
6
- import { Cacheable, CacheableMemory } from 'cacheable';
7
- import { KeyvStoreAdapter } from 'keyv';
8
-
9
- declare class WritrCache {
10
- private _markdownStore;
11
- private readonly _markdownStoreSync;
12
- private readonly _hashStore;
13
- get markdownStore(): Cacheable;
14
- get markdownStoreSync(): CacheableMemory;
15
- get hashStore(): CacheableMemory;
16
- getMarkdown(markdown: string, options?: RenderOptions): Promise<string | undefined>;
17
- getMarkdownSync(markdown: string, options?: RenderOptions): string | undefined;
18
- setMarkdown(markdown: string, value: string, options?: RenderOptions): Promise<boolean>;
19
- setMarkdownSync(markdown: string, value: string, options?: RenderOptions): boolean;
20
- get(key: string): Promise<string | undefined>;
21
- getSync(key: string): string | undefined;
22
- set(key: string, value: string): Promise<boolean>;
23
- setSync(key: string, value: string): boolean;
24
- clear(): Promise<void>;
25
- setStorageAdapter(adapter: KeyvStoreAdapter): void;
26
- hash(markdown: string, options?: RenderOptions): string;
27
- }
28
-
29
- type WritrOptions = {
30
- openai?: string;
31
- renderOptions?: RenderOptions;
32
- };
33
- type RenderOptions = {
34
- emoji?: boolean;
35
- toc?: boolean;
36
- slug?: boolean;
37
- highlight?: boolean;
38
- gfm?: boolean;
39
- math?: boolean;
40
- mdx?: boolean;
41
- caching?: boolean;
42
- };
43
- declare class Writr {
44
- engine: unified.Processor<mdast.Root, mdast.Root, hast.Root, hast.Root, string>;
45
- private readonly _options;
46
- private _content;
47
- private readonly _cache;
48
- constructor(arguments1?: string | WritrOptions, arguments2?: WritrOptions);
49
- get options(): WritrOptions;
50
- get content(): string;
51
- set content(value: string);
52
- get cache(): WritrCache;
53
- get frontMatterRaw(): string;
54
- get body(): string;
55
- get markdown(): string;
56
- get frontMatter(): Record<string, any>;
57
- set frontMatter(data: Record<string, any>);
58
- getFrontMatterValue<T>(key: string): T;
59
- render(options?: RenderOptions): Promise<string>;
60
- renderSync(options?: RenderOptions): string;
61
- renderReact(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): Promise<string | React.JSX.Element | React.JSX.Element[]>;
62
- renderReactSync(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): string | React.JSX.Element | React.JSX.Element[];
63
- loadFromFile(filePath: string): Promise<void>;
64
- loadFromFileSync(filePath: string): void;
65
- saveToFile(filePath: string): Promise<void>;
66
- saveToFileSync(filePath: string): void;
67
- private isCacheEnabled;
68
- private createProcessor;
69
- }
70
-
71
- export { type RenderOptions, Writr, type WritrOptions };