diff --git a/.dockerignore b/.dockerignore
index e391b818..f4d2b6d0 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -7,11 +7,6 @@ _etc/
.gitignore
.pre-commit-config.yaml
.tool-versions
-CODE_OF_CONDUCT.md
-CONTRIBUTING.md
Dockerfile
LICENSE
-pre-commit.ts
README.md
-SECURITY.md
-version.txt
diff --git a/.github/ARCHITECTURE.md b/.github/ARCHITECTURE.md
new file mode 100644
index 00000000..bf255689
--- /dev/null
+++ b/.github/ARCHITECTURE.md
@@ -0,0 +1,5 @@
+# Architecture Guide
+
+This guide aims to explain how this codebase is organized.
+
+## File Structure
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000..c3f98d63
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+* @eser
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..9fae8aa8
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,4 @@
+# Code of Conduct
+
+See [@eser/directives](./pkg/directives/README.md) for our sets of rules and
+recommendations we follow.
diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md
similarity index 88%
rename from CONTRIBUTING.md
rename to .github/CONTRIBUTING.md
index 84ba9dd3..fe383658 100644
--- a/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -12,9 +12,9 @@ in a pull request.
### Code of Conduct
This project and everyone participating in it is governed by the
-[cool/directives](directives/README.md). By participating, you are expected to
-uphold this code. Please report unacceptable behavior as in specified in the
-link.
+[@eser/directives](./pkg/directives/README.md). By participating, you are
+expected to uphold this code. Please report unacceptable behavior as in
+specified in the link.
### Technical Requirements
@@ -53,7 +53,7 @@ from:
## Submitting a Pull Request
-- Adhere to [cool/directives](directives/README.md)
+- Adhere to [@eser/directives](./pkg/directives/README.md)
- Fork the repo
- Make your changes in a new branch
- Provide tests for your changes, particularly for new features or fixes
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index b4956819..686805d2 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,10 +1,9 @@
---
name: Bug report
about: Create a report to help us improve
-title: Bug report
-labels: bug
+title: ''
+labels: bug, needs triage
assignees: ''
-
---
**Describe the bug**\
@@ -24,18 +23,11 @@ A clear and concise description of what you expected to happen.
**Screenshots**\
If applicable, add screenshots to help explain your problem.
-**Desktop (please complete the following information):**
-
-- OS: [e.g. iOS]
-- Browser [e.g. chrome, safari]
-- Version [e.g. 22]
-
-**Smartphone (please complete the following information):**
+**Environment (please complete the following information):**
-- Device: [e.g. iPhone6]
-- OS: [e.g. iOS8.1]
-- Browser [e.g. stock browser, safari]
-- Version [e.g. 22]
+- OS: [e.g. Ubuntu 20.04, MacOS 11]
+- Deno Version:
+- Cool Version:
**Additional context**\
Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 0a449ce7..5009c32d 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -4,7 +4,6 @@ about: Suggest an idea or voice a concern
title: 'Feature request: '
labels: enhancement
assignees: ''
-
---
**Is your feature request related to a problem? Please describe.**\
diff --git a/SECURITY.md b/.github/SECURITY.md
similarity index 100%
rename from SECURITY.md
rename to .github/SECURITY.md
diff --git a/typos.toml b/.github/typos.toml
similarity index 100%
rename from typos.toml
rename to .github/typos.toml
diff --git a/.gitignore b/.gitignore
index 9347de2d..a0d61828 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,9 +15,6 @@ Thumbs.db
.env.local
.env.*.local
-# tool outputs
-*.tsbuildinfo
-
# sensitive files
*.key
*.pem
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a32873cc..85ead5a7 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,12 +1,12 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.5.0
+ rev: v4.6.0
hooks:
- id: check-added-large-files
args: ["--maxkb=1024"]
exclude: |
(?x)^(
- bundler/esbuild_v0.20.0.wasm
+ pkg/bundler/esbuild_v0.20.0.wasm
)$
- id: check-case-conflict
- id: check-executables-have-shebangs
@@ -29,18 +29,19 @@ repos:
args: ["--autofix", "--no-ensure-ascii", "--no-sort-keys"]
- id: trailing-whitespace
- repo: https://github.com/crate-ci/typos
- rev: v1.16.23
+ rev: v1.23.2
hooks:
- id: typos
verbose: true
- args: [
- ]
+ args:
+ - "--config"
+ - ".github/typos.toml"
exclude: |
(?x)^(
- docs/.*
+ docs/.*|
)$
- repo: https://github.com/compilerla/conventional-pre-commit
- rev: v3.0.0
+ rev: v3.3.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
@@ -50,7 +51,7 @@ repos:
- id: local-precommit
name: local pre-commit tasks
description: Runs local pre-commit tasks.
- entry: bash -c 'deno run -A pre-commit.ts; git add -u' --
+ entry: bash -c 'deno task script:validate-configs; git add -u' --
always_run: true
pass_filenames: false
language: system
@@ -62,36 +63,29 @@ repos:
exclude: |
(?x)^(
_etc/.*|
- .github/FUNDING.yml|
- .github/ISSUE_TEMPLATE/bug_report.md|
- .github/ISSUE_TEMPLATE/feature_request.md|
- .github/PULL_REQUEST_TEMPLATE.md|
+ .github/.*|
.git/COMMIT_EDITMSG|
- appserver/README.md|
- bundler/README.md|
- bundler/esbuild_v0.20.0.wasm|
- collector/README.md|
- di/README.md|
- directives/README.md|
docs/.*|
- dotenv/README.md|
- events/README.md|
- file-loader/README.md|
- fp/README.md|
- functions/README.md|
- jsx-runtime/README.md|
- jsx-runtime.test/README.md|
- lime/README.md|
- lime.test/README.md|
- parsing/README.md|
- standards/README.md|
- CODEOWNERS|
- CODE_OF_CONDUCT.md|
- CONTRIBUTING.md|
+ pkg/app-runtime/README.md|
+ pkg/bundler/README.md|
+ pkg/bundler/esbuild_v0.20.0.wasm|
+ pkg/collector/README.md|
+ pkg/config/README.md|
+ pkg/di/README.md|
+ pkg/directives/README.md|
+ pkg/dotenv/README.md|
+ pkg/events/README.md|
+ pkg/fp/README.md|
+ pkg/functions/README.md|
+ pkg/jsx-runtime/README.md|
+ pkg/jsx-runtime.test/README.md|
+ pkg/lime/README.md|
+ pkg/lime.test/README.md|
+ pkg/parsing/README.md|
+ pkg/standards/README.md|
Dockerfile|
LICENSE|
- README.md|
- SECURITY.md
+ README.md
)$
- id: check-integrity
name: check integrity
diff --git a/.tool-versions b/.tool-versions
index 265c7b2c..9193924e 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1,2 +1,2 @@
-deno 1.41.3
-pre-commit 3.6.2
+deno 1.45.1
+pre-commit 3.7.1
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index cc790eeb..00000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Code of Conduct
-
-See [cool/directives](directives/README.md) for our sets of rules and
-recommendations we follow.
diff --git a/Dockerfile b/Dockerfile
index 65992b4e..8701e046 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,7 +14,7 @@ COPY deps.ts .
RUN deno cache deps.ts
# These steps will be re-run upon each file change in your working directory:
-COPY ./ ./
+COPY ./pkg/ ./
# Compile the main app so that it doesn't need to be compiled each startup/entry.
RUN deno cache mod.ts
diff --git a/README.md b/README.md
index ab511fb3..1199ec02 100644
--- a/README.md
+++ b/README.md
@@ -61,14 +61,14 @@ strives to offer you an intuitive and delightful development experience.
### Component Set
-| Component | Area | Description |
-| --------------------------------- | ----------------- | --------------------------------------------------- |
-| 📓 [cool/directives](directives/) | Rules | The ground rules adhered to by the entire ecosystem |
-| 📑 [cool/standards](standards/) | Abstraction | Provides common abstraction layers for DI |
-| ⚙️ [cool/di](di/) | Manager | Dependency injection system |
-| 🧱 [cool/fp](fp/) | Functions Library | Tools for functional programming |
-| 🔐 [cool/dotenv](dotenv/) | Manager | Load configurations from environment |
-| 〰️ [cool/parsing](parsing/) | Manager | Parsing tools for various strings and streams |
+| Component | Area | Description |
+| -------------------------------------- | ----------------- | --------------------------------------------------- |
+| 📓 [@eser/directives](pkg/directives/) | Rules | The ground rules adhered to by the entire ecosystem |
+| 📑 [@eser/standards](pkg/standards/) | Abstraction | Provides common abstraction layers for DI |
+| ⚙️ [@eser/di](pkg/di/) | Manager | Dependency injection system |
+| 🧱 [@eser/fp](pkg/fp/) | Functions Library | Tools for functional programming |
+| 🔐 [@eser/dotenv](pkg/dotenv/) | Manager | Load configurations from environment |
+| 〰️ [@eser/parsing](pkg/parsing/) | Manager | Parsing tools for various strings and streams |
Visit the respective component page for detailed usage instructions.
@@ -78,7 +78,7 @@ We strive to run the following code seamlessly across
[all platforms we support](#platform-support):
```js
-import { Runtime, Context } from "$cool/runtime/mod.ts";
+import { Runtime, Context } from "@eser/runtime";
const home = (ctx: Context) => {
return ctx.results.jsx(
Hello there!
);
@@ -159,7 +159,7 @@ done.
If you're going to report a bug or request a new feature, please ensure first
that you comply with the conditions found under
-[cool/directives](https://github.com/eser/cool/blob/dev/directives/README.md).
+[@eser/directives](https://github.com/eser/cool/blob/dev/pkg/directives/README.md).
After that, you can report an issue or request using
[GitHub Issues](https://github.com/eser/cool/issues). Thanks in advance.
diff --git a/_etc/tasks/check-license.ts b/_etc/tasks/check-license.ts
deleted file mode 100644
index a74fa5b0..00000000
--- a/_etc/tasks/check-license.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-// Copied from $std/_tools/check_license.ts
-
-import * as runtime from "../../standards/runtime.ts";
-import { walk } from "./deps.ts";
-
-const EXTENSIONS = ["*.js", ".ts", "*.jsx", ".tsx"];
-
-const ROOT = new URL("../../", import.meta.url);
-const CHECK = runtime.current.getArgs().includes("--check");
-const BASE_YEAR = "2023";
-// const CURRENT_YEAR = new Date().getFullYear();
-const RX_COPYRIGHT = new RegExp(
- `// Copyright ([0-9]{4})-present Eser Ozvataf and other contributors\\. All rights reserved\\. ([0-9A-Za-z-.]+) license\\.\n`,
-);
-const COPYRIGHT =
- `// Copyright ${BASE_YEAR}-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.`;
-
-let failed = false;
-
-for await (
- const entry of walk.walk(ROOT, {
- exts: EXTENSIONS,
- skip: [
- /_etc\/coverage\/*$/,
- /_etc\/temp\/*$/,
- /_etc\/templates\/*$/,
- /manifest\.gen\.ts$/,
- ],
- includeDirs: false,
- })
-) {
- const content = await runtime.current.readTextFile(entry.path);
- const match = content.match(RX_COPYRIGHT);
-
- if (!match) {
- if (CHECK) {
- console.error(`Missing copyright header: ${entry.path}`);
- failed = true;
- } else {
- const contentWithCopyright = COPYRIGHT + "\n" + content;
- await runtime.current.writeTextFile(entry.path, contentWithCopyright);
- console.log("Copyright header automatically added to " + entry.path);
- }
- } else if (match[1] !== BASE_YEAR) {
- if (CHECK) {
- console.error(`Incorrect copyright year: ${entry.path}`);
- failed = true;
- } else {
- const index = match.index ?? 0;
- const contentWithoutCopyright = content.replace(match[0], "");
- const contentWithCopyright = contentWithoutCopyright.substring(0, index) +
- COPYRIGHT + "\n" + contentWithoutCopyright.substring(index);
- await runtime.current.writeTextFile(entry.path, contentWithCopyright);
- console.log("Copyright header automatically updated in " + entry.path);
- }
- }
-}
-
-if (failed) {
- console.info(`Copyright header should be "${COPYRIGHT}"`);
- runtime.current.exit(1);
-}
diff --git a/_etc/tasks/deps.ts b/_etc/tasks/deps.ts
deleted file mode 100644
index 03922a43..00000000
--- a/_etc/tasks/deps.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as walk from "jsr:@std/fs@0.220/walk";
diff --git a/appserver/appserver.ts b/appserver/appserver.ts
deleted file mode 100644
index 42e51796..00000000
--- a/appserver/appserver.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import * as runModes from "../standards/run-modes.ts";
-import { events } from "../events/events.ts";
-import { di } from "../di/services.ts";
-
-import { type Channel } from "./channel.ts";
-import { type Module } from "./module.ts";
-
-export class AppServer {
- static default = Symbol("default");
-
- runMode: runModes.RunMode;
- events: typeof events;
- di: typeof di;
- channels: Map;
- modules: Map;
- // deno-lint-ignore no-explicit-any
- awaits: Array> = [];
-
- constructor() {
- this.runMode = runModes.RunModes.NotSet;
- this.events = events;
- this.di = di;
- this.channels = new Map();
- this.modules = new Map();
- }
-
- addModule(module: Module) {
- const name = module.name ?? module.constructor.name;
-
- this.modules.set(name, module);
- }
-
- addChannel(channel: Channel) {
- const name = channel.name ?? channel.constructor.name;
-
- this.channels.set(name, channel);
- }
-
- setAsDefaultAppServer() {
- this.di.set(AppServer.default, this);
- }
-
- async awaitAll() {
- await Promise.all(this.awaits);
- this.awaits.splice(0);
- }
-
- // execute(_options: unknown) {
- // }
-}
diff --git a/bundler/aot-snapshot.ts b/bundler/aot-snapshot.ts
deleted file mode 100644
index 32e024f8..00000000
--- a/bundler/aot-snapshot.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import * as runtime from "../standards/runtime.ts";
-import { colors, path } from "./deps.ts";
-import { type BuildSnapshot, type BuildSnapshotJson } from "./mod.ts";
-import { setBuildId } from "./build-id.ts";
-
-export class AotSnapshot implements BuildSnapshot {
- #files: Map;
- #dependencies: Map>;
-
- constructor(
- files: Map,
- dependencies: Map>,
- ) {
- this.#files = files;
- this.#dependencies = dependencies;
- }
-
- get paths(): Array {
- return Array.from(this.#files.keys());
- }
-
- async read(pathStr: string): Promise | null> {
- const filePath = this.#files.get(pathStr);
- if (filePath !== undefined) {
- try {
- const file = await runtime.current.open(filePath, { read: true });
- return file.readable;
- } catch (_err) {
- return null;
- }
- }
-
- // Handler will turn this into a 404
- return null;
- }
-
- dependencies(pathStr: string): Array {
- return this.#dependencies.get(pathStr) ?? [];
- }
-}
-
-export async function loadAotSnapshot(
- snapshotDirPath: string,
-): Promise {
- try {
- if ((await runtime.current.stat(snapshotDirPath)).isDirectory) {
- console.log(
- `Using snapshot found at ${colors.cyan(snapshotDirPath)}`,
- );
-
- const snapshotPath = path.join(snapshotDirPath, "snapshot.json");
- const json = JSON.parse(
- await runtime.current.readTextFile(snapshotPath),
- ) as BuildSnapshotJson;
- setBuildId(json.build_id);
-
- const dependencies = new Map>(
- Object.entries(json.files),
- );
-
- const files = new Map();
- Object.keys(json.files).forEach((name) => {
- const filePath = path.join(snapshotDirPath, name);
- files.set(name, filePath);
- });
-
- return new AotSnapshot(files, dependencies);
- }
- return null;
- } catch (err) {
- if (!(err instanceof runtime.current.errors.NotFound)) {
- throw err;
- }
-
- return null;
- }
-}
diff --git a/bundler/deps.ts b/bundler/deps.ts
deleted file mode 100644
index 21a64e6f..00000000
--- a/bundler/deps.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as colors from "jsr:@std/fmt@0.220/colors";
-export * as hex from "jsr:@std/encoding@0.220/hex";
-export * as path from "jsr:@std/path@0.220";
-export * as regexpEscape from "jsr:@std/regexp@0.220/escape";
-
-export * as esbuild from "npm:esbuild@0.20";
-// Import the WASM build on platforms where running subprocesses is not
-// permitted, such as Deno Deploy, or when running without `--allow-run`.
-// export * as esbuild from "npm:esbuild-wasm@0.20";
-
-export { denoPlugins as esbuildDenoPlugins } from "jsr:@luca/esbuild-deno-loader@0.10";
diff --git a/collector/deps-dev.ts b/collector/deps-dev.ts
deleted file mode 100644
index 1e79ac74..00000000
--- a/collector/deps-dev.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as assert from "jsr:@std/assert@0.220";
-export * as bdd from "jsr:@std/testing@0.220/bdd";
diff --git a/collector/deps.ts b/collector/deps.ts
deleted file mode 100644
index 61203922..00000000
--- a/collector/deps.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as path from "jsr:@std/path@0.220";
-export * as posix from "jsr:@std/path@0.220/posix";
-export * as walk from "jsr:@std/fs@0.220/walk";
diff --git a/collector/manifest.test.ts b/collector/manifest.test.ts
deleted file mode 100644
index a3e84dbd..00000000
--- a/collector/manifest.test.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-// This file contains code from deno fresh (https://github.com/denoland/fresh),
-// which is a web framework, licensed under the MIT license.
-
-// Copyright (c) 2023 Eser Ozvataf and other contributors
-// Copyright (c) 2021-2023 Luca Casonato
-
-import { assert, bdd } from "./deps-dev.ts";
-import * as manifest from "./manifest.ts";
-
-bdd.describe("cool/collector/manifest", () => {
- bdd.it("specifierToIdentifier", () => {
- const used = new Set();
-
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/bar.ts", used),
- "foo_bar",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/bar.json.ts", used),
- "foo_bar_json",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/[id]/bar", used),
- "foo_id_bar",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/[...all]/bar", used),
- "foo_all_bar",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/[[optional]]/bar", used),
- "foo_optional_bar",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/as-df/bar", used),
- "foo_as_df_bar",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/as@df", used),
- "foo_as_df",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/foo.bar.baz.tsx", used),
- "foo_foo_bar_baz",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("404", used),
- "_404",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/_middleware", used),
- "foo_middleware",
- );
- });
-
- bdd.it("specifierToIdentifier deals with duplicates", () => {
- const used = new Set();
-
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/bar", used),
- "foo_bar",
- );
- assert.assertEquals(
- manifest.specifierToIdentifier("foo/bar", used),
- "foo_bar_1",
- );
- });
-});
diff --git a/deno.jsonc b/deno.jsonc
index 187fdf2e..f6f4b9b1 100644
--- a/deno.jsonc
+++ b/deno.jsonc
@@ -1,7 +1,5 @@
{
- "name": "@cool/cool",
- "version": "0.7.17",
- "exports": "./mod.ts",
+ "version": "0.7.20",
"lock": false,
"nodeModulesDir": false,
"unstable": [
@@ -10,29 +8,29 @@
"temporal"
],
"tasks": {
- "cleanup": "rm -rf ./_etc/coverage/ ./_etc/coverage.lcov ./deno.lock && deno cache --reload ./mod.ts",
- "check:license": "deno run --allow-read --allow-write ./_etc/tasks/check-license.ts",
- "check:mod": "deno run --check --reload ./mod.ts",
- "doc:lint": "deno doc --lint ./mod.ts",
- "doc:generate": "rm -rf ./docs/ && deno doc --name='cool' --output=./docs/ --html ./mod.ts",
+ "cleanup": "rm -rf ./_etc/coverage/ ./_etc/coverage.lcov ./deno.lock && deno task check:mod",
+ "script:validate-licenses": "deno run --allow-read --allow-write ./scripts/validate-licenses.ts",
+ "script:validate-configs": "deno run --allow-net --allow-env --allow-read --allow-write ./scripts/validate-configs.ts",
+ "check:mod": "deno run --check --reload --allow-env --allow-read ./pkg/mod.ts",
+ "doc:lint": "deno doc --lint ./pkg/mod.ts",
+ "doc:generate": "rm -rf ./docs/ && deno doc --name='cool' --output=./docs/ --html ./pkg/mod.ts",
"test": "DENO_KV_PATH=:memory: deno test --allow-sys --allow-net --allow-env --allow-read --allow-write --allow-run --parallel --watch",
- "test:run": "DENO_KV_PATH=:memory: deno test --allow-sys --allow-net --allow-env --allow-read --allow-write --allow-run --parallel --trace-ops --coverage=./_etc/coverage/",
+ "test:run": "DENO_KV_PATH=:memory: deno test --allow-sys --allow-net --allow-env --allow-read --allow-write --allow-run --parallel --trace-leaks --coverage=./_etc/coverage/",
"test:coverage": "deno coverage ./_etc/coverage/ --exclude='\\.(j|t)sx$'",
"test:coverage-gen": "deno coverage ./_etc/coverage --exclude='\\.(j|t)sx$' --lcov --output=./_etc/coverage.lcov",
- "ok": "deno fmt --check && deno lint && deno task check:license --check && deno task check:mod && deno task test:run",
+ "ok": "deno fmt --check && deno lint && deno task script:validate-licenses --check && deno task check:mod && deno task test:run",
"repl": "deno repl --unstable-cron --unstable-kv --unstable-temporal --allow-all --eval-file=./repl-init.ts",
"container:build": "docker build -t cool .",
"container:run": "docker run --interactive --tty --rm cool"
},
"compilerOptions": {
"jsx": "precompile",
- "jsxImportSource": "$cool",
-
+ "jsxImportSource": "@eser",
"strict": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
-
+ "noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": false
},
"lint": {
@@ -40,14 +38,49 @@
"tags": [
"recommended"
]
- }
+ },
+ "include": [
+ "ban-untagged-todo",
+ "camelcase",
+ "default-param-last",
+ "eqeqeq",
+ "no-await-in-loop",
+ "no-console",
+ "no-const-assign",
+ "no-eval",
+ "no-external-import",
+ "no-non-null-asserted-optional-chain",
+ "no-self-compare",
+ "no-sparse-arrays",
+ "no-sync-fn-in-async-fn",
+ "no-throw-literal",
+ "no-top-level-await",
+ "no-undef",
+ "prefer-ascii",
+ "single-var-declarator",
+ "verbatim-module-syntax"
+ ]
},
"exclude": [
+ ".git",
"_etc/temp/",
"docs/"
],
- "imports": {
- "$cool/jsx-runtime": "./jsx-runtime/mod.ts",
- "$cool/": "./"
- }
+ "workspace": [
+ "./scripts",
+ "./pkg/app-runtime",
+ "./pkg/bundler",
+ "./pkg/collector",
+ "./pkg/config",
+ "./pkg/di",
+ "./pkg/events",
+ "./pkg/fp",
+ "./pkg/functions",
+ "./pkg/jsx-runtime",
+ "./pkg/jsx-runtime.test",
+ "./pkg/lime",
+ "./pkg/logging",
+ "./pkg/parsing",
+ "./pkg/standards"
+ ]
}
diff --git a/deps.ts b/deps.ts
deleted file mode 100644
index 171d5271..00000000
--- a/deps.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as posix from "jsr:@std/path@0.220/posix";
-export * as jsonc from "jsr:@std/jsonc@0.220";
diff --git a/di/container.test.ts b/di/container.test.ts
deleted file mode 100644
index 21dc908b..00000000
--- a/di/container.test.ts
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd, mock } from "./deps-dev.ts";
-import { Registry } from "./container.ts";
-
-bdd.describe("cool/di/container", () => {
- bdd.it("non-existent key", () => {
- const registry = new Registry();
-
- const container = registry.build();
-
- assert.assertStrictEquals(container.get("_"), undefined);
- });
-
- bdd.it("symbol key", () => {
- const registry = new Registry();
- const a = Symbol("a");
-
- registry.set(a, 6);
-
- const container = registry.build();
-
- assert.assertStrictEquals(container.get(a), 6);
- });
-
- bdd.it("mixed keys", () => {
- const registry = new Registry();
-
- registry.set(Object.keys, "Object.keys method");
- registry.set(Object.values, "Object.values method");
- registry.set(Object.entries, "Object.entries method");
-
- const container = registry.build();
-
- assert.assertStrictEquals(container.get(Object.keys), "Object.keys method");
- assert.assertStrictEquals(
- container.get(Object.values),
- "Object.values method",
- );
- assert.assertStrictEquals(
- container.get(Object.entries),
- "Object.entries method",
- );
- });
-
- bdd.it("singleton value", () => {
- const registry = new Registry();
-
- registry.set("b", 5);
-
- const container = registry.build();
-
- assert.assertStrictEquals(container.get("b"), 5);
- });
-
- bdd.it("singleton nullables", () => {
- const registry = new Registry();
-
- registry.set("c", null);
- registry.set("d", undefined);
-
- const container = registry.build();
-
- assert.assertStrictEquals(container.get("c"), null);
- assert.assertStrictEquals(container.get("d"), undefined);
- assert.assertStrictEquals(container.get("e", "non-exists"), "non-exists");
- assert.assertStrictEquals(container.get("f"), undefined);
- });
-
- bdd.it("singleton functions", () => {
- const registry = new Registry();
-
- registry.set("g", (x: number) => x + 3);
-
- const container = registry.build();
-
- const result = container.get("g");
-
- assert.assertStrictEquals(result.constructor, Function);
- assert.assertStrictEquals(result(5), 8);
- });
-
- bdd.it("lazy value", () => {
- const registry = new Registry();
-
- const spyFn = mock.spy();
-
- let number = 1;
- registry.setLazy("h", () => {
- spyFn();
- return ++number;
- });
-
- const container = registry.build();
-
- assert.assertStrictEquals(number, 1);
- assert.assertStrictEquals(container.get("h"), 2);
- assert.assertStrictEquals(number, 2);
-
- mock.assertSpyCalls(spyFn, 1);
- });
-
- bdd.it("lazy nullable", () => {
- const registry = new Registry();
-
- const iSpyFn = mock.spy();
- const jSpyFn = mock.spy();
-
- registry.setLazy("i", () => {
- iSpyFn();
- return null;
- });
-
- registry.setLazy("j", () => {
- jSpyFn();
- return undefined;
- });
-
- const container = registry.build();
-
- assert.assertStrictEquals(container.get("i"), null);
- assert.assertStrictEquals(container.get("j"), undefined);
-
- mock.assertSpyCalls(iSpyFn, 1);
- mock.assertSpyCalls(jSpyFn, 1);
- });
-
- bdd.it("scoped value", () => {
- const registry = new Registry();
-
- const kSpyFn = mock.spy();
- const lSpyFn = mock.spy();
-
- let number = 1;
- registry.setLazy("k", () => {
- kSpyFn();
- return ++number;
- });
- registry.setScoped("l", () => {
- lSpyFn();
- return ++number;
- });
-
- const container = registry.build();
- const subScope = container.createScope();
-
- assert.assertStrictEquals(number, 1);
- assert.assertStrictEquals(container.get("k"), 2);
- assert.assertStrictEquals(container.get("k"), 2);
- assert.assertStrictEquals(container.get("l"), 3);
- assert.assertStrictEquals(container.get("l"), 3);
- assert.assertStrictEquals(subScope.get("k"), 2);
- assert.assertStrictEquals(subScope.get("k"), 2);
- assert.assertStrictEquals(subScope.get("l"), 4);
- assert.assertStrictEquals(subScope.get("l"), 4);
- assert.assertStrictEquals(container.get("l"), 3);
- assert.assertStrictEquals(number, 4);
-
- mock.assertSpyCalls(kSpyFn, 1);
- mock.assertSpyCalls(lSpyFn, 2);
- });
-
- bdd.it("transient functions", () => {
- const registry = new Registry();
-
- let number = 1;
- registry.setTransient("m", () => number++);
-
- const container = registry.build();
-
- assert.assertStrictEquals(container.get("m"), 1);
- assert.assertStrictEquals(container.get("m"), 2);
- assert.assertStrictEquals(container.get("m"), 3);
- });
-
- bdd.it("transient promise", async () => {
- const registry = new Registry();
-
- registry.setTransient("n", () => Promise.resolve("test"));
-
- const container = registry.build();
-
- assert.assertStrictEquals(await container.get("n"), "test");
- });
-
- bdd.it("getMany", () => {
- const registry = new Registry();
-
- const lazySpyFn = mock.spy();
- const transientSpyFn = mock.spy();
-
- let number = 1;
- registry.set("o", number);
- registry.setLazy("p", () => {
- lazySpyFn();
- return ++number;
- });
- registry.setTransient("q", () => {
- transientSpyFn();
- return ++number;
- });
-
- const container = registry.build();
-
- assert.assertStrictEquals(number, 1);
-
- const [o, p, q, r, s] = container.getMany("o", "p", "q", "q", "s");
-
- assert.assertStrictEquals(number, 4);
- assert.assertStrictEquals(o, 1);
- assert.assertStrictEquals(p, 2);
- assert.assertStrictEquals(q, 3);
- assert.assertStrictEquals(r, 4);
- assert.assertStrictEquals(s, undefined);
-
- mock.assertSpyCalls(lazySpyFn, 1);
- mock.assertSpyCalls(transientSpyFn, 2);
- });
-});
diff --git a/di/deps-dev.ts b/di/deps-dev.ts
deleted file mode 100644
index 350b70eb..00000000
--- a/di/deps-dev.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as assert from "jsr:@std/assert@0.220";
-export * as bdd from "jsr:@std/testing@0.220/bdd";
-export * as mock from "jsr:@std/testing@0.220/mock";
diff --git a/di/fluent-api-factory.test.ts b/di/fluent-api-factory.test.ts
deleted file mode 100644
index b124814e..00000000
--- a/di/fluent-api-factory.test.ts
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd, mock } from "./deps-dev.ts";
-import { Registry } from "./container.ts";
-import { factory } from "./fluent-api-factory.ts";
-
-const create = () => {
- const registry = new Registry();
-
- const services = registry.build();
-
- const di = factory(services);
-
- return { di, registry, services };
-};
-
-bdd.describe("cool/di/fluent-api-factory", () => {
- bdd.it("di template strings: non-existent key", () => {
- const { di } = create();
-
- assert.assertStrictEquals(di`_`, undefined);
- });
-
- bdd.it("di template strings: singleton value", () => {
- const { di } = create();
-
- di.set("a", "value");
-
- assert.assertStrictEquals(di`a`, "value");
- });
-
- bdd.it("di template strings: literals", () => {
- const { di } = create();
-
- di.set("b", "c2");
- di.set("d", "e4");
-
- assert.assertStrictEquals(di`${"b"} = ${"d"}.`, "c2 = e4.");
- });
-
- bdd.it("di.get(): non-string keys", () => {
- const { di } = create();
-
- const fnKey = () => null;
- di.set(fnKey, "zz6");
-
- const result = di.get(fnKey);
-
- assert.assertStrictEquals(result, "zz6");
- });
-
- bdd.it("di.getMany()", () => {
- const { di } = create();
-
- di.set("f", "h3");
- di.set("g", "i5");
-
- assert.assertEquals(di.getMany("f", "g"), ["h3", "i5"]);
- });
-
- bdd.it("di.invoke(): lambda", () => {
- const { di } = create();
-
- di.set("j", mock.spy());
-
- // deno-fmt-ignore
- const fn: (_: () => void) => void = j => j();
-
- di.invoke(fn);
- di.invoke(fn);
-
- mock.assertSpyCalls(di`j`, 2);
- });
-
- bdd.it("di.invoke(): lambda, multiple", () => {
- const { di } = create();
-
- di.set("k", mock.spy());
- di.set("l", mock.spy());
- di.set("m", mock.spy());
-
- const fn = (k: () => void, l: () => void, m: () => void) => {
- k();
- l();
- l();
- m();
- m();
- m();
- };
-
- di.invoke(fn);
-
- mock.assertSpyCalls(di`k`, 1);
- mock.assertSpyCalls(di`l`, 2);
- mock.assertSpyCalls(di`m`, 3);
- });
-
- bdd.it("di.invoke(): anonymous function", () => {
- const { di } = create();
-
- di.set("n", mock.spy());
-
- const fn = (n: () => void) => {
- n();
- };
-
- di.invoke(fn);
- di.invoke(fn);
-
- mock.assertSpyCalls(di`n`, 2);
- });
-
- bdd.it("di.invoke(): anonymous function, multiple", () => {
- const { di } = create();
-
- di.set("o", mock.spy());
- di.set("p", mock.spy());
- di.set("q", mock.spy());
-
- const fn = (o: () => void, p: () => void, q: () => void) => {
- o();
- p();
- p();
- q();
- q();
- q();
- };
-
- di.invoke(fn);
-
- mock.assertSpyCalls(di`o`, 1);
- mock.assertSpyCalls(di`p`, 2);
- mock.assertSpyCalls(di`q`, 3);
- });
-
- bdd.it("di.invoke(): named function", () => {
- const { di } = create();
-
- di.set("r", mock.spy());
-
- const fn = (r: () => void) => {
- r();
- };
-
- di.invoke(fn);
- di.invoke(fn);
-
- mock.assertSpyCalls(di`r`, 2);
- });
-
- bdd.it("di.invoke(): named function, multiple", () => {
- const { di } = create();
-
- di.set("s", mock.spy());
- di.set("t", mock.spy());
- di.set("u", mock.spy());
-
- const fn = (s: () => void, t: () => void, u: () => void) => {
- s();
- t();
- t();
- u();
- u();
- u();
- };
-
- di.invoke(fn);
-
- mock.assertSpyCalls(di`s`, 1);
- mock.assertSpyCalls(di`t`, 2);
- mock.assertSpyCalls(di`u`, 3);
- });
-
- bdd.it("di.invoke(): generator function", () => {
- const { di } = create();
-
- di.set("v", mock.spy());
-
- const fn = function* (v: () => void) {
- yield v();
- };
-
- for (const _ of di.invoke(fn)) { /* noop */ }
- for (const _ of di.invoke(fn)) { /* noop */ }
-
- mock.assertSpyCalls(di`v`, 2);
- });
-
- bdd.it("di.invoke(): generator function, multiple", () => {
- const { di } = create();
-
- di.set("w", mock.spy());
- di.set("x", mock.spy());
- di.set("y", mock.spy());
-
- const fn = function* (w: () => void, x: () => void, y: () => void) {
- yield w();
- yield x();
- yield x();
- yield y();
- yield y();
- yield y();
- };
-
- for (const _ of di.invoke(fn)) { /* noop */ }
-
- mock.assertSpyCalls(di`w`, 1);
- mock.assertSpyCalls(di`x`, 2);
- mock.assertSpyCalls(di`y`, 3);
- });
-
- bdd.it("di.invoke(): async function", async () => {
- const { di } = create();
-
- di.set("z", mock.spy());
-
- const fn = async (z: () => void) => {
- await Promise.resolve(z());
- };
-
- await di.invoke(fn);
- await di.invoke(fn);
-
- mock.assertSpyCalls(di`z`, 2);
- });
-
- bdd.it("di.invoke(): async function, multiple", async () => {
- const { di } = create();
-
- di.set("aa", mock.spy());
- di.set("ab", mock.spy());
- di.set("ac", mock.spy());
-
- const fn = async (
- aa: () => void,
- ab: () => void,
- ac: () => void,
- ) => {
- await Promise.all([
- Promise.resolve(aa()),
- Promise.resolve(ab()),
- Promise.resolve(ab()),
- Promise.resolve(ac()),
- Promise.resolve(ac()),
- Promise.resolve(ac()),
- ]);
- };
-
- await di.invoke(fn);
-
- mock.assertSpyCalls(di`aa`, 1);
- mock.assertSpyCalls(di`ab`, 2);
- mock.assertSpyCalls(di`ac`, 3);
- });
-
- bdd.it("di.invoke(): async generator function", async () => {
- const { di } = create();
-
- di.set("ad", mock.spy());
-
- const fn = async function* (ad: () => void) {
- yield await Promise.resolve(ad());
- };
-
- for await (const _ of di.invoke(fn)) { /* noop */ }
- for await (const _ of di.invoke(fn)) { /* noop */ }
-
- mock.assertSpyCalls(di`ad`, 2);
- });
-
- bdd.it("di.invoke(): async generator function, multiple", async () => {
- const { di } = create();
-
- di.set("ae", mock.spy());
- di.set("af", mock.spy());
- di.set("ag", mock.spy());
-
- const fn = async function* (
- ae: () => void,
- af: () => void,
- ag: () => void,
- ) {
- yield await Promise.resolve(ae());
- yield await Promise.resolve(af());
- yield await Promise.resolve(af());
- yield await Promise.resolve(ag());
- yield await Promise.resolve(ag());
- yield await Promise.resolve(ag());
- };
-
- for await (const _ of di.invoke(fn)) { /* noop */ }
-
- mock.assertSpyCalls(di`ae`, 1);
- mock.assertSpyCalls(di`af`, 2);
- mock.assertSpyCalls(di`ag`, 3);
- });
-});
diff --git a/di/invoker.test.ts b/di/invoker.test.ts
deleted file mode 100644
index 9b3bad36..00000000
--- a/di/invoker.test.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { Registry } from "./container.ts";
-import { invoke } from "./invoker.ts";
-
-const create = () => {
- const registry = new Registry();
-
- const services = registry.build();
-
- return { registry, services };
-};
-
-bdd.describe("cool/di/invoker", () => {
- bdd.it("basic", () => {
- const { registry, services } = create();
-
- let count = 0;
-
- registry.set("singleton", "value1");
- registry.setLazy("lazy", () => "value2");
- registry.setTransient("transient", () => `value${++count + 2}`);
-
- const result = invoke(services, (singleton, lazy, transient) => {
- return { singleton, lazy, transient };
- });
-
- assert.assertEquals(result, {
- singleton: "value1",
- lazy: "value2",
- transient: "value3",
- });
- });
-});
diff --git a/di/services.ts b/di/services.ts
deleted file mode 100644
index a7926809..00000000
--- a/di/services.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { type Factory, type ServiceScope } from "./primitives.ts";
-import { Registry } from "./container.ts";
-import { factory } from "./fluent-api-factory.ts";
-
-export const registry: Registry = new Registry();
-export const services: ServiceScope = registry.build();
-
-export const di: Factory = factory(services);
-
-export { di as default };
diff --git a/dotenv/deps.ts b/dotenv/deps.ts
deleted file mode 100644
index 29baee53..00000000
--- a/dotenv/deps.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as dotenv from "jsr:@std/dotenv@0.220";
diff --git a/dotenv/mod.ts b/dotenv/mod.ts
deleted file mode 100644
index 3484cb11..00000000
--- a/dotenv/mod.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * from "./base.ts";
-export * from "./loader.ts";
-export * from "./reader.ts";
-export * from "./configure.ts";
diff --git a/events/container.test.ts b/events/container.test.ts
deleted file mode 100644
index be5797c2..00000000
--- a/events/container.test.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd, mock } from "./deps-dev.ts";
-import { Registry } from "./container.ts";
-
-bdd.describe("cool/events/container", () => {
- bdd.it("simple", () => {
- const spyFn = mock.spy();
-
- const registry = new Registry();
- registry.add("ev", () => spyFn());
-
- const dispatcher = registry.build();
- dispatcher.dispatch("ev");
-
- mock.assertSpyCalls(spyFn, 1);
- });
-
- bdd.it("multiple", () => {
- const spyFn = mock.spy();
-
- const registry = new Registry();
- registry.add("ev", () => spyFn());
-
- const dispatcher = registry.build();
- dispatcher.dispatch("ev");
- dispatcher.dispatch("ev");
-
- mock.assertSpyCalls(spyFn, 2);
- });
-
- bdd.it("once", () => {
- const spyFn = mock.spy();
-
- const registry = new Registry();
- registry.add("ev", () => spyFn(), { once: true });
-
- const dispatcher = registry.build();
- dispatcher.dispatch("ev");
- dispatcher.dispatch("ev");
-
- mock.assertSpyCalls(spyFn, 1);
- });
-
- bdd.it("parameters", () => {
- const spyFn = mock.spy();
-
- const registry = new Registry();
- registry.add("ev", (e) => spyFn(e));
-
- const dispatcher = registry.build();
- dispatcher.dispatch("ev", { detail: "xx" });
-
- mock.assertSpyCalls(spyFn, 1);
-
- const arg = spyFn.calls[0]?.args[0] as CustomEvent;
- assert.assertEquals(arg.detail, "xx");
- });
-
- bdd.it("no parameters", () => {
- const spyFn = mock.spy();
-
- const registry = new Registry();
- registry.add("ev", (e) => spyFn(e));
-
- const dispatcher = registry.build();
- dispatcher.dispatch("ev");
-
- mock.assertSpyCalls(spyFn, 1);
-
- const arg = spyFn.calls[0]?.args[0] as CustomEvent;
- assert.assertStrictEquals(arg.detail, undefined);
- });
-});
diff --git a/events/container.ts b/events/container.ts
deleted file mode 100644
index 9b9d3a9c..00000000
--- a/events/container.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { type EventDispatcher, type EventRegistry } from "./primitives.ts";
-
-export class Registry implements EventRegistry {
- target: EventTarget = new EventTarget();
-
- add(
- type: string,
- listener: EventListener,
- options?: AddEventListenerOptions,
- ): this {
- this.target.addEventListener(type, listener, options);
-
- return this;
- }
-
- remove(
- type: string,
- listener: EventListener,
- options?: EventListenerOptions,
- ): this {
- this.target.removeEventListener(type, listener, options);
-
- return this;
- }
-
- build(): EventDispatcher {
- return new Dispatcher(this);
- }
-}
-
-export class Dispatcher implements EventDispatcher {
- registry: EventRegistry;
-
- constructor(registry: EventRegistry) {
- this.registry = registry;
- }
-
- dispatch(type: string, eventInitDict?: CustomEventInit): boolean {
- return this.registry.target.dispatchEvent(
- new CustomEvent(type, eventInitDict),
- );
- }
-}
diff --git a/events/deps-dev.ts b/events/deps-dev.ts
deleted file mode 100644
index 350b70eb..00000000
--- a/events/deps-dev.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as assert from "jsr:@std/assert@0.220";
-export * as bdd from "jsr:@std/testing@0.220/bdd";
-export * as mock from "jsr:@std/testing@0.220/mock";
diff --git a/file-loader/deps.ts b/file-loader/deps.ts
deleted file mode 100644
index 297d91f3..00000000
--- a/file-loader/deps.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as jsonc from "jsr:@std/jsonc@0.220";
-export * as toml from "jsr:@std/toml@0.220";
-export * as yaml from "jsr:@std/yaml@0.220";
-export * as path from "jsr:@std/path@0.220";
-export * as fs from "jsr:@std/fs@0.220";
diff --git a/file-loader/loader.ts b/file-loader/loader.ts
deleted file mode 100644
index 347ec85e..00000000
--- a/file-loader/loader.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import * as runtime from "../standards/runtime.ts";
-import { fs, jsonc, path, toml, yaml } from "./deps.ts";
-
-// TODO(@eser) introduce strategy pattern for "search parents" and "recursive search" options
-
-export const locate = async (
- baseDir: string,
- filenames: Array,
- searchParents = false,
-): Promise => {
- let dir = baseDir;
-
- while (true) {
- for (const name of filenames) {
- const filepath = path.join(dir, name);
- const isExists = await fs.exists(filepath, { isFile: true });
-
- if (isExists) {
- return filepath;
- }
- }
-
- if (!searchParents) {
- break;
- }
-
- const parent = path.dirname(dir);
- if (parent === dir) {
- break;
- }
-
- dir = parent;
- }
-
- return undefined;
-};
-
-export const parse = async (
- filepath: string,
- extension?: string,
-): Promise => {
- const ext = extension ?? path.extname(filepath);
-
- const file = await runtime.current.readTextFile(filepath);
-
- if (ext === ".json") {
- return JSON.parse(file) as T;
- }
-
- if (ext === ".jsonc") {
- return jsonc.parse(file) as T;
- }
-
- if (ext === ".yaml" || ext === ".yml") {
- return yaml.parse(file) as T;
- }
-
- if (ext === ".toml") {
- return toml.parse(file) as T;
- }
-
- throw new Error(`Unsupported file extension: ${ext}`);
-};
-
-export type LoadResult = {
- content: T | undefined;
- path: string | undefined;
-};
-
-export const load = async (
- baseDir: string,
- filenames: Array,
- searchParents = false,
-): Promise> => {
- const filepath = await locate(baseDir, filenames, searchParents);
-
- if (filepath === undefined) {
- return {
- content: undefined,
- path: undefined,
- };
- }
-
- const result = await parse(filepath);
-
- return {
- content: result,
- path: filepath,
- };
-};
diff --git a/fp/append-to-array.test.ts b/fp/append-to-array.test.ts
deleted file mode 100644
index 4cd86de3..00000000
--- a/fp/append-to-array.test.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { appendToArray } from "./append-to-array.ts";
-
-bdd.describe("cool/fp/append-to-array", () => {
- bdd.it("basic", () => {
- const arr1 = ["a", "b"];
- const str1 = "c";
-
- const result = appendToArray(arr1, str1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, ["a", "b", "c"]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield "a";
- yield "b";
- };
- const str1 = "c";
-
- const generated1 = gen1();
- const result = appendToArray(generated1, str1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, ["a", "b", "c"]);
- });
-});
diff --git a/fp/append-to-object.test.ts b/fp/append-to-object.test.ts
deleted file mode 100644
index 54e702e1..00000000
--- a/fp/append-to-object.test.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { appendToObject } from "./append-to-object.ts";
-
-bdd.describe("cool/fp/append-to-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2 };
- const obj2 = { c: 3 };
-
- const result = appendToObject(obj1, obj2);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertNotStrictEquals(result, obj2);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, { a: 1, b: 2, c: 3 });
- });
-});
diff --git a/fp/associate-array.test.ts b/fp/associate-array.test.ts
deleted file mode 100644
index bc5c09c6..00000000
--- a/fp/associate-array.test.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { associateArray } from "./associate-array.ts";
-
-bdd.describe("cool/fp/associate-array", () => {
- bdd.it("basic", () => {
- const arr1 = [
- { id: 1, name: "foo" },
- { id: 2, name: "bar" },
- { id: 3, name: "baz" },
- ];
- const func1 = (value: { id: number }) => value.id;
-
- const result = associateArray(arr1, func1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, arr1);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, {
- 1: { id: 1, name: "foo" },
- 2: { id: 2, name: "bar" },
- 3: { id: 3, name: "baz" },
- });
- });
-
- bdd.it("with-value-skipping", () => {
- const arr1 = [
- { id: 1, name: "foo", skip: false },
- { id: 2, name: "bar", skip: false },
- { id: 3, name: "baz", skip: true },
- ];
- const func1 = (value: { id: number; skip: boolean }) =>
- value.skip ? undefined : value.id;
-
- const result = associateArray(arr1, func1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, arr1);
- assert.assertEquals(Object.keys(result).length, 2);
- assert.assertEquals(result, {
- 1: { id: 1, name: "foo", skip: false },
- 2: { id: 2, name: "bar", skip: false },
- });
- });
-});
diff --git a/fp/associate-object.test.ts b/fp/associate-object.test.ts
deleted file mode 100644
index f3c231a2..00000000
--- a/fp/associate-object.test.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { associateObject } from "./associate-object.ts";
-
-bdd.describe("cool/fp/associate-object", () => {
- bdd.it("basic", () => {
- const obj1 = {
- a: { id: 1, name: "foo" },
- b: { id: 2, name: "bar" },
- c: { id: 3, name: "baz" },
- };
- const func1 = (value: { id: number }) => value.id;
-
- const result = associateObject(obj1, func1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, {
- 1: { id: 1, name: "foo" },
- 2: { id: 2, name: "bar" },
- 3: { id: 3, name: "baz" },
- });
- });
-
- bdd.it("with-value-skipping", () => {
- const obj1 = {
- a: { id: 1, name: "foo", skip: false },
- b: { id: 2, name: "bar", skip: false },
- c: { id: 3, name: "baz", skip: true },
- };
- const func1 = (value: { id: number; skip: boolean }) =>
- value.skip ? undefined : value.id;
-
- const result = associateObject(obj1, func1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 2);
- assert.assertEquals(result, {
- 1: { id: 1, name: "foo", skip: false },
- 2: { id: 2, name: "bar", skip: false },
- });
- });
-});
diff --git a/fp/compose.test.ts b/fp/compose.test.ts
deleted file mode 100644
index 4d2cc7ee..00000000
--- a/fp/compose.test.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { compose } from "./compose.ts";
-
-bdd.describe("cool/fp/compose", () => {
- bdd.it("basic", () => {
- const lower = (x: string) => x.toLowerCase();
- const chars = (x: string) => x.replace(/[^\w \\-]+/g, "");
- const spaces = (x: string) => x.split(" ");
- const dashes = (x: Array) => x.join("-");
-
- const slug = compose(dashes, spaces, chars, lower);
-
- const result = slug("Hello World!");
-
- assert.assertEquals(result, "hello-world");
- });
-});
diff --git a/fp/compose.ts b/fp/compose.ts
deleted file mode 100644
index f9b1e9e6..00000000
--- a/fp/compose.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { type ArgList, type GenericFunction } from "../standards/functions.ts";
-
-type ComposableFunction = GenericFunction;
-
-export const compose = (
- ...funcs: ReadonlyArray
-): ComposableFunction => {
- return funcs.reduce(
- (previousFunction, currentFunction) => (...args: ArgList) =>
- previousFunction(currentFunction(...args)),
- );
-};
-
-export { compose as default };
diff --git a/fp/curry-right.test.ts b/fp/curry-right.test.ts
deleted file mode 100644
index af56a032..00000000
--- a/fp/curry-right.test.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { curryRight } from "./curry-right.ts";
-
-bdd.describe("cool/fp/curry-right", () => {
- bdd.it("basic", () => {
- const dec = (a: number, b: number) => a - b;
-
- const decWith5 = curryRight(dec, 5);
-
- const result = decWith5(3);
-
- assert.assertEquals(result, -2);
- });
-});
diff --git a/fp/curry-right.ts b/fp/curry-right.ts
deleted file mode 100644
index 9f50d73a..00000000
--- a/fp/curry-right.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export const curryRight = (
- func: (...args: readonly [...ReadonlyArray, ...ReadonlyArray]) => T3,
- ...args: ReadonlyArray
-): (...args: ReadonlyArray) => T3 => {
- return (...args2: ReadonlyArray) => func(...args2, ...args);
-};
-
-export { curryRight as default };
diff --git a/fp/curry.test.ts b/fp/curry.test.ts
deleted file mode 100644
index 62cabb67..00000000
--- a/fp/curry.test.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { curry } from "./curry.ts";
-
-bdd.describe("cool/fp/curry", () => {
- bdd.it("basic", () => {
- const sum = (a: number, b: number) => a + b;
-
- const sumWith5 = curry(sum, 5);
-
- const result = sumWith5(3);
-
- assert.assertEquals(result, 8);
- });
-});
diff --git a/fp/curry.ts b/fp/curry.ts
deleted file mode 100644
index 1270464a..00000000
--- a/fp/curry.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export const curry = (
- func: (...args: readonly [...ReadonlyArray, ...ReadonlyArray]) => T3,
- ...args: ReadonlyArray
-): (...args: ReadonlyArray) => T3 => {
- return (...args2: ReadonlyArray) => func(...args, ...args2);
-};
-
-export { curry as default };
diff --git a/fp/decorate.test.ts b/fp/decorate.test.ts
deleted file mode 100644
index e1ba8001..00000000
--- a/fp/decorate.test.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { decorate } from "./decorate.ts";
-
-bdd.describe("cool/fp/decorate", () => {
- bdd.it("basic", () => {
- let generator = () => 5;
-
- generator = decorate(generator, (x) => x() * 2);
- generator = decorate(generator, (x) => x() + 1);
-
- const result = generator();
-
- assert.assertEquals(result, 11);
- });
-
- bdd.it("parameters", () => {
- let generator = (a: number) => a + 5;
-
- generator = decorate(generator, (x, a) => x(a) * 2);
- generator = decorate(generator, (x, a) => x(a) + 1);
-
- const result = generator(3);
-
- assert.assertEquals(result, 17);
- });
-});
diff --git a/fp/deep-copy.test.ts b/fp/deep-copy.test.ts
deleted file mode 100644
index 1045b698..00000000
--- a/fp/deep-copy.test.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { deepCopy } from "./deep-copy.ts";
-
-class Dummy {
- prop: unknown;
-
- constructor(prop: unknown) {
- this.prop = prop;
- }
-}
-
-bdd.describe("cool/fp/deep-copy", () => {
- bdd.it("basic", () => {
- const obj1 = { value: 5 };
-
- const result = deepCopy(obj1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertStrictEquals(result.constructor, Object);
- assert.assertEquals(result, obj1);
- assert.assertEquals(result, { value: 5 });
- });
-
- bdd.it("classes", () => {
- const obj1 = new Dummy({ value: 5 });
-
- const result = deepCopy(obj1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertStrictEquals(result.constructor, Dummy);
- assert.assertEquals(result, obj1);
- assert.assertEquals(result, new Dummy({ value: 5 }));
- });
-});
diff --git a/fp/deep-merge.test.ts b/fp/deep-merge.test.ts
deleted file mode 100644
index 258cf1fa..00000000
--- a/fp/deep-merge.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { deepMerge } from "./deep-merge.ts";
-
-type Dummy1Prop = {
- inners: {
- inner1: number;
- inner2: Array;
- inner3?: number;
- };
- outer?: string;
-};
-
-class Dummy1 {
- prop: Dummy1Prop;
-
- constructor(prop: Dummy1Prop) {
- this.prop = prop;
- }
-}
-
-type Dummy2Prop = {
- inners: {
- inner2: Array;
- inner3: number;
- };
- outer: string;
-};
-
-class Dummy2 {
- prop: Dummy2Prop;
-
- constructor(prop: Dummy2Prop) {
- this.prop = prop;
- }
-}
-
-bdd.describe("cool/fp/deep-merge", () => {
- bdd.it("basic", () => {
- const obj1 = {
- a: {
- b: [1, 2, 3],
- c: {
- d: 4,
- },
- },
- };
-
- const obj2 = {
- a: {
- b: [55],
- },
- e: "hello",
- };
-
- const result = deepMerge(obj1, obj2);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertNotStrictEquals(result, obj2);
- assert.assertStrictEquals(result.constructor, Object);
- assert.assertEquals(result, {
- a: {
- b: [55],
- c: {
- d: 4,
- },
- },
- e: "hello",
- });
- });
-
- bdd.it("classes", () => {
- const obj1 = new Dummy1({
- inners: {
- inner1: 1,
- inner2: [2, 3],
- },
- });
-
- const obj2 = new Dummy2({
- inners: {
- inner2: [4, 5],
- inner3: 6,
- },
- outer: "sub-mariner",
- });
-
- const result = deepMerge(obj1, obj2);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertNotStrictEquals(result, obj2);
- assert.assertStrictEquals(result.constructor, Dummy1);
- assert.assertEquals(
- result,
- new Dummy1({
- inners: {
- inner1: 1,
- inner2: [4, 5],
- inner3: 6,
- },
- outer: "sub-mariner",
- }),
- );
- });
-});
diff --git a/fp/deps-dev.ts b/fp/deps-dev.ts
deleted file mode 100644
index 1e79ac74..00000000
--- a/fp/deps-dev.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as assert from "jsr:@std/assert@0.220";
-export * as bdd from "jsr:@std/testing@0.220/bdd";
diff --git a/fp/dispatcher.test.ts b/fp/dispatcher.test.ts
deleted file mode 100644
index abe81501..00000000
--- a/fp/dispatcher.test.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { dispatcher, type LogType, type NextType } from "./dispatcher.ts";
-
-type StateType = Record;
-
-bdd.describe("cool/fp/dispatcher", () => {
- bdd.it("basic", async () => {
- const initialState = { quarter: 1, year: 2018, sum: 1 };
-
- const actionAdd5 = (state: StateType, next: NextType) =>
- next({ ...state, sum: (state["sum"] ?? 0) + 5 });
- const actionDiv2 = (state: StateType, next: NextType) =>
- next({ ...state, sum: (state["sum"] ?? 0) / 2 });
-
- const result = await dispatcher(initialState, [actionAdd5, actionDiv2]);
-
- assert.assertEquals(result, { quarter: 1, year: 2018, sum: 3 });
- });
-
- bdd.it("logger", async () => {
- const initialState = { quarter: 1, year: 2018, sum: 1 };
-
- const actionAdd5 = (state: StateType, next: NextType) =>
- next({ ...state, sum: (state["sum"] ?? 0) + 5 });
- const actionDiv2 = (state: StateType, next: NextType) =>
- next({ ...state, sum: (state["sum"] ?? 0) / 2 });
-
- const logs: Array> = [];
- const logger = (entry: LogType) => logs.push(entry);
-
- const result = await dispatcher(initialState, [actionAdd5, actionDiv2], [
- logger,
- ]);
-
- assert.assertEquals(result, { quarter: 1, year: 2018, sum: 3 });
- assert.assertEquals(logs, [
- {
- action: "actionAdd5",
- previousState: { quarter: 1, year: 2018, sum: 1 },
- newState: { quarter: 1, year: 2018, sum: 6 },
- },
- {
- action: "actionDiv2",
- previousState: { quarter: 1, year: 2018, sum: 6 },
- newState: { quarter: 1, year: 2018, sum: 3 },
- },
- ]);
- });
-
- bdd.it("promises", async () => {
- const initialState = 0;
-
- const delay = (num: number) =>
- new Promise((resolve) => setTimeout(() => resolve(num), 200));
- const actionFirst = async (state: number, next: NextType) =>
- next(state + await delay(5));
- const actionSecond = async (state: number, next: NextType) =>
- next(state + await delay(3));
-
- const result = await dispatcher(initialState, [actionFirst, actionSecond]);
-
- assert.assertEquals(result, 8);
- });
-});
diff --git a/fp/distinct-array.test.ts b/fp/distinct-array.test.ts
deleted file mode 100644
index 544f321c..00000000
--- a/fp/distinct-array.test.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { distinctArray } from "./distinct-array.ts";
-
-bdd.describe("cool/fp/distinct-array", () => {
- bdd.it("basic", () => {
- const arr1 = [
- { id: 1, name: "foo", parent: 0 },
- { id: 2, name: "bar", parent: 1 },
- { id: 3, name: "baz", parent: 1 },
- ];
- const func1 = (item: { parent: number }) => item.parent;
-
- const result = distinctArray(arr1, func1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(Object.keys(result).length, 2);
- assert.assertEquals(result, [
- { id: 1, name: "foo", parent: 0 },
- { id: 2, name: "bar", parent: 1 },
- ]);
- });
-});
diff --git a/fp/distinct-object.test.ts b/fp/distinct-object.test.ts
deleted file mode 100644
index a22743b4..00000000
--- a/fp/distinct-object.test.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { distinctObject } from "./distinct-object.ts";
-
-bdd.describe("cool/fp/distinct-object", () => {
- bdd.it("basic", () => {
- const obj1 = {
- a: { id: 1, name: "foo", parent: 0 },
- b: { id: 2, name: "bar", parent: 1 },
- c: { id: 3, name: "baz", parent: 1 },
- };
- const func1 = (item: { parent: number }) => item.parent;
-
- const result = distinctObject(obj1, func1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 2);
- assert.assertEquals(result, {
- a: { id: 1, name: "foo", parent: 0 },
- b: { id: 2, name: "bar", parent: 1 },
- });
- });
-});
diff --git a/fp/drop-from-array.test.ts b/fp/drop-from-array.test.ts
deleted file mode 100644
index a00dd73a..00000000
--- a/fp/drop-from-array.test.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { dropFromArray } from "./drop-from-array.ts";
-
-bdd.describe("cool/fp/drop-from-array", () => {
- bdd.it("basic", () => {
- const arr1 = ["a", "b", "c"];
- const int1 = 1;
-
- const result = dropFromArray(arr1, int1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 2);
- assert.assertEquals(result, ["b", "c"]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield "a";
- yield "b";
- yield "c";
- };
- const int1 = 1;
-
- const generated1 = gen1();
- const result = dropFromArray(generated1, int1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 2);
- assert.assertEquals(result, ["b", "c"]);
- });
-});
diff --git a/fp/drop-from-object.test.ts b/fp/drop-from-object.test.ts
deleted file mode 100644
index 076eba74..00000000
--- a/fp/drop-from-object.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { dropFromObject } from "./drop-from-object.ts";
-
-bdd.describe("cool/fp/drop-from-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3 };
- const int1 = 1;
-
- const result = dropFromObject(obj1, int1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 2);
- assert.assertEquals(result, { b: 2, c: 3 });
- });
-});
diff --git a/fp/emitter.test.ts b/fp/emitter.test.ts
deleted file mode 100644
index 0fc3c1ac..00000000
--- a/fp/emitter.test.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { emitter, type LogType } from "./emitter.ts";
-
-bdd.describe("cool/fp/emitter", () => {
- bdd.it("basic", async () => {
- let sideEffectCounter = 0;
-
- const subscriberOne = () => {
- sideEffectCounter += 1;
- };
- const subscriberTwo = () => {
- sideEffectCounter += 2;
- };
-
- const events = {
- calculate: [subscriberOne, subscriberTwo],
- };
-
- await emitter(events, "calculate");
-
- assert.assertEquals(sideEffectCounter, 3);
- });
-
- bdd.it("many events", async () => {
- let sideEffectCounter = 0;
-
- const subscriberAddOne = () => {
- sideEffectCounter += 1;
- };
- const subscriberAddTwo = () => {
- sideEffectCounter += 2;
- };
- const subscriberSubOne = () => {
- sideEffectCounter -= 1;
- };
-
- const events = {
- add: [subscriberAddOne, subscriberAddTwo],
- sub: [subscriberSubOne],
- };
-
- await emitter(events, "add");
- await emitter(events, "sub");
-
- assert.assertEquals(sideEffectCounter, 2);
- });
-
- bdd.it("wildcard events", async () => {
- let sideEffectCounter = 0;
-
- const subscriberOne = () => {
- sideEffectCounter += 1;
- };
- const subscriberTwo = () => {
- sideEffectCounter -= 2;
- };
-
- const events = {
- inc: [subscriberOne],
- dec: [subscriberTwo],
- };
-
- await emitter(events, "*");
-
- assert.assertEquals(sideEffectCounter, -1);
- });
-
- bdd.it("parameters", async () => {
- let sideEffectCounter = 0;
-
- const subscriberOne = (value: number) => {
- sideEffectCounter += value;
- };
- const subscriberTwo = (value: number) => {
- sideEffectCounter += value * 2;
- };
-
- const events = {
- calculate: [subscriberOne, subscriberTwo],
- };
-
- await emitter(events, "calculate", [5]);
-
- assert.assertEquals(sideEffectCounter, 15);
- });
-
- bdd.it("subscribers", async () => {
- let sideEffectCounter = 0;
-
- const subscriberOne = (value: number) => {
- sideEffectCounter += value;
- };
- const subscriberTwo = (value: number) => {
- sideEffectCounter += value * 2;
- };
-
- const events = {
- calculate: [subscriberOne, subscriberTwo],
- };
-
- const logs: Array = [];
- const logger = (entry: LogType) => logs.push(entry);
-
- await emitter(events, "calculate", [5], [logger]);
-
- assert.assertEquals(sideEffectCounter, 15);
- assert.assertEquals(logs, [
- {
- event: "calculate",
- subscriber: "subscriberOne",
- args: [5],
- },
- {
- event: "calculate",
- subscriber: "subscriberTwo",
- args: [5],
- },
- ]);
- });
-});
diff --git a/fp/filter-array.test.ts b/fp/filter-array.test.ts
deleted file mode 100644
index 498a10d7..00000000
--- a/fp/filter-array.test.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { filterArray } from "./filter-array.ts";
-
-bdd.describe("cool/fp/filter-array", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 2, 3, 4, 5];
- const func1 = (x: number) => x <= 3;
-
- const result = filterArray(arr1, func1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, [1, 2, 3]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- yield 4;
- yield 5;
- };
- const func1 = (x: number) => x <= 3;
-
- const generated1 = gen1();
- const result = filterArray(generated1, func1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, [1, 2, 3]);
- });
-});
diff --git a/fp/filter-object.test.ts b/fp/filter-object.test.ts
deleted file mode 100644
index 4e8f5cf8..00000000
--- a/fp/filter-object.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { filterObject } from "./filter-object.ts";
-
-bdd.describe("cool/fp/filter-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- const func1 = (x: number) => x <= 3;
-
- const result = filterObject(obj1, func1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, { a: 1, b: 2, c: 3 });
- });
-});
diff --git a/fp/iterate.test.ts b/fp/iterate.test.ts
deleted file mode 100644
index c8efbd50..00000000
--- a/fp/iterate.test.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { pipe } from "./pipe.ts";
-import { iterate } from "./iterate.ts";
-
-bdd.describe("cool/fp/iterate", () => {
- bdd.it("basic", async () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- };
-
- let total = 0;
-
- const func1 = (x: number) => {
- total += x;
- };
-
- await iterate(gen1(), func1);
-
- assert.assertEquals(total, 6);
- });
-
- bdd.it("async", async () => {
- const delay = (ms: number, value: number): Promise =>
- new Promise((resolve, _reject) => {
- setTimeout(
- () => resolve(value),
- ms,
- );
- });
-
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- };
-
- let total = 0;
-
- const func1 = async (x: number) => {
- total += await delay(10, x);
- };
-
- await iterate(gen1(), func1);
-
- assert.assertEquals(total, 6);
- });
-
- bdd.it("pipe", async () => {
- const gen1 = function* () {
- yield { value: 1 };
- yield { value: 2 };
- yield { value: 3 };
- };
-
- let total = 0;
-
- const getValue = (x: { value: number }) => Promise.resolve(x.value);
- const add5 = async (value: Promise) => await value + 5;
- const sumWithTotal = async (value: Promise) => {
- total += await value;
- };
-
- await iterate(
- gen1(),
- pipe(
- getValue,
- add5,
- sumWithTotal,
- ),
- );
-
- assert.assertEquals(total, 21);
- });
-});
diff --git a/fp/map-array.test.ts b/fp/map-array.test.ts
deleted file mode 100644
index 8c2e4483..00000000
--- a/fp/map-array.test.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { mapArray } from "./map-array.ts";
-
-bdd.describe("cool/fp/map-array", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 2, 3, 4, 5];
- const func1 = (x: number) => x - 1;
-
- const result = mapArray(arr1, func1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [0, 1, 2, 3, 4]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- yield 4;
- yield 5;
- };
- const func1 = (x: number) => x - 1;
-
- const generated1 = gen1();
- const result = mapArray(generated1, func1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [0, 1, 2, 3, 4]);
- });
-});
diff --git a/fp/map-object.test.ts b/fp/map-object.test.ts
deleted file mode 100644
index 7f15bcc9..00000000
--- a/fp/map-object.test.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { mapObject } from "./map-object.ts";
-
-bdd.describe("cool/fp/map-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- const func1 = (value: number, key: string | number | symbol) => ({
- [key]: value - 1,
- });
-
- const result = mapObject(obj1, func1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 5);
- assert.assertEquals(result, { a: 0, b: 1, c: 2, d: 3, e: 4 });
- });
-
- bdd.it("with-value-skipping", () => {
- const obj1 = { a: 1, b: 2, c: null };
- const func1 = (
- value: number | null,
- key: string | number | symbol,
- ) => {
- if (value === null) {
- return null;
- }
-
- return { [key]: value - 1 };
- };
-
- const result = mapObject(obj1, func1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, obj1);
- assert.assertEquals(Object.keys(result).length, 2);
- assert.assertEquals(result, { a: 0, b: 1 });
- });
-});
diff --git a/fp/match.test.ts b/fp/match.test.ts
deleted file mode 100644
index 246e62cc..00000000
--- a/fp/match.test.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { match } from "./match.ts";
-
-bdd.describe("cool/fp/match", () => {
- bdd.it("basic", () => {
- const str1 = "apple";
-
- const result = match(str1, [
- ["apple", () => "Apple is selected."],
- ["pear", () => "Pear is selected."],
- ["banana", () => "Banana is selected."],
- ]);
-
- assert.assertEquals(
- result,
- "Apple is selected.",
- );
- });
-
- bdd.it("conditions", () => {
- const str1 = "appLe"; // intentionally mixed case
- const str2 = "pear";
- const str3 = "banana";
-
- const result = match(true, [
- // @ts-ignore - intentionally testing for falsey values
- [str1 === "apple", () => "Apple is selected."],
- [str2 === "pear", () => "Pear is selected."],
- [str3 === "banana", () => "Banana is selected."],
- ]);
-
- assert.assertEquals(
- result,
- "Pear is selected.",
- );
- });
-});
diff --git a/fp/merge-arrays.test.ts b/fp/merge-arrays.test.ts
deleted file mode 100644
index 0c3c049a..00000000
--- a/fp/merge-arrays.test.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { mergeArrays } from "./merge-arrays.ts";
-
-bdd.describe("cool/fp/merge-arrays", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 2, 3];
- const arr2 = [4, 5];
-
- const result = mergeArrays(arr1, arr2);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertNotStrictEquals(result, arr2);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [1, 2, 3, 4, 5]);
- });
-
- bdd.it("with-generator-1", () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- };
- const arr1 = [4, 5];
-
- const generated1 = gen1();
- const result = mergeArrays(generated1, arr1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [1, 2, 3, 4, 5]);
- });
-
- bdd.it("with-generator-2", () => {
- const arr1 = [1, 2, 3];
- const gen1 = function* () {
- yield 4;
- yield 5;
- };
-
- const generated1 = gen1();
- const result = mergeArrays(arr1, generated1);
-
- assert.assertNotStrictEquals(result, arr1);
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [1, 2, 3, 4, 5]);
- });
-});
diff --git a/fp/merge-objects.test.ts b/fp/merge-objects.test.ts
deleted file mode 100644
index ca5a3711..00000000
--- a/fp/merge-objects.test.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { mergeObjects } from "./merge-objects.ts";
-
-bdd.describe("cool/fp/merge-objects", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2 };
- const obj2 = { c: 3 };
-
- const result = mergeObjects(obj1, obj2);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertNotStrictEquals(result, obj2);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, { a: 1, b: 2, c: 3 });
- });
-});
diff --git a/fp/mutate.test.ts b/fp/mutate.test.ts
deleted file mode 100644
index 1a279f51..00000000
--- a/fp/mutate.test.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { mutate } from "./mutate.ts";
-
-bdd.describe("cool/fp/mutate", () => {
- bdd.it("basic", () => {
- const obj1 = {
- firstName: "Eser",
- lastName: "Ozvataf",
- aliases: [],
- };
-
- const result = mutate(obj1, (x) => x.firstName = "Helo");
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(
- result,
- {
- firstName: "Helo",
- lastName: "Ozvataf",
- aliases: [],
- },
- );
- });
-
- bdd.it("array-push", () => {
- const obj1 = {
- firstName: "Eser",
- lastName: "Ozvataf",
- aliases: > [],
- };
-
- const result = mutate(obj1, (x) => {
- x.firstName = "Helo";
-
- x.aliases.push("laroux");
- });
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(
- result,
- {
- firstName: "Helo",
- lastName: "Ozvataf",
- aliases: [
- "laroux",
- ],
- },
- );
- });
-
- bdd.it("with-class", () => {
- class dummy {
- items: Array;
-
- constructor() {
- this.items = [];
- }
- }
-
- const obj1 = new dummy();
-
- const result = mutate(obj1, (x) => {
- x.items.push("laroux");
- });
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(result.constructor, dummy);
- assert.assertEquals(Object.keys(result), ["items"]);
- assert.assertEquals(
- result.items,
- [
- "laroux",
- ],
- );
- });
-});
diff --git a/fp/pick-from-array.test.ts b/fp/pick-from-array.test.ts
deleted file mode 100644
index 5ba2da8a..00000000
--- a/fp/pick-from-array.test.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { pickFromArray } from "./pick-from-array.ts";
-
-bdd.describe("cool/fp/pick-from-array", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 2, 3, 4, 5];
- const arr2 = [2, 3, 6];
-
- const result = pickFromArray(arr1, arr2);
-
- assert.assertNotStrictEquals(result.items, arr1);
- assert.assertNotStrictEquals(result.items, arr2);
- assert.assertEquals(result.items.length, 2);
- assert.assertEquals(result.items, [2, 3]);
-
- assert.assertNotStrictEquals(result.rest, arr1);
- assert.assertNotStrictEquals(result.rest, arr2);
- assert.assertEquals(result.rest.length, 3);
- assert.assertEquals(result.rest, [1, 4, 5]);
- });
-
- bdd.it("with-generator-1", () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- yield 4;
- yield 5;
- };
-
- const arr1 = [2, 3, 6];
-
- const generated1 = gen1();
- const result = pickFromArray(generated1, arr1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result.items, generated1);
- assert.assertNotStrictEquals(result.items, arr1);
- assert.assertEquals(result.items.length, 2);
- assert.assertEquals(result.items, [2, 3]);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result.rest, generated1);
- assert.assertNotStrictEquals(result.rest, arr1);
- assert.assertEquals(result.rest.length, 3);
- assert.assertEquals(result.rest, [1, 4, 5]);
- });
-
- bdd.it("with-generator-2", () => {
- const arr1 = [1, 2, 3, 4, 5];
- const gen1 = function* () {
- yield 2;
- yield 3;
- yield 6;
- };
-
- const generated1 = gen1();
- const result = pickFromArray(arr1, generated1);
-
- assert.assertNotStrictEquals(result.items, arr1);
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result.items, generated1);
- assert.assertEquals(result.items.length, 2);
- assert.assertEquals(result.items, [2, 3]);
-
- assert.assertNotStrictEquals(result.rest, arr1);
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result.rest, generated1);
- assert.assertEquals(result.rest.length, 3);
- assert.assertEquals(result.rest, [1, 4, 5]);
- });
-});
diff --git a/fp/pick-from-object.test.ts b/fp/pick-from-object.test.ts
deleted file mode 100644
index 311165e0..00000000
--- a/fp/pick-from-object.test.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { pickFromObject } from "./pick-from-object.ts";
-
-bdd.describe("cool/fp/pick-from-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- const arr1 = ["b", "c", "f"];
-
- const result = pickFromObject(obj1, arr1);
-
- assert.assertNotStrictEquals(result.items, obj1);
- assert.assertEquals(Object.keys(result.items).length, 2);
- assert.assertEquals(result.items, { b: 2, c: 3 });
-
- assert.assertNotStrictEquals(result.rest, obj1);
- assert.assertEquals(Object.keys(result.rest).length, 3);
- assert.assertEquals(result.rest, { a: 1, d: 4, e: 5 });
- });
-});
diff --git a/fp/pipe.test.ts b/fp/pipe.test.ts
deleted file mode 100644
index 2a36d90c..00000000
--- a/fp/pipe.test.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { pipe } from "./pipe.ts";
-
-bdd.describe("cool/fp/pipe", () => {
- bdd.it("basic", () => {
- const lower = (x: string) => x.toLowerCase();
- const chars = (x: string) => x.replace(/[^\w \\-]+/g, "");
- const spaces = (x: string) => x.split(" ");
- const dashes = (x: Array) => x.join("-");
-
- const slug = pipe(lower, chars, spaces, dashes);
-
- const result = slug("Hello World!");
-
- assert.assertEquals(result, "hello-world");
- });
-});
diff --git a/fp/pipe.ts b/fp/pipe.ts
deleted file mode 100644
index 34f315cf..00000000
--- a/fp/pipe.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { type ArgList, type GenericFunction } from "../standards/functions.ts";
-
-type ComposableFunction = GenericFunction;
-
-export const pipe = (
- ...funcs: ReadonlyArray
-): ComposableFunction => {
- return funcs.reduce(
- (previousFunction, currentFunction) => (...args: ArgList) =>
- currentFunction(previousFunction(...args)),
- );
-};
-
-export { pipe as default };
diff --git a/fp/prepend-to-array.test.ts b/fp/prepend-to-array.test.ts
deleted file mode 100644
index 84a57c31..00000000
--- a/fp/prepend-to-array.test.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { prependToArray } from "./prepend-to-array.ts";
-
-bdd.describe("cool/fp/prepend-to-array", () => {
- bdd.it("basic", () => {
- const arr1 = ["b", "c"];
- const str1 = "a";
-
- const result = prependToArray(arr1, str1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, ["a", "b", "c"]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield "b";
- yield "c";
- };
- const str1 = "a";
-
- const generated1 = gen1();
- const result = prependToArray(generated1, str1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, ["a", "b", "c"]);
- });
-});
diff --git a/fp/prepend-to-object.test.ts b/fp/prepend-to-object.test.ts
deleted file mode 100644
index 580b625e..00000000
--- a/fp/prepend-to-object.test.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { prependToObject } from "./prepend-to-object.ts";
-
-bdd.describe("cool/fp/prepend-to-object", () => {
- bdd.it("basic", () => {
- const obj1 = { b: 2, c: 3 };
- const obj2 = { a: 1 };
-
- const result = prependToObject(obj1, obj2);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertNotStrictEquals(result, obj2);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, { a: 1, b: 2, c: 3 });
- });
-});
diff --git a/fp/remove-first-match-from-array.test.ts b/fp/remove-first-match-from-array.test.ts
deleted file mode 100644
index ab0f1e9d..00000000
--- a/fp/remove-first-match-from-array.test.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { removeFirstMatchFromArray } from "./remove-first-match-from-array.ts";
-
-bdd.describe("cool/fp/remove-first-match-from-array", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 5, 2, 3, 4, 5];
- const func1 = (x: number) => x === 5;
-
- const result = removeFirstMatchFromArray(arr1, func1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [1, 2, 3, 4, 5]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield 1;
- yield 5;
- yield 2;
- yield 3;
- yield 4;
- yield 5;
- };
- const func1 = (x: number) => x === 5;
-
- const generated1 = gen1();
- const result = removeFirstMatchFromArray(generated1, func1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [1, 2, 3, 4, 5]);
- });
-});
diff --git a/fp/remove-first-match-from-object.test.ts b/fp/remove-first-match-from-object.test.ts
deleted file mode 100644
index c49d7d89..00000000
--- a/fp/remove-first-match-from-object.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { removeFirstMatchFromObject } from "./remove-first-match-from-object.ts";
-
-bdd.describe("cool/fp/remove-first-match-from-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, f: 5, b: 2, c: 3, d: 4, e: 5 };
- const func1 = (x: number) => x === 5;
-
- const result = removeFirstMatchFromObject(obj1, func1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 5);
- assert.assertEquals(result, { a: 1, b: 2, c: 3, d: 4, e: 5 });
- });
-});
diff --git a/fp/remove-index-from-array.test.ts b/fp/remove-index-from-array.test.ts
deleted file mode 100644
index e03f7bda..00000000
--- a/fp/remove-index-from-array.test.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { removeIndexFromArray } from "./remove-index-from-array.ts";
-
-bdd.describe("cool/fp/remove-index-from-array", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 2, 3, 4, 5];
- const int1 = 2;
- const int2 = 3;
-
- const result = removeIndexFromArray(arr1, int1, int2);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, [1, 2, 5]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- yield 4;
- yield 5;
- };
- const int1 = 2;
- const int2 = 3;
-
- const generated1 = gen1();
- const result = removeIndexFromArray(generated1, int1, int2);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, [1, 2, 5]);
- });
-});
diff --git a/fp/remove-key-from-object.test.ts b/fp/remove-key-from-object.test.ts
deleted file mode 100644
index 45548fa5..00000000
--- a/fp/remove-key-from-object.test.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { removeKeyFromObject } from "./remove-key-from-object.ts";
-
-bdd.describe("cool/fp/remove-key-from-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- const str1 = "b";
- const str2 = "c";
-
- const result = removeKeyFromObject(obj1, str1, str2);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, { a: 1, d: 4, e: 5 });
- });
-});
diff --git a/fp/remove-value-from-array.test.ts b/fp/remove-value-from-array.test.ts
deleted file mode 100644
index 86cd1064..00000000
--- a/fp/remove-value-from-array.test.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { removeValueFromArray } from "./remove-value-from-array.ts";
-
-bdd.describe("cool/fp/remove-value-from-array", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 2, 3, 4, 5];
- const int1 = 2;
- const int2 = 3;
-
- const result = removeValueFromArray(arr1, int1, int2);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, [1, 4, 5]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- yield 4;
- yield 5;
- };
- const int1 = 2;
- const int2 = 3;
-
- const generated1 = gen1();
- const result = removeValueFromArray(generated1, int1, int2);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 3);
- assert.assertEquals(result, [1, 4, 5]);
- });
-});
diff --git a/fp/remove-value-from-object.test.ts b/fp/remove-value-from-object.test.ts
deleted file mode 100644
index 976163c7..00000000
--- a/fp/remove-value-from-object.test.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { removeValueFromObject } from "./remove-value-from-object.ts";
-
-bdd.describe("cool/fp/remove-value-from-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: "Ia", b: "IIb", c: "IIIc", d: "IVd", e: "Ve" };
- const str1 = "IIb";
- const str2 = "IIIc";
-
- const result = removeValueFromObject(obj1, str1, str2);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, { a: "Ia", d: "IVd", e: "Ve" });
- });
-});
diff --git a/fp/reverse-array.test.ts b/fp/reverse-array.test.ts
deleted file mode 100644
index c48a4d59..00000000
--- a/fp/reverse-array.test.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { reverseArray } from "./reverse-array.ts";
-
-bdd.describe("cool/fp/reverse-array", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 2, 3, 4, 5];
-
- const result = reverseArray(arr1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [5, 4, 3, 2, 1]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- yield 4;
- yield 5;
- };
-
- const generated1 = gen1();
- const result = reverseArray(generated1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 5);
- assert.assertEquals(result, [5, 4, 3, 2, 1]);
- });
-});
diff --git a/fp/reverse-object.test.ts b/fp/reverse-object.test.ts
deleted file mode 100644
index 63d1747b..00000000
--- a/fp/reverse-object.test.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { reverseObject } from "./reverse-object.ts";
-
-bdd.describe("cool/fp/reverse-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
-
- const result = reverseObject(obj1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 5);
- assert.assertEquals(result, { e: 5, d: 4, c: 3, b: 2, a: 1 });
- });
-});
diff --git a/fp/split-array.test.ts b/fp/split-array.test.ts
deleted file mode 100644
index 75148a9b..00000000
--- a/fp/split-array.test.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { splitArray } from "./split-array.ts";
-
-bdd.describe("cool/fp/split-array", () => {
- bdd.it("basic", () => {
- const arr1 = [1, 2, 3, 4, 5];
- const int1 = 3;
-
- const result = splitArray(arr1, int1);
-
- assert.assertNotStrictEquals(result.items, arr1);
- assert.assertEquals(result.items.length, 3);
- assert.assertEquals(result.items, [1, 2, 3]);
-
- assert.assertNotStrictEquals(result.rest, arr1);
- assert.assertEquals(result.rest.length, 2);
- assert.assertEquals(result.rest, [4, 5]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield 1;
- yield 2;
- yield 3;
- yield 4;
- yield 5;
- };
-
- const int1 = 3;
-
- const generated1 = gen1();
- const result = splitArray(generated1, int1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result.items, generated1);
- assert.assertEquals(result.items.length, 3);
- assert.assertEquals(result.items, [1, 2, 3]);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result.rest, generated1);
- assert.assertEquals(result.rest.length, 2);
- assert.assertEquals(result.rest, [4, 5]);
- });
-});
diff --git a/fp/split-object.test.ts b/fp/split-object.test.ts
deleted file mode 100644
index 7b709882..00000000
--- a/fp/split-object.test.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { splitObject } from "./split-object.ts";
-
-bdd.describe("cool/fp/split-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- const int1 = 3;
-
- const result = splitObject(obj1, int1);
-
- assert.assertNotStrictEquals(result.items, obj1);
- assert.assertEquals(Object.keys(result.items).length, 3);
- assert.assertEquals(result.items, { a: 1, b: 2, c: 3 });
-
- assert.assertNotStrictEquals(result.rest, obj1);
- assert.assertEquals(Object.keys(result.rest).length, 2);
- assert.assertEquals(result.rest, { d: 4, e: 5 });
- });
-});
diff --git a/fp/take-from-array.test.ts b/fp/take-from-array.test.ts
deleted file mode 100644
index b6256cc1..00000000
--- a/fp/take-from-array.test.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { takeFromArray } from "./take-from-array.ts";
-
-bdd.describe("cool/fp/take-from-array", () => {
- bdd.it("basic", () => {
- const arr1 = ["a", "b", "c"];
- const int1 = 2;
-
- const result = takeFromArray(arr1, int1);
-
- assert.assertNotStrictEquals(result, arr1);
- assert.assertEquals(result.length, 2);
- assert.assertEquals(result, ["a", "b"]);
- });
-
- bdd.it("with-generator", () => {
- const gen1 = function* () {
- yield "a";
- yield "b";
- yield "c";
- };
- const int1 = 2;
-
- const generated1 = gen1();
- const result = takeFromArray(generated1, int1);
-
- // deno-lint-ignore no-explicit-any
- assert.assertNotStrictEquals( result, generated1);
- assert.assertEquals(result.length, 2);
- assert.assertEquals(result, ["a", "b"]);
- });
-});
diff --git a/fp/take-from-object.test.ts b/fp/take-from-object.test.ts
deleted file mode 100644
index defbe804..00000000
--- a/fp/take-from-object.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { takeFromObject } from "./take-from-object.ts";
-
-bdd.describe("cool/fp/take-from-object", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3 };
- const int1 = 2;
-
- const result = takeFromObject(obj1, int1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 2);
- assert.assertEquals(result, { a: 1, b: 2 });
- });
-});
diff --git a/fp/wth.test.ts b/fp/wth.test.ts
deleted file mode 100644
index 3095c869..00000000
--- a/fp/wth.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { wth } from "./wth.ts";
-
-bdd.describe("cool/fp/wth", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- const obj2 = { b: 6, f: 8 };
-
- const result = wth(obj1, obj2);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 6);
- assert.assertEquals(result, { a: 1, b: 6, c: 3, d: 4, e: 5, f: 8 });
- });
-});
diff --git a/fp/wthout.test.ts b/fp/wthout.test.ts
deleted file mode 100644
index efdb3edb..00000000
--- a/fp/wthout.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { wthout } from "./wthout.ts";
-
-bdd.describe("cool/fp/wthout", () => {
- bdd.it("basic", () => {
- const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
- const arr1 = ["a", "d"];
-
- const result = wthout(obj1, ...arr1);
-
- assert.assertNotStrictEquals(result, obj1);
- assert.assertEquals(Object.keys(result).length, 3);
- assert.assertEquals(result, { b: 2, c: 3, e: 5 });
- });
-});
diff --git a/functions/deps-dev.ts b/functions/deps-dev.ts
deleted file mode 100644
index 350b70eb..00000000
--- a/functions/deps-dev.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as assert from "jsr:@std/assert@0.220";
-export * as bdd from "jsr:@std/testing@0.220/bdd";
-export * as mock from "jsr:@std/testing@0.220/mock";
diff --git a/functions/fn.test.ts b/functions/fn.test.ts
deleted file mode 100644
index 550c8c1c..00000000
--- a/functions/fn.test.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd, mock } from "./deps-dev.ts";
-import { Ok, type Result } from "./results.ts";
-import { fn } from "./fn.ts";
-
-bdd.describe("cool/functions/fn", () => {
- bdd.it("simple fn().run()", async () => {
- const spyFn = mock.spy();
-
- const fns = fn>(
- () => {
- spyFn();
-
- return Ok("Testing");
- },
- );
-
- const result = await fns.run();
-
- mock.assertSpyCalls(spyFn, 1);
- assert.assertEquals(result[0]?.payload, "Testing");
- });
-
- bdd.it("simple fn().iterate()", async () => {
- const spyFn = mock.spy();
-
- const fns = fn(
- function* () {
- spyFn();
-
- yield Ok("hello");
- yield Ok("world");
- },
- );
-
- const items = [];
- for await (const item of fns.iterate()) {
- items.push(item.payload);
- }
-
- mock.assertSpyCalls(spyFn, 1);
- assert.assertEquals(items, ["hello", "world"]);
- });
-
- bdd.it("multiple fn().iterate()", async () => {
- const spyFn1 = mock.spy();
- const spyFn2 = mock.spy();
-
- const fns = fn>(
- async function* (c) {
- spyFn1();
-
- yield Ok("hello");
- yield* c.next();
- },
- async function* () {
- spyFn2();
-
- yield Ok("world");
- },
- );
-
- const items = [];
- for await (const item of fns.iterate()) {
- items.push(item.payload);
- }
-
- mock.assertSpyCalls(spyFn1, 1);
- mock.assertSpyCalls(spyFn2, 1);
- assert.assertEquals(items, ["hello", "world"]);
- });
-
- bdd.it("fn().use().run()", async () => {
- const spyFn1 = mock.spy();
- const spyFn2 = mock.spy();
-
- const fns = fn>()
- .use(
- async function* (c) {
- spyFn1();
-
- yield Ok("hello");
- yield* c.next();
- },
- )
- .use(
- async function* () {
- spyFn2();
-
- yield Ok("world");
- },
- );
-
- const items = await fns.run();
-
- mock.assertSpyCalls(spyFn1, 1);
- mock.assertSpyCalls(spyFn2, 1);
- assert.assertEquals(items, [
- { payload: "hello" },
- { payload: "world" },
- ]);
- });
-
- bdd.it("alias fn()", async () => {
- const spyFn = mock.spy();
-
- const express = fn;
-
- const result = await express>()
- .use(
- async function* (c) {
- spyFn();
-
- yield Ok("Testing");
- yield* c.next();
- },
- )
- .run();
-
- mock.assertSpyCalls(spyFn, 1);
- assert.assertEquals(result[0]?.payload, "Testing");
- });
-});
diff --git a/jsx-runtime.test/deno.jsonc b/jsx-runtime.test/deno.jsonc
deleted file mode 100644
index baf9c3f8..00000000
--- a/jsx-runtime.test/deno.jsonc
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "compilerOptions": {
- "jsx": "precompile",
- "jsxImportSource": "$cool"
- },
- "lock": false,
- "imports": {
- "$cool/jsx-runtime": "../jsx-runtime/mod.ts",
- "$cool/": "../"
- }
-}
diff --git a/jsx-runtime.test/deps-dev.ts b/jsx-runtime.test/deps-dev.ts
deleted file mode 100644
index 350b70eb..00000000
--- a/jsx-runtime.test/deps-dev.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as assert from "jsr:@std/assert@0.220";
-export * as bdd from "jsr:@std/testing@0.220/bdd";
-export * as mock from "jsr:@std/testing@0.220/mock";
diff --git a/jsx-runtime.test/root.test.tsx b/jsx-runtime.test/root.test.tsx
deleted file mode 100644
index 596cf05a..00000000
--- a/jsx-runtime.test/root.test.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import * as jsxRuntimeInternal from "../jsx-runtime/index.js";
-import { assert, bdd, mock } from "./deps-dev.ts";
-import * as root from "./root.tsx";
-
-bdd.describe("cool/jsx-runtime", () => {
- bdd.it("should return the root component", () => {
- const actual = root.Root();
-
- assert.assertObjectMatch(actual, {
- constructor: undefined,
- type: root.Component,
- props: {
- "foo": "bar",
- "lime-hack": true,
- },
- key: undefined,
- ref: undefined,
- });
- });
-
- bdd.it("should call the hook", () => {
- const spyFn = mock.spy();
-
- // deno-lint-ignore no-explicit-any
- const hook = (vnode: any) => {
- if (vnode.props["lime-hack"]) {
- spyFn();
- }
- };
-
- // @ts-ignore typescript don't recognize this
- jsxRuntimeInternal.options.tagHelperHook = hook;
-
- root.Root();
-
- mock.assertSpyCalls(spyFn, 1);
-
- jsxRuntimeInternal.options.tagHelperHook = null;
- });
-});
diff --git a/jsx-runtime/index.js b/jsx-runtime/index.js
deleted file mode 100644
index 089a29f9..00000000
--- a/jsx-runtime/index.js
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-// This file contains code from preact (https://github.com/preactjs/preact),
-// which is a React alternative, licensed under the MIT license.
-
-// Copyright (c) 2023 Eser Ozvataf and other contributors
-// Copyright (c) 2015-present Jason Miller
-
-import { encodeEntities } from "./encoder.js";
-
-export const elements = {
- Fragment: null,
-};
-
-export const options = {
- attr: null,
- tagHelperHook: null,
-};
-
-export const IS_NON_DIMENSIONAL =
- /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
-
-let vnodeId = 0;
-
-/**
- * @fileoverview
- * This file exports various methods that implement Babel's "automatic" JSX runtime API:
- * - jsx(type, props, key)
- * - jsxs(type, props, key)
- * - jsxDEV(type, props, key, __source, __self)
- *
- * The implementation of createVNode here is optimized for performance.
- * Benchmarks: https://esbench.com/bench/5f6b54a0b4632100a7dcd2b3
- */
-
-/**
- * JSX.Element factory used by Babel's {runtime:"automatic"} JSX transform
- * @param {VNode['type']} type
- * @param {VNode['props']} props
- * @param {VNode['key']} [key]
- * @param {unknown} [_isStaticChildren]
- * @param {unknown} [__source]
- * @param {unknown} [__self]
- */
-export const jsx = (type, props, key, _isStaticChildren, __source, __self) => {
- // We'll want to preserve `ref` in props to get rid of the need for
- // forwardRef components in the future, but that should happen via
- // a separate PR.
- const normalizedProps = {};
- let ref, i;
-
- for (i in props) {
- if (i == "ref") {
- ref = props[i];
- continue;
- }
-
- normalizedProps[i] = props[i];
- }
-
- /** @type {VNode & { __source: any; __self: any }} */
- const vnode = {
- type,
- props: normalizedProps,
- key,
- ref,
- _children: null,
- _parent: null,
- _depth: 0,
- _dom: null,
- _nextDom: undefined,
- _component: null,
- constructor: undefined,
- _original: --vnodeId,
- _index: -1,
- _flags: 0,
- __source,
- __self,
- };
-
- // If a Component VNode, check for and apply defaultProps.
- // Note: `type` is often a String, and can be `undefined` in development.
- if (typeof type === "function" && (ref = type.defaultProps)) {
- for (i in ref) {
- if (typeof normalizedProps[i] === "undefined") {
- normalizedProps[i] = ref[i];
- }
- }
- }
-
- if (options.tagHelperHook) {
- options.tagHelperHook(vnode);
- }
-
- return vnode;
-};
-
-export const jsxs = jsx;
-export const jsxDEV = jsx;
-
-/**
- * Create a template vnode. This function is not expected to be
- * used directly, but rather through a precompile JSX transform
- * @param {string[]} templates
- * @param {Array} exprs
- * @returns {VNode}
- */
-export const jsxTemplate = (templates, ...exprs) => {
- const vnode = createVNode(elements.Fragment, { tpl: templates, exprs });
- // Bypass render to string top level Fragment optimization
- vnode.key = vnode._vnode;
-
- return vnode;
-};
-
-const JS_TO_CSS = {};
-const CSS_REGEX = /[A-Z]/g;
-
-/**
- * Serialize an HTML attribute to a string. This function is not
- * expected to be used directly, but rather through a precompile
- * JSX transform
- * @param {string} name The attribute name
- * @param {*} value The attribute value
- * @returns {string}
- */
-export const jsxAttr = (name, value) => {
- if (options.attr) {
- const result = options.attr(name, value);
-
- if (typeof result === "string") {
- return result;
- }
- }
-
- if (name === "ref" || name === "key") {
- return "";
- }
-
- if (name === "style" && typeof value === "object") {
- let str = "";
-
- for (const prop in value) {
- const val = value[prop];
-
- if (val != null && val !== "") {
- const name = prop[0] == "-" ? prop : JS_TO_CSS[prop] ||
- (JS_TO_CSS[prop] = prop.replace(CSS_REGEX, "-$&").toLowerCase());
-
- let suffix = ";";
- if (
- typeof val === "number" &&
- // Exclude custom-attributes
- !name.startsWith("--") &&
- !IS_NON_DIMENSIONAL.test(name)
- ) {
- suffix = "px;";
- }
-
- str = `${str}${name}:${val}${suffix}`;
- }
- }
-
- return `${name}="${str}"`;
- }
-
- if (
- value == null ||
- value === false ||
- typeof value === "function" ||
- typeof value === "object"
- ) {
- return "";
- }
-
- if (value === true) {
- return name;
- }
-
- return `${name}="${encodeEntities(value)}"`;
-};
-
-/**
- * Escape a dynamic child passed to `jsxTemplate`. This function
- * is not expected to be used directly, but rather through a
- * precompile JSX transform
- * @param {*} value
- * @returns {string | null | VNode | Array}
- */
-export const jsxEscape = (value) => {
- if (
- value == null ||
- typeof value === "boolean" ||
- typeof value === "function"
- ) {
- return null;
- }
-
- if (typeof value === "object") {
- // Check for VNode
- if (value.constructor === undefined) {
- return value;
- }
-
- if (Array.isArray(value)) {
- for (let i = 0; i < value.length; i++) {
- value[i] = jsxEscape(value[i]);
- }
-
- return value;
- }
- }
-
- return encodeEntities("" + value);
-};
diff --git a/lime/deps.ts b/lime/deps.ts
deleted file mode 100644
index 65cc2bfe..00000000
--- a/lime/deps.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as posix from "jsr:@std/path@0.220/posix";
diff --git a/logging/logger.ts b/logging/logger.ts
deleted file mode 100644
index 9aa34e1b..00000000
--- a/logging/logger.ts
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-// This file contains code from deno std lib (https://github.com/denoland/deno_std),
-// which is a standard library, licensed under the MIT license.
-
-// Copyright (c) 2023-2024 Eser Ozvataf and other contributors
-// Copyright (c) 2021-2023 the Deno authors
-
-import * as runtime from "../standards/runtime.ts";
-import * as logging from "../standards/logging.ts";
-import * as functions from "../standards/functions.ts";
-import * as formatters from "./formatters.ts";
-
-export const DEFAULT_LEVEL = logging.Severities.Info;
-
-export type LogRecord = {
- message: string;
- args: functions.ArgList;
- datetime: Date;
- severity: logging.Severity;
- loggerName: string;
-};
-
-export const Logger = class implements logging.Logger {
- readonly loggerName: string;
- readonly targetStream: WritableStream;
- loglevel: logging.Severity;
- readonly formatter: formatters.FormatterFn;
- encoder: TextEncoder;
-
- constructor(
- loggerName: string,
- targetStream: WritableStream,
- loglevel: logging.Severity = DEFAULT_LEVEL,
- formatter: formatters.FormatterFn = formatters.jsonFormatter,
- ) {
- this.loggerName = loggerName;
- this.targetStream = targetStream;
- this.loglevel = loglevel;
- this.formatter = formatter;
- this.encoder = new TextEncoder();
- }
-
- /**
- * If the level of the logger is greater than the level to log, then nothing
- * is logged, otherwise a log record is passed to each log handler. `message` data
- * passed in is returned. If a function is passed in, it is only evaluated
- * if the message will be logged and the return value will be the result of the
- * function, not the function itself, unless the function isn't called, in which
- * case undefined is returned. All types are coerced to strings for logging.
- */
- async log(
- severity: logging.Severity,
- message: (T extends functions.GenericFunction ? never : T) | (() => T),
- ...args: functions.ArgList
- ): Promise {
- if (this.loglevel > severity) {
- return message instanceof Function ? undefined : message;
- }
-
- let fnResult: T | undefined;
- let logMessage: string;
- if (message instanceof Function) {
- fnResult = message();
- logMessage = this.asString(fnResult);
- } else {
- logMessage = this.asString(message);
- }
- const record: LogRecord = {
- message: logMessage,
- args: args,
- datetime: new Date(),
- severity: severity,
- loggerName: this.loggerName,
- };
-
- const outputWriter = this.targetStream.getWriter();
- await outputWriter.ready;
-
- const formatted = this.formatter(record);
- const encoded = this.encoder.encode(formatted);
- await outputWriter.write(encoded);
-
- outputWriter.releaseLock();
-
- return message instanceof Function ? fnResult : message;
- }
-
- asString(data: unknown, isProperty = false): string {
- if (typeof data === "string") {
- if (isProperty) {
- return `"${data}"`;
- }
-
- return data;
- }
-
- if (
- data === null ||
- typeof data === "number" ||
- typeof data === "bigint" ||
- typeof data === "boolean" ||
- typeof data === "undefined" ||
- typeof data === "symbol"
- ) {
- return String(data);
- }
-
- if (data instanceof Error) {
- return data.stack!;
- }
-
- if (typeof data === "object") {
- return `{${
- Object.entries(data)
- .map(([k, v]) => `"${k}":${this.asString(v, true)}`)
- .join(",")
- }}`;
- }
-
- return "undefined";
- }
-
- debug(
- message: () => T,
- ...args: functions.ArgList
- ): Promise;
- debug(
- message: T extends functions.GenericFunction ? never : T,
- ...args: functions.ArgList
- ): Promise;
- debug(
- message: (T extends functions.GenericFunction ? never : T) | (() => T),
- ...args: functions.ArgList
- ): Promise {
- return this.log(logging.Severities.Debug, message, ...args);
- }
-
- info(message: () => T, ...args: functions.ArgList): Promise;
- info(
- message: T extends functions.GenericFunction ? never : T,
- ...args: functions.ArgList
- ): Promise;
- info(
- message: (T extends functions.GenericFunction ? never : T) | (() => T),
- ...args: functions.ArgList
- ): Promise {
- return this.log(logging.Severities.Info, message, ...args);
- }
-
- warn(message: () => T, ...args: functions.ArgList): Promise;
- warn(
- message: T extends functions.GenericFunction ? never : T,
- ...args: functions.ArgList
- ): Promise;
- warn(
- message: (T extends functions.GenericFunction ? never : T) | (() => T),
- ...args: functions.ArgList
- ): Promise {
- return this.log(logging.Severities.Warning, message, ...args);
- }
-
- error(
- message: () => T,
- ...args: functions.ArgList
- ): Promise;
- error(
- message: T extends functions.GenericFunction ? never : T,
- ...args: functions.ArgList
- ): Promise;
- error(
- message: (T extends functions.GenericFunction ? never : T) | (() => T),
- ...args: functions.ArgList
- ): Promise {
- return this.log(logging.Severities.Error, message, ...args);
- }
-
- critical(
- message: () => T,
- ...args: functions.ArgList
- ): Promise;
- critical(
- message: T extends functions.GenericFunction ? never : T,
- ...args: functions.ArgList
- ): Promise;
- critical(
- message: (T extends functions.GenericFunction ? never : T) | (() => T),
- ...args: functions.ArgList
- ): Promise {
- return this.log(logging.Severities.Critical, message, ...args);
- }
-};
-
-export const current = new Logger(
- "default",
- runtime.current.getStdout(),
- DEFAULT_LEVEL,
-);
diff --git a/parsing/deps-dev.ts b/parsing/deps-dev.ts
deleted file mode 100644
index 1e79ac74..00000000
--- a/parsing/deps-dev.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-export * as assert from "jsr:@std/assert@0.220";
-export * as bdd from "jsr:@std/testing@0.220/bdd";
diff --git a/parsing/lexer/lexer.test.ts b/parsing/lexer/lexer.test.ts
deleted file mode 100644
index 19ba3476..00000000
--- a/parsing/lexer/lexer.test.ts
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "../deps-dev.ts";
-import { simpleTokens } from "./tokens/simple.ts";
-import { Tokenizer } from "./lexer.ts";
-
-bdd.describe("cool/parsing/lexer", () => {
- bdd.it("operators and symbols", () => {
- const lexer = new Tokenizer(simpleTokens);
-
- const input = "=+-*_/%<>!&|?:;,.()[]{}^";
-
- const result = Array.from(lexer.tokenizeFromString(input));
-
- assert.assertEquals(
- result,
- [
- { kind: "T_EQUALS", value: "=" },
- { kind: "T_PLUS", value: "+" },
- { kind: "T_HYPHEN", value: "-" },
- { kind: "T_ASTERISK", value: "*" },
- { kind: "T_UNDERSCORE", value: "_" },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_PERCENT", value: "%" },
- { kind: "T_IS_SMALLER", value: "<" },
- { kind: "T_IS_GREATER", value: ">" },
- { kind: "T_EXCLAMATION_MARK", value: "!" },
- { kind: "T_AMPERSAND", value: "&" },
- { kind: "T_PIPE", value: "|" },
- { kind: "T_QUESTION_MARK", value: "?" },
- { kind: "T_COLON", value: ":" },
- { kind: "T_SEMICOLON", value: ";" },
- { kind: "T_COMMA", value: "," },
- { kind: "T_DOT", value: "." },
- { kind: "T_PARENTHESIS_OPEN", value: "(" },
- { kind: "T_PARENTHESIS_CLOSE", value: ")" },
- { kind: "T_SQUARE_BRACKET_OPEN", value: "[" },
- { kind: "T_SQUARE_BRACKET_CLOSE", value: "]" },
- { kind: "T_CURLY_BRACKET_OPEN", value: "{" },
- { kind: "T_CURLY_BRACKET_CLOSE", value: "}" },
- { kind: "T_CARET", value: "^" },
- { kind: "T_END", value: "" },
- ],
- );
- });
-
- bdd.it("numbers", () => {
- const lexer = new Tokenizer(simpleTokens);
-
- const input = `1234 5678`;
-
- const result = Array.from(lexer.tokenizeFromString(input));
- assert.assertEquals(
- result,
- [
- { kind: "T_NUMERIC", value: "1234" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_NUMERIC", value: "5678" },
- { kind: "T_END", value: "" },
- ],
- );
- });
-
- bdd.it("whitespace and comments", () => {
- const lexer = new Tokenizer(simpleTokens);
-
- const input = ` // This is a comment
- /* This is a
- multiline comment */ `;
-
- const result = Array.from(lexer.tokenizeFromString(input));
- assert.assertEquals(
- result,
- [
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "This" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "is" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "a" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "comment" },
- { kind: "T_NEWLINE", value: "\n" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_ASTERISK", value: "*" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "This" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "is" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "a" },
- { kind: "T_NEWLINE", value: "\n" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "multiline" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "comment" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ASTERISK", value: "*" },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_END", value: "" },
- ],
- );
- });
-
- bdd.it("multiline comments", () => {
- const lexer = new Tokenizer(simpleTokens);
-
- const input = `/* test */`;
-
- const result = Array.from(lexer.tokenizeFromString(input));
- assert.assertEquals(
- result,
- [
- { kind: "T_SLASH", value: "/" },
- { kind: "T_ASTERISK", value: "*" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "test" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ASTERISK", value: "*" },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_END", value: "" },
- ],
- );
- });
-
- bdd.it("singleline comments", () => {
- const lexer = new Tokenizer(simpleTokens);
-
- const input = `// test`;
-
- const result = Array.from(lexer.tokenizeFromString(input));
- assert.assertEquals(
- result,
- [
- { kind: "T_SLASH", value: "/" },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "test" },
- { kind: "T_END", value: "" },
- ],
- );
- });
-
- bdd.it("mixed expression", () => {
- const lexer = new Tokenizer(simpleTokens);
-
- const input = `rocketLauncher++ /* Comment */ && test123`;
-
- const result = Array.from(lexer.tokenizeFromString(input));
- assert.assertEquals(
- result,
- [
- { kind: "T_ALPHANUMERIC", value: "rocketLauncher" },
- { kind: "T_PLUS", value: "+" },
- { kind: "T_PLUS", value: "+" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_ASTERISK", value: "*" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "Comment" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ASTERISK", value: "*" },
- { kind: "T_SLASH", value: "/" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_AMPERSAND", value: "&" },
- { kind: "T_AMPERSAND", value: "&" },
- { kind: "T_WHITESPACE", value: " " },
- { kind: "T_ALPHANUMERIC", value: "test123" },
- { kind: "T_END", value: "" },
- ],
- );
- });
-
- bdd.it("alphanumeric from readable stream", async () => {
- const lexer = new Tokenizer(simpleTokens);
-
- const readableStream = new ReadableStream({
- start(controller) {
- controller.enqueue("rocket");
- controller.enqueue("Launcher");
- controller.close();
- },
- });
-
- const result = [];
- for await (const token of lexer.tokenize(readableStream)) {
- result.push(token);
- }
-
- assert.assertEquals(
- result,
- [
- { kind: "T_ALPHANUMERIC", value: "rocketLauncher" },
- { kind: "T_END", value: "" },
- ],
- );
- });
-
- bdd.it("alphanumeric from string", () => {
- const lexer = new Tokenizer(simpleTokens);
-
- const input = `rocketLauncher`;
-
- const result = Array.from(lexer.tokenizeFromString(input));
- assert.assertEquals(
- result,
- [
- { kind: "T_ALPHANUMERIC", value: "rocketLauncher" },
- { kind: "T_END", value: "" },
- ],
- );
- });
-
- bdd.it("alphanumeric from string, buffer boundary", () => {
- const lexer = new Tokenizer(simpleTokens);
-
- lexer._reset();
- const result1 = Array.from(lexer._tokenizeChunk("rocket"));
-
- assert.assertEquals(
- result1,
- [],
- );
-
- const result2 = Array.from(lexer._tokenizeChunk("Launcher"));
- assert.assertEquals(
- result2,
- [],
- );
-
- const result3 = Array.from(lexer._tokenizeChunk(null));
- assert.assertEquals(
- result3,
- [
- { kind: "T_ALPHANUMERIC", value: "rocketLauncher" },
- { kind: "T_END", value: "" },
- ],
- );
- });
-});
diff --git a/parsing/parser.test.ts b/parsing/parser.test.ts
deleted file mode 100644
index 257d0e01..00000000
--- a/parsing/parser.test.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-
-import { assert, bdd } from "./deps-dev.ts";
-import { simpleTokens } from "./lexer/tokens/simple.ts";
-import { Tokenizer } from "./lexer/lexer.ts";
-import { sequence, token } from "./parser.ts";
-
-bdd.describe("cool/parsing/parser", () => {
- bdd.it("tokens", () => {
- const parser = token("T_NUMERIC");
-
- const tokenizer = new Tokenizer(simpleTokens);
- const tokenGenerator = tokenizer.tokenizeFromString("5");
- const result = parser(tokenGenerator);
-
- assert.assertEquals(
- result,
- [
- { kind: "token", token: { kind: "T_NUMERIC", value: "5" } },
- ],
- );
- });
-
- bdd.it("sequence", () => {
- const parser = sequence(
- token("T_NUMERIC"),
- token("T_WHITESPACE"),
- token("T_PLUS"),
- token("T_WHITESPACE"),
- token("T_NUMERIC"),
- );
-
- const tokenizer = new Tokenizer(simpleTokens);
- const tokenGenerator = tokenizer.tokenizeFromString("1 + 2 * 3");
- const result = parser(tokenGenerator);
-
- assert.assertEquals(
- result,
- [
- { kind: "token", token: { kind: "T_NUMERIC", value: "1" } },
- { kind: "token", token: { kind: "T_WHITESPACE", value: " " } },
- { kind: "token", token: { kind: "T_PLUS", value: "+" } },
- { kind: "token", token: { kind: "T_WHITESPACE", value: " " } },
- { kind: "token", token: { kind: "T_NUMERIC", value: "2" } },
- ],
- );
- });
-});
diff --git a/pkg/app-runtime/app-runtime.ts b/pkg/app-runtime/app-runtime.ts
new file mode 100644
index 00000000..7c534ffb
--- /dev/null
+++ b/pkg/app-runtime/app-runtime.ts
@@ -0,0 +1,62 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+import * as runModes from "@eser/standards/run-modes";
+import * as events from "@eser/events";
+import * as services from "@eser/di/services";
+
+import { type Channel } from "./channel.ts";
+import { type Module } from "./module.ts";
+
+export type AppRuntimeState = {
+ runMode: runModes.RunMode;
+ events: events.Factory;
+ di: typeof services.di;
+ channels: Map;
+ modules: Map;
+ // deno-lint-ignore no-explicit-any
+ awaits: Array>;
+};
+
+export const createAppRuntimeState = (): AppRuntimeState => {
+ return {
+ runMode: runModes.RunModes.NotSet,
+ events: events.events,
+ di: services.di,
+ channels: new Map(),
+ modules: new Map(),
+ awaits: [],
+ };
+};
+
+export class AppRuntime {
+ static default = Symbol("default");
+ readonly state: S;
+
+ constructor(state?: S) {
+ this.state = state ?? createAppRuntimeState() as S;
+ }
+
+ addModule(module: Module) {
+ const name = module.name ?? module.constructor.name;
+
+ this.state.modules.set(name, module);
+ }
+
+ addChannel(channel: Channel) {
+ const name = channel.name ?? channel.constructor.name;
+
+ this.state.channels.set(name, channel);
+ }
+
+ setAsDefault() {
+ this.state.di.set(AppRuntime.default, this);
+ }
+
+ async awaitAll() {
+ await Promise.all(this.state.awaits);
+ this.state.awaits.splice(0);
+ }
+
+ // execute(_options: unknown) {
+ // }
+}
diff --git a/appserver/channel.ts b/pkg/app-runtime/channel.ts
similarity index 100%
rename from appserver/channel.ts
rename to pkg/app-runtime/channel.ts
diff --git a/pkg/app-runtime/deno.jsonc b/pkg/app-runtime/deno.jsonc
new file mode 100644
index 00000000..84401a13
--- /dev/null
+++ b/pkg/app-runtime/deno.jsonc
@@ -0,0 +1,8 @@
+{
+ "name": "@eser/app-runtime",
+ "version": "0.7.20",
+ "imports": {},
+ "exports": {
+ ".": "./mod.ts"
+ }
+}
diff --git a/appserver/mod.ts b/pkg/app-runtime/mod.ts
similarity index 79%
rename from appserver/mod.ts
rename to pkg/app-runtime/mod.ts
index 2cfb68d1..368d4c51 100644
--- a/appserver/mod.ts
+++ b/pkg/app-runtime/mod.ts
@@ -1,4 +1,4 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
export * from "./module.ts";
-export * from "./appserver.ts";
+export * from "./app-runtime.ts";
diff --git a/appserver/module.ts b/pkg/app-runtime/module.ts
similarity index 100%
rename from appserver/module.ts
rename to pkg/app-runtime/module.ts
diff --git a/appserver/version-checker.ts b/pkg/app-runtime/version-checker.ts
similarity index 66%
rename from appserver/version-checker.ts
rename to pkg/app-runtime/version-checker.ts
index c21181ef..0577a66c 100644
--- a/appserver/version-checker.ts
+++ b/pkg/app-runtime/version-checker.ts
@@ -1,17 +1,17 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-import * as runtime from "../standards/runtime.ts";
-import { semver } from "./deps.ts";
+import * as semver from "@std/semver";
+import * as jsRuntime from "@eser/standards/js-runtime";
export const compareSemanticVersions = (
currentVersion: semver.SemVer,
- targetVersion: semver.SemVerRange | semver.SemVer,
+ targetVersion: semver.Range | semver.SemVer,
) => {
- if (semver.isSemVerRange(targetVersion)) {
+ if (semver.isRange(targetVersion)) {
return semver.testRange(currentVersion, targetVersion);
}
- return !semver.gte(currentVersion, targetVersion);
+ return !semver.greaterOrEqual(currentVersion, targetVersion);
};
export const compareTextVersions = (
@@ -25,5 +25,5 @@ export const compareTextVersions = (
};
export const checkMinDenoVersion = (minimumVersion: string) => {
- return compareTextVersions(runtime.version.runtime, minimumVersion);
+ return compareTextVersions(jsRuntime.current.version, minimumVersion);
};
diff --git a/pkg/bundler/aot-snapshot.ts b/pkg/bundler/aot-snapshot.ts
new file mode 100644
index 00000000..221ebcfb
--- /dev/null
+++ b/pkg/bundler/aot-snapshot.ts
@@ -0,0 +1,93 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+import * as colors from "@std/fmt/colors";
+import * as posix from "@std/path/posix";
+import * as jsRuntime from "@eser/standards/js-runtime";
+import { type BuildSnapshot, type BuildSnapshotSerialized } from "./mod.ts";
+import { setBuildId } from "./build-id.ts";
+
+export type AotSnapshotState = {
+ files: Map;
+ dependencyMapping: Map>;
+};
+
+export const createAotSnapshotState = (
+ files: Map,
+ dependencyMapping: Map>,
+): AotSnapshotState => {
+ return {
+ files: files,
+ dependencyMapping: dependencyMapping,
+ };
+};
+
+export class AotSnapshot implements BuildSnapshot {
+ readonly state: AotSnapshotState;
+
+ constructor(state: AotSnapshotState) {
+ this.state = state;
+ }
+
+ get paths(): Array {
+ return Array.from(this.state.files.keys());
+ }
+
+ async read(pathStr: string): Promise | null> {
+ const filePath = this.state.files.get(pathStr);
+
+ if (filePath !== undefined) {
+ try {
+ const file = await jsRuntime.current.open(filePath, { read: true });
+
+ return file.readable;
+ } catch (_err) {
+ return null;
+ }
+ }
+
+ // Handler will turn this into a 404
+ return null;
+ }
+
+ dependencies(pathStr: string): Array {
+ return this.state.dependencyMapping.get(pathStr) ?? [];
+ }
+}
+
+export const loadAotSnapshot = async (
+ snapshotDirPath: string,
+): Promise => {
+ try {
+ if (!(await jsRuntime.current.stat(snapshotDirPath)).isDirectory) {
+ return null;
+ }
+
+ console.log(
+ `Using snapshot found at ${colors.cyan(snapshotDirPath)}`,
+ );
+
+ const snapshotPath = posix.join(snapshotDirPath, "snapshot.json");
+ const json = JSON.parse(
+ await jsRuntime.current.readTextFile(snapshotPath),
+ ) as BuildSnapshotSerialized;
+ setBuildId(json.build_id);
+
+ const dependencies = new Map>(
+ Object.entries(json.files),
+ );
+
+ const files = new Map();
+ Object.keys(json.files).forEach((name) => {
+ const filePath = posix.join(snapshotDirPath, name);
+ files.set(name, filePath);
+ });
+
+ return new AotSnapshot(createAotSnapshotState(files, dependencies));
+ } catch (err) {
+ if (!(err instanceof jsRuntime.current.errors.NotFound)) {
+ throw err;
+ }
+
+ return null;
+ }
+};
diff --git a/bundler/build-id.ts b/pkg/bundler/build-id.ts
similarity index 67%
rename from bundler/build-id.ts
rename to pkg/bundler/build-id.ts
index 41e5df85..fdcc30a2 100644
--- a/bundler/build-id.ts
+++ b/pkg/bundler/build-id.ts
@@ -1,9 +1,9 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-import * as runtime from "../standards/runtime.ts";
-import { hex } from "./deps.ts";
+import * as hex from "@std/encoding/hex";
+import * as jsRuntime from "@eser/standards/js-runtime";
-const env = runtime.current.getEnv();
+const env = jsRuntime.current.getEnv();
const deploymentId = env["DENO_DEPLOYMENT_ID"] ||
// For CI
@@ -16,6 +16,6 @@ const buildIdHash = await crypto.subtle.digest(
export let BUILD_ID = hex.encodeHex(buildIdHash);
-export function setBuildId(buildId: string) {
+export const setBuildId = (buildId: string) => {
BUILD_ID = buildId;
-}
+};
diff --git a/pkg/bundler/deno.jsonc b/pkg/bundler/deno.jsonc
new file mode 100644
index 00000000..f72594a4
--- /dev/null
+++ b/pkg/bundler/deno.jsonc
@@ -0,0 +1,15 @@
+{
+ "name": "@eser/bundler",
+ "version": "0.7.20",
+ "imports": {
+ "@std/encoding": "jsr:@std/encoding@^1.0.1",
+ "@std/fmt": "jsr:@std/fmt@^0.225.6",
+ "@std/path": "jsr:@std/path@^1.0.0",
+ "@std/regexp": "jsr:@std/regexp@^1.0.0",
+ "@luca/esbuild-deno-loader": "jsr:@luca/esbuild-deno-loader@^0.10.3",
+ "esbuild": "npm:esbuild@^0.23.0"
+ },
+ "exports": {
+ ".": "./mod.ts"
+ }
+}
diff --git a/bundler/esbuild.ts b/pkg/bundler/esbuild.ts
similarity index 69%
rename from bundler/esbuild.ts
rename to pkg/bundler/esbuild.ts
index 523880cc..22b0f89f 100644
--- a/bundler/esbuild.ts
+++ b/pkg/bundler/esbuild.ts
@@ -1,7 +1,14 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-import * as runtime from "../standards/runtime.ts";
-import { esbuild, esbuildDenoPlugins, path, regexpEscape } from "./deps.ts";
+import * as posix from "@std/path/posix";
+import * as regexpEscape from "@std/regexp/escape";
+import * as jsRuntime from "@eser/standards/js-runtime";
+import * as esbuild from "esbuild";
+
+// Import the WASM build on platforms where running subprocesses is not
+// permitted, such as Deno Deploy, or when running without `--allow-run`.
+import { denoPlugins as esbuildDenoPlugins } from "@luca/esbuild-deno-loader";
+
import { Builder, BuildSnapshot } from "./mod.ts";
// import { BUNDLE_PUBLIC_PATH } from "../server/constants.ts";
@@ -22,15 +29,27 @@ export type EsbuildBuilderOptions = {
basePath?: string;
};
+export type EsbuildBuilderState = {
+ options: EsbuildBuilderOptions;
+};
+
+export const createEsbuildBuilderState = (
+ options: EsbuildBuilderOptions,
+): EsbuildBuilderState => {
+ return {
+ options,
+ };
+};
+
export class EsbuildBuilder implements Builder {
- #options: EsbuildBuilderOptions;
+ readonly state: EsbuildBuilderState;
- constructor(options: EsbuildBuilderOptions) {
- this.#options = options;
+ constructor(state: EsbuildBuilderState) {
+ this.state = state;
}
- async build(): Promise {
- const opts = this.#options;
+ async build(): Promise {
+ const opts = this.state.options;
try {
const absWorkingDir = opts.absoluteWorkingDir;
@@ -49,7 +68,7 @@ export class EsbuildBuilder implements Builder {
entryPoints: opts.entrypoints,
platform: "browser",
- target: this.#options.target,
+ target: opts.target,
format: "esm",
bundle: true,
@@ -84,7 +103,7 @@ export class EsbuildBuilder implements Builder {
const dependencies = new Map>();
for (const file of bundle.outputFiles) {
- const relativePath = path.relative(absWorkingDir, file.path);
+ const relativePath = posix.relative(absWorkingDir, file.path);
files.set(relativePath, file.contents);
}
@@ -102,14 +121,16 @@ export class EsbuildBuilder implements Builder {
dependencies.set(pathStr, imports);
}
- return new EsbuildSnapshot(files, dependencies);
+ return new EsbuildSnapshot(
+ createEsbuildSnapshotState(files, dependencies),
+ );
} finally {
esbuild.stop();
}
}
}
-function devClientUrlPlugin(basePath?: string): esbuild.Plugin {
+const devClientUrlPlugin = (basePath?: string): esbuild.Plugin => {
return {
name: "dev-client-url",
setup(build) {
@@ -117,7 +138,7 @@ function devClientUrlPlugin(basePath?: string): esbuild.Plugin {
{ filter: /client\.ts$/, namespace: "file" },
async (args) => {
// Load the original script
- const contents = await runtime.current.readTextFile(args.path);
+ const contents = await jsRuntime.current.readTextFile(args.path);
// Replace the URL
const modifiedContents = contents.replace(
@@ -133,15 +154,15 @@ function devClientUrlPlugin(basePath?: string): esbuild.Plugin {
);
},
};
-}
+};
-function buildIdPlugin(buildId: string): esbuild.Plugin {
+const buildIdPlugin = (buildId: string): esbuild.Plugin => {
const file = import.meta.resolve("../runtime/build-id.ts");
const url = new URL(file);
let options: esbuild.OnLoadOptions;
if (url.protocol === "file:") {
- const pathNormalized = path.fromFileUrl(url);
+ const pathNormalized = posix.fromFileUrl(url);
const filter = new RegExp(`^${regexpEscape.escape(pathNormalized)}$`);
options = { filter, namespace: "file" };
} else {
@@ -160,29 +181,39 @@ function buildIdPlugin(buildId: string): esbuild.Plugin {
);
},
};
-}
+};
+
+export type EsbuildSnapshotState = {
+ files: Map;
+ dependencyMapping: Map>;
+};
+
+export const createEsbuildSnapshotState = (
+ files: Map,
+ dependencies: Map>,
+): EsbuildSnapshotState => {
+ return {
+ files,
+ dependencyMapping: dependencies,
+ };
+};
export class EsbuildSnapshot implements BuildSnapshot {
- #files: Map;
- #dependencies: Map>;
-
- constructor(
- files: Map,
- dependencies: Map>,
- ) {
- this.#files = files;
- this.#dependencies = dependencies;
+ readonly state: EsbuildSnapshotState;
+
+ constructor(state: EsbuildSnapshotState) {
+ this.state = state;
}
get paths(): Array {
- return Array.from(this.#files.keys());
+ return Array.from(this.state.files.keys());
}
read(pathStr: string): Uint8Array | null {
- return this.#files.get(pathStr) ?? null;
+ return this.state.files.get(pathStr) ?? null;
}
dependencies(pathStr: string): Array {
- return this.#dependencies.get(pathStr) ?? [];
+ return this.state.dependencyMapping.get(pathStr) ?? [];
}
}
diff --git a/jsx-runtime/mod.ts b/pkg/bundler/mod.ts
similarity index 51%
rename from jsx-runtime/mod.ts
rename to pkg/bundler/mod.ts
index 3d4e880e..8c48b102 100644
--- a/jsx-runtime/mod.ts
+++ b/pkg/bundler/mod.ts
@@ -1,3 +1,5 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-export { jsx, jsxAttr, jsxEscape, jsxTemplate } from "./index.js";
+export * from "./primitives.ts";
+export * from "./esbuild.ts";
+export * from "./aot-snapshot.ts";
diff --git a/bundler/mod.ts b/pkg/bundler/primitives.ts
similarity index 81%
rename from bundler/mod.ts
rename to pkg/bundler/primitives.ts
index 4fb9c93b..8625c559 100644
--- a/bundler/mod.ts
+++ b/pkg/bundler/primitives.ts
@@ -1,12 +1,5 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-export {
- EsbuildBuilder,
- type EsbuildBuilderOptions,
- EsbuildSnapshot,
-} from "./esbuild.ts";
-export { AotSnapshot } from "./aot-snapshot.ts";
-
export interface Builder {
build(): Promise;
}
@@ -31,7 +24,7 @@ export type BuildSnapshot = {
dependencies(pathStr: string): Array;
};
-export type BuildSnapshotJson = {
+export type BuildSnapshotSerialized = {
build_id: string;
files: Record>;
};
diff --git a/collector/collector.ts b/pkg/collector/collector.ts
similarity index 78%
rename from collector/collector.ts
rename to pkg/collector/collector.ts
index be5d2c64..cdfb2acd 100644
--- a/collector/collector.ts
+++ b/pkg/collector/collector.ts
@@ -6,15 +6,15 @@
// Copyright (c) 2023 Eser Ozvataf and other contributors
// Copyright (c) 2021-2023 Luca Casonato
-import { path, walk } from "./deps.ts";
-import * as patterns from "../standards/patterns.ts";
-// import { runtime } from "$cool/standards/mod.ts";
+import * as posix from "@std/path/posix";
+import * as walk from "@std/fs/walk";
+import * as patterns from "@eser/standards/patterns";
export async function* walkFiles(
baseDir: string,
globFilter: string | undefined,
ignoreFilePattern: RegExp,
-) {
+): AsyncGenerator {
const routesFolder = walk.walk(baseDir, {
includeDirs: false,
includeFiles: true,
@@ -23,9 +23,9 @@ export async function* walkFiles(
});
for await (const entry of routesFolder) {
- const rel = path.relative(baseDir, entry.path);
+ const rel = posix.relative(baseDir, entry.path);
- if (globFilter !== undefined && !path.globToRegExp(globFilter).test(rel)) {
+ if (globFilter !== undefined && !posix.globToRegExp(globFilter).test(rel)) {
continue;
}
@@ -40,12 +40,16 @@ export type CollectExportsOptions = {
ignoreFilePattern?: RegExp;
};
-export const collectExports = async (options: CollectExportsOptions) => {
+export type ExportItem = [string, Array<[string, unknown]>];
+
+export const collectExports = async (
+ options: CollectExportsOptions,
+): Promise> => {
// const mainModule = runtime.current.getMainModule();
const ignoreFilePattern = options.ignoreFilePattern ??
patterns.JS_TEST_FILE_PATTERN;
- const exports: Array<[string, Array<[string, unknown]>]> = [];
+ const exports: Array = [];
for await (
const entry of walkFiles(
diff --git a/pkg/collector/deno.jsonc b/pkg/collector/deno.jsonc
new file mode 100644
index 00000000..54d59132
--- /dev/null
+++ b/pkg/collector/deno.jsonc
@@ -0,0 +1,12 @@
+{
+ "name": "@eser/collector",
+ "version": "0.7.20",
+ "imports": {
+ "@std/assert": "jsr:@std/assert@^1.0.0",
+ "@std/path": "jsr:@std/path@^1.0.0",
+ "@std/fs": "jsr:@std/fs@^0.229.3"
+ },
+ "exports": {
+ ".": "./mod.ts"
+ }
+}
diff --git a/collector/formatter.ts b/pkg/collector/formatter.ts
similarity index 85%
rename from collector/formatter.ts
rename to pkg/collector/formatter.ts
index 08a959ff..8015f192 100644
--- a/collector/formatter.ts
+++ b/pkg/collector/formatter.ts
@@ -6,10 +6,10 @@
// Copyright (c) 2023 Eser Ozvataf and other contributors
// Copyright (c) 2021-2023 Luca Casonato
-import * as runtime from "../standards/runtime.ts";
+import * as jsRuntime from "@eser/standards/js-runtime";
export const format = async (input: string) => {
- const proc = new runtime.current.Command(runtime.current.execPath(), {
+ const proc = new jsRuntime.current.Command(jsRuntime.current.execPath(), {
args: ["fmt", "-"],
stdin: "piped",
stdout: "piped",
diff --git a/pkg/collector/manifest.test.ts b/pkg/collector/manifest.test.ts
new file mode 100644
index 00000000..55725ca1
--- /dev/null
+++ b/pkg/collector/manifest.test.ts
@@ -0,0 +1,68 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+// This file contains code from deno fresh (https://github.com/denoland/fresh),
+// which is a web framework, licensed under the MIT license.
+
+// Copyright (c) 2023 Eser Ozvataf and other contributors
+// Copyright (c) 2021-2023 Luca Casonato
+
+import * as assert from "@std/assert";
+import * as manifest from "./manifest.ts";
+
+Deno.test("specifierToIdentifier", () => {
+ const used = new Set();
+
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/bar.ts", used),
+ "foo_bar",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/bar.json.ts", used),
+ "foo_bar_json",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/[id]/bar", used),
+ "foo_id_bar",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/[...all]/bar", used),
+ "foo_all_bar",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/[[optional]]/bar", used),
+ "foo_optional_bar",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/as-df/bar", used),
+ "foo_as_df_bar",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/as@df", used),
+ "foo_as_df",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/foo.bar.baz.tsx", used),
+ "foo_foo_bar_baz",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("404", used),
+ "_404",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/_middleware", used),
+ "foo_middleware",
+ );
+});
+
+Deno.test("specifierToIdentifier deals with duplicates", () => {
+ const used = new Set();
+
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/bar", used),
+ "foo_bar",
+ );
+ assert.assertEquals(
+ manifest.specifierToIdentifier("foo/bar", used),
+ "foo_bar_1",
+ );
+});
diff --git a/collector/manifest.ts b/pkg/collector/manifest.ts
similarity index 91%
rename from collector/manifest.ts
rename to pkg/collector/manifest.ts
index 3de76db4..07983bd6 100644
--- a/collector/manifest.ts
+++ b/pkg/collector/manifest.ts
@@ -6,9 +6,9 @@
// Copyright (c) 2023 Eser Ozvataf and other contributors
// Copyright (c) 2021-2023 Luca Casonato
-import { path, posix } from "./deps.ts";
-import * as runtime from "../standards/runtime.ts";
-import * as logger from "../logging/logger.ts";
+import * as posix from "@std/path/posix";
+import * as jsRuntime from "@eser/standards/js-runtime";
+import * as logger from "@eser/logging/logger";
import * as validatorIdentifier from "./validator-identifier/mod.ts";
import * as collector from "./collector.ts";
import * as formatter from "./formatter.ts";
@@ -35,9 +35,12 @@ const toImportSpecifier = (file: string) => {
// valid file names in Windows, macOS and Linux and every identifier we
// create here will be prefixed with at least one "$". This greatly
// simplifies the invalid characters we have to account for.
-export const specifierToIdentifier = (specifier: string, used: Set) => {
+export const specifierToIdentifier = (
+ specifier: string,
+ used: Set,
+): string => {
// specifier = specifier.replace(/^(?:\.\/pkg)\//, "");
- const ext = path.extname(specifier);
+ const ext = posix.extname(specifier);
if (ext) {
specifier = specifier.slice(0, -ext.length);
}
@@ -88,11 +91,11 @@ const placeholder = (text: string) => {
export const writeManifestToString = async (
collection: Array<[string, Array<[string, unknown]>]>,
-) => {
+): Promise => {
const sortFn = getSortFn();
const used = new Set();
- const imports = [];
+ const imports: Array = [];
const manifest = {
// baseUrl: placeholder("import.meta.url"),
exports: [] as Array,
@@ -141,7 +144,7 @@ export const manifest = ${manifestSerialized};
export const buildManifest = async (
target: WritableStream,
options: collector.CollectExportsOptions,
-) => {
+): Promise => {
const collection = await collector.collectExports(options);
const manifestStr = await writeManifestToString(collection);
@@ -168,8 +171,8 @@ export const buildManifest = async (
export const buildManifestFile = async (
filepath: string,
options: collector.CollectExportsOptions,
-) => {
- const target = await runtime.current.open(filepath, {
+): Promise => {
+ const target = await jsRuntime.current.open(filepath, {
create: true,
write: true,
});
diff --git a/collector/mod.ts b/pkg/collector/mod.ts
similarity index 100%
rename from collector/mod.ts
rename to pkg/collector/mod.ts
diff --git a/collector/validator-identifier/char-codes.ts b/pkg/collector/validator-identifier/char-codes.ts
similarity index 100%
rename from collector/validator-identifier/char-codes.ts
rename to pkg/collector/validator-identifier/char-codes.ts
diff --git a/collector/validator-identifier/mod.ts b/pkg/collector/validator-identifier/mod.ts
similarity index 99%
rename from collector/validator-identifier/mod.ts
rename to pkg/collector/validator-identifier/mod.ts
index a7bdc482..7784471d 100644
--- a/collector/validator-identifier/mod.ts
+++ b/pkg/collector/validator-identifier/mod.ts
@@ -27,12 +27,12 @@ const isInAstralSet = (code: number, set: readonly number[]) => {
let pos = 0x10000;
for (let i = 0, length = set.length; i < length; i += 2) {
- pos += set[i];
+ pos += set[i]!;
if (pos > code) {
return false;
}
- pos += set[i + 1];
+ pos += set[i + 1]!;
if (pos >= code) {
return true;
}
diff --git a/dotenv/README.md b/pkg/config/README.md
similarity index 80%
rename from dotenv/README.md
rename to pkg/config/README.md
index 98d828b8..d4203755 100644
--- a/dotenv/README.md
+++ b/pkg/config/README.md
@@ -1,6 +1,6 @@
-# 🔐 [cool/dotenv](./)
+# 🔐 [@eser/config](./)
-`cool/dotenv` helps you load configurations from `.env.*` files and environment
+`@eser/config` helps you load configurations from `.env.*` files and environment
variables, a practice based on **The 12-Factor App** methodology which
recommends separating configuration from code.
@@ -20,10 +20,10 @@ The 12-Factor App is a set of best practices designed to enable applications to
be built with portability and resilience when deployed to the web.
[Learn more about The 12-Factor App](https://12factor.net/).
-## 🤔 What cool/dotenv offers?
+## 🤔 What @eser/config offers?
-`cool/dotenv` helps you handle these configurations properly. With using
-`cool/dotenv`, the environment variables are loaded from the following sources:
+`@eser/config` helps you handle these configurations properly. With using
+`@eser/config`, the environment variables are loaded from the following sources:
- Environment variables that passed to the Deno process.
- Environment variables defined by the system's shell.
@@ -40,7 +40,7 @@ from file or environment variable) takes precedence. That means you can use the
## 🛠 Usage and API Reference
-Here you'll find a list of features provided by `cool/dotenv` along with brief
+Here you'll find a list of features provided by `@eser/config` along with brief
descriptions and usage examples.
### Loading environment variables
@@ -48,7 +48,7 @@ descriptions and usage examples.
**Basic usage:**
```js
-import { load } from "$cool/dotenv/mod.ts";
+import { load } from "@eser/config";
const vars = await load();
console.log(vars);
@@ -57,7 +57,7 @@ console.log(vars);
**Load from different directory:**
```js
-import { load } from "$cool/dotenv/mod.ts";
+import { load } from "@eser/config";
const vars = await load({ baseDir: "./config" });
console.log(vars);
@@ -68,7 +68,7 @@ console.log(vars);
**Basic usage:**
```js
-import { configure, env } from "$cool/dotenv/mod.ts";
+import { configure, env } from "@eser/config";
const options = await configure(
(reader, acc) => {
@@ -84,7 +84,7 @@ const options = await configure(
**With custom interfaces:**
```js
-import { configure, env } from "$cool/dotenv/mod.ts";
+import { configure, env } from "@eser/config";
type Options = {
env: string;
diff --git a/pkg/config/config.test.ts b/pkg/config/config.test.ts
new file mode 100644
index 00000000..b9e7f670
--- /dev/null
+++ b/pkg/config/config.test.ts
@@ -0,0 +1,32 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+import * as assert from "@std/assert";
+import * as config from "./mod.ts";
+
+// TODO FileLoader: constructor'u transformer alacak, CONSTANTS veya AS_IS gibi.
+// TODO FileLoader.File: config file'ları "json", "toml", "yaml" ve ".env" gibi farklı formatlarda olabilecekler.
+// TODO FileLoader.FileStack: config file'lar bir load order ile environment'a göre farklı stackler oluşturabilecekler.
+// TODO FileLoader.FileStack: olmayan dosyalar atlanabilecek.
+
+// TODO: Config Source FileLoader: FileLoader kullanan bir config source olacak.
+// TODO: Config Source Environment: Environment variable'ları kullanan bir config source olacak.
+// TODO: her config source'un kendini refresh ettiği bir TTL'si olacak (default: infinite0, bir süre geçtikten sonra veya invalidate() komutu ile bu resetlenebilecek.
+
+Deno.test("new Config", () => {
+ const result = new config.Config();
+
+ assert.assertInstanceOf(result, config.Config);
+});
+
+Deno.test("setting config meta", () => {
+ const result = new config.Config();
+
+ result.setKeyMeta("sampleKey", {
+ description: "sample description",
+ type: "string",
+ ttl: 1000,
+ disallowSource: ["env"],
+ });
+
+ assert.assertInstanceOf(result, config.Config);
+});
diff --git a/pkg/config/config.ts b/pkg/config/config.ts
new file mode 100644
index 00000000..f6e4f5aa
--- /dev/null
+++ b/pkg/config/config.ts
@@ -0,0 +1,25 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+import * as primitives from "./primitives.ts";
+
+export type ConfigState = {
+ meta: Record;
+};
+
+export const createConfigState = (): ConfigState => {
+ return {
+ meta: {},
+ };
+};
+
+export class Config {
+ readonly state: ConfigState;
+
+ constructor(state?: ConfigState) {
+ this.state = state ?? createConfigState();
+ }
+
+ setKeyMeta(key: string, meta: primitives.ConfigItemMeta) {
+ this.state.meta[key] = meta;
+ }
+}
diff --git a/pkg/config/deno.jsonc b/pkg/config/deno.jsonc
new file mode 100644
index 00000000..aa6a0f13
--- /dev/null
+++ b/pkg/config/deno.jsonc
@@ -0,0 +1,17 @@
+{
+ "name": "@eser/config",
+ "version": "0.7.20",
+ "imports": {
+ "@std/assert": "jsr:@std/assert@^1.0.0",
+ "@std/collections": "jsr:@std/collections@^1.0.4",
+ "@std/fs": "jsr:@std/fs@^0.229.3",
+ "@std/jsonc": "jsr:@std/jsonc@^0.224.3",
+ "@std/path": "jsr:@std/path@^1.0.0",
+ "@std/toml": "jsr:@std/toml@^1.0.0",
+ "@std/yaml": "jsr:@std/yaml@^0.224.3"
+ },
+ "exports": {
+ ".": "./mod.ts",
+ "./file": "./file/mod.ts"
+ }
+}
diff --git a/pkg/config/dotenv-source.ts b/pkg/config/dotenv-source.ts
new file mode 100644
index 00000000..befcbb87
--- /dev/null
+++ b/pkg/config/dotenv-source.ts
@@ -0,0 +1,51 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+import * as primitives from "./primitives.ts";
+
+export type DotenvSourceState = primitives.SourceState;
+
+export const createDotenvSourceState = (): DotenvSourceState => {
+ return {
+ id: "dotenv",
+ };
+};
+
+export class DotenvSource implements primitives.Source {
+ readonly state: DotenvSourceState;
+
+ constructor(state?: DotenvSourceState) {
+ this.state = state ?? createDotenvSourceState();
+ }
+
+ getBooleanValue(
+ _flagKey: string,
+ defaultValue: boolean,
+ _requestContext?: primitives.RequestContext,
+ ): Promise {
+ return Promise.resolve(defaultValue);
+ }
+
+ getNumberValue(
+ _flagKey: string,
+ defaultValue: T,
+ _requestContext?: primitives.RequestContext,
+ ): Promise {
+ return Promise.resolve(defaultValue);
+ }
+
+ getObjectValue(
+ _flagKey: string,
+ defaultValue: T,
+ _requestContext?: primitives.RequestContext,
+ ): Promise {
+ return Promise.resolve(defaultValue);
+ }
+
+ getStringValue(
+ _flagKey: string,
+ defaultValue: T,
+ _requestContext?: primitives.RequestContext,
+ ): Promise {
+ return Promise.resolve(defaultValue);
+ }
+}
diff --git a/dotenv/base.ts b/pkg/config/dotenv/base.ts
similarity index 100%
rename from dotenv/base.ts
rename to pkg/config/dotenv/base.ts
diff --git a/dotenv/configure.ts b/pkg/config/dotenv/configure.ts
similarity index 90%
rename from dotenv/configure.ts
rename to pkg/config/dotenv/configure.ts
index 11991bfb..de3d84e4 100644
--- a/dotenv/configure.ts
+++ b/pkg/config/dotenv/configure.ts
@@ -1,6 +1,6 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-import { type Promisable } from "../standards/promises.ts";
+import * as promises from "@eser/standards/promises";
import { env } from "./base.ts";
import { load, type LoaderOptions } from "./loader.ts";
import { createEnvReader, type EnvReader } from "./reader.ts";
@@ -15,7 +15,7 @@ export type EnvVariables = BaseEnvVariables & Record;
export type ConfigureFn = (
reader: EnvReader,
target: T,
-) => Promisable;
+) => promises.Promisable;
// public functions
export const configure = async (
diff --git a/dotenv/loader.ts b/pkg/config/dotenv/loader.ts
similarity index 87%
rename from dotenv/loader.ts
rename to pkg/config/dotenv/loader.ts
index c5d598cd..b1ca3cea 100644
--- a/dotenv/loader.ts
+++ b/pkg/config/dotenv/loader.ts
@@ -1,7 +1,7 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-import * as runtime from "../standards/runtime.ts";
-import { dotenv } from "./deps.ts";
+import * as dotenv from "@std/dotenv";
+import * as jsRuntime from "@eser/standards/js-runtime";
import { defaultEnvValue, defaultEnvVar, env, type EnvMap } from "./base.ts";
// type definitions
@@ -22,7 +22,7 @@ export const parseEnvFromFile = async (
filepath: string,
): Promise> => {
try {
- const data = await runtime.current.readFile(filepath);
+ const data = await jsRuntime.current.readFile(filepath);
const decoded = new TextDecoder("utf-8").decode(data);
const escaped = decodeURIComponent(decoded);
@@ -30,7 +30,7 @@ export const parseEnvFromFile = async (
return result;
} catch (e) {
- if (e instanceof runtime.current.errors.NotFound) {
+ if (e instanceof jsRuntime.current.errors.NotFound) {
return {};
}
@@ -50,7 +50,7 @@ export const load = async (
options,
);
- const sysVars = runtime.current.getEnv();
+ const sysVars = jsRuntime.current.getEnv();
const envName = sysVars[options_.defaultEnvVar] ?? options_.defaultEnvValue;
const vars = new Map();
diff --git a/dotenv/reader.ts b/pkg/config/dotenv/reader.ts
similarity index 100%
rename from dotenv/reader.ts
rename to pkg/config/dotenv/reader.ts
diff --git a/pkg/config/file/loader.ts b/pkg/config/file/loader.ts
new file mode 100644
index 00000000..2d102816
--- /dev/null
+++ b/pkg/config/file/loader.ts
@@ -0,0 +1,145 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+import * as fs from "@std/fs";
+import * as jsonc from "@std/jsonc";
+import * as posix from "@std/path/posix";
+import * as toml from "@std/toml";
+import * as yaml from "@std/yaml";
+import * as jsRuntime from "@eser/standards/js-runtime";
+import * as primitives from "./primitives.ts";
+
+// TODO(@eser) introduce strategy pattern for "search parents" and "recursive search" options
+
+export const locate = async (
+ baseDir: string,
+ filenames: Array,
+ searchParents = false,
+): Promise => {
+ let dir = baseDir;
+
+ while (true) {
+ for (const name of filenames) {
+ const filepath = posix.join(dir, name);
+ const isExists = await fs.exists(filepath, { isFile: true });
+
+ if (isExists) {
+ return filepath;
+ }
+ }
+
+ if (!searchParents) {
+ break;
+ }
+
+ const parent = posix.dirname(dir);
+ if (parent === dir) {
+ break;
+ }
+
+ dir = parent;
+ }
+
+ return undefined;
+};
+
+export const getFileFormat = (filepath: string): primitives.FileFormat => {
+ const ext = posix.extname(filepath);
+
+ if (ext === ".json") {
+ return primitives.FileFormats.Json;
+ }
+
+ if (ext === ".jsonc") {
+ return primitives.FileFormats.JsonWithComments;
+ }
+
+ if (ext === ".yaml" || ext === ".yml") {
+ return primitives.FileFormats.Yaml;
+ }
+
+ if (ext === ".toml") {
+ return primitives.FileFormats.Toml;
+ }
+
+ if (ext === ".env") {
+ return primitives.FileFormats.EnvironmentFile;
+ }
+
+ return primitives.FileFormats.Unknown;
+};
+
+export type ParseResult = {
+ content: T | undefined;
+ filepath: string | undefined;
+ format: primitives.FileFormat;
+};
+
+export const parse = async (
+ filepath: string,
+ format?: primitives.FileFormat,
+): Promise> => {
+ const formatFinal = format ?? getFileFormat(filepath);
+
+ const textContent = await jsRuntime.current.readTextFile(filepath);
+
+ if (formatFinal === primitives.FileFormats.Json) {
+ return {
+ content: JSON.parse(textContent) as T,
+ filepath: filepath,
+ format: formatFinal,
+ };
+ }
+
+ if (formatFinal === primitives.FileFormats.JsonWithComments) {
+ return {
+ content: jsonc.parse(textContent) as T,
+ filepath: filepath,
+ format: formatFinal,
+ };
+ }
+
+ if (formatFinal === primitives.FileFormats.Yaml) {
+ return {
+ content: yaml.parse(textContent) as T,
+ filepath: filepath,
+ format: formatFinal,
+ };
+ }
+
+ if (formatFinal === primitives.FileFormats.Toml) {
+ return {
+ content: toml.parse(textContent) as T,
+ filepath: filepath,
+ format: formatFinal,
+ };
+ }
+
+ return {
+ content: undefined,
+ filepath: filepath,
+ format: primitives.FileFormats.Unknown,
+ };
+};
+
+export type LoadResult = ParseResult;
+
+export const load = async (
+ baseDir: string,
+ filenames: Array,
+ forceFormat?: primitives.FileFormat,
+ searchParents = false,
+): Promise> => {
+ const filepath = await locate(baseDir, filenames, searchParents);
+
+ if (filepath === undefined) {
+ return {
+ content: undefined,
+ filepath: undefined,
+ format: primitives.FileFormats.Unknown,
+ };
+ }
+
+ const result = await parse(filepath, forceFormat);
+
+ return result;
+};
diff --git a/file-loader/mod.ts b/pkg/config/file/mod.ts
similarity index 100%
rename from file-loader/mod.ts
rename to pkg/config/file/mod.ts
diff --git a/pkg/config/file/primitives.ts b/pkg/config/file/primitives.ts
new file mode 100644
index 00000000..529bf8ed
--- /dev/null
+++ b/pkg/config/file/primitives.ts
@@ -0,0 +1,16 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+export const FileFormats = {
+ Unknown: 0,
+ EnvironmentFile: 1,
+ Json: 2,
+ JsonWithComments: 3,
+ Toml: 4,
+ Yaml: 5,
+} as const;
+
+export type FileFormatKey = Exclude<
+ keyof typeof FileFormats,
+ number
+>;
+export type FileFormat = typeof FileFormats[FileFormatKey];
diff --git a/file-loader/resolver.ts b/pkg/config/file/resolver.ts
similarity index 96%
rename from file-loader/resolver.ts
rename to pkg/config/file/resolver.ts
index c89e802c..4a4d0a7f 100644
--- a/file-loader/resolver.ts
+++ b/pkg/config/file/resolver.ts
@@ -3,7 +3,7 @@
export const resolvePath = (
filepath: string,
baseUrl: string | null = null,
-) => {
+): string => {
if (baseUrl === null || filepath[0] === "/") {
return filepath;
}
diff --git a/appserver/deps.ts b/pkg/config/mod.ts
similarity index 51%
rename from appserver/deps.ts
rename to pkg/config/mod.ts
index bf88a7f5..0c6f1bfc 100644
--- a/appserver/deps.ts
+++ b/pkg/config/mod.ts
@@ -1,3 +1,5 @@
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
-export * as semver from "jsr:@std/semver@0.220";
+export * from "./primitives.ts";
+export * from "./config.ts";
+export * from "./dotenv-source.ts";
diff --git a/pkg/config/primitives.ts b/pkg/config/primitives.ts
new file mode 100644
index 00000000..cf11213a
--- /dev/null
+++ b/pkg/config/primitives.ts
@@ -0,0 +1,53 @@
+// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
+
+export type ConfigItemMeta = {
+ description: string;
+ type: string;
+ ttl: number;
+ disallowSource: string[];
+};
+
+export type ConfigItem = {
+ key: string;
+ value: T;
+ meta: ConfigItemMeta;
+};
+
+export type RequestContext = {
+ [key: string]: unknown;
+};
+
+export interface ContainerReadable {
+ getBooleanValue(
+ flagKey: string,
+ defaultValue: boolean,
+ requestContext?: RequestContext,
+ ): Promise;
+ getNumberValue(
+ flagKey: string,
+ defaultValue: boolean,
+ requestContext?: RequestContext,
+ ): Promise;
+ getObjectValue(
+ flagKey: string,
+ defaultValue: boolean,
+ requestContext?: RequestContext,
+ ): Promise;
+ getStringValue(
+ flagKey: string,
+ defaultValue: boolean,
+ requestContext?: RequestContext,
+ ): Promise;
+}
+
+export type SourceState = {
+ id: string;
+};
+
+export type Source = {
+ readonly state: SourceState;
+};
+
+export type Provider = ContainerReadable & {
+ sources: Array