diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e7d70fd..fa086b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,4 +103,5 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/main' permissions: contents: write + id-token: write # JSR OIDC publishing (the called workflow requests it) uses: ./.github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b41d62..ad4768e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,7 @@ on: permissions: contents: write + id-token: write # JSR OIDC publishing jobs: release: @@ -27,6 +28,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: true + fetch-depth: 0 # commit count = the JSR prerelease number - uses: dtolnay/rust-toolchain@stable with: targets: wasm32-unknown-unknown @@ -63,13 +65,14 @@ jobs: { echo "Prerelease \`${TAG}\` at ${GITHUB_SHA}." echo - echo "Artifacts: the prebuilt translator shim wasm (standard release" - echo "build — what the test suites run against), the size-tuned" - echo "variant per crates/translator-shim/README.md, and the embedder" + echo "Artifacts: the prebuilt translator shim wasm (size-tuned — the" + echo "exact artifact every test suite runs against) and the embedder" echo "bundle deltic-embedder.mjs (one platform-neutral ES module:" echo "embedder API + Translator + ct-runner + wasi-shims — browsers" - echo "and plain Node, no flags). Consumers need no Rust toolchain;" - echo "see README.md for status and usage." + echo "and plain Node, no flags). Consumers need no Rust toolchain." + echo "The same commit is published to JSR as an unstable prerelease" + echo "of @deltic/{runtime,translator,wasi-shims,ct-runner}; see" + echo "README.md for usage." echo echo '```' cat SHA256SUMS @@ -81,8 +84,28 @@ jobs: --prerelease \ --title "deltic $TAG" \ --notes-file notes.md \ - deltic-translator-shim.wasm deltic-translator-shim-min.wasm \ + deltic-translator-shim.wasm \ deltic-embedder.mjs SHA256SUMS env: GH_TOKEN: ${{ github.token }} TAG: ${{ steps.tag.outputs.tag }} + + - name: publish unstable prereleases to JSR + # Version scheme (issue #16, interim): 0.1.0-pre.
+ # — monotonic, derived from the ref being released, and unique per + # commit (JSR refuses duplicate versions, which also makes re-runs + # of this workflow no-ops-by-failure like the tag guard above). + # The stamped versions are CI-working-tree-only (never committed); + # cross-package workspace deps are rewritten by `deno publish`. + # Auth: OIDC (permissions.id-token) — the @deltic packages must + # exist on jsr.io and be linked to this repository (one-time + # manual setup; see the #16 checklist). + run: | + COUNT=$(git rev-list --count HEAD) + VERSION="0.1.0-pre.${COUNT}" + echo "publishing @deltic/* ${VERSION}" + for p in runtime translator wasi-shims ct-runner; do + jq --arg v "$VERSION" '.version = $v' "$p/deno.json" > "$p/deno.json.tmp" + mv "$p/deno.json.tmp" "$p/deno.json" + done + deno publish --allow-dirty diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ct-runner/deno.json b/ct-runner/deno.json index d2af31c..18a164e 100644 --- a/ct-runner/deno.json +++ b/ct-runner/deno.json @@ -10,5 +10,12 @@ "tasks": { "test": "deno test --allow-read=..,/tmp --allow-write=/tmp --allow-run", "check": "deno check src tests" - } + }, + "publish": { + "exclude": [ + "tests/", + "testdata/" + ] + }, + "license": "Apache-2.0" } diff --git a/ct-runner/src/import-analysis.ts b/ct-runner/src/import-analysis.ts index 6cc1b31..b70eddd 100644 --- a/ct-runner/src/import-analysis.ts +++ b/ct-runner/src/import-analysis.ts @@ -10,8 +10,8 @@ import { NameCollisionError, type PlanLike, requiredImports, -} from "../../runtime/src/embedder/mod.ts"; -import { ImportResolver } from "../../runtime/src/embedder/version.ts"; +} from "@deltic/runtime/embedder"; +import { ImportResolver } from "@deltic/runtime/embedder"; import { TEST_CONTEXT_INTERFACE } from "./context.ts"; /** One or more of the suite's import leaves cannot be resolved (yet). */ diff --git a/ct-runner/src/main.ts b/ct-runner/src/main.ts index 44df70c..a529f17 100644 --- a/ct-runner/src/main.ts +++ b/ct-runner/src/main.ts @@ -20,7 +20,7 @@ // checkout it defaults to the local release build under `target/`. import { Translator } from "../../runtime/src/shim/mod.ts"; -import type { ComponentArtifacts } from "../../runtime/src/embedder/mod.ts"; +import type { ComponentArtifacts } from "@deltic/runtime/embedder"; import { MissingImportsError, runSuite } from "./mod.ts"; const REPO_ROOT = new URL("../../", import.meta.url); diff --git a/ct-runner/src/run-suite.ts b/ct-runner/src/run-suite.ts index 7821b18..e2d397e 100644 --- a/ct-runner/src/run-suite.ts +++ b/ct-runner/src/run-suite.ts @@ -16,7 +16,7 @@ import { instantiate, Trap, WitError, -} from "../../runtime/src/embedder/mod.ts"; +} from "@deltic/runtime/embedder"; import { Context, testContextImportRecord } from "./context.ts"; import { analyzeImports, requireImportsResolved } from "./import-analysis.ts"; import { diff --git a/examples/deno.json b/examples/deno.json index 9989481..89d6a62 100644 --- a/examples/deno.json +++ b/examples/deno.json @@ -1,6 +1,4 @@ { - "name": "@deltic/examples", - "version": "0.0.0", "exports": {}, "tasks": { "hello-world": "./hello-world/run.sh", diff --git a/harness/deno.json b/harness/deno.json index cc86f05..6098fb4 100644 --- a/harness/deno.json +++ b/harness/deno.json @@ -1,5 +1,4 @@ { - "name": "@deltic/harness", "exports": { "./executor": "./src/executor.ts", "./runner": "./src/runner.ts", diff --git a/justfile b/justfile index f36fc12..4a0de6d 100644 --- a/justfile +++ b/justfile @@ -218,15 +218,10 @@ iroh-exam: shim # the size-tuned build leaves the MIN shim in target/; rerun `just shim` # before running test suites locally afterwards. # The release artifacts, exactly as the release workflow publishes them. -release-artifacts: - cargo build -p translator-shim --target wasm32-unknown-unknown --release +# Since the shim recipe adopted the size tuning (#58), the tuned build IS +# the artifact every suite runs against, and the former separate "min" +# variant is redundant — one shim, tested and shipped identically. +release-artifacts: shim cp target/wasm32-unknown-unknown/release/translator_shim.wasm deltic-translator-shim.wasm - cargo build -p translator-shim --release --target wasm32-unknown-unknown \ - --config 'profile.release.opt-level="z"' \ - --config profile.release.lto=true \ - --config profile.release.codegen-units=1 \ - --config 'profile.release.panic="abort"' \ - --config 'profile.release.strip=true' - cp target/wasm32-unknown-unknown/release/translator_shim.wasm deltic-translator-shim-min.wasm deno run -A tools/release-bundle/build.ts --out deltic-embedder.mjs - sha256sum deltic-translator-shim.wasm deltic-translator-shim-min.wasm deltic-embedder.mjs > SHA256SUMS + sha256sum deltic-translator-shim.wasm deltic-embedder.mjs > SHA256SUMS diff --git a/runtime/deno.json b/runtime/deno.json index 399535e..a44d759 100644 --- a/runtime/deno.json +++ b/runtime/deno.json @@ -1,5 +1,6 @@ { "name": "@deltic/runtime", + "version": "0.1.0", "exports": { "./cabi": "./src/cabi/mod.ts", "./cache": "./src/cache/mod.ts", @@ -15,5 +16,11 @@ "test": "deno test --allow-read=..,/tmp --allow-write=/tmp", "check": "deno check src tests", "gen-fixtures": "python3 tests/fixtures/generate.py" - } + }, + "publish": { + "exclude": [ + "tests/" + ] + }, + "license": "Apache-2.0" } diff --git a/runtime/src/jspi/bridge.ts b/runtime/src/jspi/bridge.ts index 5870302..3814418 100644 --- a/runtime/src/jspi/bridge.ts +++ b/runtime/src/jspi/bridge.ts @@ -42,7 +42,7 @@ // results to become Promises where cabi needs a number synchronously. import { assert_ } from "../cabi/trap.ts"; -import { isSupported, makePromising, makeSuspending } from "./mechanics.ts"; +import { type SuspendingImport, isSupported, makePromising, makeSuspending } from "./mechanics.ts"; import { withActivation, claimActivationAmbient, @@ -300,7 +300,7 @@ function attributeContinuation(owner: unknown, r: PromiseLike): Promise export function suspendingImport unknown>( fn: T, mode: SuspensionMode, -): T | WebAssembly.Suspending { +): T | SuspendingImport { if (mode === "plain") return fn; assert_(isSupported(), "jspi mode selected on an engine without JSPI"); const claimingFn = (...args: unknown[]): unknown => { diff --git a/runtime/src/jspi/mechanics.ts b/runtime/src/jspi/mechanics.ts index fb8b6ad..0b895b8 100644 --- a/runtime/src/jspi/mechanics.ts +++ b/runtime/src/jspi/mechanics.ts @@ -36,6 +36,19 @@ import "./types.ts"; +/** + * Opaque public alias for `WebAssembly.Suspending` instances. + * + * The real class is declared by this package's GLOBAL augmentation + * (./types.ts) because JSPI is not yet in the standard TS libs — but a + * published package must not require consumers to hold that augmentation + * just to read our signatures (JSR's public-type output drops `declare + * global`). Public API therefore names this opaque brand; the value is + * exactly a `WebAssembly.Suspending`, usable anywhere an import value is + * expected. + */ +export type SuspendingImport = { readonly __delticSuspending: unique symbol }; + /** True if the current engine implements `WebAssembly.promising` and * `WebAssembly.Suspending`. Both are phase-4 API surface (docs/architecture.md §3): no * fallback path exists or is planned for engines without them. */ @@ -106,7 +119,9 @@ export function makeSuspending< TReturn = unknown, >( fn: (...args: TArgs) => TReturn | Promise, -): WebAssembly.Suspending { +): SuspendingImport { assertSupported(); - return new WebAssembly.Suspending(fn as (...args: unknown[]) => unknown); + return new WebAssembly.Suspending( + fn as (...args: unknown[]) => unknown, + ) as unknown as SuspendingImport; } diff --git a/runtime/src/task/scheduler.ts b/runtime/src/task/scheduler.ts index 719b875..2aff197 100644 --- a/runtime/src/task/scheduler.ts +++ b/runtime/src/task/scheduler.ts @@ -650,7 +650,7 @@ export class Store { * exec/boundary.ts. (definitions.py has no analogue: its host functions run * on real threads.) */ - readonly pendingHostCalls = new Set>(); + readonly pendingHostCalls: Set> = new Set(); /** * An exception raised by a host import's promise (a rejection, or a trap @@ -682,7 +682,7 @@ export class Store { * loop tracks them separately and resumes them when their promise settles. */ // deno-lint-ignore no-explicit-any - readonly awaiting = new Set(); + readonly awaiting: Set = new Set(); /** * Settled-but-unserviced activation tails, in settle order. diff --git a/translator/deno.json b/translator/deno.json index f2609ab..f710095 100644 --- a/translator/deno.json +++ b/translator/deno.json @@ -1,9 +1,18 @@ { "name": "@deltic/translator", "version": "0.1.0", - "exports": { ".": "./mod.ts" }, + "exports": { + ".": "./mod.ts" + }, "tasks": { "test": "deno test --allow-read tests/", "check": "deno check mod.ts tests/" - } + }, + "publish": { + "exclude": [ + "!translator_shim.wasm", + "tests/" + ] + }, + "license": "Apache-2.0" } diff --git a/wasi-shims/deno.json b/wasi-shims/deno.json index ce9fb8b..06841e2 100644 --- a/wasi-shims/deno.json +++ b/wasi-shims/deno.json @@ -1,9 +1,17 @@ { "name": "@deltic/wasi-shims", "version": "0.1.0", - "exports": { ".": "./src/mod.ts" }, + "exports": { + ".": "./src/mod.ts" + }, "tasks": { "test": "deno test --allow-read tests/", "check": "deno check src tests" - } + }, + "publish": { + "exclude": [ + "tests/" + ] + }, + "license": "Apache-2.0" }