diff --git a/.github/workflows/gh-repo-ci.yml b/.github/workflows/gh-repo-ci.yml index e293fb3..ec4e09d 100644 --- a/.github/workflows/gh-repo-ci.yml +++ b/.github/workflows/gh-repo-ci.yml @@ -5,8 +5,8 @@ on: branches: - main paths: - - "src/readme.md" - - "src/license.md" + - "readme.md" + - "license.md" permissions: contents: write @@ -18,18 +18,18 @@ jobs: - name: clone repo uses: actions/checkout@v3 - - name: copy readme.md - run: cp "src/readme.md" ".github/readme.md" + - name: copy "/readme.md" to "/src/readme.md" + run: cp "readme.md" "src/readme.md" - - name: copy license.md - run: cp "src/license.md" "license.md" + - name: copy "/license.md" to "/src/license.md" + run: cp "license.md" "src/license.md" - name: commit additions run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - git add --force ".github/readme.md" "license.md" + git add --force "src/readme.md" "src/license.md" git commit -m "update file via \"github-repo-ci.yml\"" git push - git rm --cached ".github/readme.md" "license.md" + git rm --cached "src/readme.md" "src/license.md" git push diff --git a/.gitignore b/.gitignore index 6344ebd..61f2eaf 100644 --- a/.gitignore +++ b/.gitignore @@ -12,5 +12,5 @@ /deno.d.ts # automatic file clones -/.github/readme.md -/license.md +/src/readme.md +/src/license.md diff --git a/build_dist.ts b/build_dist.ts index e8b85a6..a52bb3e 100644 --- a/build_dist.ts +++ b/build_dist.ts @@ -1,5 +1,4 @@ -import { ensureFile } from "https://deno.land/std@0.204.0/fs/mod.ts" -import { doubleCompileFiles } from "./build_tools.ts" +import { doubleCompileFiles, ensureFile } from "./build_tools.ts" /** use: diff --git a/build_docs.ts b/build_docs.ts index 0d24599..3d32b5e 100644 --- a/build_docs.ts +++ b/build_docs.ts @@ -1,7 +1,8 @@ -import { copy as copyFolder, ensureFile } from "https://deno.land/std@0.204.0/fs/mod.ts" -import { dirname as pathDirname, join as pathJoin } from "https://deno.land/std@0.204.0/path/mod.ts" -import { Application as typedocApp } from "npm:typedoc" -import { TemporaryFiles, createNPMFiles, doubleCompileFiles, getDenoJson, mainEntrypoint, subEntrypoints } from "./build_tools.ts" +import { Application as typedocApp } from "npm:typedoc@0.25.9" +import { + TemporaryFiles, copyDir, createNPMFiles, doubleCompileFiles, + ensureFile, getDenoJson, pathDirname, pathJoin, walkDir, +} from "./build_tools.ts" /** use: @@ -12,6 +13,10 @@ const site_root = Deno.args[0] ?? "/" const docs_output_dir = "./docs/" const docs_src_output_dir = "./docs/src/" const docs_dist_output_dir = "./docs/dist/" +const example_files_dir = "./examples/" +const extra_directories_to_copy: string[] = [ + // "./examples/assets/", +] interface CustomCSS_Artifacts extends TemporaryFiles { @@ -32,7 +37,8 @@ const createCustomCssFiles = async (base_dir: string = "./", content: string): P } const npm_file_artifacts = await createNPMFiles("./") -const { repository } = await getDenoJson() +const { repository, exports } = await getDenoJson() +const { ".": mainEntrypoint, ...subEntrypoints } = exports const custom_css_artifacts = await createCustomCssFiles("./temp/", ` table { border-collapse: collapse; } th { background-color: rgba(128, 128, 128, 0.50); } @@ -40,13 +46,15 @@ th, td { border: 0.1em solid rgba(0, 0, 0, 0.75); padding: 0.1em; } `) const custom_css_file_path = pathJoin(custom_css_artifacts.dir, custom_css_artifacts.files[0]) const typedoc_app = await typedocApp.bootstrapWithPlugins({ - entryPoints: [mainEntrypoint, ...subEntrypoints], + // even though the intermediate `package.json` created by `createNPMFiles` contains the `exports` field, `typedoc` can't figure out the entrypoints on its own. + entryPoints: [mainEntrypoint, ...Object.values(subEntrypoints)], out: docs_output_dir, - readme: "./src/readme.md", + readme: "./readme.md", navigationLinks: { "github": repository.url.replace("git+", "").replace(".git", ""), "readme": site_root, "source": site_root + "src/mod.ts", + "examples": site_root + "examples/index.html", "distribution": site_root + "dist/esm.js", }, skipErrorChecking: true, @@ -69,13 +77,13 @@ if (typedoc_project) { // copy the source code to the docs' "src" subdirectory, so that it can be hosted on github pages similar to a cdn // assuming `site_root` is the root url of the hosted site, `${site_root}/src/*.ts` will contain all of the source typescript files -await copyFolder("./src/", docs_src_output_dir, { overwrite: true }) +await copyDir("./src/", docs_src_output_dir, { overwrite: true }) // copy the compiled distribution files in the docs' "dist" sub directory, so that it can be hosted on github pages similar to a cdn // assuming `site_root` is the root url of the hosted site, `${site_root}/dist/*.js` will contain various bundled javascript distributions const - js_dist = (await doubleCompileFiles("./src/mod.ts", docs_dist_output_dir, {}, { minify: false }))[0], - js_dist_minified = (await doubleCompileFiles("./src/mod.ts", docs_dist_output_dir, {}, { minify: true }))[0] + js_dist = (await doubleCompileFiles("./src/mod.ts", docs_dist_output_dir, {}, { minify: false }, false))[0], + js_dist_minified = (await doubleCompileFiles("./src/mod.ts", docs_dist_output_dir, {}, { minify: true }, false))[0] js_dist.path = pathJoin(pathDirname(js_dist.path), "./esm.js") js_dist_minified.path = pathJoin(pathDirname(js_dist_minified.path), "./esm.min.js") const output_dist_files = [js_dist, js_dist_minified] @@ -86,5 +94,50 @@ await Promise.all(output_dist_files.map( } )) +// compile example files, and copy them over +const example_ts_files = [] +const example_html_files = [] +const example_misc_files = [] +for await (const { path } of walkDir(example_files_dir, { exts: ["index.ts", "index.tsx", ".html", ".css"], includeDirs: false })) { + if (path.endsWith(".ts") || path.endsWith(".tsx")) { example_ts_files.push(path) } + else if (path.endsWith(".html")) { example_html_files.push(path) } + else { example_misc_files.push(path) } +} +const example_ts_files_compiled = await doubleCompileFiles("", pathJoin(docs_output_dir, example_files_dir), + { + entryPoints: example_ts_files, + outbase: example_files_dir, + bundle: true, + splitting: true, + platform: "browser", + }, + { minify: true }, +) +console.log("writing the following transpiled files:", example_ts_files_compiled.map((out_file) => out_file.path)) +await Promise.all(example_ts_files_compiled.map( + async ({ text, path }, file_number) => { + await ensureFile(path) + await Deno.writeTextFile(path, text) + } +)) +await Promise.all(example_html_files.map( + async (path) => { + const text = await Deno.readTextFile(path) + const output_path = pathJoin(docs_output_dir, path) + await ensureFile(output_path) + await Deno.writeTextFile(output_path, text.replaceAll(/\.tsx?\"/gm, ".js\"")) + } +)) +await Promise.all(extra_directories_to_copy.map( + async (path) => { + await copyDir(path, pathJoin(docs_output_dir, path), { overwrite: true }) + } +)) +await Promise.all(example_misc_files.map( + async (path) => { + await copyDir(path, pathJoin(docs_output_dir, path), { overwrite: true }) + } +)) + await npm_file_artifacts.cleanup() await custom_css_artifacts.cleanup() diff --git a/build_npm.ts b/build_npm.ts index 837fb41..aa06fc1 100644 --- a/build_npm.ts +++ b/build_npm.ts @@ -1,13 +1,15 @@ -import { emptyDir } from "https://deno.land/std@0.204.0/fs/mod.ts" -import { basename as pathBasename, join as pathJoin } from "https://deno.land/std@0.204.0/path/mod.ts" -import { build } from "https://deno.land/x/dnt@0.38.1/mod.ts" -import { createPackageJson, createTSConfigJson, getDenoJson, mainEntrypoint, subEntrypoints } from "./build_tools.ts" +import { createPackageJson, createTSConfigJson, dntBuild, emptyDir, getDenoJson, pathJoin } from "./build_tools.ts" const npm_dir = "./npm/" const deno_json_dir = "./" -const deno_json = await getDenoJson(deno_json_dir) -const library_name = deno_json.name ?? "library" +const { + name: library_name = "library", + exports, + node_packageManager, +} = await getDenoJson(deno_json_dir) +const mainEntrypoint = exports["."] + const package_json = await createPackageJson(deno_json_dir, { scripts: { "build-dist": `npm run build-esm && npm run build-esm-minify && npm run build-iife && npm run build-iife-minify`, @@ -15,20 +17,21 @@ const package_json = await createPackageJson(deno_json_dir, { "build-esm-minify": `npx esbuild "${mainEntrypoint}" --bundle --minify --format=esm --outfile="./dist/${library_name}.esm.min.js"`, "build-iife": `npx esbuild "${mainEntrypoint}" --bundle --format=iife --outfile="./dist/${library_name}.iife.js"`, "build-iife-minify": `npx esbuild "${mainEntrypoint}" --bundle --minify --format=iife --outfile="./dist/${library_name}.iife.min.js"`, - } }) const tsconfig_json = await createTSConfigJson(deno_json_dir) +// we must delete the `exports` property, as it will override the correct version generated by `dntBuild`. +delete package_json["exports"] await emptyDir(npm_dir) -await build({ - entryPoints: [ - mainEntrypoint, - ...subEntrypoints.map(path => ({ name: "./" + pathBasename(path, ".ts"), path: path })), - ], +await dntBuild({ + entryPoints: Object.entries(exports).map(([export_path, source_path]) => ({ + name: export_path, + path: source_path, + })), outDir: npm_dir, - shims: { deno: true }, - packageManager: deno_json.node_packageManager, + shims: { deno: "dev" }, + packageManager: node_packageManager, package: { ...package_json }, @@ -38,28 +41,22 @@ await build({ esModule: true, scriptModule: false, test: false, - mappings: Object.fromEntries( - ["builtin_aliases_deps", "eightpack", "typedbuffer", "typedefs",].map((submodule_path) => { - return [ - "https://deno.land/x/kitchensink_ts@v0.7.3/" + submodule_path + ".ts", - { - name: "kitchensink_ts", - version: "^v0.7.3", - subPath: submodule_path, - } - ] - }) - ) + // override the test pattern, so that no tests are included, and no Deno.test shims are created for the entirety of the transpiled package. + // see the details here: "https://github.com/denoland/dnt?tab=readme-ov-file#test-file-matching" + testPattern: "TEST_NOTHING", + // TODO: there's no need for mapping, as jsr imports are converted into npm-compatible packages on the fly. + // however, I loose the ability to map it from my package's npm releases as a consequence. + // consider whether or not I'd like to have my dependencies as jsr imports or npm imports. + mappings: Object.fromEntries([]) }) // copy other files -Deno.copyFileSync("./src/readme.md", pathJoin(npm_dir, "./src/readme.md")) -Deno.copyFileSync("./src/readme.md", pathJoin(npm_dir, "readme.md")) -Deno.copyFileSync("./src/license.md", pathJoin(npm_dir, "license.md")) -Deno.copyFileSync("./.github/code_of_conduct.md", pathJoin(npm_dir, "code_of_conduct.md")) -Deno.writeTextFileSync(pathJoin(npm_dir, ".gitignore"), "/node_modules/\n") -Deno.writeTextFileSync(pathJoin(npm_dir, "tsconfig.json"), JSON.stringify(tsconfig_json)) -Deno.writeTextFileSync(pathJoin(npm_dir, ".npmignore"), ` +await Deno.copyFile("./readme.md", pathJoin(npm_dir, "readme.md")) +await Deno.copyFile("./license.md", pathJoin(npm_dir, "license.md")) +await Deno.copyFile("./.github/code_of_conduct.md", pathJoin(npm_dir, "code_of_conduct.md")) +await Deno.writeTextFile(pathJoin(npm_dir, ".gitignore"), "/node_modules/\n") +await Deno.writeTextFile(pathJoin(npm_dir, "tsconfig.json"), JSON.stringify(tsconfig_json)) +await Deno.writeTextFile(pathJoin(npm_dir, ".npmignore"), ` code_of_conduct.md dist/ docs/ diff --git a/build_tools.ts b/build_tools.ts index ee406cf..9252e37 100644 --- a/build_tools.ts +++ b/build_tools.ts @@ -1,32 +1,24 @@ /** some build specific utility functions */ -import { ensureDir } from "https://deno.land/std@0.204.0/fs/mod.ts" -import { join as pathJoin } from "https://deno.land/std@0.204.0/path/mod.ts" -import { BuildOptions, PackageJson } from "https://deno.land/x/dnt@0.38.1/mod.ts" +export type { + BuildOptions as ESBuildOptions, + OutputFile as ESOutputFile, + TransformOptions as ESTransformOptions +} from "https://deno.land/x/esbuild@v0.20.1/mod.js" +export { build as dntBuild } from "jsr:@deno/dnt@0.41.0" +export { copy as copyDir, emptyDir, ensureDir, ensureFile, walk as walkDir } from "jsr:@std/fs@0.218.2" +export { dirname as pathDirname, join as pathJoin, relative as relativePath } from "jsr:@std/path@0.218.2" import { BuildOptions as ESBuildOptions, OutputFile as ESOutputFile, TransformOptions as ESTransformOptions, build as esbuild, stop as esstop, transform as estransform -} from "https://deno.land/x/esbuild@v0.17.19/mod.js" -import { denoPlugins } from "https://deno.land/x/esbuild_deno_loader@0.8.1/mod.ts" -export { ensureDir, ensureFile, walk as walkDir } from "https://deno.land/std@0.204.0/fs/mod.ts" -export { join as pathJoin, relative as relativePath } from "https://deno.land/std@0.204.0/path/mod.ts" -export { stop as esstop } from "https://deno.land/x/esbuild@v0.17.19/mod.js" -export type { - BuildOptions as ESBuildOptions, - OutputFile as ESOutputFile, - TransformOptions as ESTransformOptions -} from "https://deno.land/x/esbuild@v0.17.19/mod.js" +} from "https://deno.land/x/esbuild@v0.20.1/mod.js" +import { BuildOptions, PackageJson } from "jsr:@deno/dnt@0.41.0" +import { denoPlugins } from "jsr:@luca/esbuild-deno-loader@0.9.0" +import { ensureDir } from "jsr:@std/fs@0.218.2" +import { join as pathJoin } from "jsr:@std/path@0.218.2" -export const mainEntrypoint: string = "./src/mod.ts" -export const subEntrypoints: string[] = [ - "./src/binary_composition_steps.ts", - "./src/binary_conditional_steps.ts", - "./src/binary_primitive_steps.ts", - "./src/typedefs.ts", -] - export interface LeftoverArtifacts { cleanup: () => Promise } @@ -40,18 +32,25 @@ interface NPM_Artifacts extends TemporaryFiles { files: ["package.json", "tsconfig.json"] } -let deno_json: { [key: string]: any } +const get_deno_json = async () => { return (await import("./deno.json", { with: { type: "json" } })).default } +const add_leading_relative_path_slash = (path: string) => path.startsWith("./") ? path : "./" + path +let deno_json: ReturnType export const getDenoJson = async (base_dir: string = "./") => { - deno_json ??= JSON.parse(await Deno.readTextFile(pathJoin(base_dir, "./deno.json"))) + deno_json ??= (await import( + add_leading_relative_path_slash(pathJoin(base_dir, "./deno.json")), + { with: { type: "json" } }) + ).default return deno_json } export const createPackageJson = async (deno_json_dir: string = "./", overrides: Partial = {}): Promise => { - const { name, version, description, author, license, repository, bugs, devDependencies } = await getDenoJson(deno_json_dir) + const { name, version, description, author, license, repository, bugs, exports, package_json } = await getDenoJson(deno_json_dir) + // note that if you use dnt (deno-to-node), then you will have to delete the `exports` property, otherwise it will ruin the output. return { name: name ?? "", version: version ?? "0.0.0", - description, author, license, repository, bugs, devDependencies, + description, author, license, repository, bugs, exports, + ...package_json, ...overrides } } @@ -59,7 +58,7 @@ export const createPackageJson = async (deno_json_dir: string = "./", overrides: export const createTSConfigJson = async (deno_json_dir: string = "./", overrides: Partial<{ compilerOptions: BuildOptions["compilerOptions"] }> = {}): Promise<{ "$schema": string, compilerOptions: BuildOptions["compilerOptions"] }> => { const { compilerOptions } = await getDenoJson(deno_json_dir) // remove "deno.ns" from compiler options, as it breaks `dnt` (I think) - compilerOptions.lib = (compilerOptions.lib as string[]).filter((v) => v.toLowerCase() !== "deno.ns") + compilerOptions.lib = (compilerOptions.lib).filter((v) => v.toLowerCase() !== "deno.ns") Object.assign(compilerOptions, { target: "ESNext", @@ -74,7 +73,7 @@ export const createTSConfigJson = async (deno_json_dir: string = "./", overrides "$schema": "https://json.schemastore.org/tsconfig", ...overrides, compilerOptions, - } + } as any } export const createNPMFiles = async ( @@ -136,7 +135,7 @@ export const doubleCompileFiles = async ( }) const bundled_files = await Promise.all(bundled_code.outputFiles.map( - async ({ text, path }, file_number): Promise => { + async ({ text, path, hash }, file_number): Promise => { const js_text = (await estransform(text, { minify: true, @@ -149,6 +148,7 @@ export const doubleCompileFiles = async ( console.log("bundled file", file_number, "\n\t", "output path:", path, "\n\t", "binary size:", js_text_uint8.byteLength / 1024, "kb") return { path, + hash, text: js_text, contents: js_text_uint8 } diff --git a/deno.json b/deno.json index 5502de9..ad1c867 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { - "name": "fbicodec_ts", - "version": "0.1.1", + "name": "@oazmi/fbicodec", + "version": "0.1.2", "description": "Forward-Backward-Interfaced general purpose invertible codec library", "author": "Omar Azmi", "license": "Anti-Competition License", @@ -11,6 +11,39 @@ "bugs": { "url": "https://github.com/omar-azmi/fbicodec_ts/issues" }, + "exports": { + ".": "./src/mod.ts", + "./binary_composition_steps": "./src/binary_composition_steps.ts", + "./binary_conditional_steps": "./src/binary_conditional_steps.ts", + "./binary_primitive_steps": "./src/binary_primitive_steps.ts", + "./typedefs": "./src/typedefs.ts" + }, + "publish": { + "exclude": [ + "./.vscode/", + "./.github/", + "./examples/", + "./test/", + "./build*.ts", + "./clean.ts" + ] + }, + "test": { + "include": [ + "./test/", + "./src/mod.ts" + ] + }, + "fmt": { + "useTabs": true, + "semiColons": false, + "singleQuote": false, + "lineWidth": 800, + "proseWrap": "never", + "include": [ + "./src/" + ] + }, "compilerOptions": { "lib": [ "esnext", @@ -20,9 +53,17 @@ "strict": true, "allowJs": true }, - "devDependencies": { - "typescript": "^5.0.0", - "esbuild": "^0.17.19" + "package_json": { + "dependencies": {}, + "devDependencies": { + "typescript": "^5.0.0", + "esbuild": "^0.20.1" + }, + "keywords": [ + "utility", + "modular", + "typescript" + ] }, "node_packageManager": "npm", "tasks": { @@ -32,6 +73,7 @@ "build-npm-dist": "cd \"./npm/\" && npm run build-dist", "build-examples": "deno run -A ./build_dist.ts \"./examples/png_parser.ts\" && deno run -A ./build_dist.ts \"./examples/tar_parser.ts\" && deno run -A ./build_dist.ts \"./examples/ogg_parser.ts\"", "clean": "deno run -A ./clean.ts", - "test": "deno test -A ./src/mod.ts && deno test -A ./test/" + "test": "deno test -A", + "publish-jsr": "deno publish --allow-slow-types" } } diff --git a/examples/ogg_page_parser.ts b/examples/ogg_page_parser.ts index d77dce2..9d2181e 100644 --- a/examples/ogg_page_parser.ts +++ b/examples/ogg_page_parser.ts @@ -1,4 +1,4 @@ -import { sum } from "https://deno.land/x/kitchensink_ts@v0.7.3/numericmethods.ts" +import { sum } from "jsr:@oazmi/kitchensink@0.7.5/numericmethods" import { BinaryArrayStep, BinaryHeaderLengthedStep, BinaryRecordStep } from "../src/binary_composition_steps.ts" import { BinaryBytesStep, BinaryDefaultArgs, BinaryNumberArrayStep, BinaryNumberStep, BinaryStringStep } from "../src/binary_primitive_steps.ts" import { BinaryInput, BinaryOutput, PureStep } from "../src/typedefs.ts" diff --git a/examples/ogg_parser.ts b/examples/ogg_parser.ts index d3a2ca8..28b7dab 100644 --- a/examples/ogg_parser.ts +++ b/examples/ogg_parser.ts @@ -1,4 +1,4 @@ -import { FileParser } from "https://deno.land/x/kitchensink_ts@v0.7.3/devdebug.ts" +import { FileParser } from "jsr:@oazmi/kitchensink@0.7.5/devdebug" import { AllOggPages, AllStreamPages } from "./ogg_page_parser.ts" import { OpusStream, Opus_type } from "./ogg_stream_parsers.ts" diff --git a/examples/ogg_stream_parsers.ts b/examples/ogg_stream_parsers.ts index e8f0da9..35dd81e 100644 --- a/examples/ogg_stream_parsers.ts +++ b/examples/ogg_stream_parsers.ts @@ -1,4 +1,4 @@ -import { concatBytes } from "https://deno.land/x/kitchensink_ts@v0.7.3/typedbuffer.ts" +import { concatBytes } from "jsr:@oazmi/kitchensink@0.7.5/typedbuffer" import { BinaryArrayStep, BinaryHeaderLengthedStep, BinaryRecordStep } from "../src/binary_composition_steps.ts" import { BinaryDefaultArgs, BinaryNumberArrayStep, BinaryNumberStep, BinaryStringStep } from "../src/binary_primitive_steps.ts" import { BinaryInput, BinaryOutput, LengthedArgs, PureStep } from "../src/typedefs.ts" diff --git a/examples/png_parser.ts b/examples/png_parser.ts index fb4b5ec..c1a104e 100644 --- a/examples/png_parser.ts +++ b/examples/png_parser.ts @@ -1,5 +1,5 @@ -import { Crc32 } from "https://deno.land/x/kitchensink_ts@v0.7.3/crypto.ts" -import { FileParser } from "https://deno.land/x/kitchensink_ts@v0.7.3/devdebug.ts" +import { Crc32 } from "jsr:@oazmi/kitchensink@0.7.5/crypto" +import { FileParser } from "jsr:@oazmi/kitchensink@0.7.5/devdebug" import { ArrayArgs, BinaryArrayStep, BinaryRecordStep } from "../src/binary_composition_steps.ts" import { BinaryBytesStep, BinaryDefaultArgs, BinaryNumberStep, BinaryStringStep } from "../src/binary_primitive_steps.ts" import { concatBytes } from "../src/deps.ts" diff --git a/examples/tar_parser.ts b/examples/tar_parser.ts index 3502981..ef1b17c 100644 --- a/examples/tar_parser.ts +++ b/examples/tar_parser.ts @@ -1,4 +1,4 @@ -import { FileParser } from "https://deno.land/x/kitchensink_ts@v0.7.3/devdebug.ts" +import { FileParser } from "jsr:@oazmi/kitchensink@0.7.5/devdebug" import { BinaryArrayStep, BinaryRecordStep, SequentialSteps } from "../src/binary_composition_steps.ts" import { BinaryBytesStep, BinaryDefaultArgs, BinaryInputWrapStep, BinaryOutputUnwrapStep, BinaryStringStep } from "../src/binary_primitive_steps.ts" import { concatBytes, math_ceil } from "../src/deps.ts" diff --git a/.github/readme.md b/readme.md similarity index 100% rename from .github/readme.md rename to readme.md diff --git a/src/deps.ts b/src/deps.ts index ecbfd5b..3b89dba 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -1,7 +1,7 @@ -export * from "https://deno.land/x/kitchensink_ts@v0.7.3/builtin_aliases_deps.ts" -export * from "https://deno.land/x/kitchensink_ts@v0.7.3/eightpack.ts" -export { concatBytes, concatTyped } from "https://deno.land/x/kitchensink_ts@v0.7.3/typedbuffer.ts" -export type * from "https://deno.land/x/kitchensink_ts@v0.7.3/typedefs.ts" +export * from "jsr:@oazmi/kitchensink@0.7.5/builtin_aliases_deps" +export * from "jsr:@oazmi/kitchensink@0.7.5/eightpack" +export { concatBytes, concatTyped } from "jsr:@oazmi/kitchensink@0.7.5/typedbuffer" +export type * from "jsr:@oazmi/kitchensink@0.7.5/typedefs" export const enum DEBUG { @@ -11,12 +11,6 @@ export const enum DEBUG { MINIFY = 1, } -// TODO: add these to `kitchensink_ts/builtin_aliases_deps.ts` . I am tired of redefining it in half of my repos -export const { - isFinite: number_isFinite, - parseInt: number_parseInt, -} = Number - export const { ceil: math_ceil, } = Math diff --git a/src/license.md b/src/license.md deleted file mode 100644 index 97c2d96..0000000 --- a/src/license.md +++ /dev/null @@ -1,32 +0,0 @@ -# Anti-Competition License - -Copyright (c) [2024] [Omar Azmi] - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -4. The software may be used in open source and closed source projects. -If used in a closed source project, the project must provide attribution to this software. - -5. Redistributions of this software in any form must not be used in the development, training, or operation of an Artificial Intelligence system. - -6. The software or its derivatives must not be used in any form of crawling or caching that is not directly related to code archiving. - -7. No portion of this software may be copied or used in another codebase without proper attribution to the original work. - -8. Derivative works that directly compete with the original software are not permitted. -Major enhancements or modifications should ideally be contributed back to the original software's development. -This is to prevent the intent of diverting existing or potential users away from the original work. - -9. Redistribution for the sole purpose of competing with the original software is not permitted. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/readme.md b/src/readme.md deleted file mode 100644 index 6e274b3..0000000 --- a/src/readme.md +++ /dev/null @@ -1,80 +0,0 @@ -# FBIcodec - -FBIcodec is so cleanly invertible, it's the last thing the FBI would investigate! - -This is a typescript library for building bidirectional (encoding and decoding) codecs using composable steps. -The "FBI" part in the name stands for "Forward-Backward-Interfaced", and Codec stands for an invertible data transformation. - -The main building block of the library is its general purpose `Step` interface, which ensures the ability for a forward transformation to be reversed. -The forward and backward methods take a single argument, allowing Steps to be composed into more complex Codecs. - - -### Features - -- Composable steps for encoding and decoding binary data -- Steps for primitive types like numbers, strings, bytes -- Steps for composing records, arrays, sequences -- Invertible - encoding and decoding are symmetric -- Type safe - - -### Overview - -The main abstractions are: -- `Step` - encodes `forward` and decodes `backward` between a source and target type. -- `Binarystep` - a `Step` for encoding/decoding binary data. - -To work with binary data of primitive types, such as: numbers, strings, bytes etc..., you can use the the `BinaryPureStep`s inside the file [`binary_primitive_steps.ts`](/src/binary_primitive_steps.ts). -- `BinaryNumberStep` - supports signed/unsigned integers of 8, 16, 32 and 64 bits, and floats of 32 and 64 bits, in both little-endian and big-endian formats. -- `BinaryStringStep` - for strings with varying lengths (based on the `args.length` parameter). -- `BinaryCStringStep` - for NUL (`"\x00"`) terminated strings. -- `BinaryBytesStep` - for sequence of bytes (based on the `args.length` parameter). -- `BinaryNumberArrayStep` - for numeric array of numbers (based on the `args.length` parameter). - -To work with binary data of composite types, such as: records, arrays, sequences etc..., you can use the the `BinaryPureStep`s inside the file [`binary_composition_steps`](/src/binary_composition_steps.ts). -- `BinaryRecordStep` - encodes a record with named fields, when provided with a sequence of `Steps` for each field. -- `BinaryArrayStep` - encodes an array of items, when provided with a single `Step` for the item type. -- `SequentialSteps` - chains multiple `Step`s. - - -For example, here is a step that decode and then repack PNG image file's metadata blocks: -```ts -class PNG_Codec_Step extends PureStep { - forward(input: Uint8Array): GeneralChunk_schema[] { - // parse input into chunks - } - backward(input: GeneralChunk_schema[]): Uint8Array { - // encode chunks into binary - } -} -``` - - -## Theory - -The key components that enable building robust bidirectional transformations are: - -- `Step` - - Defines symmetric forward and backward methods between source `FROM` and target `TO` types. - Any lost information should be stored in the `LOST` private property. - -- `PureStep extends Step` - - This is a `Step` that is guaranteed to not lose information during forward transformation, allowing backward transformation to fully reconstruct the original value. -It also means that one may reuse a single instance of this kind of step for multiple forward and backward transformations, in whatever order it is deemed convenient. -Hence, these kind of steps are suitable for being applied repeatdly by larger compositional steps. - -- `BinaryStep extends Step<{ bin: Uint8Array, pos: number, args: ARGS }, { val: OUT, len: number }, LOST>` - - A step that specialized for parsing binary data. -backward encodes the wrapped `OUT` value back into a wrapped `Uint8Array` object. - -- `BinaryPureStep extends PureStep<{ bin: Uint8Array, pos: number, args: ARGS }>` - - Similar to `BinaryStep`, but is guaranteed not to lose data during forward transformation. -This is the class that is basically used by all implementations of `BinaryStep`s. - - -These simple interfaces allow `Step`s to be composed in a type-safe way. - -Moreover, the compositions form a tree structure that preserves invertibility - as long as each `Step` inside implements their `forward` and `backward` methods correctly, the entire composition will be robustly reversible. - -It also makes diagnosing issues easier - if there is a decoding error, it must be within one of the composed Steps. -The composition tree narrows down where the issue lies.