cmpl
Version:
no deps, no operations, no vowels - just a tiny compiler
8 lines (7 loc) • 22.3 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/index.ts"],
"sourcesContent": ["export interface Path {\n join: (...segments: string[]) => string;\n basename: (path: string, ext?: string) => string;\n extname: (path: string) => string;\n relative: (a: string, b: string) => string;\n dirname: (path: string) => string;\n}\nexport interface Fs {\n readdir: (dir: string) => Promise<string[]>;\n stat: (\n dirOrFile: string,\n ) => Promise<{ isDirectory: () => boolean; mtimeMs: number }>;\n readFile: (path: string) => Promise<Buffer>;\n mkdir: (\n path: string,\n opts?: { recursive: true },\n ) => Promise<string | undefined>;\n writeFile: (path: string, contents: Buffer) => Promise<void>;\n}\nexport interface Crypto {\n createHash: (algorithm: 'sha256') => {\n update: (content: Buffer) => { digest: (encoding: 'hex') => string };\n };\n}\nexport type TransformResult =\n | Buffer\n | {\n content: Buffer;\n name: string;\n }\n | {\n content: Buffer;\n name: string;\n }[]\n | null;\nexport type TransformFn = (\n content: Buffer,\n file: string,\n) => TransformResult | Promise<TransformResult>;\nexport type FileNamerFn = (\n originalName: string,\n contents: Buffer,\n) => string | Promise<string>;\n\nexport interface BasePrcssr {\n outDir: string;\n recursive?: boolean;\n include?: (\n name: string,\n isDir: boolean,\n getContents?: () => Promise<Buffer | null>,\n ) => boolean | Promise<boolean>;\n}\nexport interface RenamePrcssr extends BasePrcssr {\n rename?: FileNamerFn;\n}\nexport interface TransformPrcssr extends BasePrcssr {\n transform: TransformFn;\n}\nexport type Prcssr = RenamePrcssr | TransformPrcssr;\nexport interface CmplOptions {\n entry: string;\n processors: (Prcssr | Promise<Prcssr>)[];\n path?: Path | Promise<Path>;\n fs?: Fs | Promise<Fs>;\n}\n\nexport const cntntHsh =\n (\n length: number = 8,\n crypto: Crypto | Promise<Crypto> = import('node:crypto'),\n path: Path | Promise<Path> = import('node:path'),\n ): FileNamerFn =>\n async (name, content) => {\n const { createHash } = await crypto;\n const { basename, extname } = await path;\n\n return `${basename(name, extname(name))}-${createHash('sha256')\n .update(content)\n .digest('hex')\n .substring(0, length)\n .toUpperCase()}${extname(name)}`;\n };\n\nexport const cntntChngd = (\n crypto: Crypto | Promise<Crypto> = import('node:crypto'),\n): ((\n ...args: Parameters<NonNullable<BasePrcssr['include']>>\n) => Promise<boolean>) => {\n const state = new Map<string, string>();\n return async (name, isDir, getContents) => {\n const { createHash } = await crypto;\n const contents = (await getContents?.()) || null;\n if (contents === null || isDir) {\n return true;\n }\n const checksum = createHash('sha256').update(contents).digest('hex');\n\n if (!state.has(name) || state.get(name) !== checksum) {\n state.set(name, checksum);\n return true;\n }\n\n return false;\n };\n};\n\nexport async function prcss(\n file: string,\n {\n entry,\n fs = import('node:fs/promises'),\n path = import('node:path'),\n }: Pick<CmplOptions, 'entry' | 'fs' | 'path'>,\n processors: (Prcssr | null)[],\n): Promise<(null | Record<string, string | string[]>)[]> {\n const { relative, dirname, join } = await path;\n const { readFile, mkdir, writeFile } = await fs;\n const contentsP = readFile(file);\n const inName = relative(entry, file);\n\n return Promise.all(\n processors.map(async (p) => {\n if (!p) {\n return p;\n }\n\n const copyName = (await path).basename(inName);\n if (!isRenamePrcssr(p) && typeof (p as any).rename === 'function') {\n console.warn(\n 'WARING: unexpected rename method on transform processor, will be ignored!',\n 'Return new name from transform method via { content: Buffer, name: string }',\n );\n }\n\n const contents = isRenamePrcssr(p)\n ? {\n content: await contentsP,\n name: (await p.rename?.(inName, await contentsP)) || copyName,\n }\n : await p.transform(await contentsP, inName);\n\n if (contents === null) {\n return null;\n }\n\n const targerDir = join(p.outDir, relative(entry, dirname(file)));\n\n const writes = Array.isArray(contents)\n ? contents\n : contents instanceof Buffer\n ? [{ content: contents, name: copyName }]\n : [contents];\n\n if (writes.length === 0) {\n return null;\n }\n\n const outFiles = await Promise.all(\n writes.map(async ({ content, name }) => {\n const targetFile = join(targerDir, name);\n\n await mkdir(dirname(targetFile), { recursive: true });\n await writeFile(targetFile, content);\n\n return relative(p.outDir, targetFile);\n }),\n );\n\n return {\n [inName]: Array.isArray(contents) ? outFiles : outFiles[0],\n };\n }),\n );\n}\n\nexport async function cmpl({\n entry,\n processors,\n fs = import('node:fs/promises'),\n path = import('node:path'),\n}: CmplOptions) {\n const manifest: Record<string, string>[] = Array.from({\n length: processors.length,\n }).map(() => ({}));\n const { relative, join, dirname } = await path;\n const { readdir, stat, readFile } = await fs;\n let entryDir: string | null;\n\n const handle = async (\n subEntry: string,\n parentDir: string,\n processors: (Prcssr | null)[],\n ) => {\n const entryPath = join(parentDir, subEntry);\n const isDir = (await stat(entryPath)).isDirectory();\n if (!entryDir) {\n entryDir = isDir ? entry : dirname(entry);\n }\n\n if (isDir) {\n let relevantDir = false;\n const dirProcessors = await Promise.all(\n processors.map(async (p) => {\n const incl =\n p &&\n (subEntry === entry ||\n (p.recursive !== false &&\n (!p.include ||\n (await p.include(relative(entryDir!, entryPath), true)))));\n if (incl) {\n relevantDir = true;\n }\n return incl ? p : null;\n }),\n );\n\n if (relevantDir) {\n await readDir(entryPath, dirProcessors);\n }\n }\n\n if (!isDir) {\n let relevantFile = false;\n const fileProcessors = await Promise.all(\n processors.map(async (p) => {\n const incl =\n p &&\n (!p.include ||\n (await p.include(relative(entryDir!, entryPath), false, () =>\n readFile(entryPath),\n )))\n ? p\n : null;\n\n if (incl) {\n relevantFile = true;\n }\n return incl;\n }),\n );\n\n if (!relevantFile) {\n return;\n }\n\n (\n await prcss(\n entryPath,\n { fs, path, entry: entry === subEntry ? entryDir! : entry },\n fileProcessors,\n )\n ).forEach((v, i) => {\n if (v !== null) {\n Object.assign(manifest[i], v);\n }\n });\n }\n };\n\n const readDir = async (\n dir: string,\n processors: (Prcssr | null)[],\n ): Promise<void> => {\n await Promise.all(\n (await readdir(dir)).map((e) => handle(e, dir, processors)),\n );\n };\n\n await handle(entry, '', await Promise.all(processors));\n\n if (processors.length === 1) {\n return manifest[0];\n }\n\n return manifest;\n}\n\nexport interface WatchEvent {\n eventType: 'rename' | 'change';\n filename: string;\n}\nexport interface WatchFs extends Fs {\n watch: (\n path: string,\n opts?: { recursive: boolean; signal?: AbortSignal },\n ) => AsyncIterable<WatchEvent>;\n}\n\nexport interface WtchOpts extends Omit<CmplOptions, 'fs'> {\n signal?: AbortSignal;\n fs?: WatchFs | Promise<WatchFs>;\n poll?: boolean | number;\n onError?: (err: unknown) => void;\n}\n\nexport async function* wtch({\n signal,\n entry,\n processors,\n poll = pllOptFromEnv(),\n onError = process.env.CI\n ? (err) => {\n throw err;\n }\n : (err) => console.log(err instanceof Error ? err.message : err),\n fs = import('node:fs/promises'),\n path = import('node:path'),\n}: WtchOpts) {\n const cmplOpts = {\n entry,\n fs,\n processors,\n path,\n };\n const { join, dirname } = await path;\n const { watch, stat, readFile } = await fs;\n\n let manifest: Record<string, string>[] | null = null;\n const exportManifest = () =>\n manifest!.length === 1\n ? Object.assign({}, manifest![0])\n : manifest!.map((m) => Object.assign({}, m));\n\n try {\n const m = await cmpl(cmplOpts);\n manifest = Array.isArray(m) ? m : [m];\n yield exportManifest();\n } catch (err) {\n onError(err);\n }\n\n const isDir = (await stat(entry)).isDirectory();\n const baseDir = isDir ? entry : dirname(entry);\n const prcssOpts = isDir\n ? cmplOpts\n : {\n ...cmplOpts,\n entry: baseDir,\n };\n\n const recursive = (await Promise.all(processors)).some(\n ({ recursive }) => recursive !== false,\n );\n\n const wtchOrPll = poll\n ? createPll({\n fs,\n path,\n interval: typeof poll === 'number' ? poll : undefined,\n })\n : watch;\n\n const queue = new AsyncQueue<WatchEvent>();\n\n // @ts-ignore\n signal?.addEventListener('abort', () => {\n queue.done(true);\n });\n\n async function startWatching() {\n for await (const event of wtchOrPll(entry, {\n recursive: isDir ? recursive : false,\n signal,\n })) {\n queue.push(event);\n }\n queue.done();\n }\n\n startWatching();\n\n for await (const event of queue) {\n try {\n if (!manifest) {\n const m = await cmpl(cmplOpts);\n manifest = Array.isArray(m) ? m : [m];\n yield exportManifest();\n } else {\n switch (event.eventType) {\n case 'rename': {\n const exists = manifest.some((m) => m[event.filename]);\n if (exists) {\n manifest.forEach((m) => {\n if (m[event.filename]) {\n delete m[event.filename];\n }\n });\n yield exportManifest();\n\n break;\n }\n }\n case 'change': {\n let relevantChange = false;\n const changeProcessors = await Promise.all(\n (\n await Promise.all(processors)\n ).map(async (p) => {\n const incl =\n p &&\n (!p.include ||\n (await p.include(event.filename, false, async () => {\n try {\n return await readFile(join(baseDir, event.filename));\n } catch (err) {\n if ((err as any)?.code === 'ENOENT') {\n return null;\n }\n throw err;\n }\n })))\n ? p\n : null;\n\n if (incl) {\n relevantChange = true;\n }\n return incl;\n }),\n );\n\n if (relevantChange) {\n (\n await prcss(\n join(baseDir, event.filename),\n prcssOpts,\n changeProcessors,\n )\n ).forEach((v, i) => {\n if (v !== null) {\n Object.assign(manifest![i], v);\n }\n });\n yield exportManifest();\n }\n break;\n }\n }\n }\n } catch (err) {\n onError(err);\n }\n }\n}\n\nfunction createPll({\n path,\n fs,\n interval = 300,\n}: Required<Pick<CmplOptions, 'path' | 'fs'>> & { interval?: number }) {\n return async function* pll(\n entry: string,\n opts: { recursive: boolean; signal?: AbortSignal },\n ): AsyncIterable<WatchEvent> {\n const { join, relative } = await path;\n const { readdir, stat } = await fs;\n const readDir = async (\n dir: string,\n state: Record<string, number> = {},\n ): Promise<Record<string, number>> => {\n await Promise.all(\n (\n await readdir(dir)\n ).map(async (entryName) => {\n const dirEntry = join(dir, entryName);\n const s = await stat(dirEntry);\n if (s.isDirectory() && opts.recursive) {\n await readDir(dirEntry, state);\n } else {\n state[relative(entry, dirEntry)] = s.mtimeMs;\n }\n }),\n );\n\n return state;\n };\n\n let state = await readDir(entry);\n\n while (!opts.signal?.aborted) {\n await new Promise((res) => setTimeout(res, interval));\n if (opts.signal?.aborted) {\n break;\n }\n const nextState = await readDir(entry);\n if (opts.signal?.aborted) {\n break;\n }\n\n const oldEntries = Object.entries(state);\n for (let i = 0, l = oldEntries.length; i < l; i++) {\n const [filename, mtime] = oldEntries[i];\n if (!nextState[filename]) {\n yield { eventType: 'rename', filename };\n } else if (nextState[filename] !== mtime) {\n yield { eventType: 'change', filename };\n }\n }\n\n const newEntires = Object.entries(state);\n for (let i = 0, l = newEntires.length; i < l; i++) {\n const [filename] = newEntires[i];\n if (!state[filename]) {\n yield { eventType: 'rename', filename };\n }\n }\n\n state = nextState;\n }\n };\n}\n\nfunction pllOptFromEnv() {\n if (!process.env.CMPL_USE_POLLING) {\n return false;\n }\n const n = parseInt(process.env.CMPL_USE_POLLING);\n if (!isNaN(n)) {\n return n;\n }\n return true;\n}\n\nfunction isRenamePrcssr(prcssr: Prcssr): prcssr is RenamePrcssr {\n return typeof (prcssr as any).transform !== 'function';\n}\n\nclass AsyncQueue<Value> {\n private queue: Array<Value> = [];\n private resolveNext: (() => void) | null = null;\n private isDone?: boolean | 'abort' = false;\n private onAbort?: (err: 'done') => void;\n\n public done(abort?: boolean): void {\n this.isDone = abort ? 'abort' : true;\n this.onAbort?.('done');\n }\n\n public push(value: Value): void {\n if (this.isDone) {\n throw new Error('Can not push to done queue');\n }\n this.queue.push(value);\n if (this.resolveNext) {\n this.resolveNext();\n }\n }\n\n private async pop(): Promise<Value> {\n if (this.queue.length === 0) {\n if (this.isDone) {\n throw 'done';\n }\n await new Promise<void>((resolve, reject) => {\n this.onAbort = reject;\n this.resolveNext = resolve;\n });\n this.onAbort = undefined;\n }\n\n const value = this.queue.shift()!;\n return value;\n }\n\n public [Symbol.asyncIterator](): AsyncIterator<Value> {\n return {\n next: async (): Promise<IteratorResult<Value>> => {\n try {\n if (this.isDone === 'abort') {\n throw 'done';\n }\n\n const value = await this.pop();\n return {\n value,\n done: false,\n };\n } catch (err) {\n if (err === 'done') {\n return { done: true, value: undefined };\n }\n throw err;\n }\n },\n };\n }\n}\n"],
"mappings": "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",
"names": []
}