diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c5f2725..18aeb0e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,7 @@ jobs: - js - jupyter - rust - # - rustjswasm + - rustjswasm os: - ubuntu-latest - macos-latest @@ -58,7 +58,7 @@ jobs: - uses: actions-ext/node/setup@main with: - version: 20.x + version: 22.x js_folder: "." - uses: actions-ext/rust/setup@main diff --git a/Makefile b/Makefile index dad8dee..35132f4 100644 --- a/Makefile +++ b/Makefile @@ -88,11 +88,11 @@ test-rust: cd ../python-template-rust && make test test-rustjswasm: - cd ../python-template-rust && git config --global user.name "github-actions" && git config --global user.email "41898282+github-actions[bot]@users.noreply.github.c@example.com" && git init && git add . && git commit -m "initial commit" - cd ../python-template-rust && make develop - cd ../python-template-rust && git add Cargo.lock && git commit -m "lockfile" - cd ../python-template-rust && make lint - cd ../python-template-rust && make checks - cd ../python-template-rust && make test + cd ../python-template-rustjswasm && git config --global user.name "github-actions" && git config --global user.email "41898282+github-actions[bot]@users.noreply.github.c@example.com" && git init && git add . && git commit -m "initial commit" + cd ../python-template-rustjswasm && make develop + cd ../python-template-rustjswasm && git add Cargo.lock && git commit -m "lockfile" + cd ../python-template-rustjswasm && make lint + cd ../python-template-rustjswasm && make checks + cd ../python-template-rustjswasm && make test diff --git a/cpp/.gitignore.jinja b/cpp/.gitignore.jinja index cd4b688..f067a0d 100644 --- a/cpp/.gitignore.jinja +++ b/cpp/.gitignore.jinja @@ -138,6 +138,8 @@ js/coverage js/dist js/lib js/node_modules +js/test-results +js/playwright-report js/*.tgz {{module}}/extension diff --git a/cpp/Makefile.jinja b/cpp/Makefile.jinja index 37ec244..1da8ca9 100644 --- a/cpp/Makefile.jinja +++ b/cpp/Makefile.jinja @@ -113,7 +113,7 @@ major: ## bump a major version ######## .PHONY: dist dist-py dist-check publish -dist-py: # build python dists +dist-py: ## build python dists python -m build -w -s dist-check: ## run python dist checker with twine @@ -121,7 +121,7 @@ dist-check: ## run python dist checker with twine dist: clean build dist-js dist-py dist-check ## build all dists -publish: dist # publish python assets +publish: dist ## publish python assets ######### # CLEAN # diff --git a/js/.github/workflows/build.yaml.jinja b/js/.github/workflows/build.yaml.jinja index f3055f0..9e99c58 100644 --- a/js/.github/workflows/build.yaml.jinja +++ b/js/.github/workflows/build.yaml.jinja @@ -42,7 +42,7 @@ jobs: - uses: actions-ext/node/setup@main with: - version: 20.x + version: 22.x - name: Install dependencies run: make develop diff --git a/js/.gitignore.jinja b/js/.gitignore.jinja index cd4b688..f067a0d 100644 --- a/js/.gitignore.jinja +++ b/js/.gitignore.jinja @@ -138,6 +138,8 @@ js/coverage js/dist js/lib js/node_modules +js/test-results +js/playwright-report js/*.tgz {{module}}/extension diff --git a/js/Makefile.jinja b/js/Makefile.jinja index 91c73f0..b31e2d8 100644 --- a/js/Makefile.jinja +++ b/js/Makefile.jinja @@ -134,7 +134,7 @@ major: ## bump a major version ######## .PHONY: dist dist-py dist-js dist-check publish -dist-py: # build python dists +dist-py: ## build python dists python -m build -w -s dist-js: # build js dists @@ -145,7 +145,7 @@ dist-check: ## run python dist checker with twine dist: clean build dist-js dist-py dist-check ## build all dists -publish: dist # publish python assets +publish: dist ## publish python assets ######### # CLEAN # diff --git a/js/js/.prettierignore b/js/js/.prettierignore deleted file mode 100644 index 664db10..0000000 --- a/js/js/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -*.png -*.svg diff --git a/js/js/package.json.jinja b/js/js/package.json.jinja index c8b8293..fccf0af 100644 --- a/js/js/package.json.jinja +++ b/js/js/package.json.jinja @@ -30,8 +30,8 @@ "build": "node build.mjs", "clean": "rm -rf dist playwright-report ../{{module}}/extension", "dev": "npm-run-all -p start watch", - "lint": "prettier --check \"src/**/*\" \"tests/**/*\" \"*.mjs\" \"*.json\"", - "fix": "prettier --write \"src/**/*\" \"tests/**/*\" \"*.mjs\" \"*.json\"", + "lint": "prettier --check \"src/**/*.{js,ts,jsx,tsx,less,css}\" \"tests/**/*.{js,ts,jsx,tsx}\" \"*.mjs\" \"*.json\"", + "fix": "prettier --write \"src/**/*.{js,ts,jsx,tsx,less,css}\" \"tests/**/*.{js,ts,jsx,tsx}\" \"*.mjs\" \"*.json\"", "preinstall": "npx only-allow pnpm", "prepack": "npm run build", "start": "http-server -p 3000 -o examples/", diff --git a/js/pyproject.toml.jinja b/js/pyproject.toml.jinja index 88996e3..8c2d878 100644 --- a/js/pyproject.toml.jinja +++ b/js/pyproject.toml.jinja @@ -113,9 +113,7 @@ exclude = [ [tool.hatch.build.targets.wheel] packages = ["{{module}}"] -exclude = [ - "/js" -] +exclude = ["/js"] [tool.hatch.build.hooks.hatch-js] path = "js" diff --git a/jupyter/.github/workflows/build.yaml.jinja b/jupyter/.github/workflows/build.yaml.jinja index fbb08c2..446c9a8 100644 --- a/jupyter/.github/workflows/build.yaml.jinja +++ b/jupyter/.github/workflows/build.yaml.jinja @@ -42,7 +42,7 @@ jobs: - uses: actions-ext/node/setup@main with: - version: 20.x + version: 22.x - name: Install dependencies run: make develop diff --git a/jupyter/.gitignore.jinja b/jupyter/.gitignore.jinja index cd4b688..f067a0d 100644 --- a/jupyter/.gitignore.jinja +++ b/jupyter/.gitignore.jinja @@ -138,6 +138,8 @@ js/coverage js/dist js/lib js/node_modules +js/test-results +js/playwright-report js/*.tgz {{module}}/extension diff --git a/jupyter/Makefile.jinja b/jupyter/Makefile.jinja index 4518f15..2bbfaf2 100644 --- a/jupyter/Makefile.jinja +++ b/jupyter/Makefile.jinja @@ -134,7 +134,7 @@ major: ## bump a major version ######## .PHONY: dist dist-py dist-js dist-check publish -dist-py: # build python dists +dist-py: ## build python dists python -m build -w -s dist-js: # build js dists @@ -145,7 +145,7 @@ dist-check: ## run python dist checker with twine dist: clean build dist-js dist-py dist-check ## build all dists -publish: dist # publish python assets +publish: dist ## publish python assets ######### # CLEAN # diff --git a/python/.gitignore.jinja b/python/.gitignore.jinja index cd4b688..f067a0d 100644 --- a/python/.gitignore.jinja +++ b/python/.gitignore.jinja @@ -138,6 +138,8 @@ js/coverage js/dist js/lib js/node_modules +js/test-results +js/playwright-report js/*.tgz {{module}}/extension diff --git a/python/Makefile.jinja b/python/Makefile.jinja index 6d394c3..e2bce1b 100644 --- a/python/Makefile.jinja +++ b/python/Makefile.jinja @@ -100,7 +100,7 @@ dist-check: ## run python dist checker with twine dist: clean dist-build dist-check ## build all dists -publish: dist # publish python assets +publish: dist ## publish python assets ######### # CLEAN # diff --git a/rust/.gitignore.jinja b/rust/.gitignore.jinja index cd4b688..f067a0d 100644 --- a/rust/.gitignore.jinja +++ b/rust/.gitignore.jinja @@ -138,6 +138,8 @@ js/coverage js/dist js/lib js/node_modules +js/test-results +js/playwright-report js/*.tgz {{module}}/extension diff --git a/rust/Makefile.jinja b/rust/Makefile.jinja index 31f55ef..50f8a46 100644 --- a/rust/Makefile.jinja +++ b/rust/Makefile.jinja @@ -21,29 +21,19 @@ requirements-rs: ## install prerequisite rust build requirements requirements: requirements-rs requirements-py ## setup project for development -.PHONY: build-py build-rs build dev +.PHONY: build-py build-rs build build-py: python -m build -w -n build-rs: make -C rust build -dev: build ## lightweight in-place build for iterative dev - $(_CP_COMMAND) - build: build-rs build-py ## build the project .PHONY: install install: ## install python library uv pip install . -UNAME := $(shell uname) -ifeq ($(UNAME), Darwin) - _CP_COMMAND := cp target/debug/lib{{module}}.dylib {{module}}/{{module}}.abi3.so -else - _CP_COMMAND := cp target/debug/lib{{module}}.so {{module}}/{{module}}.abi3.so -endif - ######### # LINTS # ######### @@ -146,13 +136,13 @@ major: ## bump a major version ######## .PHONY: dist-py-wheel dist-py-sdist dist-rs dist-check dist publish -dist-py-wheel: # build python wheel +dist-py-wheel: ## build python wheel python -m cibuildwheel --output-dir dist -dist-py-sdist: # build python sdist +dist-py-sdist: ## build python sdist python -m build --sdist -o dist -dist-rs: # build rust dists +dist-rs: ## build rust dists make -C rust dist dist-check: ## run python dist checker with twine @@ -160,7 +150,7 @@ dist-check: ## run python dist checker with twine dist: clean build dist-rs dist-py-wheel dist-py-sdist dist-check ## build all dists -publish: dist # publish python assets +publish: dist ## publish python assets ######### # CLEAN # diff --git a/rust/pyproject.toml.jinja b/rust/pyproject.toml.jinja index 9f2bed8..17aa740 100644 --- a/rust/pyproject.toml.jinja +++ b/rust/pyproject.toml.jinja @@ -91,24 +91,23 @@ ignore = [ ] [tool.cibuildwheel] -before-build = "curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y" +before-all = "curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y" build = "cp39-*" -skip = "*musllinux*" test-command = "pytest -vvv {project}/{{module}}/tests" test-requires = ["pytest", "pytest-cov", "pytest-sugar", "pytest-xdist"] [tool.cibuildwheel.linux] -before-build = """ +before-all = """ curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y rustup target add aarch64-unknown-linux-gnu rustup target add x86_64-unknown-linux-gnu rustup show """ environment = {PATH="$HOME/.cargo/bin:$PATH", CARGO_TERM_COLOR="always"} -skip = "*i686 musllinux*" +skip = "*i686* *musllinux*" [tool.cibuildwheel.macos] -before-build = """ +before-all = """ curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y rustup target add aarch64-apple-darwin rustup target add x86_64-apple-darwin @@ -118,7 +117,7 @@ environment = {PATH="$HOME/.cargo/bin:$PATH", CARGO_TERM_COLOR="always", MACOS_D archs = "arm64" [tool.cibuildwheel.windows] -before-build = """ +before-all = """ curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y rustup target add x86_64-pc-windows-msvc rustup target add aarch64-pc-windows-msvc diff --git a/rustjswasm/.github/workflows/build.yaml.jinja b/rustjswasm/.github/workflows/build.yaml.jinja index 4adf9a3..b63a5fe 100644 --- a/rustjswasm/.github/workflows/build.yaml.jinja +++ b/rustjswasm/.github/workflows/build.yaml.jinja @@ -31,6 +31,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["{{python_version_primary}}"] + cibuildwheel: ["cp{{python_version_primary.replace('.', '')}}"] node-version: [20.x] steps: @@ -44,13 +45,14 @@ jobs: - uses: actions-ext/node/setup@main with: - version: 20.x + version: 22.x - name: Install dependencies run: make develop - name: Lint run: make lint + if: matrix.os == 'ubuntu-latest' - name: Checks run: make checks @@ -67,7 +69,7 @@ jobs: with: name: {% raw %}test-results-${{ matrix.os }}-${{ matrix.python-version }}{% endraw %} path: '**/junit.xml' - if: {% raw %}${{ always() }}{% endraw %} + if: matrix.os == 'ubuntu-latest' - name: Publish Unit Test Results uses: EnricoMi/publish-unit-test-result-action@v2 @@ -92,6 +94,8 @@ jobs: make dist-py-sdist make dist-py-wheel make dist-check + env: + CIBW_BUILD: {% raw %}"${{ matrix.cibuildwheel }}-manylinux*"{% endraw %} if: matrix.os == 'ubuntu-latest' - name: Make dist diff --git a/rustjswasm/.github/workflows/{% if add_docs %}docs.yaml{% endif %}.jinja b/rustjswasm/.github/workflows/{% if add_docs %}docs.yaml{% endif %}.jinja index 875ab4d..429cd14 100644 --- a/rustjswasm/.github/workflows/{% if add_docs %}docs.yaml{% endif %}.jinja +++ b/rustjswasm/.github/workflows/{% if add_docs %}docs.yaml{% endif %}.jinja @@ -15,6 +15,7 @@ jobs: - uses: actions-ext/python/setup@main - uses: actions-ext/rust/setup@main - uses: actions-ext/node/setup@main + - run: make develop - run: uv pip install . - run: uv pip install yardang - run: yardang build diff --git a/rustjswasm/.gitignore.jinja b/rustjswasm/.gitignore.jinja index 9de3414..f067a0d 100644 --- a/rustjswasm/.gitignore.jinja +++ b/rustjswasm/.gitignore.jinja @@ -138,11 +138,16 @@ js/coverage js/dist js/lib js/node_modules +js/test-results +js/playwright-report js/*.tgz +{{module}}/extension # Jupyter .ipynb_checkpoints .autoversion +!{{module}}/extension/{{module}}.json +!{{module}}/extension/install.json {{module}}/nbextension {{module}}/labextension diff --git a/rustjswasm/Makefile.jinja b/rustjswasm/Makefile.jinja index 1f69b83..9af636a 100644 --- a/rustjswasm/Makefile.jinja +++ b/rustjswasm/Makefile.jinja @@ -26,9 +26,9 @@ requirements-rs: ## install prerequisite rust build requirements requirements: requirements-rs requirements-js requirements-py ## setup project for development -.PHONY: build-py build-js build-rs build dev +.PHONY: build-py build-js build-rs build build-py: - maturin build + python -m build -w -n build-js: cd js; pnpm build @@ -36,22 +36,12 @@ build-js: build-rs: make -C rust build -dev: build ## lightweight in-place build for iterative dev - $(_CP_COMMAND) - build: build-rs build-js build-py ## build the project .PHONY: install install: ## install python library uv pip install . -UNAME := $(shell uname) -ifeq ($(UNAME), Darwin) - _CP_COMMAND := cp target/debug/lib{{module}}.dylib {{module}}/{{module}}.abi3.so -else - _CP_COMMAND := cp target/debug/lib{{module}}.so {{module}}/{{module}}.abi3.so -endif - ######### # LINTS # ######### @@ -169,16 +159,16 @@ major: ## bump a major version ######## .PHONY: dist-py-wheel dist-py-sdist dist-rs dist-check dist publish -dist-py-wheel: # build python wheel +dist-py-wheel: ## build python wheel python -m cibuildwheel --output-dir dist -dist-py-sdist: # build python sdist +dist-py-sdist: ## build python sdist python -m build --sdist -o dist dist-js: # build js dists cd js; pnpm pack -dist-rs: # build rust dists +dist-rs: ## build rust dists make -C rust dist dist-check: ## run python dist checker with twine @@ -186,7 +176,7 @@ dist-check: ## run python dist checker with twine dist: clean build dist-rs dist-js dist-py-wheel dist-py-sdist dist-check ## build all dists -publish: dist # publish python assets +publish: dist ## publish python assets ######### # CLEAN # diff --git a/rustjswasm/js/.eslintrc.js b/rustjswasm/js/.eslintrc.js deleted file mode 100644 index 1882e1e..0000000 --- a/rustjswasm/js/.eslintrc.js +++ /dev/null @@ -1,59 +0,0 @@ -module.exports = { - parser: "@babel/eslint-parser", - extends: ["airbnb-base", "prettier", "plugin:json/recommended"], - plugins: ["prettier", "jest"], - env: { - browser: true, - commonjs: true, - es6: true, - node: true, - jasmine: true, - jest: true, - "jest/globals": true, - }, - parserOptions: { - ecmaVersion: 2017, - ecmaFeatures: {}, - sourceType: "module", - experimentalObjectRestSpread: true, - }, - rules: { - "prettier/prettier": [ - "error", - { - printWidth: 200, - tabWidth: 2, - bracketSpacing: false, - }, - ], - "max-len": [ - "warn", - { - code: 200, - comments: 200, - ignoreTrailingComments: true, - }, - ], - camelcase: "off", - "class-methods-use-this": "off", - "constructor-super": "error", - indent: "off", - "linebreak-style": ["error", "unix"], - "no-const-assign": "error", - "no-nested-ternary": "warn", - "no-this-before-super": "error", - "no-undef": "error", - "no-underscore-dangle": "off", - "no-unreachable": "error", - "no-unused-vars": "warn", - "object-curly-spacing": "off", - quotes: "off", - "spaced-comment": "off", - "valid-typeof": "error", - - "import/extensions": "off", - "import/no-unresolved": "off", - "import/prefer-default-export": "off", - "import/no-extraneous-dependencies": "off", - }, -}; \ No newline at end of file diff --git a/rustjswasm/js/Cargo.lock.jinja b/rustjswasm/js/Cargo.lock.jinja new file mode 100644 index 0000000..aa4be8d --- /dev/null +++ b/rustjswasm/js/Cargo.lock.jinja @@ -0,0 +1,192 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "{{module}}" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "{{module}}_js" +version = "0.1.0" +dependencies = [ + "{{module}}", + "wasm-bindgen", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] diff --git a/rustjswasm/js/Cargo.toml.jinja b/rustjswasm/js/Cargo.toml.jinja new file mode 100644 index 0000000..cc867b0 --- /dev/null +++ b/rustjswasm/js/Cargo.toml.jinja @@ -0,0 +1,20 @@ +[package] +name = "{{module}}_js" +version = "0.1.0" +edition = "2021" +publish = false +keywords = ["experimental"] +include = ["src/**/*", "Cargo.toml", "package.json"] + +[lib] +name = "{{module}}" +path = "src/rust/lib.rs" +crate-type = ["cdylib"] + +[dependencies] +{{module}} = { path = "../rust", version = "*" } +wasm-bindgen = "0.2.84" + +[profile.release] +panic = 'abort' +lto = true \ No newline at end of file diff --git a/rustjswasm/js/babel.config.js b/rustjswasm/js/babel.config.js deleted file mode 100644 index e7f0622..0000000 --- a/rustjswasm/js/babel.config.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - presets: [ - [ - "@babel/preset-env", - { - targets: { - node: "current", - }, - }, - ], - ], - }; \ No newline at end of file diff --git a/rustjswasm/js/build.mjs.jinja b/rustjswasm/js/build.mjs.jinja new file mode 100644 index 0000000..e8f3e67 --- /dev/null +++ b/rustjswasm/js/build.mjs.jinja @@ -0,0 +1,95 @@ +import { NodeModulesExternal } from "@finos/perspective-esbuild-plugin/external.js"; +import { build } from "@finos/perspective-esbuild-plugin/build.js"; +import { BuildCss } from "@prospective.co/procss/target/cjs/procss.js"; +import { getarg } from "./tools/getarg.mjs"; +import fs from "fs"; +import cpy from "cpy"; +import path_mod from "path"; + +const DEBUG = getarg("--debug"); + +const COMMON_DEFINE = { + global: "window", + "process.env.DEBUG": `${DEBUG}`, +}; + +const BUILD = [ + { + define: COMMON_DEFINE, + entryPoints: ["src/ts/index.ts"], + plugins: [NodeModulesExternal()], + format: "esm", + loader: { + ".css": "text", + ".html": "text", + }, + outfile: "dist/esm/index.js", + }, + { + define: COMMON_DEFINE, + entryPoints: ["src/ts/index.ts"], + plugins: [], + format: "esm", + loader: { + ".css": "text", + ".html": "text", + }, + outfile: "dist/cdn/index.js", + }, +]; + +async function compile_css() { + const process_path = (path) => { + const outpath = path.replace("src/less", "dist/css"); + fs.mkdirSync(outpath, { recursive: true }); + + fs.readdirSync(path).forEach((file_or_folder) => { + if (file_or_folder.endsWith(".less")) { + const outfile = file_or_folder.replace(".less", ".css"); + const builder = new BuildCss(""); + builder.add( + `${path}/${file_or_folder}`, + fs + .readFileSync(path_mod.join(`${path}/${file_or_folder}`)) + .toString(), + ); + fs.writeFileSync( + `${path.replace("src/less", "dist/css")}/${outfile}`, + builder.compile().get(outfile), + ); + } else { + process_path(`${path}/${file_or_folder}`); + } + }); + }; + // recursively process all less files in src/less + process_path("src/less"); + cpy("src/css/*", "dist/css/"); +} + +async function copy_html() { + fs.mkdirSync("dist/html", { recursive: true }); + cpy("src/html/*", "dist/html"); + // also copy to top level + cpy("src/html/*", "dist/"); +} + +async function copy_img() { + fs.mkdirSync("dist/img", { recursive: true }); + cpy("src/img/*", "dist/img"); +} + +async function copy_to_python() { + fs.mkdirSync("../{{module}}/extension", { recursive: true }); + cpy("dist/**/*", "../{{module}}/extension"); +} + +async function build_all() { + await compile_css(); + await copy_html(); + await copy_img(); + await Promise.all(BUILD.map(build)).catch(() => process.exit(1)); + await copy_to_python(); +} + +build_all(); diff --git a/rustjswasm/js/jest.config.js b/rustjswasm/js/jest.config.js deleted file mode 100644 index 764a009..0000000 --- a/rustjswasm/js/jest.config.js +++ /dev/null @@ -1,32 +0,0 @@ -const esModules = [ - "@finos", - "@jupyter", - "@jupyterlab", - "@jupyter-widgets", - "@microsoft", - "@rjsf", - "delaunator", - "exenv-es6", - "internmap", - "lib0", - "lodash-es", - "nanoid", - "robust-predicates", - "y-protocols", -].join("|"); - -module.exports = { - moduleDirectories: ["node_modules", "src", "tests"], - moduleNameMapper: { - "\\.(css|less|sass|scss)$": "/tests/styleMock.js", - "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/tests/fileMock.js", - }, - reporters: [ "default", "jest-junit" ], - setupFiles: ["/tests/setup.js"], - testEnvironment: "jsdom", - transform: { - "^.+\\.jsx?$": "babel-jest", - ".+\\.(css|styl|less|sass|scss)$": "jest-transform-css", - }, - transformIgnorePatterns: [`/node_modules/.pnpm/(?!(${esModules}))`], -}; diff --git a/rustjswasm/js/package.json.jinja b/rustjswasm/js/package.json.jinja index 85b6ac1..6e4ac80 100644 --- a/rustjswasm/js/package.json.jinja +++ b/rustjswasm/js/package.json.jinja @@ -5,72 +5,62 @@ "repository": "git@github.com:{{github}}/{{project_name_formatted}}.git", "author": "{{team}} <{{email}}>", "license": "Apache-2.0", - "keywords": [ - "jupyter", - "jupyterlab", - "jupyterlab-extension" - ], - "main": "lib/index.js", + "private": true, + "type": "module", + "unpkg": "dist/cdn/index.js", + "jsdelivr": "dist/cdn/index.js", + "exports": { + ".": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "./dist/*": "./dist/*", + "./package.json": "./package.json" + }, "files": [ - "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", - "style/**/*.css" + "dist/**/*", + "index.d.ts" ], - "jupyterlab": { - "extension": "lib/index.js", - "outputDir": "../{{module}}/labextension", - "discovery": { - "server": { - "base": { - "name": "{{module}}" - }, - "managers": [ - "pip" - ] - } - } + "types": "./dist/esm/index.d.ts", + "publishConfig": { + "access": "public" }, "scripts": { - "build:babel": "babel src/ --source-maps --out-dir lib/", - "build:nbextension": "mkdirp ../{{module}}/nbextension/static/ && cpy --flat 'src/notebook.js' '../{{module}}/nbextension/static/'", - "build:labextension": "rimraf ../{{module}}/labextension && jupyter labextension build .", - "build": "pnpm clean && pnpm build:babel && pnpm build:labextension && pnpm build:nbextension", - "clean": "rimraf lib", - "fix": "pnpm lint --fix", - "lint": "eslint -c .eslintrc.js --ext .js src/ tests/", + "setup": "cargo install -f wasm-bindgen-cli", + "build:debug": "node build.mjs --debug", + "build:rust": "cargo build --release --all-features --target wasm32-unknown-unknown", + "build:wasm-bindgen": "wasm-bindgen target/wasm32-unknown-unknown/release/{{module}}.wasm --out-dir ./dist/pkg --target web", + "build:prod": "node build.mjs", + "build": "npm-run-all build:rust build:wasm-bindgen build:prod", + "clean": "rm -rf dist lib playwright-report ../{{module}}/extension", + "dev": "npm-run-all -p start watch", + "lint:js": "prettier --check \"src/**/*.{js,ts,jsx,tsx,less,css}\" \"tests/**/*.{js,ts,jsx,tsx}\" \"*.mjs\" \"*.json\"", + "lint:rust": "cargo clippy --all-features && cargo fmt --all -- --check", + "lint": "npm-run-all lint:*", + "fix:js": "prettier --write \"src/**/*.{js,ts,jsx,tsx,less,css}\" \"tests/**/*.{js,ts,jsx,tsx}\" \"*.mjs\" \"*.json\"", + "fix:rust": "cargo fmt --all", + "fix": "npm-run-all fix:*", "preinstall": "npx only-allow pnpm", - "prepublishOnly": "pnpm run build", - "test": "jest --coverage --collectCoverageFrom=src/*.{js}" - }, - "dependencies": { - "@jupyterlab/application": "^4.4.2", - "@jupyterlab/apputils": "^4.5.2", - "@jupyterlab/notebook": "^4.4.2", - "@jupyterlab/services": "^7.4.2", - "@lumino/disposable": "^2.1.4" + "prepack": "pnpm run build", + "start": "http-server -p 3000 -o examples/", + "start:tests": "http-server -p 3000 ", + "test:js": "playwright test", + "test:rust": "cargo test -- --show-output", + "test": "npm-run-all test:rust test:js", + "watch": "nodemon --watch src -e ts,less,html --exec \"pnpm build:debug\"" }, + "dependencies": {}, "devDependencies": { - "@babel/cli": "^7.27.2", - "@babel/core": "^7.27.1", - "@babel/eslint-parser": "^7.27.1", - "@babel/preset-env": "^7.27.2", - "@jupyterlab/builder": "^4.4.2", - "babel-jest": "^29.7.0", - "cpy-cli": "^5.0.0", - "eslint": "^8.57.1", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-config-prettier": "^10.1.5", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-jest": "^28.11.0", - "eslint-plugin-json": "^3.1.0", - "eslint-plugin-prettier": "^5.4.0", - "isomorphic-fetch": "^3.0.0", - "jest": "^29.7.0", - "jest-environment-jsdom": "^29.7.0", - "jest-junit": "^16.0.0", - "jest-transform-css": "^6.0.2", - "mkdirp": "^3.0.1", - "prettier": "^3.5.3", - "rimraf": "^6.0.1" + "@finos/perspective-esbuild-plugin": "^3.2.1", + "@playwright/test": "^1.54.2", + "@prospective.co/procss": "^0.1.17", + "cpy": "^11.1.0", + "esbuild": "^0.25.5", + "esbuild-plugin-less": "^1.3.25", + "http-server": "^14.1.1", + "nodemon": "^3.1.10", + "npm-run-all": "^4.1.5", + "prettier": "^3.6.2", + "typescript": "^5.9.2" } } diff --git a/rustjswasm/js/playwright.config.js b/rustjswasm/js/playwright.config.js new file mode 100644 index 0000000..e49718b --- /dev/null +++ b/rustjswasm/js/playwright.config.js @@ -0,0 +1,30 @@ +import { defineConfig, devices } from "@playwright/test"; + +export default defineConfig({ + testDir: "tests", + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: [ + ["line"], + ["html", { outputFile: "playwright-report/index.html", open: "never" }], + ["junit", { outputFile: "junit.xml" }], + ], + use: { + baseURL: "http://127.0.0.1:3000", + trace: "on-first-retry", + }, + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] }, + }, + ], + webServer: { + command: "yarn start:tests", + url: "http://127.0.0.1:3000", + reuseExistingServer: !process.env.CI, + timeout: 120 * 1000, + }, +}); diff --git a/rustjswasm/js/src/html/index.html.jinja b/rustjswasm/js/src/html/index.html.jinja new file mode 100644 index 0000000..5ecca1e --- /dev/null +++ b/rustjswasm/js/src/html/index.html.jinja @@ -0,0 +1,13 @@ + + + + {{project_name}} + + + + + + + + + diff --git a/rustjswasm/js/src/index.js.jinja b/rustjswasm/js/src/index.js.jinja deleted file mode 100644 index 44b4e24..0000000 --- a/rustjswasm/js/src/index.js.jinja +++ /dev/null @@ -1,17 +0,0 @@ -import "../style/index.css"; - -async function activate(app) { - // eslint-disable-next-line no-console - console.log("JupyterLab extension {{project_name_formatted}} is activated!"); -} - -const extension = { - activate, - autoStart: true, - id: "{{project_name_formatted}}", - optional: [], - requires: [], -}; - -export default extension; -export {activate as _activate}; diff --git a/rustjswasm/js/src/notebook.js b/rustjswasm/js/src/less/index.less similarity index 100% rename from rustjswasm/js/src/notebook.js rename to rustjswasm/js/src/less/index.less diff --git a/rustjswasm/js/src/rust/lib.rs b/rustjswasm/js/src/rust/lib.rs new file mode 100644 index 0000000..065776c --- /dev/null +++ b/rustjswasm/js/src/rust/lib.rs @@ -0,0 +1,7 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn foo() -> u32 { + // do something + 1 + 1 +} diff --git a/rustjswasm/js/src/ts/css.d.ts b/rustjswasm/js/src/ts/css.d.ts new file mode 100644 index 0000000..31058d4 --- /dev/null +++ b/rustjswasm/js/src/ts/css.d.ts @@ -0,0 +1,4 @@ +declare module "*.css" { + const content: string; + export default content; +} diff --git a/rustjswasm/js/src/ts/index.ts.jinja b/rustjswasm/js/src/ts/index.ts.jinja new file mode 100644 index 0000000..4c904a0 --- /dev/null +++ b/rustjswasm/js/src/ts/index.ts.jinja @@ -0,0 +1,7 @@ +import * as wasm from "../../dist/pkg/{{module}}"; + +export * as wasm from "../../dist/pkg/{{module}}"; + +export const placeholder = ""; + +export const foo = () => wasm.foo(); diff --git a/rustjswasm/js/style/index.css b/rustjswasm/js/style/index.css deleted file mode 100644 index e69de29..0000000 diff --git a/rustjswasm/js/tests/activate.test.js b/rustjswasm/js/tests/activate.test.js deleted file mode 100644 index 97638e7..0000000 --- a/rustjswasm/js/tests/activate.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import "isomorphic-fetch"; - -import {_activate} from "../src/index"; - -describe("Checks activate", () => { - test("Check activate", () => { - expect(_activate); - }); -}); diff --git a/rustjswasm/js/tests/assetsTransformer.js b/rustjswasm/js/tests/assetsTransformer.js deleted file mode 100644 index 24a24d5..0000000 --- a/rustjswasm/js/tests/assetsTransformer.js +++ /dev/null @@ -1,5 +0,0 @@ -import {basename} from "path"; - -export function process(src, filename) { - return `module.exports = ${JSON.stringify(basename(filename))};`; -} diff --git a/rustjswasm/js/tests/export.test.js b/rustjswasm/js/tests/export.test.js deleted file mode 100644 index ddef5cf..0000000 --- a/rustjswasm/js/tests/export.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import "isomorphic-fetch"; - -import * as extension from "../src/index"; - -describe("Checks exports", () => { - test("Check extension", () => { - expect(extension); - }); -}); diff --git a/rustjswasm/js/tests/fileMock.js b/rustjswasm/js/tests/fileMock.js deleted file mode 100644 index 0a445d0..0000000 --- a/rustjswasm/js/tests/fileMock.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = "test-file-stub"; diff --git a/rustjswasm/js/tests/index.spec.js b/rustjswasm/js/tests/index.spec.js new file mode 100644 index 0000000..0fa5b16 --- /dev/null +++ b/rustjswasm/js/tests/index.spec.js @@ -0,0 +1,7 @@ +import { test, expect } from "@playwright/test"; + +test.describe("Basics", () => { + test("basic", async ({ page }) => { + await expect("").toBe(""); + }); +}); diff --git a/rustjswasm/js/tests/setup.js b/rustjswasm/js/tests/setup.js deleted file mode 100644 index 99f6af5..0000000 --- a/rustjswasm/js/tests/setup.js +++ /dev/null @@ -1,17 +0,0 @@ -Object.defineProperty(window, "DragEvent", { - value: class DragEvent {}, -}); - -Object.defineProperty(window, "matchMedia", { - writable: true, - value: jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // Deprecated - removeListener: jest.fn(), // Deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), -}); diff --git a/rustjswasm/js/tests/styleMock.js b/rustjswasm/js/tests/styleMock.js deleted file mode 100644 index f053ebf..0000000 --- a/rustjswasm/js/tests/styleMock.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {}; diff --git a/rustjswasm/js/tools/getarg.mjs b/rustjswasm/js/tools/getarg.mjs new file mode 100644 index 0000000..30793a7 --- /dev/null +++ b/rustjswasm/js/tools/getarg.mjs @@ -0,0 +1,23 @@ +export const getarg = (flag, ...args) => { + if (Array.isArray(flag)) { + flag = flag.map((x, i) => x + (args[i] || "")).join(""); + } + const argv = process.argv.slice(2); + if (flag) { + const index = argv.indexOf(flag); + if (index > -1) { + const next = argv[index + 1]; + if (next) { + return next; + } else { + return true; + } + } + } else { + return argv + .map(function (arg) { + return "'" + arg.replace(/'/g, "'\\''") + "'"; + }) + .join(" "); + } + }; \ No newline at end of file diff --git a/rustjswasm/js/tsconfig.json b/rustjswasm/js/tsconfig.json new file mode 100644 index 0000000..b25bdae --- /dev/null +++ b/rustjswasm/js/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "allowImportingTsExtensions": true, + "declaration": true, + "emitDeclarationOnly": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "isolatedModules": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "outDir": "./dist/esm", + "resolveJsonModule": true, + "rootDir": ".", + "skipLibCheck": true, + "strict": true, + "target": "ES2020", + "useDefineForClassFields": true + }, + "include": ["./src/ts/*.ts", "./tests/*.ts"] +} diff --git a/rustjswasm/pyproject.toml.jinja b/rustjswasm/pyproject.toml.jinja index 2ed40e9..c107ef1 100644 --- a/rustjswasm/pyproject.toml.jinja +++ b/rustjswasm/pyproject.toml.jinja @@ -35,7 +35,8 @@ develop = [ "check-manifest", "cibuildwheel", "codespell>=2.4,<2.5", - "hatch-jupyter-builder", + "hatch-js", + "hatch-rs", "hatchling", "mdformat>=0.7.22,<0.8", "mdformat-tables>=1", @@ -73,6 +74,11 @@ filename = "js/package.json" search = '"version": "{current_version}"' replace = '"version": "{new_version}"' +[[tool.bumpversion.files]] +filename = "js/Cargo.toml" +search = 'version = "{current_version}"' +replace = 'version = "{new_version}"' + [[tool.bumpversion.files]] filename = "Cargo.toml" search = 'version = "{current_version}"' @@ -86,9 +92,12 @@ replace = 'version = "{new_version}"' [tool.check-manifest] ignore = [ ".copier-answers.yaml", + "Cargo.toml", + "Cargo.lock", "js/pnpm-lock.yaml", "Makefile", ".vscode/*", + "{{module}}/extension/**/*", "docs/**/*", "js/dist/**/*", "rust/.config/*", @@ -97,9 +106,7 @@ ignore = [ ] [tool.cibuildwheel] -before-build = "curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y" build = "cp39-*" -skip = "*musllinux*" test-command = "pytest -vvv {project}/{{module}}/tests" test-requires = ["pytest", "pytest-cov", "pytest-sugar", "pytest-xdist"] @@ -108,30 +115,17 @@ before-build = """ curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y rustup target add aarch64-unknown-linux-gnu rustup target add x86_64-unknown-linux-gnu -rustup show """ -environment = {PATH="$HOME/.cargo/bin:$PATH", CARGO_TERM_COLOR="always"} -archs = "x86_64 aarch64" +environment = {PATH="$HOME/.cargo/bin:$PATH", CARGO_TERM_COLOR="always", SKIP_HATCH_JS="1" } +skip = "*i686* *musllinux*" [tool.cibuildwheel.macos] -before-build = """ -curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y -rustup target add aarch64-apple-darwin -rustup target add x86_64-apple-darwin -rustup show -""" environment = {PATH="$HOME/.cargo/bin:$PATH", CARGO_TERM_COLOR="always", MACOS_DEPLOYMENT_TARGET=11.0} -archs = "x86_64 arm64" +archs = "arm64" [tool.cibuildwheel.windows] -before-build = """ -curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=stable --profile=minimal -y -rustup target add x86_64-pc-windows-msvc -rustup target add aarch64-pc-windows-msvc -rustup show -""" environment = {PATH="$UserProfile\\.cargo\bin;$PATH", CARGO_TERM_COLOR="always"} -archs = "AMD64 ARM64" +skip = "*win32 *arm_64" [tool.coverage.run] branch = true @@ -147,22 +141,24 @@ exclude_also = [ ignore_errors = true fail_under = 50 -[tool.hatch.build.hooks.jupyter-builder] -build-function = "hatch_jupyter_builder.npm_builder" -ensured-targets = [ - "{{module}}/extension/cdn/index.js", -] -skip-if-exists = [ - "{{module}}/extension/cdn/index.js", -] -dependencies = [ - "hatch-jupyter-builder", -] - -[tool.hatch.build.hooks.jupyter-builder.build-kwargs] +[tool.hatch.build.hooks.hatch-js] path = "js" build_cmd = "build" -npm = "pnpm" +tool = "pnpm" +targets = ["{{module}}/extension/cdn/index.js"] + +[tool.hatch.build.hooks.hatch-rs] +verbose = true +module = "{{module}}" +path = "." + +[tool.hatch.build.targets.sdist] +packages = ["{{module}}", "/js", "/rust", "/src"] +sources = ["."] + +[tool.hatch.build.targets.wheel] +packages = ["{{module}}"] +exclude = ["/js", "/rust", "/src"] [tool.pytest.ini_options] addopts = ["-vvv", "--junitxml=junit.xml"] diff --git a/rustjswasm/rust/Makefile.jinja b/rustjswasm/rust/Makefile.jinja index 9951d42..16d2d73 100644 --- a/rustjswasm/rust/Makefile.jinja +++ b/rustjswasm/rust/Makefile.jinja @@ -5,6 +5,8 @@ requirements: ## install required dev dependencies rustup component add clippy cargo install cargo-nextest cargo install cargo-llvm-cov + cargo install -f wasm-bindgen-cli + rustup target add wasm32-unknown-unknown develop: requirements ## install required dev dependencies