diff --git a/lib/bytes.ts b/lib/bytes.ts index 03f08dbdaea64fea236d70b972fe5d3c6548b2e9..b1733dba492274b0b571a95b6127656b9a0ff8d7 100644 --- a/lib/bytes.ts +++ b/lib/bytes.ts @@ -1,7 +1,7 @@ export function eql( a: T, b: T, -) { +): boolean { const l = a.byteLength; if (l !== b.byteLength) return false; for (let i = 0; i < l; i++) if (a[i] !== b[i]) return false; diff --git a/lib/deno.json b/lib/deno.json index dcc4816eb0bf1eefb7eb62746e6b28168744277a..43704fbd7ff49484986762f3d6968a59b6f35f2d 100644 --- a/lib/deno.json +++ b/lib/deno.json @@ -6,9 +6,10 @@ "exports": { "./assert.ts": "./assert.ts", "./async.ts": "./async.ts", + "./bytes.ts": "./bytes.ts", "./error.ts": "./error.ts", + "./Events.ts": "./Events.ts", "./log.ts": "./log.ts", - "./log/headless.ts": "./log/headless.ts", "./log/stack.ts": "./log/stack.ts", "./Lru.ts": "./Lru.ts", "./mime.ts": "./mime.ts", @@ -18,10 +19,12 @@ "./render.ts": "./render.ts", "./render/jsx-runtime.ts": "./render/jsx-runtime.ts", "./render/meta.ts": "./render/meta.ts", + "./stream.ts": "./stream.ts", "./string.ts": "./string.ts", "./string/ansi.ts": "./string/ansi.ts", "./subprocess.ts": "./subprocess.ts", "./subprocess/ffmpeg.ts": "./subprocess/ffmpeg.ts", + "./testing.ts": "./testing.ts", "./ts.ts": "./ts.ts" }, "compilerOptions": { @@ -36,4 +39,4 @@ "readme.npm.md", "deno.lock" ] -} +} \ No newline at end of file diff --git a/lib/log.ts b/lib/log.ts index 638fff8c7afd51f8c9688e004f6553b3c1206d5c..b3c98536f6422365b42fa6ae6e95da1b5f2ad3ae 100644 --- a/lib/log.ts +++ b/lib/log.ts @@ -140,7 +140,7 @@ export function replaceGlobalFormatFunction( globalMessageFormatFunction = format; } -export function formatMessage(msg: Message, colors: boolean) { +export function formatMessage(msg: Message, colors: boolean): string { return globalMessageFormatFunction(msg, colors); } @@ -187,7 +187,7 @@ export function getDrawLock(): ts.Dispose { } export function headlessScope(dispatch: DispatchFunction): Scope { - return new Scope(dispatch); + return new ScopeImpl(dispatch); } /** see {@linkcode startWidget} */ @@ -500,7 +500,7 @@ let withinDispatch = false; let withinStackCapture = false; /** this class is an implementation detail */ -const Scope = class Scope implements Scope { +const ScopeImpl = class Scope implements Scope { name: string | undefined; // TODO: this abstraction implementation has low performance. making every // scope define it's own dispatch is needed to correctly implement `tee`. @@ -669,7 +669,7 @@ const globalLog = /* @__PURE__ */ (() => { } console[level](...args); }; - return new Scope(globalOutputFunction); + return new ScopeImpl(globalOutputFunction); })(); export type DispatchFunction = (message: Message) => void; diff --git a/lib/progress.ts b/lib/progress.ts index edc42afd4a654c3b5d7fc5707deb4f7c231e5449..061a2ca7874ff8f0be9f38d1224ee9e5f014945f 100644 --- a/lib/progress.ts +++ b/lib/progress.ts @@ -182,17 +182,21 @@ export interface StartOptions { * specify how `value` and `total` is formed into text. * this has some discoverable presets on `StartOptions.units`. */ - valueFormatter?: (value: number, total: number | null) => string; + valueFormatter?: ValueFormatter; /** pre-fill the list of log messages */ messages?: log.Message[]; } +export type ValueFormatter = (value: number, total: number | null) => string; + /** * creates a function to use as a `Node.valueFormatter` by using a single * number formatter, and then joining the node's value and total with a "/", * but leaving it out if there is no total. */ -export function slashValueFormatter(fmtNumber: (value: number) => string) { +export function slashValueFormatter( + fmtNumber: (value: number) => string, +): ValueFormatter { return (value: number, total: number | null) => value > 0 ? fmtNumber(value) + @@ -201,15 +205,18 @@ export function slashValueFormatter(fmtNumber: (value: number) => string) { } /** the formatter used when passing `units: "count"` to {@linkcode start} */ -export const defaultValueFormatter = /* @__PURE__ */ +export const defaultValueFormatter: ValueFormatter = /* @__PURE__ */ slashValueFormatter(String); /** the formatter used when passing `units: "bytes"` to {@linkcode start} */ -export const bytesValueFormatter = /* @__PURE__ */ +export const bytesValueFormatter: ValueFormatter = /* @__PURE__ */ slashValueFormatter(string.formatByteSize); /** the formatter used when passing `units: "percent"` to {@linkcode start} */ -export function percentValueFormatter(value: number, total: number | null) { +export function percentValueFormatter( + value: number, + total: number | null, +): string { if (total != null && total > 0) { value /= total; } @@ -1724,14 +1731,17 @@ export const global: Ref = * for testing. not covered by semver * @internal */ -const uncastInternals = /** @__PURE__ */ (() => ({ +export const internals: { + readStreamEvent: typeof readStreamEvent; + writeStreamEvent: typeof writeStreamEvent; + kNode: symbol; + EncodedKey: EncodedKey; +} = /** @__PURE__ */ (() => ({ readStreamEvent, writeStreamEvent, kNode: kNode as unknown as symbol, - newNode, EncodedKey: 0 as EncodedKey, }))(); -export const internals: typeof uncastInternals = uncastInternals; import * as ansi from "./string/ansi.ts"; import * as async from "./async.ts"; diff --git a/lib/stream.ts b/lib/stream.ts index e793de3e9f0c7e12b0feaefbae54d64ec932c87a..04233e5aeb123d5efed46f64e9e9704ca31e8458 100644 --- a/lib/stream.ts +++ b/lib/stream.ts @@ -244,7 +244,7 @@ export class BufferedReader implements Disposable { this.#reader = reader; } - get available() { + get available(): number { return this.#available; } @@ -352,68 +352,68 @@ export class BufferedReader implements Disposable { } } - async u8() { + async u8(): Promise { const int = await this.peekU8(); this.#shiftOffset(1); return int; } - async peekU8() { + async peekU8(): Promise { await this.ensureAvailable(1); return UNWRAP(UNWRAP(this.#buffer[0])[this.#offset]); } - async i8() { + async i8(): Promise { await this.ensureAvailable(2); return this.#collectLimitedView(1).getInt8(0); } - async u16() { + async u16(): Promise { await this.ensureAvailable(2); return this.#collectLimitedView(2).getUint16(0, true); } - async i16() { + async i16(): Promise { await this.ensureAvailable(2); return this.#collectLimitedView(2).getInt16(0, true); } - async u32() { + async u32(): Promise { await this.ensureAvailable(4); return this.#collectLimitedView(4).getUint32(0, true); } - async i32() { + async i32(): Promise { await this.ensureAvailable(4); return this.#collectLimitedView(4).getInt32(0, true); } - async u64() { + async u64(): Promise { await this.ensureAvailable(8); return this.#collectLimitedView(8).getBigUint64(0, true); } - async i64() { + async i64(): Promise { await this.ensureAvailable(8); return this.#collectLimitedView(8).getBigInt64(0, true); } - async f16() { + async f16(): Promise { await this.ensureAvailable(2); return this.#collectLimitedView(2).getFloat16(0, true); } - async f32() { + async f32(): Promise { await this.ensureAvailable(4); return this.#collectLimitedView(4).getFloat32(0, true); } - async f64() { + async f64(): Promise { await this.ensureAvailable(8); return this.#collectLimitedView(8).getFloat64(0, true); } - async varUint() { + async varUint(): Promise { let result = 0; let shift = 1; let byte; @@ -425,7 +425,7 @@ export class BufferedReader implements Disposable { return result; } - async stringWithLength() { + async stringWithLength(): Promise { const len = await this.varUint(); return string.decodeUtf8(await this.readExactly(len)); } @@ -441,7 +441,7 @@ export class BufferedReader implements Disposable { } [Symbol.dispose]() { - return this.releaseLock(); + this.releaseLock(); } } @@ -472,14 +472,5 @@ export function readWritePair(): [ return [reader, unbuffered]; } -export function fromChunks(chunks: T[]) { - return new ReadableStream({ - start(c) { - for (const chunk of chunks) c.enqueue(chunk); - c.close(); - }, - }); -} - import * as string from "./string.ts"; import { ASSERT, UNWRAP } from "./assert.ts"; diff --git a/lib/string.ts b/lib/string.ts index a371a900da1a589640c381d2d32f2d7e75f249b0..cdfebb68d1f6873d2ff83dbefbe0598bf49c2d8a 100644 --- a/lib/string.ts +++ b/lib/string.ts @@ -43,7 +43,7 @@ export function decodeUtf8(input: Uint8Array): string { } const byteUnits = "kMGTPEZYRQ"; // kilo, mega, giga, etc -export function formatByteSize(bytes: number) { +export function formatByteSize(bytes: number): string { if (!Number.isFinite(bytes)) return bytes.toString(); let prefix = ""; if (bytes < 0) bytes = -bytes, prefix = "-"; @@ -60,7 +60,7 @@ export function formatByteSize(bytes: number) { byteUnits.charAt(unit - 1) + "B"; } -export function formatBinaryByteSize(bytes: number) { +export function formatBinaryByteSize(bytes: number): string { let prefix = ""; if (bytes < 0) bytes = -bytes, prefix = "-"; if (bytes < 1024) return (Math.round(bytes * 100) / 100) + "B"; @@ -74,7 +74,7 @@ export function formatBinaryByteSize(bytes: number) { } // TODO: -export function formatDurationLetters(seconds: number) { +export function formatDurationLetters(seconds: number): string { const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; if (minutes < 1) return `${remainingSeconds}s`; diff --git a/lib/string/ansi.ts b/lib/string/ansi.ts index 410802741dea832e021c5a7d9bbd983114940494..240a72bafef724a47e02aa0dbbc85d3a51de7c96 100644 --- a/lib/string/ansi.ts +++ b/lib/string/ansi.ts @@ -322,7 +322,8 @@ const leadingNonPrintingRegex = /^[\p{Default_Ignorable_Code_Point}\p{Control}\p{Format}\p{Mark}\p{Surrogate}]+/v; const rgiEmojiRegex = /^\p{RGI_Emoji}$/v; -export function strip(text: string) { +/** remove all ansi escape sequences */ +export function strip(text: string): string { return text.replace(ansiEscapes, ""); } diff --git a/lib/subprocess/ffmpeg.ts b/lib/subprocess/ffmpeg.ts index 5f87cfc284f2a6af661c4aac1c1ce2cb11ea8bf6..c452209e6cbe40aeb93527afa1f1101ef8baf290 100644 --- a/lib/subprocess/ffmpeg.ts +++ b/lib/subprocess/ffmpeg.ts @@ -191,10 +191,10 @@ export class Parse { } import * as child_process from "node:child_process"; -import * as subprocess from "lib/subprocess.ts"; import * as readline from "node:readline"; import * as process from "node:process"; import events from "node:events"; import * as path from "node:path"; +import * as subprocess from "../subprocess.ts"; import type * as progress from "../progress.ts"; import * as string from "../string.ts"; diff --git a/lib/testing.ts b/lib/testing.ts index 04081bbf21f2754f230829a417ccd27280021a45..06937d1584bf534091be60cc25ce81ac6b68240c 100644 --- a/lib/testing.ts +++ b/lib/testing.ts @@ -118,7 +118,7 @@ export class FakeTimers { }> = []; waitTime = 0; - now = () => { + now: () => number = () => { return this.time; }; delay: typeof async.delay = (ms) => { @@ -174,7 +174,7 @@ export class MockScreen implements Disposable, log.HeadlessWidgetHost { delay: log.HeadlessWidgetHost["delay"]; now: log.HeadlessWidgetHost["now"]; - static sync(text: string[]) { + static sync(text: string[]): string { return ansi.syncStart + text.join("") + ansi.syncEnd; } @@ -271,8 +271,8 @@ export class MockScreen implements Disposable, log.HeadlessWidgetHost { } } -import * as ansi from "lib/string/ansi.ts"; -import { ASSERT, UNWRAP } from "lib/assert.ts"; -import * as log from "lib/log.ts"; -import * as async from "lib/async.ts"; -import * as stack from "lib/log/stack.ts"; +import * as ansi from "./string/ansi.ts"; +import { ASSERT, UNWRAP } from "./assert.ts"; +import * as log from "./log.ts"; +import * as async from "./async.ts"; +import * as stack from "./log/stack.ts"; diff --git a/src/bin/package-lib.ts b/src/bin/package-lib.ts index b26cde479d91bcbcb1e0ebf7d9009b7a1b0dc313..0680dfb05bb08d47ef2d797bbb7e7d8f1cd9957a 100644 --- a/src/bin/package-lib.ts +++ b/src/bin/package-lib.ts @@ -20,207 +20,11 @@ export async function updateJsrPackageExportsToAll( await fs.writeFile(manifestPath, JSON.stringify(deno, null, 2)); } -export async function transpileForNpm( - absPath: string, - p: progress.Ref, - packageJson: Record, -) { - using node = p.start("transpile into js for npm"); - const manifestPath = path.join(absPath, "deno.json"); - const deno = JSON.parse( - await fs.readFile(manifestPath, "utf-8"), - ); - const distPath = path.join(absPath, "dist-npm"); - await fs.rm(distPath, { recursive: true, force: true }); - await fs.mkdir(distPath, { recursive: true }); - - const files: string[] = []; - const exports: Record = {}; - for (const subPath of await fs.readdir(absPath, { recursive: true })) { - if (!subPath.match(/\.tsx?$/)) continue; - if (subPath.startsWith("dist")) continue; - files.push(subPath); - } - const tsFiles: string[] = []; - for (const subPath of files) { - using _ = node.start(subPath); - const targetSubPath = subPath.replace(/\.tsx?$/, ".js"); - if (!subPath.match(/\.(test|sample)\.tsx?$/)) { - exports["./" + subPath] = "./" + targetSubPath; - } - const out = path.join(distPath, subPath); - await fs.mkdir(path.dirname(out), { recursive: true }); - tsFiles.push(out); - - let code = await fs.readFile(path.join(absPath, subPath), "utf-8"); - code = code.replace( - / from "lib\/([^"]+)"/g, - (_, src) => { - return ' from "./' + path.relative( - path.dirname(subPath), - src.replace(/\.tsx?$/, ".js"), - ) + '"'; - }, - ); - await fs.writeFile(out, code); - } - await subprocess.spawnAndWait({ - cmd: [ - "npx", - "tsc", - "--outdir", - distPath, - "--sourceMap", - "--declarationMap", - "--declaration", - "--module", - "nodenext", - "--lib", - "esnext", - "--skipLibCheck", - "--jsx", - "react-jsx", - "--jsxImportSource", - "./lib/dist-npm/render", - "--target", - "esnext", - "--isolatedModules", - "--verbatimModuleSyntax", - "--allowSyntheticDefaultImports", - "--moduleResolution", - "nodenext", - ...tsFiles, - ], - }); - await fs.writeFile( - path.join(distPath, "readme.md"), - (await fs.readFile(path.join(absPath, "readme.md"), "utf-8")).replace( - "\n", - await fs.readFile(path.join(absPath, "readme.npm.md"), "utf-8"), - ), - ).catch((e) => { - if (e.code !== "ENOENT") throw e; - }); - await fs.cp( - path.join(absPath, "readme.changes.md"), - path.join(distPath, "readme.changes.md"), - ).catch((e) => { - if (e.code !== "ENOENT") throw e; - }); - const { name, description, ...rest } = packageJson; - await fs.writeFile( - path.join(distPath, "package.json"), - JSON.stringify( - { - name, - description, - version: deno.version, - type: "module", - exports, - ...rest, - }, - null, - 2, - ), - ); -} - -// TODO: failed experiment -// -// export async function transpileForNpm( -// absPath: string, -// p: progress.Ref, -// packageJson: Record, -// ) { -// const { transpileFile } = await import("ts-to-jsdoc") as TsToJsdoc; -// -// using node = p.start("transpile into jsdoc for npm"); -// const manifestPath = path.join(absPath, "deno.json"); -// const deno = JSON.parse( -// await fs.readFile(manifestPath, "utf-8"), -// ); -// const distPath = path.join(absPath, "dist-npm"); -// await fs.rm(distPath, { recursive: true, force: true }); -// await fs.mkdir(distPath, { recursive: true }); -// -// const files: string[] = []; -// const exports: Record = {}; -// for (const subPath of await fs.readdir(absPath, { recursive: true })) { -// if (!subPath.match(/\.tsx?$/)) continue; -// if (subPath.startsWith("dist")) continue; -// files.push(subPath); -// } -// node.estimate = Object.keys(exports).length; -// for (const subPath of files) { -// using _ = node.start(subPath); -// const targetSubPath = subPath.replace(/\.tsx?$/, ".js"); -// if (!subPath.match(/\.(test|sample)\.tsx?$/)) { -// exports["./" + subPath] = "./" + targetSubPath; -// } -// -// let code = transpileFile({ -// code: await fs.readFile(path.join(absPath, subPath), "utf-8"), -// }); -// code = code.replace( -// / from "lib\/([^"]+)"/g, -// (_, src) => { -// return ' from "./' + path.relative( -// path.dirname(subPath), -// src.replace(/\.tsx?$/, ".js"), -// ) + '"'; -// }, -// ); -// if (packageJson.homepage) { -// code = -// "// This file is transpiled from TypeScript from paper clover's sitegen\n" + -// "// " + packageJson.homepage + "/" + subPath + "\n" + -// code; -// } -// const out = path.join(distPath, targetSubPath); -// await fs.mkdir(path.dirname(out), { recursive: true }); -// await fs.writeFile(out, code); -// node.value += 1; -// } -// await fs.cp( -// path.join(absPath, "readme.npm.md"), -// path.join(distPath, "readme.md"), -// ).catch((e) => { -// if (e.code !== "ENOENT") throw e; -// }); -// await fs.cp( -// path.join(absPath, "readme.changes.md"), -// path.join(distPath, "readme.changes.md"), -// ).catch((e) => { -// if (e.code !== "ENOENT") throw e; -// }); -// const { name, description, ...rest } = packageJson; -// await fs.writeFile( -// path.join(distPath, "package.json"), -// JSON.stringify({ -// name, -// description, -// version: deno.version, -// type: "module", -// ...rest, -// }), -// ); -// } -// -export function main() { +export async function main() { const main = path.resolve("lib"); - updateJsrPackageExportsToAll(main, progress) - .then(() => - transpileForNpm(main, progress, { - name: "@paperclover/lib", - description: "high quality typescript libraries", - homepage: - "https://git.paperclover.net/clo/sitegen/src/branch/master/lib", - }) - ); + await updateJsrPackageExportsToAll(main, progress); } import * as progress from "lib/progress.ts"; import * as path from "node:path"; import * as fs from "node:fs/promises"; -import * as subprocess from "lib/subprocess.ts"; -import { UNWRAP } from "lib/assert.ts";