authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-01-12 04:10:48-08:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-01-14 01:08:17-08:00
loge41ee359a2b3a22fe11104311555852d3f661d41
treecbea9c0801f4eceedaf4a3690ef1a162f68d4ca1
parent692bc30864b34cdc3fe5297a7186605fbc73337f
signature Commit is signed but in an unrecognized format.

chore: prepare for deno publish


10 files changed, 59 insertions(+), 250 deletions(-)

lib/bytes.ts+1-1
......@@ -1,7 +1,7 @@
11export function eql<T extends ArrayBufferView & { [n: number]: number }>(
22 a: T,
33 b: T,
4) {
4): boolean {
55 const l = a.byteLength;
66 if (l !== b.byteLength) return false;
77 for (let i = 0; i < l; i++) if (a[i] !== b[i]) return false;
lib/deno.json+5-2
......@@ -6,9 +6,10 @@
66 "exports": {
77 "./assert.ts": "./assert.ts",
88 "./async.ts": "./async.ts",
9 "./bytes.ts": "./bytes.ts",
910 "./error.ts": "./error.ts",
11 "./Events.ts": "./Events.ts",
1012 "./log.ts": "./log.ts",
11 "./log/headless.ts": "./log/headless.ts",
1213 "./log/stack.ts": "./log/stack.ts",
1314 "./Lru.ts": "./Lru.ts",
1415 "./mime.ts": "./mime.ts",
......@@ -18,10 +19,12 @@
1819 "./render.ts": "./render.ts",
1920 "./render/jsx-runtime.ts": "./render/jsx-runtime.ts",
2021 "./render/meta.ts": "./render/meta.ts",
22 "./stream.ts": "./stream.ts",
2123 "./string.ts": "./string.ts",
2224 "./string/ansi.ts": "./string/ansi.ts",
2325 "./subprocess.ts": "./subprocess.ts",
2426 "./subprocess/ffmpeg.ts": "./subprocess/ffmpeg.ts",
27 "./testing.ts": "./testing.ts",
2528 "./ts.ts": "./ts.ts"
2629 },
2730 "compilerOptions": {
......@@ -36,4 +39,4 @@
3639 "readme.npm.md",
3740 "deno.lock"
3841 ]
39}
42}
\ No newline at end of file
lib/log.ts+4-4
......@@ -140,7 +140,7 @@ export function replaceGlobalFormatFunction(
140140 globalMessageFormatFunction = format;
141141}
142142
143export function formatMessage(msg: Message, colors: boolean) {
143export function formatMessage(msg: Message, colors: boolean): string {
144144 return globalMessageFormatFunction(msg, colors);
145145}
146146
......@@ -187,7 +187,7 @@ export function getDrawLock(): ts.Dispose {
187187}
188188
189189export function headlessScope(dispatch: DispatchFunction): Scope {
190 return new Scope(dispatch);
190 return new ScopeImpl(dispatch);
191191}
192192
193193/** see {@linkcode startWidget} */
......@@ -500,7 +500,7 @@ let withinDispatch = false;
500500let withinStackCapture = false;
501501
502502/** this class is an implementation detail */
503const Scope = class Scope implements Scope {
503const ScopeImpl = class Scope implements Scope {
504504 name: string | undefined;
505505 // TODO: this abstraction implementation has low performance. making every
506506 // scope define it's own dispatch is needed to correctly implement `tee`.
......@@ -669,7 +669,7 @@ const globalLog = /* @__PURE__ */ (() => {
669669 }
670670 console[level](...args);
671671 };
672 return new Scope(globalOutputFunction);
672 return new ScopeImpl(globalOutputFunction);
673673})();
674674
675675export type DispatchFunction = (message: Message) => void;
lib/progress.ts+18-8
......@@ -182,17 +182,21 @@ export interface StartOptions {
182182 * specify how `value` and `total` is formed into text.
183183 * this has some discoverable presets on `StartOptions.units`.
184184 */
185 valueFormatter?: (value: number, total: number | null) => string;
185 valueFormatter?: ValueFormatter;
186186 /** pre-fill the list of log messages */
187187 messages?: log.Message[];
188188}
189189
190export type ValueFormatter = (value: number, total: number | null) => string;
191
190192/**
191193 * creates a function to use as a `Node.valueFormatter` by using a single
192194 * number formatter, and then joining the node's value and total with a "/",
193195 * but leaving it out if there is no total.
194196 */
195export function slashValueFormatter(fmtNumber: (value: number) => string) {
197export function slashValueFormatter(
198 fmtNumber: (value: number) => string,
199): ValueFormatter {
196200 return (value: number, total: number | null) =>
197201 value > 0
198202 ? fmtNumber(value) +
......@@ -201,15 +205,18 @@ export function slashValueFormatter(fmtNumber: (value: number) => string) {
201205}
202206
203207/** the formatter used when passing `units: "count"` to {@linkcode start} */
204export const defaultValueFormatter = /* @__PURE__ */
208export const defaultValueFormatter: ValueFormatter = /* @__PURE__ */
205209 slashValueFormatter(String);
206210
207211/** the formatter used when passing `units: "bytes"` to {@linkcode start} */
208export const bytesValueFormatter = /* @__PURE__ */
212export const bytesValueFormatter: ValueFormatter = /* @__PURE__ */
209213 slashValueFormatter(string.formatByteSize);
210214
211215/** the formatter used when passing `units: "percent"` to {@linkcode start} */
212export function percentValueFormatter(value: number, total: number | null) {
216export function percentValueFormatter(
217 value: number,
218 total: number | null,
219): string {
213220 if (total != null && total > 0) {
214221 value /= total;
215222 }
......@@ -1724,14 +1731,17 @@ export const global: Ref =
17241731 * for testing. not covered by semver
17251732 * @internal
17261733 */
1727const uncastInternals = /** @__PURE__ */ (() => ({
1734export const internals: {
1735 readStreamEvent: typeof readStreamEvent;
1736 writeStreamEvent: typeof writeStreamEvent;
1737 kNode: symbol;
1738 EncodedKey: EncodedKey;
1739} = /** @__PURE__ */ (() => ({
17281740 readStreamEvent,
17291741 writeStreamEvent,
17301742 kNode: kNode as unknown as symbol,
1731 newNode,
17321743 EncodedKey: 0 as EncodedKey,
17331744}))();
1734export const internals: typeof uncastInternals = uncastInternals;
17351745
17361746import * as ansi from "./string/ansi.ts";
17371747import * as async from "./async.ts";
lib/stream.ts+16-25
......@@ -244,7 +244,7 @@ export class BufferedReader implements Disposable {
244244 this.#reader = reader;
245245 }
246246
247 get available() {
247 get available(): number {
248248 return this.#available;
249249 }
250250
......@@ -352,68 +352,68 @@ export class BufferedReader implements Disposable {
352352 }
353353 }
354354
355 async u8() {
355 async u8(): Promise<number> {
356356 const int = await this.peekU8();
357357 this.#shiftOffset(1);
358358 return int;
359359 }
360360
361 async peekU8() {
361 async peekU8(): Promise<number> {
362362 await this.ensureAvailable(1);
363363 return UNWRAP(UNWRAP(this.#buffer[0])[this.#offset]);
364364 }
365365
366 async i8() {
366 async i8(): Promise<number> {
367367 await this.ensureAvailable(2);
368368 return this.#collectLimitedView(1).getInt8(0);
369369 }
370370
371 async u16() {
371 async u16(): Promise<number> {
372372 await this.ensureAvailable(2);
373373 return this.#collectLimitedView(2).getUint16(0, true);
374374 }
375375
376 async i16() {
376 async i16(): Promise<number> {
377377 await this.ensureAvailable(2);
378378 return this.#collectLimitedView(2).getInt16(0, true);
379379 }
380380
381 async u32() {
381 async u32(): Promise<number> {
382382 await this.ensureAvailable(4);
383383 return this.#collectLimitedView(4).getUint32(0, true);
384384 }
385385
386 async i32() {
386 async i32(): Promise<number> {
387387 await this.ensureAvailable(4);
388388 return this.#collectLimitedView(4).getInt32(0, true);
389389 }
390390
391 async u64() {
391 async u64(): Promise<bigint> {
392392 await this.ensureAvailable(8);
393393 return this.#collectLimitedView(8).getBigUint64(0, true);
394394 }
395395
396 async i64() {
396 async i64(): Promise<bigint> {
397397 await this.ensureAvailable(8);
398398 return this.#collectLimitedView(8).getBigInt64(0, true);
399399 }
400400
401 async f16() {
401 async f16(): Promise<number> {
402402 await this.ensureAvailable(2);
403403 return this.#collectLimitedView(2).getFloat16(0, true);
404404 }
405405
406 async f32() {
406 async f32(): Promise<number> {
407407 await this.ensureAvailable(4);
408408 return this.#collectLimitedView(4).getFloat32(0, true);
409409 }
410410
411 async f64() {
411 async f64(): Promise<number> {
412412 await this.ensureAvailable(8);
413413 return this.#collectLimitedView(8).getFloat64(0, true);
414414 }
415415
416 async varUint() {
416 async varUint(): Promise<number> {
417417 let result = 0;
418418 let shift = 1;
419419 let byte;
......@@ -425,7 +425,7 @@ export class BufferedReader implements Disposable {
425425 return result;
426426 }
427427
428 async stringWithLength() {
428 async stringWithLength(): Promise<string> {
429429 const len = await this.varUint();
430430 return string.decodeUtf8(await this.readExactly(len));
431431 }
......@@ -441,7 +441,7 @@ export class BufferedReader implements Disposable {
441441 }
442442
443443 [Symbol.dispose]() {
444 return this.releaseLock();
444 this.releaseLock();
445445 }
446446}
447447
......@@ -472,14 +472,5 @@ export function readWritePair(): [
472472 return [reader, unbuffered];
473473}
474474
475export function fromChunks<T>(chunks: T[]) {
476 return new ReadableStream<T>({
477 start(c) {
478 for (const chunk of chunks) c.enqueue(chunk);
479 c.close();
480 },
481 });
482}
483
484475import * as string from "./string.ts";
485476import { ASSERT, UNWRAP } from "./assert.ts";
lib/string.ts+3-3
......@@ -43,7 +43,7 @@ export function decodeUtf8(input: Uint8Array): string {
4343}
4444
4545const byteUnits = "kMGTPEZYRQ"; // kilo, mega, giga, etc
46export function formatByteSize(bytes: number) {
46export function formatByteSize(bytes: number): string {
4747 if (!Number.isFinite(bytes)) return bytes.toString();
4848 let prefix = "";
4949 if (bytes < 0) bytes = -bytes, prefix = "-";
......@@ -60,7 +60,7 @@ export function formatByteSize(bytes: number) {
6060 byteUnits.charAt(unit - 1) + "B";
6161}
6262
63export function formatBinaryByteSize(bytes: number) {
63export function formatBinaryByteSize(bytes: number): string {
6464 let prefix = "";
6565 if (bytes < 0) bytes = -bytes, prefix = "-";
6666 if (bytes < 1024) return (Math.round(bytes * 100) / 100) + "B";
......@@ -74,7 +74,7 @@ export function formatBinaryByteSize(bytes: number) {
7474}
7575
7676// TODO:
77export function formatDurationLetters(seconds: number) {
77export function formatDurationLetters(seconds: number): string {
7878 const minutes = Math.floor(seconds / 60);
7979 const remainingSeconds = seconds % 60;
8080 if (minutes < 1) return `${remainingSeconds}s`;
lib/string/ansi.ts+2-1
......@@ -322,7 +322,8 @@ const leadingNonPrintingRegex =
322322 /^[\p{Default_Ignorable_Code_Point}\p{Control}\p{Format}\p{Mark}\p{Surrogate}]+/v;
323323const rgiEmojiRegex = /^\p{RGI_Emoji}$/v;
324324
325export function strip(text: string) {
325/** remove all ansi escape sequences */
326export function strip(text: string): string {
326327 return text.replace(ansiEscapes, "");
327328}
328329
lib/subprocess/ffmpeg.ts+1-1
......@@ -191,10 +191,10 @@ export class Parse {
191191}
192192
193193import * as child_process from "node:child_process";
194import * as subprocess from "lib/subprocess.ts";
195194import * as readline from "node:readline";
196195import * as process from "node:process";
197196import events from "node:events";
198197import * as path from "node:path";
198import * as subprocess from "../subprocess.ts";
199199import type * as progress from "../progress.ts";
200200import * as string from "../string.ts";
lib/testing.ts+7-7
......@@ -118,7 +118,7 @@ export class FakeTimers {
118118 }> = [];
119119 waitTime = 0;
120120
121 now = () => {
121 now: () => number = () => {
122122 return this.time;
123123 };
124124 delay: typeof async.delay = (ms) => {
......@@ -174,7 +174,7 @@ export class MockScreen implements Disposable, log.HeadlessWidgetHost {
174174 delay: log.HeadlessWidgetHost["delay"];
175175 now: log.HeadlessWidgetHost["now"];
176176
177 static sync(text: string[]) {
177 static sync(text: string[]): string {
178178 return ansi.syncStart + text.join("") + ansi.syncEnd;
179179 }
180180
......@@ -271,8 +271,8 @@ export class MockScreen implements Disposable, log.HeadlessWidgetHost {
271271 }
272272}
273273
274import * as ansi from "lib/string/ansi.ts";
275import { ASSERT, UNWRAP } from "lib/assert.ts";
276import * as log from "lib/log.ts";
277import * as async from "lib/async.ts";
278import * as stack from "lib/log/stack.ts";
274import * as ansi from "./string/ansi.ts";
275import { ASSERT, UNWRAP } from "./assert.ts";
276import * as log from "./log.ts";
277import * as async from "./async.ts";
278import * as stack from "./log/stack.ts";
src/bin/package-lib.ts+2-198
......@@ -20,207 +20,11 @@ export async function updateJsrPackageExportsToAll(
2020 await fs.writeFile(manifestPath, JSON.stringify(deno, null, 2));
2121}
2222
23export async function transpileForNpm(
24 absPath: string,
25 p: progress.Ref,
26 packageJson: Record<string, unknown>,
27) {
28 using node = p.start("transpile into js for npm");
29 const manifestPath = path.join(absPath, "deno.json");
30 const deno = JSON.parse(
31 await fs.readFile(manifestPath, "utf-8"),
32 );
33 const distPath = path.join(absPath, "dist-npm");
34 await fs.rm(distPath, { recursive: true, force: true });
35 await fs.mkdir(distPath, { recursive: true });
36
37 const files: string[] = [];
38 const exports: Record<string, string> = {};
39 for (const subPath of await fs.readdir(absPath, { recursive: true })) {
40 if (!subPath.match(/\.tsx?$/)) continue;
41 if (subPath.startsWith("dist")) continue;
42 files.push(subPath);
43 }
44 const tsFiles: string[] = [];
45 for (const subPath of files) {
46 using _ = node.start(subPath);
47 const targetSubPath = subPath.replace(/\.tsx?$/, ".js");
48 if (!subPath.match(/\.(test|sample)\.tsx?$/)) {
49 exports["./" + subPath] = "./" + targetSubPath;
50 }
51 const out = path.join(distPath, subPath);
52 await fs.mkdir(path.dirname(out), { recursive: true });
53 tsFiles.push(out);
54
55 let code = await fs.readFile(path.join(absPath, subPath), "utf-8");
56 code = code.replace(
57 / from "lib\/([^"]+)"/g,
58 (_, src) => {
59 return ' from "./' + path.relative(
60 path.dirname(subPath),
61 src.replace(/\.tsx?$/, ".js"),
62 ) + '"';
63 },
64 );
65 await fs.writeFile(out, code);
66 }
67 await subprocess.spawnAndWait({
68 cmd: [
69 "npx",
70 "tsc",
71 "--outdir",
72 distPath,
73 "--sourceMap",
74 "--declarationMap",
75 "--declaration",
76 "--module",
77 "nodenext",
78 "--lib",
79 "esnext",
80 "--skipLibCheck",
81 "--jsx",
82 "react-jsx",
83 "--jsxImportSource",
84 "./lib/dist-npm/render",
85 "--target",
86 "esnext",
87 "--isolatedModules",
88 "--verbatimModuleSyntax",
89 "--allowSyntheticDefaultImports",
90 "--moduleResolution",
91 "nodenext",
92 ...tsFiles,
93 ],
94 });
95 await fs.writeFile(
96 path.join(distPath, "readme.md"),
97 (await fs.readFile(path.join(absPath, "readme.md"), "utf-8")).replace(
98 "<!--%npm%-->\n",
99 await fs.readFile(path.join(absPath, "readme.npm.md"), "utf-8"),
100 ),
101 ).catch((e) => {
102 if (e.code !== "ENOENT") throw e;
103 });
104 await fs.cp(
105 path.join(absPath, "readme.changes.md"),
106 path.join(distPath, "readme.changes.md"),
107 ).catch((e) => {
108 if (e.code !== "ENOENT") throw e;
109 });
110 const { name, description, ...rest } = packageJson;
111 await fs.writeFile(
112 path.join(distPath, "package.json"),
113 JSON.stringify(
114 {
115 name,
116 description,
117 version: deno.version,
118 type: "module",
119 exports,
120 ...rest,
121 },
122 null,
123 2,
124 ),
125 );
126}
127
128// TODO: failed experiment
129//
130// export async function transpileForNpm(
131// absPath: string,
132// p: progress.Ref,
133// packageJson: Record<string, unknown>,
134// ) {
135// const { transpileFile } = await import("ts-to-jsdoc") as TsToJsdoc;
136//
137// using node = p.start("transpile into jsdoc for npm");
138// const manifestPath = path.join(absPath, "deno.json");
139// const deno = JSON.parse(
140// await fs.readFile(manifestPath, "utf-8"),
141// );
142// const distPath = path.join(absPath, "dist-npm");
143// await fs.rm(distPath, { recursive: true, force: true });
144// await fs.mkdir(distPath, { recursive: true });
145//
146// const files: string[] = [];
147// const exports: Record<string, string> = {};
148// for (const subPath of await fs.readdir(absPath, { recursive: true })) {
149// if (!subPath.match(/\.tsx?$/)) continue;
150// if (subPath.startsWith("dist")) continue;
151// files.push(subPath);
152// }
153// node.estimate = Object.keys(exports).length;
154// for (const subPath of files) {
155// using _ = node.start(subPath);
156// const targetSubPath = subPath.replace(/\.tsx?$/, ".js");
157// if (!subPath.match(/\.(test|sample)\.tsx?$/)) {
158// exports["./" + subPath] = "./" + targetSubPath;
159// }
160//
161// let code = transpileFile({
162// code: await fs.readFile(path.join(absPath, subPath), "utf-8"),
163// });
164// code = code.replace(
165// / from "lib\/([^"]+)"/g,
166// (_, src) => {
167// return ' from "./' + path.relative(
168// path.dirname(subPath),
169// src.replace(/\.tsx?$/, ".js"),
170// ) + '"';
171// },
172// );
173// if (packageJson.homepage) {
174// code =
175// "// This file is transpiled from TypeScript from paper clover's sitegen\n" +
176// "// " + packageJson.homepage + "/" + subPath + "\n" +
177// code;
178// }
179// const out = path.join(distPath, targetSubPath);
180// await fs.mkdir(path.dirname(out), { recursive: true });
181// await fs.writeFile(out, code);
182// node.value += 1;
183// }
184// await fs.cp(
185// path.join(absPath, "readme.npm.md"),
186// path.join(distPath, "readme.md"),
187// ).catch((e) => {
188// if (e.code !== "ENOENT") throw e;
189// });
190// await fs.cp(
191// path.join(absPath, "readme.changes.md"),
192// path.join(distPath, "readme.changes.md"),
193// ).catch((e) => {
194// if (e.code !== "ENOENT") throw e;
195// });
196// const { name, description, ...rest } = packageJson;
197// await fs.writeFile(
198// path.join(distPath, "package.json"),
199// JSON.stringify({
200// name,
201// description,
202// version: deno.version,
203// type: "module",
204// ...rest,
205// }),
206// );
207// }
208//
209export function main() {
23export async function main() {
21024 const main = path.resolve("lib");
211 updateJsrPackageExportsToAll(main, progress)
212 .then(() =>
213 transpileForNpm(main, progress, {
214 name: "@paperclover/lib",
215 description: "high quality typescript libraries",
216 homepage:
217 "https://git.paperclover.net/clo/sitegen/src/branch/master/lib",
218 })
219 );
25 await updateJsrPackageExportsToAll(main, progress);
22026}
22127
22228import * as progress from "lib/progress.ts";
22329import * as path from "node:path";
22430import * as fs from "node:fs/promises";
225import * as subprocess from "lib/subprocess.ts";
226import { UNWRAP } from "lib/assert.ts";