diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1cbd653b..db0e4841 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: with: deno-version: v2.x - name: Build - run: deno task debug + run: deno task debug-no-opt - name: Upload build artifacts uses: actions/upload-artifact@v4 with: @@ -24,25 +24,22 @@ jobs: ./src/datex-web/datex_web.internal.js ./src/datex-web/datex_web.wasm retention-days: 5 - - test: - runs-on: ubuntu-latest - name: Test + lint: + name: Lint needs: build + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: submodules: "true" + - uses: denoland/setup-deno@v2 + with: + deno-version: v2.x - name: Download build artifacts uses: actions/download-artifact@v4 with: name: build path: ./src/datex-web - - - uses: denoland/setup-deno@v2 - with: - deno-version: v2.x - - name: Check formatting run: deno fmt --check @@ -52,6 +49,24 @@ jobs: - name: Type Checking run: deno check -I ./src ./test + test: + runs-on: ubuntu-latest + name: Test + needs: build + steps: + - uses: actions/checkout@v4 + with: + submodules: "true" + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build + path: ./src/datex-web + + - uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + - name: Run Tests run: deno task test-no-build diff --git a/Cargo.lock b/Cargo.lock index e3b2dd6c..7b398b39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -350,9 +350,8 @@ dependencies = [ [[package]] name = "datex-core" -version = "0.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "828f8fd2544e3e7062641e6e1bc64cf2d05d749f8f0765d0f4fd4e588c2a080d" +version = "0.0.11" +source = "git+https://github.com/unyt-org/datex?branch=release%2F0.0.11#fe3421a6e19ef07285ab914fd3436805e477f000" dependencies = [ "ariadne", "async-select", @@ -406,8 +405,7 @@ dependencies = [ [[package]] name = "datex-crypto-facade" version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ea2af04cab3b42b4ab122ed2e850a7837e6d402bb4b9a9ffe0b9cfca7ad26d" +source = "git+https://github.com/unyt-org/datex?branch=release%2F0.0.11#fe3421a6e19ef07285ab914fd3436805e477f000" dependencies = [ "bs58", ] @@ -415,8 +413,7 @@ dependencies = [ [[package]] name = "datex-crypto-web" version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07a56e4ff8e888b4609dd502a1f63e17fd669ae050eee06af97f2a195bdb77c0" +source = "git+https://github.com/unyt-org/datex?branch=release%2F0.0.11#fe3421a6e19ef07285ab914fd3436805e477f000" dependencies = [ "datex-crypto-facade", "wasm-bindgen", @@ -427,8 +424,7 @@ dependencies = [ [[package]] name = "datex-macros-internal" version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6717768303603f37c8d6fd393ae7da7b78ae33b1ad0d6980253fa19005d0b84" +source = "git+https://github.com/unyt-org/datex?branch=release%2F0.0.11#fe3421a6e19ef07285ab914fd3436805e477f000" dependencies = [ "proc-macro2", "quote", @@ -2283,9 +2279,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] @@ -2393,3 +2389,11 @@ name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[patch.unused]] +name = "datex-core" +version = "0.0.11" + +[[patch.unused]] +name = "datex-crypto-facade" +version = "0.0.2" diff --git a/datex-browser-demo/package-lock.json b/datex-browser-demo/package-lock.json index 3f0646ec..7c3fff41 100644 --- a/datex-browser-demo/package-lock.json +++ b/datex-browser-demo/package-lock.json @@ -37,7 +37,7 @@ }, "../npm": { "name": "@unyt/datex", - "version": "0.0.12", + "version": "0.0.14", "license": "MIT" }, "node_modules/@babel/code-frame": { diff --git a/datex-browser-demo/src/demo/demo-runtime.ts b/datex-browser-demo/src/demo/demo-runtime.ts index fe27390f..1efb1b01 100644 --- a/datex-browser-demo/src/demo/demo-runtime.ts +++ b/datex-browser-demo/src/demo/demo-runtime.ts @@ -1,4 +1,4 @@ -import { Ref, Runtime } from "datex"; +import { Endpoint, Range, Ref, Runtime } from "datex"; export const runtime = await Runtime.create( { @@ -6,7 +6,7 @@ export const runtime = await Runtime.create( { type: "websocket-client", config: { - url: "ws://localhost:8043", + url: "wss://example.unyt.land", }, }, ], @@ -25,3 +25,9 @@ runtime.comHub.printMetadata(); globalThis.Datex = runtime; // @ts-ignore global variable for debugging globalThis.Ref = Ref; + +// @ts-ignore global variable for debugging +globalThis.Range = Range; + +// @ts-ignore global variable for debugging +globalThis.Endpoint = Endpoint; diff --git a/deno.json b/deno.json index 0e8571f6..9c82bfc9 100644 --- a/deno.json +++ b/deno.json @@ -16,9 +16,9 @@ ] }, "tasks": { - "debug": "deno run -A scripts/build-wasm.ts --profile debug --features debug", + "debug": "deno run -A scripts/build-wasm.ts --profile debug", "release": "deno run -A scripts/build-wasm.ts --profile release", - "debug-unsecure": "deno run -A scripts/build-wasm.ts --profile debug --features debug,allow_unsigned_blocks", + "debug-unsecure": "deno run -A scripts/build-wasm.ts --profile debug --features allow_unsigned_blocks", "debug-no-opt": "deno task debug --no-opt", "test": "deno task debug-no-opt && deno test -A", @@ -31,7 +31,7 @@ "browser-demo-no-build": "deno task build-npm && cd datex-browser-demo && npm install && npm run dev", "fmt": "deno fmt && cargo fmt", - "lint": "deno lint --fix && cargo clippy --fix --features debug" + "lint": "deno lint --fix && cargo clippy --fix" }, "fmt": { "indentWidth": 4, diff --git a/rs-lib/Cargo.toml b/rs-lib/Cargo.toml index 9b797513..973df437 100644 --- a/rs-lib/Cargo.toml +++ b/rs-lib/Cargo.toml @@ -20,16 +20,14 @@ panic = "abort" [dependencies] log = { version = "0.4", features = ["std", "serde"] } -datex-core = { version = "0.0.10", default-features = false, features = [ +datex-core = { git = "https://github.com/unyt-org/datex", branch = "release/0.0.11", version = "0.0.11", default-features = false, features = [ "target_wasm", "compiler", "decompiler", "syntax_highlighting_legacy", "lsp_wasm", ] } -datex-crypto-facade = { version = "0.0.2" } - -# datex_macros = { git = "https://github.com/unyt-org/datex", branch = "refactor/update-loop", version = "0.1.3", package = "datex_macros" } +datex-crypto-facade = { git = "https://github.com/unyt-org/datex", branch = "release/0.0.11", version = "0.0.2" } async-trait = "0.1.87" url = { version = "2.5.7" } @@ -111,7 +109,6 @@ default = [ "webrtc", "lsp", # Make optional ] -debug = [] lsp = ["datex-core/lsp_wasm"] allow_unsigned_blocks = ["datex-core/allow_unsigned_blocks"] diff --git a/src/dif/core.ts b/src/dif/core.ts index d12aac14..4a1e0c2f 100644 --- a/src/dif/core.ts +++ b/src/dif/core.ts @@ -13,6 +13,7 @@ export const CoreTypeAddress = { map: "0c0000", never: "0d0000", unknown: "0e0000", + range: "100000", decimal: "2c0100", decimal_f32: "2d0100", decimal_f64: "2e0100", diff --git a/src/dif/dif-handler.ts b/src/dif/dif-handler.ts index a27bca2b..ca6b1ea1 100644 --- a/src/dif/dif-handler.ts +++ b/src/dif/dif-handler.ts @@ -1,6 +1,7 @@ import type { JSRuntime, RuntimeDIFHandle } from "../datex.ts"; import { Ref } from "../refs/ref.ts"; import { Endpoint } from "../lib/special-core-types/endpoint.ts"; +import { Range } from "../lib/special-core-types/range.ts"; import { type DIFArray, type DIFMap, @@ -410,6 +411,20 @@ export class DIFHandler { } // endpoint types are resolved to Endpoint instances else if (type === CoreTypeAddress.endpoint) { return Endpoint.get(value.value as string) as T; + } else if (type === CoreTypeAddress.range) { + const [start, end] = value.value as DIFArray; + const result = this.promiseAllOrSync([ + this.resolveDIFValueContainer(start), + this.resolveDIFValueContainer(end), + ]); + if (result instanceof Promise) { + return result.then(([start, end]) => { + return new Range(start, end) as T; + }); + } else { + const [start, end] = result as number[]; + return new Range(start, end) as T; + } } else if (type === CoreTypeAddress.list) { return this.promiseAllOrSync( (value.value as DIFArray).map((v) => this.resolveDIFValueContainer(v)), @@ -1142,6 +1157,14 @@ export class DIFHandler { type: CoreTypeAddress.endpoint, value: value.toString(), }; + } else if (value instanceof Range) { + return { + type: CoreTypeAddress.range, + value: [ + this.convertJSValueToDIFValueContainer(value.start), + this.convertJSValueToDIFValueContainer(value.end), + ], + }; } else if (Array.isArray(value)) { return { value: value.map((v) => this.convertJSValueToDIFValueContainer(v)), diff --git a/src/lib/special-core-types/endpoint.ts b/src/lib/special-core-types/endpoint.ts index 48e515a2..94ac3be3 100644 --- a/src/lib/special-core-types/endpoint.ts +++ b/src/lib/special-core-types/endpoint.ts @@ -52,11 +52,11 @@ export class Endpoint { return this.#endpoint; } - get [Symbol.toStringTag]() { + get [Symbol.toStringTag](): string { return this.#endpoint; } - get [Symbol.toPrimitive]() { + get [Symbol.toPrimitive](): string { return this.#endpoint; } } diff --git a/src/lib/special-core-types/range.ts b/src/lib/special-core-types/range.ts new file mode 100644 index 00000000..0b272c8d --- /dev/null +++ b/src/lib/special-core-types/range.ts @@ -0,0 +1,37 @@ +/** + * Represents a range of numbers with a start and end. + */ +export class Range { + constructor(public start: number, public end: number) {} + + /** + * Gets the length of the range (end - start). + */ + get length(): number { + return this.end - this.start; + } + + /** + * Checks if a given value is within the range (inclusive of start, exclusive of end). + * @param value The number to check. + * @returns True if the value is within the range, false otherwise. + */ + public contains(value: number): boolean { + return value >= this.start && value < this.end; + } + + /** + * Turns a string representation of the range in the format + * @returns The string representation of the range. + */ + public toString(): string { + return `${this.start}..${this.end}`; + } + + get [Symbol.toStringTag](): string { + return this.toString(); + } + get [Symbol.toPrimitive](): string { + return this.toString(); + } +} diff --git a/src/mod.ts b/src/mod.ts index 88027378..c643a755 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -23,5 +23,7 @@ export * from "./runtime/runtime.ts"; export * as DIF from "./dif/mod.ts"; export * as Network from "./network/mod.ts"; +export * from "./lib/special-core-types/endpoint.ts"; +export * from "./lib/special-core-types/range.ts"; export * from "./refs/ref.ts"; import "./utils/devtools-formatter.ts"; diff --git a/src/utils/devtools-formatter.ts b/src/utils/devtools-formatter.ts index 13998e48..c9d14b20 100644 --- a/src/utils/devtools-formatter.ts +++ b/src/utils/devtools-formatter.ts @@ -1,4 +1,5 @@ import { Endpoint } from "../lib/special-core-types/endpoint.ts"; +import { Range } from "../lib/special-core-types/range.ts"; import { Ref } from "../refs/ref.ts"; // @ts-ignore devtoolsFormatters @@ -27,6 +28,26 @@ globalThis.devtoolsFormatters = [ ], ], ]; + } else if (obj instanceof Range) { + return [ + "span", + {}, + [ + "span", + {}, + ["span", { style: "color: #d57258" }, `${obj.start}`], + ], + [ + "span", + {}, + ["span", {}, `..`], + ], + [ + "span", + {}, + ["span", { style: "color: #d57258" }, `${obj.end}`], + ], + ]; } return null; // fall back to default }, diff --git a/test/runtime/execute.test.ts b/test/runtime/execute.test.ts index 56f1d210..3061cd6e 100644 --- a/test/runtime/execute.test.ts +++ b/test/runtime/execute.test.ts @@ -2,6 +2,7 @@ import { Runtime } from "../../src/runtime/runtime.ts"; import { assertEquals } from "@std/assert"; import { Endpoint } from "../../src/lib/special-core-types/endpoint.ts"; import { CoreTypeAddress } from "../../src/dif/core.ts"; +import { Range } from "../../src/lib/special-core-types/range.ts"; Deno.test("execute sync with string result", async () => { const runtime = await Runtime.create({ endpoint: "@jonas" }); const script = "1 + 2"; @@ -112,6 +113,14 @@ Deno.test("execute sync endpoint", async () => { assertEquals(result, Endpoint.get("@jonas")); }); +Deno.test("execute sync range", async () => { + const runtime = await Runtime.create({ endpoint: "@jonas" }); + const result = runtime.executeSync("1..2"); + assertEquals(result.start, 1); + assertEquals(result.end, 2); + assertEquals(result, new Range(1, 2)); +}); + Deno.test("execute sync pass number from JS", async () => { const runtime = await Runtime.create({ endpoint: "@jonas" }); const result = runtime.executeSync("1 + ?", [41]); diff --git a/test/runtime/value-parity.test.ts b/test/runtime/value-parity.test.ts index 4367cc61..cf3fc3c9 100644 --- a/test/runtime/value-parity.test.ts +++ b/test/runtime/value-parity.test.ts @@ -4,7 +4,9 @@ * This is a test for the full integration of the JS runtime with the DATEX runtime. * NOTE: as more JS values are supported, this test should be extended to cover all of them. */ -import { Runtime } from "../../src/runtime/runtime.ts"; +import { Endpoint } from "datex/lib/special-core-types/endpoint.ts"; +import { Runtime } from "datex/runtime/runtime.ts"; +import { Range } from "datex/lib/special-core-types/range.ts"; import { assertEquals } from "@std/assert"; /** @@ -38,6 +40,8 @@ const TEST_VALUES = [ Infinity, -Infinity, 2000n, + Endpoint.get("@test"), + new Range(1, 2), ] as const; // initialization of the test cases