resolve issue with missing vite-plugin-node-polyfills

add LibreJS licenses to all demo JS
split browser build from node build
add copyright info to license files
update to use yarn v4.13.0
update to v0.9.2
This commit is contained in:
2026-03-07 20:47:14 -05:00
parent 475fcf6331
commit 1c06197be0
51 changed files with 259 additions and 56 deletions
+6
View File
@@ -1 +1,7 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
/*
* twtxt-lib
* https://twtxt-lib.itsericwoodward.com/
* Copyright (c) 2026 Eric Woodward
* Released under the MIT License
*/
+17 -7
View File
@@ -8,10 +8,11 @@ import {
rm,
writeFile,
} from "node:fs/promises";
import { dirname, join, resolve } from "node:path";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig, build as viteBuild } from "vite";
import noBundlePlugin from "vite-plugin-no-bundle";
import { nodePolyfills } from "vite-plugin-node-polyfills";
const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -21,27 +22,25 @@ const browserOutPath = `${outputPathPrefix}-browser`;
const browserOutDir = resolve(__dirname, browserOutPath);
const demoOutDir = resolve(__dirname, `${outputPathPrefix}-demo`);
const entry = "src/index.ts";
const globalConfig = {
libraryName: "twtxt-lib",
basePath: resolve(__dirname),
outDir: resolve(__dirname, outputPathPrefix),
builds: [
{
entry,
entry: "src/browser.ts",
outDir: browserOutDir,
outfile: "twtxt-lib.js",
target: "browser",
},
{
entry,
entry: "src/browser.ts",
outDir: browserOutDir,
outfile: "twtxt-lib.min.js",
target: "browser",
},
{
entry,
entry: "src/index.ts",
outDir: resolve(__dirname, `${outputPathPrefix}-node`),
target: "node",
},
@@ -84,7 +83,18 @@ const buildWithVite = async (config) => {
const plugins = [
dts({ exclude: ["./vitest.setup.ts", "**/__tests__/*.*"] }),
];
if (config.target !== "browser") plugins.push(noBundlePlugin());
if (config.target !== "browser") {
plugins.push([
noBundlePlugin(),
nodePolyfills({
include: ["buffer"],
globals: {
Buffer: true,
},
}),
]);
}
await viteBuild(
defineConfig({
+5
View File
@@ -0,0 +1,5 @@
export type * from './types.ts';
export { default as hashTwt } from './hashTwt.ts';
export { default as loadAndParseTwtxtFile } from './loadAndParseTwtxt.ts';
export { default as parseTwtxt } from './parseTwtxt.ts';
export { base32Encode } from './utils.ts';
+7 -1
View File
@@ -1,4 +1,10 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
/*
* twtxt-lib
* https://twtxt-lib.itsericwoodward.com/
* Copyright (c) 2026 Eric Woodward
* Released under the MIT License
*/
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
@@ -2894,7 +2900,6 @@ const base32Encode = (payload) => {
return encoder.write(payload).finalize();
};
const getValueOrFirstEntry = (value) => Array.isArray(value) && value.length ? value[0] : value;
globalThis.Buffer = Buffer$1;
const dateRegex = /^(\d{4})-(\d{2})-(\d{2})([tT ])(\d{2}):(\d{2}):(\d{2})\.?(\d{3})?(?:(?:([+-]\d{2}):?(\d{2}))|Z)?$/;
const formatRFC3339 = (date) => {
const pad = (num = 0) => `${+num < 10 ? 0 : ""}${+num}`;
@@ -3391,6 +3396,7 @@ function loadAndParseTwtxtFile(url = "") {
}
});
}
globalThis.Buffer = Buffer$1;
export {
base32Encode,
hashTwt,
File diff suppressed because one or more lines are too long
+8 -3
View File
@@ -1,4 +1,10 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
/*
* twtxt-lib
* https://twtxt-lib.itsericwoodward.com/
* Copyright (c) 2026 Eric Woodward
* Released under the MIT License
*/
var er = Object.defineProperty, nr = Object.defineProperties;
var ir = Object.getOwnPropertyDescriptors;
var _t = Object.getOwnPropertySymbols;
@@ -1847,9 +1853,7 @@ function br() {
})(kt)), kt;
}
var Br = br();
const Er = /* @__PURE__ */ Mt(Br), Ir = (f) => new Er.Encoder({ type: "rfc4648" }).write(f).finalize(), $r = (f) => Array.isArray(f) && f.length ? f[0] : f;
globalThis.Buffer = yr;
const Fr = /^(\d{4})-(\d{2})-(\d{2})([tT ])(\d{2}):(\d{2}):(\d{2})\.?(\d{3})?(?:(?:([+-]\d{2}):?(\d{2}))|Z)?$/, Ur = (f) => {
const Er = /* @__PURE__ */ Mt(Br), Ir = (f) => new Er.Encoder({ type: "rfc4648" }).write(f).finalize(), $r = (f) => Array.isArray(f) && f.length ? f[0] : f, Fr = /^(\d{4})-(\d{2})-(\d{2})([tT ])(\d{2}):(\d{2}):(\d{2})\.?(\d{3})?(?:(?:([+-]\d{2}):?(\d{2}))|Z)?$/, Ur = (f) => {
const l = (p = 0) => `${+p < 10 ? 0 : ""}${+p}`, x = (p = 0) => `${+p < 1e3 ? 0 : ""}${+p < 100 ? 0 : ""}${+p < 10 ? 0 : ""}${+p}`;
let d = Fr.exec(f);
d && (d == null ? void 0 : d[9]) === void 0 && (d[9] = "+00"), d && (d == null ? void 0 : d[10]) === void 0 && (d[10] = "00");
@@ -2308,6 +2312,7 @@ function te(f = "") {
}
});
}
globalThis.Buffer = yr;
export {
Ir as base32Encode,
Ar as hashTwt,
File diff suppressed because one or more lines are too long
+4
View File
@@ -1,6 +1,10 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
document.addEventListener("DOMContentLoaded", () => {
// add default #overview route
if (!window.location.hash) {
window.location.hash = "overview";
}
});
// @license-end
+7
View File
@@ -0,0 +1,7 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
const isGecko = !!navigator.userAgent.match(/gecko/i);
if (isGecko) document.body.classList.add("isGecko");
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
document.addEventListener("DOMContentLoaded", () => {
const currentHost = window.location.hostname;
@@ -10,3 +12,5 @@ document.addEventListener("DOMContentLoaded", () => {
}
});
});
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
export default function formatSource(source, panelId) {
source = (source ?? "").trim();
@@ -42,3 +44,5 @@ export default function formatSource(source, panelId) {
.getElementById(panelId)
.insertAdjacentHTML("beforeend", sourceHTML);
}
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import { hashTwt } from "/dist-browser/twtxt-lib.js";
let wasHashTwtResultAppended = false;
@@ -61,3 +63,5 @@ formHash.addEventListener("submit", (e) => {
document.body.classList.add("isLoaded");
wasHashTwtResultAppended = true;
});
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import formatSource from "./format-source.js";
formatSource(
@@ -38,3 +40,5 @@ formatSource(
`,
"tabHashTwt-panel",
);
// @license-end
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import { loadAndParseTwtxtFile } from "/dist-browser/twtxt-lib.js";
const tabLoadAndParsePanel = document.getElementById("tabLoadAndParse-panel");
@@ -77,3 +79,5 @@ const loadAndParseClickHandler = (ev) => {
.getElementById(curr)
.addEventListener("click", loadAndParseClickHandler);
});
// @license-end
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import formatSource from "./format-source.js";
formatSource(
@@ -23,3 +25,5 @@ formatSource(
`,
"tabLoadAndParse-panel",
);
// @license-end
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import { loadAndParseTwtxtFile } from "/dist-browser/twtxt-lib.js";
// run in an IIFE (or event listener) to avoid issues with top-level await
@@ -34,3 +36,5 @@ import { loadAndParseTwtxtFile } from "/dist-browser/twtxt-lib.js";
console.error(err);
}
})();
// @license-end
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import formatSource from "./format-source.js";
formatSource(
@@ -22,3 +24,5 @@ formatSource(
`,
"tabOverview-example",
);
// @license-end
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import { parseTwtxt } from "/dist-browser/twtxt-lib.js";
const tabParsePanel = document.getElementById("tabParse-panel");
@@ -74,3 +76,5 @@ const parseClickHandler = (ev) => {
.addEventListener("click", parseClickHandler);
},
);
// @license-end
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import formatSource from "./format-source.js";
formatSource(
@@ -25,3 +27,5 @@ formatSource(
`,
"tabParse-panel",
);
// @license-end
+20 -7
View File
@@ -365,24 +365,37 @@ body:not(:has(:target)) #tabOverview-link {
margin-top: -4.55rem;
}
.tab:target .tab-panel {
position: absolute;
z-index: 1;
}
body:not(:has(:target)) #tabOverview-panel {
display: block;
position: absolute;
z-index: 1;
}
.themeToggle-button {
bottom: auto;
position: absolute;
right: 1rem;
top: 1rem;
}
body:not(:has(:target)) #tabOverview-panel {
display: block;
position: absolute;
z-index: 1;
}
body.isGecko .tab-link {
margin-top: -4.65rem;
}
body.isGecko .tab-link:hover {
margin-top: -4.9rem;
}
body.isGecko .tab:target .tab-link,
body.isGecko .tab:target .tab-link:hover {
margin-top: -4.85rem;
}
}
/** State-Based Overrides */
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
document.addEventListener("DOMContentLoaded", () => {
const toggle = document.createElement("button");
@@ -27,3 +29,5 @@ document.addEventListener("DOMContentLoaded", () => {
document.body.appendChild(toggle);
});
// @license-end
+5
View File
@@ -0,0 +1,5 @@
export type * from './types.ts';
export { default as hashTwt } from './hashTwt.ts';
export { default as loadAndParseTwtxtFile } from './loadAndParseTwtxt.ts';
export { default as parseTwtxt } from './parseTwtxt.ts';
export { base32Encode } from './utils.ts';
+7 -1
View File
@@ -1,4 +1,10 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
/*
* twtxt-lib
* https://twtxt-lib.itsericwoodward.com/
* Copyright (c) 2026 Eric Woodward
* Released under the MIT License
*/
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
@@ -2894,7 +2900,6 @@ const base32Encode = (payload) => {
return encoder.write(payload).finalize();
};
const getValueOrFirstEntry = (value) => Array.isArray(value) && value.length ? value[0] : value;
globalThis.Buffer = Buffer$1;
const dateRegex = /^(\d{4})-(\d{2})-(\d{2})([tT ])(\d{2}):(\d{2}):(\d{2})\.?(\d{3})?(?:(?:([+-]\d{2}):?(\d{2}))|Z)?$/;
const formatRFC3339 = (date) => {
const pad = (num = 0) => `${+num < 10 ? 0 : ""}${+num}`;
@@ -3391,6 +3396,7 @@ function loadAndParseTwtxtFile(url = "") {
}
});
}
globalThis.Buffer = Buffer$1;
export {
base32Encode,
hashTwt,
File diff suppressed because one or more lines are too long
+8 -3
View File
@@ -1,4 +1,10 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
/*
* twtxt-lib
* https://twtxt-lib.itsericwoodward.com/
* Copyright (c) 2026 Eric Woodward
* Released under the MIT License
*/
var er = Object.defineProperty, nr = Object.defineProperties;
var ir = Object.getOwnPropertyDescriptors;
var _t = Object.getOwnPropertySymbols;
@@ -1847,9 +1853,7 @@ function br() {
})(kt)), kt;
}
var Br = br();
const Er = /* @__PURE__ */ Mt(Br), Ir = (f) => new Er.Encoder({ type: "rfc4648" }).write(f).finalize(), $r = (f) => Array.isArray(f) && f.length ? f[0] : f;
globalThis.Buffer = yr;
const Fr = /^(\d{4})-(\d{2})-(\d{2})([tT ])(\d{2}):(\d{2}):(\d{2})\.?(\d{3})?(?:(?:([+-]\d{2}):?(\d{2}))|Z)?$/, Ur = (f) => {
const Er = /* @__PURE__ */ Mt(Br), Ir = (f) => new Er.Encoder({ type: "rfc4648" }).write(f).finalize(), $r = (f) => Array.isArray(f) && f.length ? f[0] : f, Fr = /^(\d{4})-(\d{2})-(\d{2})([tT ])(\d{2}):(\d{2}):(\d{2})\.?(\d{3})?(?:(?:([+-]\d{2}):?(\d{2}))|Z)?$/, Ur = (f) => {
const l = (p = 0) => `${+p < 10 ? 0 : ""}${+p}`, x = (p = 0) => `${+p < 1e3 ? 0 : ""}${+p < 100 ? 0 : ""}${+p < 10 ? 0 : ""}${+p}`;
let d = Fr.exec(f);
d && (d == null ? void 0 : d[9]) === void 0 && (d[9] = "+00"), d && (d == null ? void 0 : d[10]) === void 0 && (d[10] = "00");
@@ -2308,6 +2312,7 @@ function te(f = "") {
}
});
}
globalThis.Buffer = yr;
export {
Ir as base32Encode,
Ar as hashTwt,
File diff suppressed because one or more lines are too long
+3 -2
View File
@@ -318,9 +318,10 @@
</ul>
<script src="/dist-browser/twtxt-lib.js" type="module"></script>
<script src="/demo/theme-toggle.js" type="module"></script>
<script src="/demo/external-links.js" type="module"></script>
<script src="/demo/add-default-route.js" type="module"></script>
<script src="/demo/browser-detection.js" type="module"></script>
<script src="/demo/external-links.js" type="module"></script>
<script src="/demo/theme-toggle.js" type="module"></script>
<script src="/demo/overview-example-source.js" type="module"></script>
<script src="/demo/overview-example-result.js" type="module"></script>
<script src="/demo/hashTwt-example-source.js" type="module"></script>
+5
View File
@@ -0,0 +1,5 @@
export type * from './types.ts';
export { default as hashTwt } from './hashTwt.ts';
export { default as loadAndParseTwtxtFile } from './loadAndParseTwtxt.ts';
export { default as parseTwtxt } from './parseTwtxt.ts';
export { base32Encode } from './utils.ts';
-2
View File
@@ -1,7 +1,5 @@
import { Buffer } from "vite-plugin-node-polyfills/shims/buffer";
import { blake2b } from "@exodus/blakejs";
import { base32Encode } from "./utils.js";
globalThis.Buffer = Buffer;
const dateRegex = /^(\d{4})-(\d{2})-(\d{2})([tT ])(\d{2}):(\d{2}):(\d{2})\.?(\d{3})?(?:(?:([+-]\d{2}):?(\d{2}))|Z)?$/;
const formatRFC3339 = (date) => {
const pad = (num = 0) => `${+num < 10 ? 0 : ""}${+num}`;
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"hashTwt.js","sources":["../src/hashTwt.ts"],"sourcesContent":["import { Buffer } from \"buffer\";\nglobalThis.Buffer = Buffer;\n\nimport type { Twt } from \"./types.ts\";\n\nimport { blake2b } from \"@exodus/blakejs\";\n\nimport { base32Encode } from \"./utils.ts\";\n\nconst dateRegex =\n\t/^(\\d{4})-(\\d{2})-(\\d{2})([tT ])(\\d{2}):(\\d{2}):(\\d{2})\\.?(\\d{3})?(?:(?:([+-]\\d{2}):?(\\d{2}))|Z)?$/;\n\nconst formatRFC3339 = (date: string) => {\n\tconst pad = (num: number | string = 0) => `${+num < 10 ? 0 : \"\"}${+num}`;\n\tconst padYear = (num: number | string = 0) =>\n\t\t`${+num < 1000 ? 0 : \"\"}${+num < 100 ? 0 : \"\"}${\n\t\t\t+num < 10 ? 0 : \"\"\n\t\t}${+num}`;\n\n\tlet m = dateRegex.exec(date);\n\n\t//if timezone is undefined, it must be Z or nothing (otherwise the group would have captured).\n\tif (m && m?.[9] === undefined) {\n\t\t//Use UTC.\n\t\tm[9] = \"+00\";\n\t}\n\tif (m && m?.[10] === undefined) {\n\t\tm[10] = \"00\";\n\t}\n\n\tconst offset = `${m?.[9]}:${m?.[10]}`.replace(/[+-]?00:00$/, \"Z\");\n\n\treturn [\n\t\tpadYear(m?.[1]),\n\t\t\"-\",\n\t\tpad(m?.[2]),\n\t\t\"-\",\n\t\tpad(m?.[3]),\n\t\tm?.[4],\n\t\tpad(m?.[5]),\n\t\t\":\",\n\t\tpad(m?.[6]),\n\t\t\":\",\n\t\tpad(m?.[7]),\n\t\t//ignore milliseconds (m[8])\n\t\toffset,\n\t].join(\"\");\n};\n\nexport default function hashTwt(twt: Twt): string {\n\tconst created = formatRFC3339(twt.created);\n\tconst payload = [twt.url, created, twt.content].join(\"\\n\");\n\n\treturn base32Encode(blake2b(payload, undefined, 32))\n\t\t.toLowerCase()\n\t\t.slice(-7);\n}\n"],"names":[],"mappings":";;;AACA,WAAW,SAAS;AAQpB,MAAM,YACL;AAED,MAAM,gBAAgB,CAAC,SAAiB;AACvC,QAAM,MAAM,CAAC,MAAuB,MAAM,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,GAAG,CAAC,GAAG;AACtE,QAAM,UAAU,CAAC,MAAuB,MACvC,GAAG,CAAC,MAAM,MAAO,IAAI,EAAE,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,GAC5C,CAAC,MAAM,KAAK,IAAI,EACjB,GAAG,CAAC,GAAG;AAER,MAAI,IAAI,UAAU,KAAK,IAAI;AAG3B,MAAI,KAAK,IAAI,CAAC,MAAM,QAAW;AAE9B,MAAE,CAAC,IAAI;AAAA,EACR;AACA,MAAI,KAAK,IAAI,EAAE,MAAM,QAAW;AAC/B,MAAE,EAAE,IAAI;AAAA,EACT;AAEA,QAAM,SAAS,GAAG,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,QAAQ,eAAe,GAAG;AAEhE,SAAO;AAAA,IACN,QAAQ,IAAI,CAAC,CAAC;AAAA,IACd;AAAA,IACA,IAAI,IAAI,CAAC,CAAC;AAAA,IACV;AAAA,IACA,IAAI,IAAI,CAAC,CAAC;AAAA,IACV,IAAI,CAAC;AAAA,IACL,IAAI,IAAI,CAAC,CAAC;AAAA,IACV;AAAA,IACA,IAAI,IAAI,CAAC,CAAC;AAAA,IACV;AAAA,IACA,IAAI,IAAI,CAAC,CAAC;AAAA;AAAA,IAEV;AAAA,EAAA,EACC,KAAK,EAAE;AACV;AAEA,SAAwB,QAAQ,KAAkB;AACjD,QAAM,UAAU,cAAc,IAAI,OAAO;AACzC,QAAM,UAAU,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,EAAE,KAAK,IAAI;AAEzD,SAAO,aAAa,QAAQ,SAAS,QAAW,EAAE,CAAC,EACjD,YAAA,EACA,MAAM,EAAE;AACX;"}
{"version":3,"file":"hashTwt.js","sources":["../src/hashTwt.ts"],"sourcesContent":["import type { Twt } from \"./types.ts\";\n\nimport { blake2b } from \"@exodus/blakejs\";\n\nimport { base32Encode } from \"./utils.ts\";\n\nconst dateRegex =\n\t/^(\\d{4})-(\\d{2})-(\\d{2})([tT ])(\\d{2}):(\\d{2}):(\\d{2})\\.?(\\d{3})?(?:(?:([+-]\\d{2}):?(\\d{2}))|Z)?$/;\n\nconst formatRFC3339 = (date: string) => {\n\tconst pad = (num: number | string = 0) => `${+num < 10 ? 0 : \"\"}${+num}`;\n\tconst padYear = (num: number | string = 0) =>\n\t\t`${+num < 1000 ? 0 : \"\"}${+num < 100 ? 0 : \"\"}${\n\t\t\t+num < 10 ? 0 : \"\"\n\t\t}${+num}`;\n\n\tlet m = dateRegex.exec(date);\n\n\t//if timezone is undefined, it must be Z or nothing (otherwise the group would have captured).\n\tif (m && m?.[9] === undefined) {\n\t\t//Use UTC.\n\t\tm[9] = \"+00\";\n\t}\n\tif (m && m?.[10] === undefined) {\n\t\tm[10] = \"00\";\n\t}\n\n\tconst offset = `${m?.[9]}:${m?.[10]}`.replace(/[+-]?00:00$/, \"Z\");\n\n\treturn [\n\t\tpadYear(m?.[1]),\n\t\t\"-\",\n\t\tpad(m?.[2]),\n\t\t\"-\",\n\t\tpad(m?.[3]),\n\t\tm?.[4],\n\t\tpad(m?.[5]),\n\t\t\":\",\n\t\tpad(m?.[6]),\n\t\t\":\",\n\t\tpad(m?.[7]),\n\t\t//ignore milliseconds (m[8])\n\t\toffset,\n\t].join(\"\");\n};\n\nexport default function hashTwt(twt: Twt): string {\n\tconst created = formatRFC3339(twt.created);\n\tconst payload = [twt.url, created, twt.content].join(\"\\n\");\n\n\treturn base32Encode(blake2b(payload, undefined, 32))\n\t\t.toLowerCase()\n\t\t.slice(-7);\n}\n"],"names":[],"mappings":";;AAMA,MAAM,YACL;AAED,MAAM,gBAAgB,CAAC,SAAiB;AACvC,QAAM,MAAM,CAAC,MAAuB,MAAM,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,GAAG,CAAC,GAAG;AACtE,QAAM,UAAU,CAAC,MAAuB,MACvC,GAAG,CAAC,MAAM,MAAO,IAAI,EAAE,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,GAC5C,CAAC,MAAM,KAAK,IAAI,EACjB,GAAG,CAAC,GAAG;AAER,MAAI,IAAI,UAAU,KAAK,IAAI;AAG3B,MAAI,KAAK,IAAI,CAAC,MAAM,QAAW;AAE9B,MAAE,CAAC,IAAI;AAAA,EACR;AACA,MAAI,KAAK,IAAI,EAAE,MAAM,QAAW;AAC/B,MAAE,EAAE,IAAI;AAAA,EACT;AAEA,QAAM,SAAS,GAAG,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,QAAQ,eAAe,GAAG;AAEhE,SAAO;AAAA,IACN,QAAQ,IAAI,CAAC,CAAC;AAAA,IACd;AAAA,IACA,IAAI,IAAI,CAAC,CAAC;AAAA,IACV;AAAA,IACA,IAAI,IAAI,CAAC,CAAC;AAAA,IACV,IAAI,CAAC;AAAA,IACL,IAAI,IAAI,CAAC,CAAC;AAAA,IACV;AAAA,IACA,IAAI,IAAI,CAAC,CAAC;AAAA,IACV;AAAA,IACA,IAAI,IAAI,CAAC,CAAC;AAAA;AAAA,IAEV;AAAA,EAAA,EACC,KAAK,EAAE;AACV;AAEA,SAAwB,QAAQ,KAAkB;AACjD,QAAM,UAAU,cAAc,IAAI,OAAO;AACzC,QAAM,UAAU,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,EAAE,KAAK,IAAI;AAEzD,SAAO,aAAa,QAAQ,SAAS,QAAW,EAAE,CAAC,EACjD,YAAA,EACA,MAAM,EAAE;AACX;"}
+6
View File
@@ -1,4 +1,10 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
/*
* twtxt-lib
* https://twtxt-lib.itsericwoodward.com/
* Copyright (c) 2026 Eric Woodward
* Released under the MIT License
*/
import { default as default2 } from "./hashTwt.js";
import { default as default3 } from "./loadAndParseTwtxt.js";
import { default as default4 } from "./parseTwtxt.js";
+3 -2
View File
@@ -318,9 +318,10 @@
</ul>
<script src="/dist-browser/twtxt-lib.js" type="module"></script>
<script src="/demo/theme-toggle.js" type="module"></script>
<script src="/demo/external-links.js" type="module"></script>
<script src="/demo/add-default-route.js" type="module"></script>
<script src="/demo/browser-detection.js" type="module"></script>
<script src="/demo/external-links.js" type="module"></script>
<script src="/demo/theme-toggle.js" type="module"></script>
<script src="/demo/overview-example-source.js" type="module"></script>
<script src="/demo/overview-example-result.js" type="module"></script>
<script src="/demo/hashTwt-example-source.js" type="module"></script>
+6 -3
View File
@@ -1,6 +1,6 @@
{
"name": "twtxt-lib",
"version": "0.9.1",
"version": "0.9.2",
"description": "An isomorphic TypeScript library of utility functions for parsing and interacting with twtxt.txt files.",
"license": "MIT",
"author": {
@@ -33,6 +33,9 @@
"preview": "vite preview",
"prepublishOnly": "yarn build",
"postpublish": "git push && git push --tags",
"publish": "npm run publish:jsr && npm run publish:npm",
"publish:jsr": "npx jsr publish",
"publish:npm": "npm publish",
"test": "vitest"
},
"dependencies": {
@@ -41,7 +44,7 @@
"dayjs": "^1.11.19"
},
"devDependencies": {
"@types/node": "^25.3.0",
"@types/node": "^25.3.5",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"unplugin-dts": "1.0.0-beta.6",
@@ -50,5 +53,5 @@
"vite-plugin-node-polyfills": "^0.25.0",
"vitest": "^4.0.18"
},
"packageManager": "yarn@4.12.0"
"packageManager": "yarn@4.13.0"
}
+4
View File
@@ -1,6 +1,10 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
document.addEventListener("DOMContentLoaded", () => {
// add default #overview route
if (!window.location.hash) {
window.location.hash = "overview";
}
});
// @license-end
+7
View File
@@ -0,0 +1,7 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
const isGecko = !!navigator.userAgent.match(/gecko/i);
if (isGecko) document.body.classList.add("isGecko");
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
document.addEventListener("DOMContentLoaded", () => {
const currentHost = window.location.hostname;
@@ -10,3 +12,5 @@ document.addEventListener("DOMContentLoaded", () => {
}
});
});
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
export default function formatSource(source, panelId) {
source = (source ?? "").trim();
@@ -42,3 +44,5 @@ export default function formatSource(source, panelId) {
.getElementById(panelId)
.insertAdjacentHTML("beforeend", sourceHTML);
}
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import { hashTwt } from "/dist-browser/twtxt-lib.js";
let wasHashTwtResultAppended = false;
@@ -61,3 +63,5 @@ formHash.addEventListener("submit", (e) => {
document.body.classList.add("isLoaded");
wasHashTwtResultAppended = true;
});
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import formatSource from "./format-source.js";
formatSource(
@@ -38,3 +40,5 @@ formatSource(
`,
"tabHashTwt-panel",
);
// @license-end
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import { loadAndParseTwtxtFile } from "/dist-browser/twtxt-lib.js";
const tabLoadAndParsePanel = document.getElementById("tabLoadAndParse-panel");
@@ -77,3 +79,5 @@ const loadAndParseClickHandler = (ev) => {
.getElementById(curr)
.addEventListener("click", loadAndParseClickHandler);
});
// @license-end
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import formatSource from "./format-source.js";
formatSource(
@@ -23,3 +25,5 @@ formatSource(
`,
"tabLoadAndParse-panel",
);
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import { loadAndParseTwtxtFile } from "/dist-browser/twtxt-lib.js";
// run in an IIFE (or event listener) to avoid issues with top-level await
@@ -34,3 +36,5 @@ import { loadAndParseTwtxtFile } from "/dist-browser/twtxt-lib.js";
console.error(err);
}
})();
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import formatSource from "./format-source.js";
formatSource(
@@ -22,3 +24,5 @@ formatSource(
`,
"tabOverview-example",
);
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import { parseTwtxt } from "/dist-browser/twtxt-lib.js";
const tabParsePanel = document.getElementById("tabParse-panel");
@@ -74,3 +76,5 @@ const parseClickHandler = (ev) => {
.addEventListener("click", parseClickHandler);
},
);
// @license-end
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
import formatSource from "./format-source.js";
formatSource(
@@ -25,3 +27,5 @@ formatSource(
`,
"tabParse-panel",
);
// @license-end
+20 -7
View File
@@ -365,24 +365,37 @@ body:not(:has(:target)) #tabOverview-link {
margin-top: -4.55rem;
}
.tab:target .tab-panel {
position: absolute;
z-index: 1;
}
body:not(:has(:target)) #tabOverview-panel {
display: block;
position: absolute;
z-index: 1;
}
.themeToggle-button {
bottom: auto;
position: absolute;
right: 1rem;
top: 1rem;
}
body:not(:has(:target)) #tabOverview-panel {
display: block;
position: absolute;
z-index: 1;
}
body.isGecko .tab-link {
margin-top: -4.65rem;
}
body.isGecko .tab-link:hover {
margin-top: -4.9rem;
}
body.isGecko .tab:target .tab-link,
body.isGecko .tab:target .tab-link:hover {
margin-top: -4.85rem;
}
}
/** State-Based Overrides */
+4
View File
@@ -1,3 +1,5 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt
document.addEventListener("DOMContentLoaded", () => {
const toggle = document.createElement("button");
@@ -27,3 +29,5 @@ document.addEventListener("DOMContentLoaded", () => {
document.body.appendChild(toggle);
});
// @license-end
+9
View File
@@ -0,0 +1,9 @@
export type * from "./types.ts";
import { Buffer } from "buffer";
globalThis.Buffer = Buffer;
export { default as hashTwt } from "./hashTwt.ts";
export { default as loadAndParseTwtxtFile } from "./loadAndParseTwtxt.ts";
export { default as parseTwtxt } from "./parseTwtxt.ts";
export { base32Encode } from "./utils.ts";
-3
View File
@@ -1,6 +1,3 @@
import { Buffer } from "buffer";
globalThis.Buffer = Buffer;
import type { Twt } from "./types.ts";
import { blake2b } from "@exodus/blakejs";
+4 -5
View File
@@ -6,16 +6,15 @@ import { nodePolyfills } from "vite-plugin-node-polyfills";
const __dirname = dirname(fileURLToPath(import.meta.url));
/* Only used for development, does not affect build */
export default defineConfig({
plugins: [
dts({ exclude: ["**/__tests__/*.*"] }),
nodePolyfills({
// Specify which polyfills to include (optional, but recommended for bundle size)
include: ["buffer"], // Only polyfill 'buffer' (add others like 'process' if needed)
// Configure global variables (e.g., expose Buffer to window)
include: ["buffer"],
globals: {
Buffer: true, // Expose Buffer as a global variable (optional but useful for some cases)
Buffer: true,
},
}),
],
+5 -5
View File
@@ -529,12 +529,12 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^25.3.0":
version: 25.3.0
resolution: "@types/node@npm:25.3.0"
"@types/node@npm:^25.3.5":
version: 25.3.5
resolution: "@types/node@npm:25.3.5"
dependencies:
undici-types: "npm:~7.18.0"
checksum: 10c0/7b2b18c9d68047157367fc2f786d4f166d22dc0ad9f82331ca02fb16f2f391854123dbe604dcb938cda119c87051e4bb71dcb9ece44a579f483a6f96d4bd41de
checksum: 10c0/4cf0834a6f6933bf0aca6afead117ae3db3b8f02a5f7187a24f871db0fb9344e5e46573ba387bc53b7505e1e219c4c535cbe67221ced95bb5ad98573223b19d0
languageName: node
linkType: hard
@@ -2909,7 +2909,7 @@ __metadata:
resolution: "twtxt-lib@workspace:."
dependencies:
"@exodus/blakejs": "npm:^1.1.1-exodus.0"
"@types/node": "npm:^25.3.0"
"@types/node": "npm:^25.3.5"
base32.js: "npm:^0.1.0"
dayjs: "npm:^1.11.19"
prettier: "npm:^3.8.1"