Compare commits

...

29 Commits

Author SHA1 Message Date
kingchenc 4d04ab8227 ci(links): exclude GitHub stargazers/network-members from link check (#358)
GitHub returns 404 for /stargazers and /network/members to anonymous clients
(anti-scraping); the README social-footer badges link there, so the lychee link
check (the non-blocking ci.yml job and the standalone links.yml, both using this
config) flagged them as dead. The pages are live in a browser. Exclude them.
2026-07-08 18:29:05 +02:00
kingchenc 7d4ca8c572 fix(deps): bump crossbeam-epoch to 0.9.20 (RUSTSEC-2026-0204) (#359)
RustSec published RUSTSEC-2026-0204: an invalid pointer dereference in the
fmt::Pointer impl for crossbeam-epoch's Atomic and Shared when the underlying
pointer is invalid. It reaches us transitively via crossbeam-deque. The fix is
a lock-only patch bump to the already-compatible 0.9.20 (no Cargo.toml or code
change). cargo-deny's advisories check now passes.
2026-07-08 18:08:37 +02:00
kingchenc d31e127ae2 ci(zizmor): suppress impostor-commit on the dtolnay/rust-toolchain pin (#357)
dtolnay/rust-toolchain moved from rolling stable/nightly branches to version
tags, so the pinned (still valid, still immutable) SHA is no longer reachable
from a branch and zizmor flags it as an impostor-commit. Add the same
`# zizmor: ignore[impostor-commit]` marker the shazam/copilot repos already
use. Comment-only; the action SHA is unchanged.
2026-07-06 12:19:51 +02:00
kingchenc ffc80754d8 docs(readme): bust Camo cache on the star-history image (#356)
The star-history snapshot in the .github repo was briefly overwritten
with a data-less chart; GitHub's Camo image proxy cached that blank SVG.
Append a ?v cache-buster to the <img> URL so Camo refetches the restored
snapshot (same technique as the self-updating banner) and the star curve
renders again.
2026-07-05 23:40:03 +02:00
kingchenc f2b92f89ee docs: add an Ecosystem section to the README (#355)
* docs: add an Ecosystem section to the README

Link the products built on the Wickra core — wickra-exchange,
wickra-backtest, wickra-terminal, wickra-screener and wickra-xray — plus
wickra-radar / wickra-copilot / wickra-shazam as coming soon, and the
docs and marketing sites.

* docs(readme): surface the ecosystem teaser at the top, under the live demo

* docs: list all eight ecosystem products as shipped

wickra-radar, wickra-copilot and wickra-shazam are now live, so drop
the 'coming soon'/'on the way' wording and link them like the rest.
2026-07-04 17:24:16 +02:00
dependabot[bot] 350230cd07 deps(actions): bump the github-actions group with 9 updates (#354)
Bumps the github-actions group with 9 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/setup-python](https://github.com/actions/setup-python) | `6.2.0` | `6.3.0` |
| [taiki-e/install-action](https://github.com/taiki-e/install-action) | `2.82.1` | `2.82.5` |
| [actions/cache](https://github.com/actions/cache) | `5.0.5` | `6.1.0` |
| [actions/setup-go](https://github.com/actions/setup-go) | `6.4.0` | `6.5.0` |
| [r-lib/actions/setup-r](https://github.com/r-lib/actions) | `2.12.0` | `2.12.1` |
| [r-lib/actions/setup-r-dependencies](https://github.com/r-lib/actions) | `2.12.0` | `2.12.1` |
| [actions/setup-java](https://github.com/actions/setup-java) | `5.3.0` | `5.4.0` |
| [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) | `4.1.0` | `4.1.1` |
| [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.6` | `0.5.7` |


Updates `actions/setup-python` from 6.2.0 to 6.3.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...ece7cb06caefa5fff74198d8649806c4678c61a1)

Updates `taiki-e/install-action` from 2.82.1 to 2.82.5
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/8b3c737da4b541bf0fb5a3e0488ff20535badac9...bffeee26d4db9be238a4ea78d8826604ebcb594d)

Updates `actions/cache` from 5.0.5 to 6.1.0
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9)

Updates `actions/setup-go` from 6.4.0 to 6.5.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/4a3601121dd01d1626a1e23e37211e3254c1c06c...924ae3a1cded613372ab5595356fb5720e22ba16)

Updates `r-lib/actions/setup-r` from 2.12.0 to 2.12.1
- [Release notes](https://github.com/r-lib/actions/releases)
- [Changelog](https://github.com/r-lib/actions/blob/v2-branch/NEWS.md)
- [Commits](https://github.com/r-lib/actions/compare/a51a8012b0aab7c32ef9d19bf54da93f3254335e...d3c5be51b12e724e68f33216ca3c148b66d5f0b6)

Updates `r-lib/actions/setup-r-dependencies` from 2.12.0 to 2.12.1
- [Release notes](https://github.com/r-lib/actions/releases)
- [Changelog](https://github.com/r-lib/actions/blob/v2-branch/NEWS.md)
- [Commits](https://github.com/r-lib/actions/compare/a51a8012b0aab7c32ef9d19bf54da93f3254335e...d3c5be51b12e724e68f33216ca3c148b66d5f0b6)

Updates `actions/setup-java` from 5.3.0 to 5.4.0
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/ad2b38190b15e4d6bdf0c97fb4fca8412226d287...1bcf9fb12cf4aa7d266a90ae39939e61372fe520)

Updates `actions/attest-build-provenance` from 4.1.0 to 4.1.1
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32...0f67c3f4856b2e3261c31976d6725780e5e4c373)

Updates `zizmorcore/zizmor-action` from 0.5.6 to 0.5.7
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](https://github.com/zizmorcore/zizmor-action/compare/5f14fd08f7cf1cb1609c1e344975f152c7ee938d...192e21d79ab29983730a13d1382995c2307fbcaa)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: taiki-e/install-action
  dependency-version: 2.82.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/cache
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-go
  dependency-version: 6.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: r-lib/actions/setup-r
  dependency-version: 2.12.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: r-lib/actions/setup-r-dependencies
  dependency-version: 2.12.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/setup-java
  dependency-version: 5.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/attest-build-provenance
  dependency-version: 4.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.5.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-03 18:44:18 +02:00
dependabot[bot] 71df1798b8 deps(nuget): Bump the nuget group with 1 update (#353)
Bumps Microsoft.NET.Test.Sdk from 18.6.0 to 18.7.0

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-03 18:33:43 +02:00
dependabot[bot] 6a86660e30 deps(maven): bump org.wickra:wickra (#352)
Bumps the maven group with 1 update in the /bindings/java/benchmarks directory: [org.wickra:wickra](https://github.com/wickra-lib/wickra).


Updates `org.wickra:wickra` from 0.9.6 to 0.9.7
- [Release notes](https://github.com/wickra-lib/wickra/releases)
- [Changelog](https://github.com/wickra-lib/wickra/blob/main/CHANGELOG.md)
- [Commits](https://github.com/wickra-lib/wickra/compare/v0.9.6...v0.9.7)

---
updated-dependencies:
- dependency-name: org.wickra:wickra
  dependency-version: 0.9.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-03 18:31:34 +02:00
kingchenc 45c11da4fc release: bump 0.9.8 -> 0.9.9 (#351)
* release: bump 0.9.8 -> 0.9.9

* ci(lychee): exclude the CHANGELOG version-compare links

The CHANGELOG compare URLs point at the release tag created *after* the bump is
merged; ci.yml runs on push/PR (never on the tag), so the tag never exists when
lychee runs and 'compare/vX...vY' / 'compare/vY...HEAD' 404. Excluded by the same
pattern mechanism already used for the crates.io / npm package URLs — one pattern
covers every future version, no per-release change needed.
2026-06-29 23:54:48 +02:00
kingchenc 2ae8976292 fix(release): napi-rs CLI 3 renamed 'napi artifacts --dir' to '--output-dir'
The napi-3 migration bumped @napi-rs/cli to 3, but release.yml still used the
CLI-2 flag 'napi artifacts --dir'. CLI 3 rejects it ('Unsupported option name'),
failing the npm publish job (and skipping the GitHub Release). This path only
runs on a v* tag, so it was not exercised by the migration PR's CI.
2026-06-28 02:44:50 +02:00
kingchenc 06b05e6c3e release: bump 0.9.7 -> 0.9.8 (#350) 2026-06-28 01:56:57 +02:00
dependabot[bot] 4ec10826be deps(actions): bump taiki-e/install-action in the github-actions group (#349)
Bumps the github-actions group with 1 update: [taiki-e/install-action](https://github.com/taiki-e/install-action).


Updates `taiki-e/install-action` from 2.82.0 to 2.82.1
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/b8cecb83565409bcc297b2df6e77f030b2a468d5...8b3c737da4b541bf0fb5a3e0488ff20535badac9)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.82.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-28 01:27:15 +02:00
kingchenc 13b2ee5231 ci(dependabot): split the cargo group — isolate napi, pin ureq to 2.x (#348)
The cargo group bundled every crate bump into one PR, which forced the
napi-rs 3 migration (a coordinated CLI + crate major) together with an
unrelated ureq bump. Give napi/napi-derive/napi-build their own group so the
napi-3 work lands as a self-contained PR, and ignore ureq major updates: ureq 3
unconditionally pulls webpki-root-certs (CDLA-Permissive-2.0), which the
native-tls / OS-trust-store setup in wickra-data deliberately avoids.
2026-06-28 00:53:10 +02:00
kingchenc 025d453293 deps(node): migrate the Node binding to napi-rs 3 (#347)
Bumps napi 2.16 -> 3.9 and napi-derive 2.16 -> 3.5 (cargo) and @napi-rs/cli
2.18 -> 3.7 (npm). napi 3's derive macros emit #[allow(unsafe_code)], which the
workspace-wide forbid(unsafe_code) cannot permit, so the Node crate gets its own
[lints] block mirroring the workspace with unsafe_code relaxed to deny — forbid
stays in force for every other crate. The CLI-3-regenerated index.d.ts / index.js
keep the identical 626-symbol public API (only the codegen format changed). MSRV
stays 1.88 (napi 3.9 requires exactly that); ureq is intentionally left at 2.x.
Verified locally: cargo clippy clean, 1108/1108 Node tests pass.

Supersedes the napi half of the cargo group bump and the @napi-rs/cli npm bump.
2026-06-28 00:45:38 +02:00
dependabot[bot] c6972dd476 deps(actions): bump the github-actions group with 4 updates (#346)
Bumps the github-actions group with 4 updates: [actions/checkout](https://github.com/actions/checkout), [taiki-e/install-action](https://github.com/taiki-e/install-action), [actions/setup-java](https://github.com/actions/setup-java) and [softprops/action-gh-release](https://github.com/softprops/action-gh-release).


Updates `actions/checkout` from 6.0.2 to 7.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6.0.2...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

Updates `taiki-e/install-action` from 2.81.10 to 2.82.0
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/7a79fe8c3a13344501c80d99cae481c1c9085912...b8cecb83565409bcc297b2df6e77f030b2a468d5)

Updates `actions/setup-java` from 5.2.0 to 5.3.0
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/be666c2fcd27ec809703dec50e508c2fdc7f6654...ad2b38190b15e4d6bdf0c97fb4fca8412226d287)

Updates `softprops/action-gh-release` from 3.0.0 to 3.0.1
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/b4309332981a82ec1c5618f44dd2e27cc8bfbfda...718ea10b132b3b2eba29c1007bb80653f286566b)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: taiki-e/install-action
  dependency-version: 2.82.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/setup-java
  dependency-version: 5.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-28 00:25:33 +02:00
dependabot[bot] 04b10cf915 deps(maven): bump the maven group across 2 directories with 2 updates (#343)
Bumps the maven group with 1 update in the /bindings/java directory: [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin).
Bumps the maven group with 1 update in the /bindings/java/benchmarks directory: [org.wickra:wickra](https://github.com/wickra-lib/wickra).


Updates `org.sonatype.central:central-publishing-maven-plugin` from 0.10.0 to 0.11.0
- [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits)

Updates `org.wickra:wickra` from 0.8.8 to 0.9.6
- [Release notes](https://github.com/wickra-lib/wickra/releases)
- [Changelog](https://github.com/wickra-lib/wickra/blob/main/CHANGELOG.md)
- [Commits](https://github.com/wickra-lib/wickra/compare/v0.8.8...v0.9.6)

---
updated-dependencies:
- dependency-name: org.sonatype.central:central-publishing-maven-plugin
  dependency-version: 0.11.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: maven
- dependency-name: org.wickra:wickra
  dependency-version: 0.9.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: maven
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-28 00:25:30 +02:00
kingchenc 9368c6655a docs: add banner + self-made badges to binding READMEs, move title under badges, add a rule (#342)
Each binding README now opens with the shared Wickra banner, a row of self-made
SVG badges (CI, codecov, the language registry, License), then the language
title and a horizontal rule separating the header from the body. The main README
gets the same rule under its badge row (no title).
2026-06-24 05:14:17 +02:00
kingchenc 063a1b5192 docs: move the Live demo badge one position forward in the README badge row (#341) 2026-06-24 03:33:19 +02:00
kingchenc fdb4c1e86b docs: link the live in-browser demo (live.wickra.org) (#340)
* docs: link the live in-browser demo (live.wickra.org)

Adds a Live-demo badge + callout to the main README and a callout to all eight
binding READMEs, pointing at the wickra-live in-browser demo of all 514
indicators. DRAFT until live.wickra.org is deployed.

* ci: exclude live.wickra.org from lychee until the wickra-live site is deployed

* Revert "ci: exclude live.wickra.org from lychee until the wickra-live site is deployed"

This reverts commit 3809d4a3b3.
2026-06-24 03:27:01 +02:00
kingchenc 57e52c67b9 ci: add external link check (lychee, hybrid non-blocking) (#339)
* ci: add external link check (lychee, scheduled + on-demand)

Adds a non-blocking external-link checker mirroring wickra-docs: an
authoritative weekly + on-demand lychee run (this workflow), kept off the
PR/release path so a flaky third-party site can never block a merge or an
irreversible publish. Fixes the one redirecting link it would flag
(docs.rs/wickra -> docs.rs/wickra/latest/wickra/ in SUPPORT.md).

* ci: run lychee as a non-blocking PR job (continue-on-error)

Hybrid link-check: the authoritative run is the scheduled links.yml; this
adds an early heads-up on PRs that never gates the merge. release.yml stays
ungated so a flaky third-party site can never block an irreversible publish.
2026-06-22 15:59:14 +02:00
kingchenc 96cd9b3f02 release: bump 0.9.6 -> 0.9.7 (#338) 2026-06-21 16:07:53 +02:00
dependabot[bot] 98bb57c868 deps(actions): bump the github-actions group with 4 updates (#336)
Bumps the github-actions group with 4 updates: [actions/setup-python](https://github.com/actions/setup-python), [actions/upload-artifact](https://github.com/actions/upload-artifact), [taiki-e/install-action](https://github.com/taiki-e/install-action) and [codecov/codecov-action](https://github.com/codecov/codecov-action).


Updates `actions/setup-python` from 5.6.0 to 6.2.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.6.0...a309ff8b426b58ec0e2a45f0f869d46889d02405)

Updates `actions/upload-artifact` from 4.6.2 to 7.0.1
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4.6.2...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a)

Updates `taiki-e/install-action` from 2.81.6 to 2.81.10
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/59012be0884e296ca2da49b530610e72c49039ad...7a79fe8c3a13344501c80d99cae481c1c9085912)

Updates `codecov/codecov-action` from 6.0.1 to 7.0.0
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/e79a6962e0d4c0c17b229090214935d2e33f8354...fb8b3582c8e4def4969c97caa2f19720cb33a72f)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: taiki-e/install-action
  dependency-version: 2.81.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: codecov/codecov-action
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-21 15:30:13 +02:00
dependabot[bot] be05eb26d5 deps(nuget): Bump the nuget group with 3 updates (#337)
Bumps Microsoft.NET.Test.Sdk from 17.11.1 to 18.6.0
Bumps xunit from 2.9.2 to 2.9.3
Bumps xunit.runner.visualstudio from 2.8.2 to 3.1.5

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.6.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: nuget
- dependency-name: xunit
  dependency-version: 2.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget
- dependency-name: xunit.runner.visualstudio
  dependency-version: 3.1.5
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: nuget
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-21 15:30:10 +02:00
dependabot[bot] af59e6eec0 deps(maven): bump org.wickra:wickra (#333)
Bumps the maven group with 1 update in the /bindings/java/benchmarks directory: [org.wickra:wickra](https://github.com/wickra-lib/wickra).


Updates `org.wickra:wickra` from 0.8.2 to 0.8.8
- [Release notes](https://github.com/wickra-lib/wickra/releases)
- [Changelog](https://github.com/wickra-lib/wickra/blob/main/CHANGELOG.md)
- [Commits](https://github.com/wickra-lib/wickra/compare/v0.8.2...v0.8.8)

---
updated-dependencies:
- dependency-name: org.wickra:wickra
  dependency-version: 0.8.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-21 15:30:07 +02:00
kingchenc 96ae63799d fix(r): credit kingchenc as R package author/maintainer (#332)
Every other binding (Python, Node, Rust core) credits kingchenc; the R
DESCRIPTION was an outlier with "Wickra contributors" as the sole
aut/cre, introduced when the binding was added (#230). Use kingchenc to
match, regenerate the package .Rd, and align the LICENSE copyright holder
with the root LICENSE-MIT ("kingchenc and the Wickra contributors").
2026-06-18 04:49:24 +02:00
kingchenc d5f5e14dda release: bump 0.9.5 -> 0.9.6 (#331)
Documentation release for the R binding. The library API and every indicator are
unchanged from `0.9.5`; only the R package's help pages change.

### What's in 0.9.6
- **R package documentation** (landed in #330): the twelve undocumented data-layer
  exports now have full man pages, the stale `AwesomeOscillatorHistogram` codoc is
  fixed, and a broken `push()` example is corrected — clearing the two `R CMD check`
  warnings r-universe reported for `0.9.5`. CI now runs `R CMD check` so doc drift
  fails the PR instead of reaching r-universe.

Pure version-string bump on top — `bump_version.py` touched 19 files. `cargo fmt`
clean.

Tag/publish waits for explicit GO (irreversible publish to crates.io / PyPI / npm
/ NuGet / Maven / Go / r-universe).
2026-06-18 02:10:03 +02:00
kingchenc 7e5d394f2a fix(r): document the data-layer exports + add an R CMD check gate (#330)
Clears the R CMD check **WARNING**s r-universe surfaced when it finally built
0.9.5 (it was stuck on 0.9.2, before the data layer existed): 11/13 platform
builds reported the same two warnings.

### Warnings fixed
1. **Undocumented code objects** — the data layer added in 0.9.3 (`BinanceFeed`,
   `CandleReader`, `Resampler`, `TickAggregator`, `fetch_binance_klines` and the
   generics `name` / `is_ready` / `warmup_period` / `push` / `read`). The roxygen
   blocks existed in `methods.R`, but the `man/*.Rd` were never regenerated, and
   the constructors had only a title.
2. **Codoc mismatch** — `AwesomeOscillatorHistogram.Rd` still documented
   `sma_period` after the argument was renamed to `lookback`.

### Changes
- Full `@param`/`@return` roxygen on the seven data-layer constructors.
- Regenerated `man/*.Rd` + `NAMESPACE` with roxygen2: 13 new pages, the stale
  AwesomeOscillator usage refreshed, and `flush` registered on `base::flush`.
- Fixed the `push()` example (`TickAggregator(1000)` was missing the required
  `gap_fill`) — it only ran once `push()` got a generated `.Rd`.
- **New CI gate:** a ubuntu-only `R CMD check` in the `r` job that fails on doc
  WARNING/ERROR, so stale docs fail the PR instead of reaching r-universe.

Verified locally with `R CMD check` (R 4.6.0 + Rtools45): *missing documentation
entries* and *Rd \usage sections* now **OK**, examples **OK**, tests **OK**. This
PR's own CI exercises the new gate.

Follow-up: a separate `0.9.6` release ships these doc fixes to r-universe.
2026-06-18 01:38:44 +02:00
kingchenc ff268500ef release: bump 0.9.4 -> 0.9.5 (#329)
Maintenance release. The library API and every indicator are unchanged from
`0.9.4`; the only change that ships to users is the R package's build script.

### What's in 0.9.5
- **R package: retry the C ABI download** (`bindings/r/configure[.win]`). A freshly
  cut release can briefly 404 while assets propagate; the download is now retried
  with a ~2 min backoff instead of failing with `cannot open URL … 404`. Landed in
  #328; ships to r-universe / source installs with this release.
- The rest of #328 — CI/release-pipeline hardening (R/NuGet dependency caching,
  job timeouts 20→30 / release 45, network-install retries, wasm-publish cache) —
  is infrastructure and does not affect the published artifacts, but makes this
  release's own pipeline more robust.

Pure version-string bump on top — `bump_version.py` touched 19 files (Cargo +
Lock, pyproject, node package.json/locks + 6 platform stubs, pom + csproj +
DESCRIPTION, SECURITY, CHANGELOG `[0.9.5]` + compare URLs). `cargo fmt` clean.

Tag/publish waits for explicit GO (irreversible publish to crates.io / PyPI /
npm / NuGet / Maven / Go / r-universe).
2026-06-17 23:55:18 +02:00
kingchenc 929fc17127 ci: harden cache, timeouts and retries across CI and release (#328)
Hardens both workflows after the R-on-ubuntu job repeatedly hit the 20-minute
job cap and was cancelled (no R-package cache + no retry + a slow source build).
Each item below maps to the requested checklist.

### CI (`ci.yml`)
- **Timeouts 20 → 30 min** on every job (backstop only; real jobs finish well under).
- **R dependencies cached**: replace the manual `install.packages(testthat/knitr)`
  with `r-lib/actions/setup-r-dependencies` — restores a cached R library and pulls
  **RSPM binaries** instead of compiling from source (the slow/flaky path that blew
  the cap). This is the actual root-cause fix.
- **NuGet cache** for the C# job (`~/.nuget/packages`, keyed on the project files).
- **Retry** the network installs that had none — `npm ci`, `dotnet test`,
  `mvn install` — via `nick-fields/retry` (2–3 attempts, backoff). On top of the
  existing env-level retries (`CARGO_NET_RETRY`, `npm_config_fetch_retries`,
  `PIP_RETRIES`) and the setup-* CDN-flake retries.
- **Go stays `cache: false`** on purpose: the module has no `go.sum` / external
  deps, so there is nothing to cache (enabling it would only warn).

### Release (`release.yml`)
- **Per-job timeouts** added (there were none — only GitHub's 6h default): **45 min**,
  higher than CI's 30 because the wheel/build jobs compile from source incl.
  **vendored OpenSSL** and must not be killed mid-build.
- **wasm-publish** gets a `Swatinem/rust-cache` like the other Rust-build jobs.
- **Retry** the no-retry network installs (`npm ci` ×2, `dotnet pack`). The actual
  publish/deploy steps are left alone — they are already idempotent
  (skip-existing / skip-duplicate), so re-running the job is the safe recovery.

### R binding download (`bindings/r/configure[.win]`)
- A freshly cut release can 404 for 1–2 min while assets propagate, which broke
  the C ABI download (`cannot open URL … 404`). Add a `wickra_download` retry
  helper (6 × 20s ≈ 2 min backoff) for both the release-asset and wasm-source
  downloads. Note: the CI R job builds the C ABI **locally** (`WICKRA_*_DIR`), so
  it never downloads — this fix covers the real-world r-universe / end-user build.

This PR's own CI exercises the CI changes (the reworked R job, caches, retries,
timeouts) before merge; the release-only changes are validated on the next tag.
2026-06-17 23:42:06 +02:00
68 changed files with 10921 additions and 6838 deletions
+2 -2
View File
@@ -23,7 +23,7 @@ runs:
using: composite using: composite
steps: steps:
- id: first - id: first
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # zizmor: ignore[impostor-commit] pinned to the stable-tag SHA (2026-03-27); tag-pinned, not a branch commit
continue-on-error: true continue-on-error: true
with: with:
toolchain: ${{ inputs.toolchain }} toolchain: ${{ inputs.toolchain }}
@@ -39,7 +39,7 @@ runs:
- name: Retry the Rust toolchain install - name: Retry the Rust toolchain install
if: steps.first.outcome == 'failure' if: steps.first.outcome == 'failure'
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # zizmor: ignore[impostor-commit] pinned to the stable-tag SHA (2026-03-27); tag-pinned, not a branch commit
with: with:
toolchain: ${{ inputs.toolchain }} toolchain: ${{ inputs.toolchain }}
components: ${{ inputs.components }} components: ${{ inputs.components }}
+13
View File
@@ -10,9 +10,22 @@ updates:
default-days: 7 default-days: 7
commit-message: commit-message:
prefix: "deps(cargo)" prefix: "deps(cargo)"
# ureq is intentionally pinned to 2.x. ureq 3 unconditionally pulls
# webpki-root-certs (CDLA-Permissive-2.0); the native-tls / OS-trust-store
# setup in wickra-data deliberately avoids that licence. Block the major
# bump (2.x patch/minor still flow through).
ignore:
- dependency-name: "ureq"
update-types: ["version-update:semver-major"]
groups: groups:
# napi-rs (napi / napi-derive / napi-build) is a coordinated major
# migration that must move with @napi-rs/cli on the npm side — keep it in
# its own PR rather than bundled with unrelated crate bumps.
napi:
patterns: ["napi", "napi-derive", "napi-build"]
cargo: cargo:
patterns: ["*"] patterns: ["*"]
exclude-patterns: ["napi", "napi-derive", "napi-build"]
# Node binding npm dependencies. # Node binding npm dependencies.
- package-ecosystem: npm - package-ecosystem: npm
+4 -4
View File
@@ -48,7 +48,7 @@ jobs:
name: Cross-library benchmark report name: Cross-library benchmark report
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -61,7 +61,7 @@ jobs:
- name: Set up Python - name: Set up Python
id: setup_python id: setup_python
continue-on-error: true continue-on-error: true
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.11" python-version: "3.11"
cache: pip cache: pip
@@ -76,7 +76,7 @@ jobs:
- name: Set up Python (retry) - name: Set up Python (retry)
if: steps.setup_python.outcome == 'failure' if: steps.setup_python.outcome == 'failure'
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.11" python-version: "3.11"
cache: pip cache: pip
@@ -122,7 +122,7 @@ jobs:
name: Rust cross-library benchmark report name: Rust cross-library benchmark report
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
+145 -56
View File
@@ -34,13 +34,13 @@ jobs:
rust: rust:
name: Rust ${{ matrix.os }} name: Rust ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -105,9 +105,9 @@ jobs:
examples-smoke: examples-smoke:
name: Examples (syntax smoke) name: Examples (syntax smoke)
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -134,7 +134,7 @@ jobs:
- name: Set up Python - name: Set up Python
id: setup_python id: setup_python
continue-on-error: true continue-on-error: true
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.12" python-version: "3.12"
@@ -147,7 +147,7 @@ jobs:
- name: Set up Python (retry) - name: Set up Python (retry)
if: steps.setup_python.outcome == 'failure' if: steps.setup_python.outcome == 'failure'
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.12" python-version: "3.12"
@@ -195,9 +195,9 @@ jobs:
clippy-bindings: clippy-bindings:
name: Clippy bindings name: Clippy bindings
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -209,7 +209,7 @@ jobs:
- name: Set up Python - name: Set up Python
id: setup_python id: setup_python
continue-on-error: true continue-on-error: true
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.12" python-version: "3.12"
@@ -222,7 +222,7 @@ jobs:
- name: Set up Python (retry) - name: Set up Python (retry)
if: steps.setup_python.outcome == 'failure' if: steps.setup_python.outcome == 'failure'
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.12" python-version: "3.12"
@@ -279,7 +279,7 @@ jobs:
msrv: msrv:
name: ${{ matrix.name }} name: ${{ matrix.name }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -291,7 +291,7 @@ jobs:
toolchain: "1.88" toolchain: "1.88"
packages: "-p wickra-node" packages: "-p wickra-node"
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -328,9 +328,9 @@ jobs:
coverage: coverage:
name: Coverage name: Coverage
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -345,7 +345,7 @@ jobs:
timeout-minutes: 6 timeout-minutes: 6
- name: Install cargo-llvm-cov - name: Install cargo-llvm-cov
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6 uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
with: with:
tool: cargo-llvm-cov tool: cargo-llvm-cov
@@ -358,7 +358,7 @@ jobs:
--lcov --output-path lcov.info --lcov --output-path lcov.info
- name: Upload to Codecov - name: Upload to Codecov
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with: with:
files: lcov.info files: lcov.info
fail_ci_if_error: false fail_ci_if_error: false
@@ -370,9 +370,9 @@ jobs:
supply-chain: supply-chain:
name: Supply-chain (cargo-deny) name: Supply-chain (cargo-deny)
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -389,9 +389,9 @@ jobs:
fuzz-smoke: fuzz-smoke:
name: Fuzz (smoke) name: Fuzz (smoke)
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -415,7 +415,7 @@ jobs:
# attributes the modern nightly compiler rejects, so the install # attributes the modern nightly compiler rejects, so the install
# never gets off the ground. The prebuilt binary avoids the entire # never gets off the ground. The prebuilt binary avoids the entire
# transitive-dep compile. # transitive-dep compile.
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6 uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
with: with:
tool: cargo-fuzz tool: cargo-fuzz
@@ -443,14 +443,14 @@ jobs:
python: python:
name: Python ${{ matrix.python-version }} on ${{ matrix.os }} name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.11", "3.12", "3.13"] python-version: ["3.9", "3.11", "3.12", "3.13"]
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -470,7 +470,7 @@ jobs:
- name: Set up Python - name: Set up Python
id: setup_python id: setup_python
continue-on-error: true continue-on-error: true
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: pip cache: pip
@@ -485,7 +485,7 @@ jobs:
- name: Set up Python (retry) - name: Set up Python (retry)
if: steps.setup_python.outcome == 'failure' if: steps.setup_python.outcome == 'failure'
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: pip cache: pip
@@ -525,9 +525,9 @@ jobs:
wasm: wasm:
name: WASM build name: WASM build
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -549,7 +549,7 @@ jobs:
# same taiki-e prebuilt-binary installer we already use for # same taiki-e prebuilt-binary installer we already use for
# cargo-llvm-cov and cargo-fuzz; it tracks the latest wasm-pack # cargo-llvm-cov and cargo-fuzz; it tracks the latest wasm-pack
# release, which has `--features` as a top-level flag (since 0.12). # release, which has `--features` as a top-level flag (since 0.12).
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6 uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
with: with:
tool: wasm-pack tool: wasm-pack
@@ -575,14 +575,14 @@ jobs:
node: node:
name: Node ${{ matrix.node-version }} on ${{ matrix.os }} name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
node-version: ["22", "24"] node-version: ["22", "24"]
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -622,9 +622,17 @@ jobs:
cache: npm cache: npm
cache-dependency-path: bindings/node/package-lock.json cache-dependency-path: bindings/node/package-lock.json
# npm's own fetch-retry (npm_config_fetch_retries) rides out per-request
# blips; wrap the whole `npm ci` once more so a longer registry hiccup
# retries the install instead of failing the job.
- name: Install Node dependencies - name: Install Node dependencies
working-directory: bindings/node uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
run: npm ci with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 20
command: cd bindings/node && npm ci
shell: bash
- name: Build native module - name: Build native module
working-directory: bindings/node working-directory: bindings/node
@@ -649,13 +657,13 @@ jobs:
c-abi: c-abi:
name: C ABI on ${{ matrix.os }} name: C ABI on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -668,7 +676,7 @@ jobs:
timeout-minutes: 6 timeout-minutes: 6
- name: Install cbindgen - name: Install cbindgen
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6 uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
with: with:
tool: cbindgen tool: cbindgen
@@ -705,13 +713,13 @@ jobs:
csharp: csharp:
name: C# on ${{ matrix.os }} name: C# on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -723,6 +731,19 @@ jobs:
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
timeout-minutes: 6 timeout-minutes: 6
# Cache the restored NuGet packages so dotnet test/build resolve from the
# local store instead of hitting nuget.org every run. No packages.lock.json
# exists, so key on the project files; never block the job on a slow restore.
- name: Cache NuGet packages
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
continue-on-error: true
timeout-minutes: 6
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: |
${{ runner.os }}-nuget-
# The binding links against the C ABI hub at runtime; build it first so the # The binding links against the C ABI hub at runtime; build it first so the
# DllImportResolver finds target/release/wickra.{dll,so,dylib}. .NET 8 SDK is # DllImportResolver finds target/release/wickra.{dll,so,dylib}. .NET 8 SDK is
# preinstalled on the GitHub runners, so no setup-dotnet step is needed. # preinstalled on the GitHub runners, so no setup-dotnet step is needed.
@@ -732,8 +753,17 @@ jobs:
- name: .NET info - name: .NET info
run: dotnet --info run: dotnet --info
# dotnet test restores from nuget.org first; retry so a transient restore
# blip retries instead of failing the job (the cached packages above make
# the retry cheap).
- name: Test the C# binding - name: Test the C# binding
run: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
with:
timeout_minutes: 15
max_attempts: 2
retry_wait_seconds: 20
command: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release
shell: bash
- name: Build the C# examples - name: Build the C# examples
shell: bash shell: bash
@@ -756,13 +786,13 @@ jobs:
go: go:
name: Go on ${{ matrix.os }} name: Go on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -772,7 +802,7 @@ jobs:
- name: Set up Go - name: Set up Go
id: setup-go id: setup-go
continue-on-error: true continue-on-error: true
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with: with:
go-version: "stable" go-version: "stable"
cache: false cache: false
@@ -786,7 +816,7 @@ jobs:
- name: Set up Go (retry) - name: Set up Go (retry)
if: steps.setup-go.outcome == 'failure' if: steps.setup-go.outcome == 'failure'
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with: with:
go-version: "stable" go-version: "stable"
cache: false cache: false
@@ -879,7 +909,7 @@ jobs:
r: r:
name: R on ${{ matrix.os }} name: R on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -888,7 +918,7 @@ jobs:
WICKRA_INCLUDE_DIR: ${{ github.workspace }}/bindings/c/include WICKRA_INCLUDE_DIR: ${{ github.workspace }}/bindings/c/include
WICKRA_LIB_DIR: ${{ github.workspace }}/target/release WICKRA_LIB_DIR: ${{ github.workspace }}/target/release
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -907,15 +937,22 @@ jobs:
run: cargo build -p wickra-c --release run: cargo build -p wickra-c --release
- name: Set up R - name: Set up R
uses: r-lib/actions/setup-r@a51a8012b0aab7c32ef9d19bf54da93f3254335e # v2 uses: r-lib/actions/setup-r@d3c5be51b12e724e68f33216ca3c148b66d5f0b6 # v2
with: with:
r-version: "release" r-version: "release"
use-public-rspm: true use-public-rspm: true
# Use the repos configured by setup-r (use-public-rspm) so Linux installs # Install the R dependencies via setup-r-dependencies: it restores a cached
# binary packages — building testthat's deps from source is slow and flaky. # package library (actions/cache) and pulls RSPM *binaries* instead of
- name: Install test dependency # compiling testthat / knitr and their deps from source — the slow, flaky
run: Rscript -e 'install.packages("testthat")' # path that previously blew past the job timeout on the ubuntu runner.
- name: Install R dependencies (cached binaries)
uses: r-lib/actions/setup-r-dependencies@d3c5be51b12e724e68f33216ca3c148b66d5f0b6 # v2
with:
working-directory: bindings/r
extra-packages: |
any::testthat
any::knitr
- name: Install and test the R binding - name: Install and test the R binding
shell: bash shell: bash
@@ -932,14 +969,39 @@ jobs:
R CMD INSTALL bindings/r R CMD INSTALL bindings/r
Rscript -e 'library(testthat); library(wickra); test_dir("bindings/r/tests/testthat", stop_on_failure = TRUE)' Rscript -e 'library(testthat); library(wickra); test_dir("bindings/r/tests/testthat", stop_on_failure = TRUE)'
# Full R CMD check, gated on the documentation problems r-universe surfaces
# (undocumented exported objects, codoc mismatches) that R CMD INSTALL above
# does not catch — exactly what shipped stale to r-universe with the 0.9.3
# data layer. Ubuntu-only; these checks are platform-independent. Vignettes
# are skipped here (building them needs pandoc and the vignette is exercised
# in the next step), so the two --no-build-vignettes warnings are ignored.
- name: R CMD check (documentation & consistency, like r-universe)
if: matrix.os == 'ubuntu-latest'
shell: bash
run: |
export WICKRA_INCLUDE_DIR="${WICKRA_INCLUDE_DIR//\\//}"
export WICKRA_LIB_DIR="${WICKRA_LIB_DIR//\\//}"
R CMD build bindings/r --no-build-vignettes --no-manual
R CMD check wickra_*.tar.gz --no-manual --no-vignettes --no-tests || true
log=$(find . -maxdepth 2 -name 00check.log | head -1)
echo "::group::00check.log"; cat "$log"; echo "::endgroup::"
problems=$(grep -E '\.\.\. (WARNING|ERROR)' "$log" \
| grep -vE "checking (files in .vignettes.|package vignettes)" || true)
if [ -n "$problems" ]; then
echo "::error::R CMD check found problems (run roxygen2::roxygenise() in bindings/r if the docs are stale):"
echo "$problems"
exit 1
fi
echo "R CMD check: documentation and consistency clean."
- name: Build the vignette code - name: Build the vignette code
shell: bash shell: bash
# The getting-started vignette runs at R CMD check time on r-universe / # The getting-started vignette runs at R CMD check time on r-universe /
# CRAN (with pandoc); this job only INSTALLs, so execute the vignette's R # CRAN (with pandoc); this job only INSTALLs, so execute the vignette's R
# chunks here (knit, no pandoc needed) to catch a broken example before it # chunks here (knit, no pandoc needed) to catch a broken example before it
# reaches the published build. # reaches the published build.
# knitr is installed by the cached setup-r-dependencies step above.
run: | run: |
Rscript -e 'install.packages("knitr", repos = Sys.getenv("RSPM", unset = "https://cloud.r-project.org"))'
Rscript -e 'knitr::knit("bindings/r/vignettes/getting-started.Rmd", output = tempfile(fileext = ".md"), quiet = TRUE); cat("vignette code OK\n")' Rscript -e 'knitr::knit("bindings/r/vignettes/getting-started.Rmd", output = tempfile(fileext = ".md"), quiet = TRUE); cat("vignette code OK\n")'
- name: Run the offline R examples - name: Run the offline R examples
@@ -961,13 +1023,13 @@ jobs:
java: java:
name: Java on ${{ matrix.os }} name: Java on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min) timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -990,7 +1052,7 @@ jobs:
- name: Set up JDK 25 - name: Set up JDK 25
id: setup-java id: setup-java
continue-on-error: true continue-on-error: true
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
with: with:
distribution: temurin distribution: temurin
java-version: "25" java-version: "25"
@@ -1005,7 +1067,7 @@ jobs:
- name: Set up JDK 25 (retry) - name: Set up JDK 25 (retry)
if: steps.setup-java.outcome == 'failure' if: steps.setup-java.outcome == 'failure'
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
with: with:
distribution: temurin distribution: temurin
java-version: "25" java-version: "25"
@@ -1016,8 +1078,16 @@ jobs:
# `install` runs the archetype test suite (the real FFI boundary check) and # `install` runs the archetype test suite (the real FFI boundary check) and
# installs the binding to the local repo so the examples can resolve it. # installs the binding to the local repo so the examples can resolve it.
# Maven resolves plugins/deps from the network on a cache miss; retry so a
# transient Central blip retries instead of failing the job.
- name: Test and install the Java binding - name: Test and install the Java binding
run: mvn -B -f bindings/java install uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
with:
timeout_minutes: 20
max_attempts: 2
retry_wait_seconds: 20
command: mvn -B -f bindings/java install
shell: bash
- name: Build the Java examples - name: Build the Java examples
run: mvn -B -f examples/java compile run: mvn -B -f examples/java compile
@@ -1050,7 +1120,7 @@ jobs:
matrix: matrix:
manylinux: [auto, musllinux_1_2] manylinux: [auto, musllinux_1_2]
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -1076,3 +1146,22 @@ jobs:
# (.github/workflows/bench.yml) — see audit finding R10. It runs nightly # (.github/workflows/bench.yml) — see audit finding R10. It runs nightly
# at 03:00 UTC and on-demand via `workflow_dispatch`, and is no longer on # at 03:00 UTC and on-demand via `workflow_dispatch`, and is no longer on
# the every-push / every-PR critical path. # the every-push / every-PR critical path.
# Non-blocking external-link heads-up on PRs. The authoritative check is the
# scheduled links.yml; here it only surfaces link rot early without ever
# gating a PR — external sites flake (rate limits, transient outages, moves),
# so `continue-on-error` keeps a third-party hiccup from blocking the merge.
# Redirects are reported as warnings (lychee only fails on hard errors).
links:
name: External links (non-blocking)
runs-on: ubuntu-latest
continue-on-error: true
timeout-minutes: 10
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
with:
args: --config lychee.toml --no-progress --root-dir "${{ github.workspace }}" "*.md" "bindings/*/README.md"
fail: true
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
build-mode: none build-mode: none
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
+28
View File
@@ -0,0 +1,28 @@
name: Link check
# External link rot is non-deterministic (third-party sites go down, rate-limit,
# or move), so the authoritative check runs on a weekly schedule and on demand
# rather than gating PRs or releases. ci.yml additionally runs a non-blocking
# lychee job on PRs for an early heads-up (continue-on-error), and release.yml is
# deliberately NOT gated on it — a transient external outage must never block an
# irreversible publish.
on:
schedule:
- cron: "0 6 * * 1" # Mondays 06:00 UTC
workflow_dispatch:
permissions:
contents: read
jobs:
links:
name: External links (lychee)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
with:
args: --config lychee.toml --no-progress --root-dir "${{ github.workspace }}" "*.md" "bindings/*/README.md"
fail: true
+63 -27
View File
@@ -36,6 +36,7 @@ jobs:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
cargo-publish: cargo-publish:
name: Publish to crates.io name: Publish to crates.io
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
runs-on: ubuntu-latest runs-on: ubuntu-latest
# The publish jobs run with long-lived registry tokens. Binding them to a # The publish jobs run with long-lived registry tokens. Binding them to a
# protected GitHub environment lets the org require a reviewer to approve # protected GitHub environment lets the org require a reviewer to approve
@@ -45,7 +46,7 @@ jobs:
# Settings -> Environments. # Settings -> Environments.
environment: release environment: release
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
- uses: ./.github/actions/setup-rust - uses: ./.github/actions/setup-rust
@@ -110,7 +111,7 @@ jobs:
# consumers can audit the published dependency tree without # consumers can audit the published dependency tree without
# re-resolving Cargo.lock. # re-resolving Cargo.lock.
- name: Install cargo-cyclonedx - name: Install cargo-cyclonedx
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6 uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
with: with:
tool: cargo-cyclonedx tool: cargo-cyclonedx
@@ -139,6 +140,7 @@ jobs:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
python-wheels: python-wheels:
name: Build wheels (${{ matrix.target }}/${{ matrix.manylinux }} on ${{ matrix.os }}) name: Build wheels (${{ matrix.target }}/${{ matrix.manylinux }} on ${{ matrix.os }})
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -157,13 +159,13 @@ jobs:
- { os: windows-11-arm, target: aarch64, manylinux: auto } - { os: windows-11-arm, target: aarch64, manylinux: auto }
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Set up Python - name: Set up Python
id: setup_python id: setup_python
continue-on-error: true continue-on-error: true
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.11" python-version: "3.11"
- name: Wait before Python retry - name: Wait before Python retry
@@ -174,7 +176,7 @@ jobs:
sleep 30 sleep 30
- name: Set up Python (retry) - name: Set up Python (retry)
if: steps.setup_python.outcome == 'failure' if: steps.setup_python.outcome == 'failure'
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.11" python-version: "3.11"
- name: Sync root README into bindings/python so it ships with the wheel - name: Sync root README into bindings/python so it ships with the wheel
@@ -209,9 +211,10 @@ jobs:
python-sdist: python-sdist:
name: Build Python sdist name: Build Python sdist
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Sync root README into bindings/python so it ships in the sdist - name: Sync root README into bindings/python so it ships in the sdist
@@ -228,6 +231,7 @@ jobs:
python-publish: python-publish:
name: Publish to PyPI name: Publish to PyPI
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
needs: [python-wheels, python-sdist] needs: [python-wheels, python-sdist]
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: release environment: release
@@ -251,6 +255,7 @@ jobs:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
node-build: node-build:
name: Node build (${{ matrix.target }}) name: Node build (${{ matrix.target }})
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -263,7 +268,7 @@ jobs:
- { host: windows-11-arm, target: aarch64-pc-windows-msvc } - { host: windows-11-arm, target: aarch64-pc-windows-msvc }
runs-on: ${{ matrix.host }} runs-on: ${{ matrix.host }}
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -296,8 +301,13 @@ jobs:
timeout-minutes: 6 timeout-minutes: 6
- name: Install Node deps - name: Install Node deps
working-directory: bindings/node uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
run: npm ci with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 20
command: cd bindings/node && npm ci
shell: bash
- name: Build native module - name: Build native module
working-directory: bindings/node working-directory: bindings/node
@@ -312,6 +322,7 @@ jobs:
node-publish: node-publish:
name: Publish to npm name: Publish to npm
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
needs: node-build needs: node-build
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: release environment: release
@@ -324,7 +335,7 @@ jobs:
contents: read contents: read
id-token: write id-token: write
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -351,8 +362,13 @@ jobs:
registry-url: "https://registry.npmjs.org" registry-url: "https://registry.npmjs.org"
- name: Install Node deps - name: Install Node deps
working-directory: bindings/node uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
run: npm ci with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 20
command: cd bindings/node && npm ci
shell: bash
- name: Download all platform binaries - name: Download all platform binaries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -365,7 +381,8 @@ jobs:
# drop the freshly built .node binary into the matching directory. # drop the freshly built .node binary into the matching directory.
- name: Move binaries into platform package layout - name: Move binaries into platform package layout
working-directory: bindings/node working-directory: bindings/node
run: npx napi artifacts --dir artifacts # napi-rs CLI 3 renamed `--dir` to `--output-dir` (`-d`).
run: npx napi artifacts --output-dir artifacts
# Publish each platform package individually. Skip versions that are # Publish each platform package individually. Skip versions that are
# already on npm. A first-attempt 403 from npm's spam filter is # already on npm. A first-attempt 403 from npm's spam filter is
@@ -484,6 +501,7 @@ jobs:
# which requires the `id-token: write` permission set at the job level. # which requires the `id-token: write` permission set at the job level.
wasm-publish: wasm-publish:
name: Publish wickra-wasm to npm name: Publish wickra-wasm to npm
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: release environment: release
# `id-token: write` lets npm publish embed a Sigstore provenance # `id-token: write` lets npm publish embed a Sigstore provenance
@@ -493,7 +511,7 @@ jobs:
contents: read contents: read
id-token: write id-token: write
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -523,10 +541,14 @@ jobs:
with: with:
targets: wasm32-unknown-unknown targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
timeout-minutes: 6
- name: Install wasm-pack (latest, via prebuilt binary) - name: Install wasm-pack (latest, via prebuilt binary)
# See the matching note in ci.yml: jetli's default installs an old # See the matching note in ci.yml: jetli's default installs an old
# 0.10.x wasm-pack whose build subcommand rejects --features. # 0.10.x wasm-pack whose build subcommand rejects --features.
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6 uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
with: with:
tool: wasm-pack tool: wasm-pack
@@ -590,6 +612,7 @@ jobs:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
c-abi-build: c-abi-build:
name: C ABI library (${{ matrix.target }}) name: C ABI library (${{ matrix.target }})
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -602,7 +625,7 @@ jobs:
- { host: windows-11-arm, target: aarch64-pc-windows-msvc } - { host: windows-11-arm, target: aarch64-pc-windows-msvc }
runs-on: ${{ matrix.host }} runs-on: ${{ matrix.host }}
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -645,6 +668,7 @@ jobs:
# workflow release.yml) exchanges the GitHub OIDC token for a short-lived key. # workflow release.yml) exchanges the GitHub OIDC token for a short-lived key.
csharp-publish: csharp-publish:
name: Publish to NuGet name: Publish to NuGet
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
needs: c-abi-build needs: c-abi-build
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: release environment: release
@@ -652,7 +676,7 @@ jobs:
contents: read contents: read
id-token: write # request the GitHub OIDC token for trusted publishing id-token: write # request the GitHub OIDC token for trusted publishing
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -689,11 +713,18 @@ jobs:
echo "staged ${RID[$target]}:"; ls -l "$dest" echo "staged ${RID[$target]}:"; ls -l "$dest"
done done
# dotnet pack restores from nuget.org first; retry so a transient restore
# blip retries instead of failing the release.
- name: Pack - name: Pack
shell: bash uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
run: | with:
version="${GITHUB_REF_NAME#v}" timeout_minutes: 15
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg max_attempts: 2
retry_wait_seconds: 20
shell: bash
command: |
version="${GITHUB_REF_NAME#v}"
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg
# Exchange the GitHub OIDC token for a short-lived (~1h) NuGet API key. # Exchange the GitHub OIDC token for a short-lived (~1h) NuGet API key.
# 'user' is the nuget.org profile name (the package owner), not an email. # 'user' is the nuget.org profile name (the package owner), not an email.
@@ -728,11 +759,12 @@ jobs:
# match the release tag (kept in sync by the version-bump checklist). # match the release tag (kept in sync by the version-bump checklist).
java-publish: java-publish:
name: Publish to Maven Central name: Publish to Maven Central
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
needs: c-abi-build needs: c-abi-build
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: release environment: release
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -772,7 +804,7 @@ jobs:
# setup-java writes a settings.xml with the 'central' server credentials # setup-java writes a settings.xml with the 'central' server credentials
# (mapped from the env vars below) and imports the GPG signing key. # (mapped from the env vars below) and imports the GPG signing key.
- name: Set up JDK 25 + Maven Central credentials + GPG - name: Set up JDK 25 + Maven Central credentials + GPG
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
with: with:
distribution: temurin distribution: temurin
java-version: "25" java-version: "25"
@@ -799,10 +831,11 @@ jobs:
# derived artifact, so its bot commit is intentionally unsigned. # derived artifact, so its bot commit is intentionally unsigned.
go-mirror: go-mirror:
name: Mirror the Go module to wickra-go name: Mirror the Go module to wickra-go
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
needs: c-abi-build needs: c-abi-build
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -882,6 +915,7 @@ jobs:
github-release: github-release:
name: Attach assets to the draft GitHub Release name: Attach assets to the draft GitHub Release
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
needs: [cargo-publish, python-publish, node-publish, wasm-publish, c-abi-build] needs: [cargo-publish, python-publish, node-publish, wasm-publish, c-abi-build]
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
@@ -892,7 +926,7 @@ jobs:
tag: ${{ steps.tag.outputs.tag }} tag: ${{ steps.tag.outputs.tag }}
version: ${{ steps.tag.outputs.version }} version: ${{ steps.tag.outputs.version }}
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
fetch-depth: 0 fetch-depth: 0
@@ -946,7 +980,7 @@ jobs:
echo "asset-count=$(ls release-assets/ | wc -l)" echo "asset-count=$(ls release-assets/ | wc -l)"
- name: Create / update the draft GitHub Release with assets - name: Create / update the draft GitHub Release with assets
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
with: with:
tag_name: ${{ steps.tag.outputs.tag }} tag_name: ${{ steps.tag.outputs.tag }}
name: Wickra ${{ steps.tag.outputs.tag }} name: Wickra ${{ steps.tag.outputs.tag }}
@@ -1007,6 +1041,7 @@ jobs:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
attestations: attestations:
name: Attest build provenance name: Attest build provenance
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
needs: [cargo-publish, python-wheels, python-sdist, github-release] needs: [cargo-publish, python-wheels, python-sdist, github-release]
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Signed SLSA build-provenance attestations for the published crates and # Signed SLSA build-provenance attestations for the published crates and
@@ -1041,7 +1076,7 @@ jobs:
merge-multiple: true merge-multiple: true
- name: Attest build provenance - name: Attest build provenance
id: attest id: attest
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
with: with:
subject-path: | subject-path: |
artifacts/crates/*.crate artifacts/crates/*.crate
@@ -1090,6 +1125,7 @@ jobs:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
publish-release: publish-release:
name: Publish the GitHub Release name: Publish the GitHub Release
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
needs: [github-release, attestations] needs: [github-release, attestations]
if: always() && needs.github-release.result == 'success' if: always() && needs.github-release.result == 'success'
runs-on: ubuntu-latest runs-on: ubuntu-latest
+2 -2
View File
@@ -24,7 +24,7 @@ jobs:
id-token: write # OIDC token to publish results to the OpenSSF API id-token: write # OIDC token to publish results to the OpenSSF API
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
@@ -44,7 +44,7 @@ jobs:
publish_results: true publish_results: true
- name: Upload SARIF artifact - name: Upload SARIF artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: SARIF file name: SARIF file
path: results.sarif path: results.sarif
+1 -1
View File
@@ -93,7 +93,7 @@ jobs:
# Fetching the now-gone `refs/heads/<branch>` then fails the run (exit 1). # Fetching the now-gone `refs/heads/<branch>` then fails the run (exit 1).
# The head SHA stays reachable via `refs/pull/N/head` after the branch is # The head SHA stays reachable via `refs/pull/N/head` after the branch is
# gone, so the checkout — and the run — survives an instant merge. # gone, so the checkout — and the run — survives an instant merge.
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
fetch-depth: 1 fetch-depth: 1
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }} ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
+2 -2
View File
@@ -14,10 +14,10 @@ jobs:
name: metadata audit name: metadata audit
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with: with:
python-version: "3.12" python-version: "3.12"
- name: Audit repo-metadata.toml drift - name: Audit repo-metadata.toml drift
+2 -2
View File
@@ -32,9 +32,9 @@ jobs:
actions: read # online audits resolve referenced actions actions: read # online audits resolve referenced actions
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Run zizmor - name: Run zizmor
uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7
+92 -1
View File
@@ -7,6 +7,92 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.9.9] - 2026-06-28
Maintenance release. No library or binding code changes from `0.9.8`; this
re-release simply runs through the corrected release workflow (the `0.9.8` npm
publish required a hotfix to the napi-rs 3 `napi artifacts` invocation, now in
place), so the published `0.9.9` artifacts are byte-identical to `0.9.8`.
## [0.9.8] - 2026-06-28
Maintenance release. The library API and every indicator are unchanged from
`0.9.7`; this release migrates the Node.js binding's build to napi-rs 3 and
carries routine dependency and CI tooling updates.
### Changed
- **Node binding built with napi-rs 3.** Migrate `napi` 2.16 → 3.9, `napi-derive`
2.16 → 3.5 (Rust) and `@napi-rs/cli` 2.18 → 3.7 (npm). The published API and
every computed value are unchanged — the generated TypeScript surface is
identical (626 symbols), only the code-generation format differs. napi 3's
derive macros emit `#[allow(unsafe_code)]`, so the Node crate's `unsafe_code`
lint is relaxed from the workspace `forbid` to `deny` for that crate only;
`forbid` stays in force for every other crate. The `engines.node` floor is
raised to `>= 22` (matching the CI test matrix). `ureq` is intentionally held
at 2.x — ureq 3 unconditionally pulls `webpki-root-certs` (CDLA-Permissive-2.0),
which the native-tls / OS-trust-store setup deliberately avoids.
- **Dependency and CI housekeeping.** Bump the Maven
`central-publishing-maven-plugin` and the GitHub Actions used by CI
(`actions/checkout`, `taiki-e/install-action`, `actions/setup-java`,
`softprops/action-gh-release`). No runtime code changes.
## [0.9.7] - 2026-06-21
Maintenance release. The library API and every indicator are unchanged from
`0.9.6`; this release carries an R package metadata fix and routine dependency
and CI tooling updates.
### Fixed
- **R package: credit `kingchenc` as the package author and maintainer.** The R
`DESCRIPTION` was the only binding still listing "Wickra contributors" as the
sole `aut`/`cre` — an outlier introduced when the binding was added. It now
matches the Python, Node, and Rust core metadata, the package `.Rd` is
regenerated, and the binding `LICENSE` copyright holder is aligned with the
root `LICENSE-MIT`.
### Changed
- **Dependency and CI housekeeping.** Bump the C# test dependencies
(`Microsoft.NET.Test.Sdk`, `xunit`, `xunit.runner.visualstudio`), the GitHub
Actions used by CI (`setup-python`, `upload-artifact`, `codecov-action`,
`taiki-e/install-action`), and the Java benchmark's `org.wickra:wickra`
dependency. No runtime code changes.
## [0.9.6] - 2026-06-18
Documentation release for the R binding. The library API and every indicator
are unchanged from `0.9.5`; only the R package's help pages change.
### Fixed
- **R package: document the data-layer exports and refresh the man pages.**
r-universe's `R CMD check` reported two warnings against the `0.9.3` data layer
it built for the first time in `0.9.5`: twelve undocumented exported objects
(`BinanceFeed`, `CandleReader`, `Resampler`, `TickAggregator`,
`fetch_binance_klines` and the `name` / `is_ready` / `warmup_period` / `push` /
`read` generics) and a codoc mismatch on `AwesomeOscillatorHistogram` (its help
page still listed `sma_period` after the argument was renamed to `lookback`).
The roxygen sources existed but the `man/*.Rd` had never been regenerated; they
are now complete, and a `push()` example that constructed a `TickAggregator`
without its required `gap_fill` argument is fixed. CI now runs `R CMD check` so
documentation drift fails the pull request instead of surfacing on r-universe.
## [0.9.5] - 2026-06-17
Maintenance release. The library API and every indicator are unchanged from
`0.9.4`; the only change that ships to users is to the R package's build script.
The rest of the release is CI / release-pipeline hardening (dependency caching,
job timeouts, and network-install retries) that does not affect the artifacts.
### Fixed
- **R package: retry the C ABI download.** `configure` / `configure.win` fetch the
prebuilt `wickra-c-<triple>.tar.gz` from the matching GitHub release. A freshly
cut release can briefly return 404 while its assets propagate across the CDN
(and a transient network blip would also fail it), so the single-shot download
is now retried with a backoff (~2 min) before giving up. Fixes
`cannot open URL … 404 Not Found` on r-universe / source installs taken right
after a release.
## [0.9.4] - 2026-06-17 ## [0.9.4] - 2026-06-17
Packaging fix for the `0.9.3` data layer. The library is identical to `0.9.3` on Packaging fix for the `0.9.3` data layer. The library is identical to `0.9.3` on
@@ -1836,7 +1922,12 @@ public API changes.
optional Binance live feed. optional Binance live feed.
- Bindings for Python, Node.js, and WebAssembly. - Bindings for Python, Node.js, and WebAssembly.
[Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.9.4...HEAD [Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.9.9...HEAD
[0.9.9]: https://github.com/wickra-lib/wickra/compare/v0.9.8...v0.9.9
[0.9.8]: https://github.com/wickra-lib/wickra/compare/v0.9.7...v0.9.8
[0.9.7]: https://github.com/wickra-lib/wickra/compare/v0.9.6...v0.9.7
[0.9.6]: https://github.com/wickra-lib/wickra/compare/v0.9.5...v0.9.6
[0.9.5]: https://github.com/wickra-lib/wickra/compare/v0.9.4...v0.9.5
[0.9.4]: https://github.com/wickra-lib/wickra/compare/v0.9.3...v0.9.4 [0.9.4]: https://github.com/wickra-lib/wickra/compare/v0.9.3...v0.9.4
[0.9.3]: https://github.com/wickra-lib/wickra/compare/v0.9.2...v0.9.3 [0.9.3]: https://github.com/wickra-lib/wickra/compare/v0.9.2...v0.9.3
[0.9.2]: https://github.com/wickra-lib/wickra/compare/v0.9.1...v0.9.2 [0.9.2]: https://github.com/wickra-lib/wickra/compare/v0.9.1...v0.9.2
Generated
+87 -34
View File
@@ -198,9 +198,9 @@ dependencies = [
[[package]] [[package]]
name = "convert_case" name = "convert_case"
version = "0.6.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49"
dependencies = [ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
@@ -277,9 +277,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.9.18" version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
dependencies = [ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
@@ -329,13 +329,9 @@ dependencies = [
[[package]] [[package]]
name = "ctor" name = "ctor"
version = "0.2.9" version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" checksum = "01334b89b69ff726750c5ce5073fc8bd860e99aa9a8fc5ca11b04730e3aee97a"
dependencies = [
"quote",
"syn",
]
[[package]] [[package]]
name = "data-encoding" name = "data-encoding"
@@ -428,12 +424,54 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "futures"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.32" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.32" version = "0.3.32"
@@ -463,10 +501,13 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [ dependencies = [
"futures-channel",
"futures-core", "futures-core",
"futures-io",
"futures-macro", "futures-macro",
"futures-sink", "futures-sink",
"futures-task", "futures-task",
"memchr",
"pin-project-lite", "pin-project-lite",
"slab", "slab",
] ]
@@ -690,9 +731,9 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]] [[package]]
name = "libloading" name = "libloading"
version = "0.8.9" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"windows-link", "windows-link",
@@ -751,15 +792,17 @@ dependencies = [
[[package]] [[package]]
name = "napi" name = "napi"
version = "2.16.17" version = "3.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" checksum = "b41bda2ac390efb5e8d22025d925ccc3f3807d8c1bea6d19b36127247c4b8f83"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"ctor", "ctor",
"napi-derive", "futures",
"napi-build",
"napi-sys", "napi-sys",
"once_cell", "nohash-hasher",
"rustc-hash",
] ]
[[package]] [[package]]
@@ -770,12 +813,12 @@ checksum = "c9c366d2c8c60b86fa632df75f745509b52f9128f91a6bad4c796e44abb505e1"
[[package]] [[package]]
name = "napi-derive" name = "napi-derive"
version = "2.16.13" version = "3.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c" checksum = "61d66f70256ad5aef58659966064471d0ad90e2897bc36a5a5e0389c85aabc1e"
dependencies = [ dependencies = [
"cfg-if",
"convert_case", "convert_case",
"ctor",
"napi-derive-backend", "napi-derive-backend",
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -784,24 +827,22 @@ dependencies = [
[[package]] [[package]]
name = "napi-derive-backend" name = "napi-derive-backend"
version = "1.0.75" version = "5.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf" checksum = "81b4b08f15eed7a2a20c3f4c6314013fc3ac890a3afa9892b594485299ebdb2d"
dependencies = [ dependencies = [
"convert_case", "convert_case",
"once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"regex",
"semver", "semver",
"syn", "syn",
] ]
[[package]] [[package]]
name = "napi-sys" name = "napi-sys"
version = "2.4.0" version = "3.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3" checksum = "1f5bcdf71abd3a50d00b49c1c2c75251cb3c913777d6139cd37dabc093a5e400"
dependencies = [ dependencies = [
"libloading", "libloading",
] ]
@@ -823,6 +864,12 @@ dependencies = [
"tempfile", "tempfile",
] ]
[[package]]
name = "nohash-hasher"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]] [[package]]
name = "nu-ansi-term" name = "nu-ansi-term"
version = "0.50.3" version = "0.50.3"
@@ -1211,6 +1258,12 @@ version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "rustc-hash"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "1.1.4" version = "1.1.4"
@@ -1785,7 +1838,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra" name = "wickra"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"approx", "approx",
"criterion", "criterion",
@@ -1796,7 +1849,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-bench" name = "wickra-bench"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"criterion", "criterion",
"kand", "kand",
@@ -1808,7 +1861,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-c" name = "wickra-c"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"tokio", "tokio",
"wickra-core", "wickra-core",
@@ -1817,7 +1870,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-core" name = "wickra-core"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"approx", "approx",
"proptest", "proptest",
@@ -1827,7 +1880,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-data" name = "wickra-data"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"approx", "approx",
"csv", "csv",
@@ -1846,7 +1899,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-examples" name = "wickra-examples"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"serde_json", "serde_json",
"tokio", "tokio",
@@ -1856,7 +1909,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-node" name = "wickra-node"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"napi", "napi",
"napi-build", "napi-build",
@@ -1868,7 +1921,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-python" name = "wickra-python"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"pyo3", "pyo3",
@@ -1879,7 +1932,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-wasm" name = "wickra-wasm"
version = "0.9.4" version = "0.9.9"
dependencies = [ dependencies = [
"console_error_panic_hook", "console_error_panic_hook",
"js-sys", "js-sys",
+3 -3
View File
@@ -14,7 +14,7 @@ members = [
exclude = ["fuzz"] exclude = ["fuzz"]
[workspace.package] [workspace.package]
version = "0.9.4" version = "0.9.9"
authors = ["kingchenc <support@wickra.org>"] authors = ["kingchenc <support@wickra.org>"]
edition = "2021" edition = "2021"
rust-version = "1.86" rust-version = "1.86"
@@ -26,8 +26,8 @@ keywords = ["finance", "trading", "indicators", "technical-analysis", "ta"]
categories = ["finance", "mathematics", "science"] categories = ["finance", "mathematics", "science"]
[workspace.dependencies] [workspace.dependencies]
wickra-core = { path = "crates/wickra-core", version = "0.9.4" } wickra-core = { path = "crates/wickra-core", version = "0.9.9" }
wickra-data = { path = "crates/wickra-data", version = "0.9.4" } wickra-data = { path = "crates/wickra-data", version = "0.9.9" }
thiserror = "2" thiserror = "2"
rayon = "1.10" rayon = "1.10"
+24 -1
View File
@@ -18,10 +18,17 @@
[![OpenSSF Best Practices](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/best-practices.svg)](https://www.bestpractices.dev/projects/13094) [![OpenSSF Best Practices](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/best-practices.svg)](https://www.bestpractices.dev/projects/13094)
[![Build provenance](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/provenance.svg)](https://github.com/wickra-lib/wickra/attestations) [![Build provenance](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/provenance.svg)](https://github.com/wickra-lib/wickra/attestations)
[![Docs](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/docs.svg)](https://docs.wickra.org) [![Docs](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/docs.svg)](https://docs.wickra.org)
[![Live demo](https://img.shields.io/badge/live%20demo-live.wickra.org-3b82f6)](https://live.wickra.org)
[![Verified across 10 languages](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/verified.svg)](https://docs.wickra.org/FAQ#do-all-the-language-bindings-compute-the-same-values) [![Verified across 10 languages](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/verified.svg)](https://docs.wickra.org/FAQ#do-all-the-language-bindings-compute-the-same-values)
---
**Streaming-first technical indicators. Install with `pip install wickra` — no system dependencies, zero third-party packages.** **Streaming-first technical indicators. Install with `pip install wickra` — no system dependencies, zero third-party packages.**
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
**Part of the [Wickra ecosystem](#ecosystem):** the same data-driven core and ten-language binding surface also power [wickra-exchange](https://github.com/wickra-lib/wickra-exchange), [wickra-backtest](https://github.com/wickra-lib/wickra-backtest), [wickra-terminal](https://github.com/wickra-lib/wickra-terminal), [wickra-screener](https://github.com/wickra-lib/wickra-screener), [wickra-xray](https://github.com/wickra-lib/wickra-xray), [wickra-radar](https://github.com/wickra-lib/wickra-radar), [wickra-copilot](https://github.com/wickra-lib/wickra-copilot) and [wickra-shazam](https://github.com/wickra-lib/wickra-shazam).
Wickra is a multi-language technical-analysis library with a Rust core and Wickra is a multi-language technical-analysis library with a Rust core and
native bindings for Python, Node.js and WASM, plus a C ABI that C, C++, native bindings for Python, Node.js and WASM, plus a C ABI that C, C++,
C#, Go, Java, R and any other C-capable language links against. Every indicator is a C#, Go, Java, R and any other C-capable language links against. Every indicator is a
@@ -435,6 +442,22 @@ order-book, trade, profile, alt-chart bars, footprint). This catches FFI wiring
bugs the math-only core tests cannot see — it has already found and fixed real bugs the math-only core tests cannot see — it has already found and fixed real
cross-language marshalling bugs in the Java and R bindings. cross-language marshalling bugs in the Java and R bindings.
## Ecosystem
Wickra is the core library. The same data-driven core + ten-language binding
pattern powers a family of products built on it:
- [**wickra-exchange**](https://github.com/wickra-lib/wickra-exchange) — unified market-data + execution across ten crypto exchanges
- [**wickra-backtest**](https://github.com/wickra-lib/wickra-backtest) — event-driven backtester over the Wickra core
- [**wickra-terminal**](https://github.com/wickra-lib/wickra-terminal) — the trading terminal: a TUI and a browser renderer over the stack
- [**wickra-screener**](https://github.com/wickra-lib/wickra-screener) — parallel multi-symbol screening over 514 streaming indicators
- [**wickra-xray**](https://github.com/wickra-lib/wickra-xray) — market-microstructure explorer: footprint, order-book heatmap, liquidation map, funding/OI divergence
- [**wickra-radar**](https://github.com/wickra-lib/wickra-radar) — perp-universe alert radar: OI delta, funding flip, book imbalance, liquidation clusters, OI/price divergence
- [**wickra-copilot**](https://github.com/wickra-lib/wickra-copilot) — local market copilot grounded in real order-book, liquidation and funding microstructure
- [**wickra-shazam**](https://github.com/wickra-lib/wickra-shazam) — match an asset's current microstructure fingerprint against its entire history
Docs live at [docs.wickra.org](https://docs.wickra.org) ([wickra-docs](https://github.com/wickra-lib/wickra-docs)); the marketing site and in-browser demo at [wickra.org](https://wickra.org) ([webpage](https://github.com/wickra-lib/webpage)).
## Contributing ## Contributing
Contributions are very welcome — issues, bug reports, ideas, and pull requests Contributions are very welcome — issues, bug reports, ideas, and pull requests
@@ -507,6 +530,6 @@ The library is provided **as is**, without warranty of any kind; see
<p align="center"> <p align="center">
<a href="https://star-history.com/#wickra-lib/wickra&Date"> <a href="https://star-history.com/#wickra-lib/wickra&Date">
<img alt="Wickra star history" width="640" <img alt="Wickra star history" width="640"
src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/star-history.svg"> src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/star-history.svg?v=2">
</a> </a>
</p> </p>
+3 -3
View File
@@ -2,13 +2,13 @@
## Supported versions ## Supported versions
Wickra is pre-1.0. Security fixes are applied to the latest released `0.9.4` Wickra is pre-1.0. Security fixes are applied to the latest released `0.9.9`
version only; please upgrade to the newest release before reporting an issue. version only; please upgrade to the newest release before reporting an issue.
| Version | Supported | | Version | Supported |
| --- | --- | | --- | --- |
| 0.9.4 (latest) | :white_check_mark: | | 0.9.9 (latest) | :white_check_mark: |
| < 0.9.4 | :x: | | < 0.9.9 | :x: |
## Reporting a vulnerability ## Reporting a vulnerability
+1 -1
View File
@@ -11,7 +11,7 @@ Most questions are answered in the documentation:
data layer, and an FAQ. data layer, and an FAQ.
- **README:** <https://github.com/wickra-lib/wickra#readme> — installation and a - **README:** <https://github.com/wickra-lib/wickra#readme> — installation and a
quick overview. quick overview.
- **API docs (Rust):** <https://docs.rs/wickra>. - **API docs (Rust):** <https://docs.rs/wickra/latest/wickra/>.
## Questions and help ## Questions and help
+12 -4
View File
@@ -1,9 +1,17 @@
<p align="center">
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![GitHub release](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/release.svg)](https://github.com/wickra-lib/wickra/releases/latest)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](https://github.com/wickra-lib/wickra#license)
# Wickra — C / C++ # Wickra — C / C++
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml) ---
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![GitHub release](https://img.shields.io/github/v/release/wickra-lib/wickra?logo=github&color=green)](https://github.com/wickra-lib/wickra/releases/latest) > **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license)
**Streaming-first technical indicators for C and C++. A prebuilt shared/static **Streaming-first technical indicators for C and C++. A prebuilt shared/static
library plus a generated `wickra.h` — no system dependencies.** library plus a generated `wickra.h` — no system dependencies.**
+12 -4
View File
@@ -1,9 +1,17 @@
<p align="center">
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![NuGet](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/nuget.svg)](https://www.nuget.org/packages/Wickra)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](https://github.com/wickra-lib/wickra#license)
# Wickra — C# # Wickra — C#
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml) ---
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![NuGet](https://img.shields.io/nuget/v/Wickra.svg?logo=nuget&color=blue)](https://www.nuget.org/packages/Wickra) > **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license)
**Streaming-first technical indicators for C#. `dotnet add package Wickra` **Streaming-first technical indicators for C#. `dotnet add package Wickra`
prebuilt native library, no system dependencies.** prebuilt native library, no system dependencies.**
@@ -9,9 +9,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="xunit" Version="2.9.2" /> <PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" /> <PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+1 -1
View File
@@ -11,7 +11,7 @@
<!-- NuGet package metadata --> <!-- NuGet package metadata -->
<PackageId>Wickra</PackageId> <PackageId>Wickra</PackageId>
<Version>0.9.4</Version> <Version>0.9.9</Version>
<Authors>kingchenc</Authors> <Authors>kingchenc</Authors>
<Description>High-performance streaming technical-analysis indicators (514 indicators) for .NET, backed by the native Rust core via the Wickra C ABI.</Description> <Description>High-performance streaming technical-analysis indicators (514 indicators) for .NET, backed by the native Rust core via the Wickra C ABI.</Description>
<PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression> <PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression>
+12 -4
View File
@@ -1,9 +1,17 @@
<p align="center">
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![Go module](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/go.svg)](https://pkg.go.dev/github.com/wickra-lib/wickra/bindings/go)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](https://github.com/wickra-lib/wickra#license)
# Wickra — Go # Wickra — Go
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml) ---
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![Go module](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/go.svg)](https://pkg.go.dev/github.com/wickra-lib/wickra/bindings/go) > **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license)
**Streaming-first technical indicators for Go, over the Wickra C ABI hub via cgo.** **Streaming-first technical indicators for Go, over the Wickra C ABI hub via cgo.**
+14 -6
View File
@@ -1,9 +1,17 @@
<p align="center">
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![Maven Central](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/maven.svg)](https://central.sonatype.com/artifact/org.wickra/wickra)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](https://github.com/wickra-lib/wickra#license)
# Wickra — Java # Wickra — Java
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml) ---
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![Maven Central](https://img.shields.io/maven-central/v/org.wickra/wickra.svg?logo=apache-maven&color=blue)](https://central.sonatype.com/artifact/org.wickra/wickra) > **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license)
**Streaming-first technical indicators for the JVM, on the Java Foreign Function **Streaming-first technical indicators for the JVM, on the Java Foreign Function
& Memory API — prebuilt native library, no JNI, no system dependencies.** & Memory API — prebuilt native library, no JNI, no system dependencies.**
@@ -30,14 +38,14 @@ Maven:
<dependency> <dependency>
<groupId>org.wickra</groupId> <groupId>org.wickra</groupId>
<artifactId>wickra</artifactId> <artifactId>wickra</artifactId>
<version>0.9.4</version> <version>0.9.9</version>
</dependency> </dependency>
``` ```
Gradle: Gradle:
```kotlin ```kotlin
implementation("org.wickra:wickra:0.9.4") implementation("org.wickra:wickra:0.9.9")
``` ```
The native library ships prebuilt per platform (Linux, macOS, Windows — x64 and The native library ships prebuilt per platform (Linux, macOS, Windows — x64 and
+1 -1
View File
@@ -21,7 +21,7 @@
<dependency> <dependency>
<groupId>org.wickra</groupId> <groupId>org.wickra</groupId>
<artifactId>wickra</artifactId> <artifactId>wickra</artifactId>
<version>0.8.2</version> <version>0.9.7</version>
</dependency> </dependency>
</dependencies> </dependencies>
+2 -2
View File
@@ -6,7 +6,7 @@
<groupId>org.wickra</groupId> <groupId>org.wickra</groupId>
<artifactId>wickra</artifactId> <artifactId>wickra</artifactId>
<version>0.9.4</version> <version>0.9.9</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Wickra</name> <name>Wickra</name>
@@ -157,7 +157,7 @@
<plugin> <plugin>
<groupId>org.sonatype.central</groupId> <groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId> <artifactId>central-publishing-maven-plugin</artifactId>
<version>0.10.0</version> <version>0.11.0</version>
<extensions>true</extensions> <extensions>true</extensions>
<configuration> <configuration>
<publishingServerId>central</publishingServerId> <publishingServerId>central</publishingServerId>
+25 -4
View File
@@ -20,14 +20,35 @@ publish = false
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]
[lints] # Mirrors [workspace.lints] (the source of truth) EXCEPT `unsafe_code`, which is
workspace = true # relaxed from the workspace `forbid` to `deny`: the napi-rs 3 derive macros emit
# `#[allow(unsafe_code)]`, which `forbid` cannot permit. `deny` still fails the
# build on any unguarded unsafe in our own code. Keep this list in sync with the
# workspace if its lints change.
[lints.rust]
unsafe_code = "deny"
missing_debug_implementations = "warn"
unreachable_pub = "warn"
unused_must_use = "deny"
[lints.clippy]
all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
module_name_repetitions = "allow"
must_use_candidate = "allow"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
cast_precision_loss = "allow"
cast_possible_truncation = "allow"
cast_sign_loss = "allow"
similar_names = "allow"
float_cmp = "allow"
[dependencies] [dependencies]
wickra-core = { workspace = true } wickra-core = { workspace = true }
wickra-data = { workspace = true, features = ["live-binance"] } wickra-data = { workspace = true, features = ["live-binance"] }
napi = { version = "2.16", features = ["napi8"] } napi = { version = "3.9", features = ["napi8"] }
napi-derive = "2.16" napi-derive = "3.5"
# Drives the async Binance feed behind the blocking poll. # Drives the async Binance feed behind the blocking poll.
tokio = { version = "1", features = ["rt", "net", "time"] } tokio = { version = "1", features = ["rt", "net", "time"] }
+12 -4
View File
@@ -1,9 +1,17 @@
<p align="center">
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![npm](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/npm.svg)](https://www.npmjs.com/package/wickra)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](https://github.com/wickra-lib/wickra#license)
# Wickra — Node.js # Wickra — Node.js
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml) ---
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![npm](https://img.shields.io/npm/v/wickra.svg?logo=npm&color=red)](https://www.npmjs.com/package/wickra) > **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license)
**Streaming-first technical indicators for Node.js. `npm install wickra` **Streaming-first technical indicators for Node.js. `npm install wickra`
prebuilt native binary, no system dependencies.** prebuilt native binary, no system dependencies.**
+6400 -5778
View File
File diff suppressed because it is too large Load Diff
+1593 -800
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "wickra-darwin-arm64", "name": "wickra-darwin-arm64",
"version": "0.9.4", "version": "0.9.9",
"description": "Native binding for wickra (macOS Apple Silicon). Installed automatically as an optional dependency of wickra on matching platforms.", "description": "Native binding for wickra (macOS Apple Silicon). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.darwin-arm64.node", "main": "wickra.darwin-arm64.node",
"files": [ "files": [
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "wickra-darwin-x64", "name": "wickra-darwin-x64",
"version": "0.9.4", "version": "0.9.9",
"description": "Native binding for wickra (macOS Intel). Installed automatically as an optional dependency of wickra on matching platforms.", "description": "Native binding for wickra (macOS Intel). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.darwin-x64.node", "main": "wickra.darwin-x64.node",
"files": [ "files": [
@@ -1,6 +1,6 @@
{ {
"name": "wickra-linux-arm64-gnu", "name": "wickra-linux-arm64-gnu",
"version": "0.9.4", "version": "0.9.9",
"description": "Native binding for wickra (linux arm64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.", "description": "Native binding for wickra (linux arm64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.linux-arm64-gnu.node", "main": "wickra.linux-arm64-gnu.node",
"files": [ "files": [
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "wickra-linux-x64-gnu", "name": "wickra-linux-x64-gnu",
"version": "0.9.4", "version": "0.9.9",
"description": "Native binding for wickra (linux x64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.", "description": "Native binding for wickra (linux x64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.linux-x64-gnu.node", "main": "wickra.linux-x64-gnu.node",
"files": [ "files": [
@@ -1,6 +1,6 @@
{ {
"name": "wickra-win32-arm64-msvc", "name": "wickra-win32-arm64-msvc",
"version": "0.9.4", "version": "0.9.9",
"description": "Native binding for wickra (Windows arm64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.", "description": "Native binding for wickra (Windows arm64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.win32-arm64-msvc.node", "main": "wickra.win32-arm64-msvc.node",
"files": [ "files": [
@@ -1,6 +1,6 @@
{ {
"name": "wickra-win32-x64-msvc", "name": "wickra-win32-x64-msvc",
"version": "0.9.4", "version": "0.9.9",
"description": "Native binding for wickra (Windows x64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.", "description": "Native binding for wickra (Windows x64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.win32-x64-msvc.node", "main": "wickra.win32-x64-msvc.node",
"files": [ "files": [
+1832 -27
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -1,6 +1,6 @@
{ {
"name": "wickra", "name": "wickra",
"version": "0.9.4", "version": "0.9.9",
"description": "Streaming-first technical indicators: incremental, fast, install-free. Node bindings powered by Rust.", "description": "Streaming-first technical indicators: incremental, fast, install-free. Node bindings powered by Rust.",
"author": "kingchenc <support@wickra.org>", "author": "kingchenc <support@wickra.org>",
"main": "index.js", "main": "index.js",
@@ -44,15 +44,15 @@
} }
}, },
"engines": { "engines": {
"node": ">= 20" "node": ">= 22"
}, },
"optionalDependencies": { "optionalDependencies": {
"wickra-linux-x64-gnu": "0.9.4", "wickra-linux-x64-gnu": "0.9.9",
"wickra-linux-arm64-gnu": "0.9.4", "wickra-linux-arm64-gnu": "0.9.9",
"wickra-darwin-x64": "0.9.4", "wickra-darwin-x64": "0.9.9",
"wickra-darwin-arm64": "0.9.4", "wickra-darwin-arm64": "0.9.9",
"wickra-win32-x64-msvc": "0.9.4", "wickra-win32-x64-msvc": "0.9.9",
"wickra-win32-arm64-msvc": "0.9.4" "wickra-win32-arm64-msvc": "0.9.9"
}, },
"scripts": { "scripts": {
"build": "napi build --platform --release", "build": "napi build --platform --release",
@@ -64,6 +64,6 @@
"bench": "node benchmarks/throughput.js" "bench": "node benchmarks/throughput.js"
}, },
"devDependencies": { "devDependencies": {
"@napi-rs/cli": "^2.18.0" "@napi-rs/cli": "^3.7.2"
} }
} }
+12 -4
View File
@@ -1,9 +1,17 @@
<p align="center">
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![PyPI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/pypi.svg)](https://pypi.org/project/wickra/)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](https://github.com/wickra-lib/wickra#license)
# Wickra — Python # Wickra — Python
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml) ---
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![PyPI](https://img.shields.io/pypi/v/wickra.svg?logo=pypi&color=blue)](https://pypi.org/project/wickra/) > **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license)
**Streaming-first technical indicators for Python. `pip install wickra` — zero **Streaming-first technical indicators for Python. `pip install wickra` — zero
third-party dependencies (not even NumPy), no system dependencies, no C build tooling.** third-party dependencies (not even NumPy), no system dependencies, no C build tooling.**
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "maturin"
[project] [project]
name = "wickra" name = "wickra"
version = "0.9.4" version = "0.9.9"
description = "Streaming-first technical indicators: incremental, fast, install-free." description = "Streaming-first technical indicators: incremental, fast, install-free."
readme = "README.md" readme = "README.md"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
+2 -2
View File
@@ -1,8 +1,8 @@
Package: wickra Package: wickra
Type: Package Type: Package
Title: Streaming-First Technical Indicators Title: Streaming-First Technical Indicators
Version: 0.9.4 Version: 0.9.9
Authors@R: person("Wickra contributors", role = c("aut", "cre"), email = "support@wickra.org") Authors@R: person("kingchenc", role = c("aut", "cre"), email = "support@wickra.org")
Description: R bindings for the Wickra technical-analysis library over its C ABI Description: R bindings for the Wickra technical-analysis library over its C ABI
hub. Exposes 514 indicators, each an O(1) streaming state machine shared with hub. Exposes 514 indicators, each an O(1) streaming state machine shared with
the Rust core and the other language bindings, so that live and historical the Rust core and the other language bindings, so that live and historical
+1 -1
View File
@@ -1,2 +1,2 @@
YEAR: 2026 YEAR: 2026
COPYRIGHT HOLDER: Wickra contributors COPYRIGHT HOLDER: kingchenc and the Wickra contributors
+1 -1
View File
@@ -1,7 +1,7 @@
# Generated by roxygen2: do not edit by hand # Generated by roxygen2: do not edit by hand
S3method(base::flush,wickra_indicator)
S3method(batch,wickra_indicator) S3method(batch,wickra_indicator)
S3method(flush,wickra_indicator)
S3method(is_ready,wickra_indicator) S3method(is_ready,wickra_indicator)
S3method(name,wickra_indicator) S3method(name,wickra_indicator)
S3method(push,wickra_indicator) S3method(push,wickra_indicator)
+46 -3
View File
@@ -479,7 +479,14 @@ Camarilla <- function() {
.wk_obj("camarilla", ptr, "Camarilla") .wk_obj("camarilla", ptr, "Camarilla")
} }
#' CandleReader: parse OHLCV candles from a CSV string #' Parse OHLCV candles from a CSV string
#'
#' Builds a reader over an in-memory CSV string with a header row and OHLCV
#' columns. Pass the result to [read()] to get every parsed candle.
#'
#' @param csv A length-one character string of CSV text (a header row followed
#' by OHLCV data rows).
#' @return A `wickra_indicator` candle reader; read its candles with [read()].
#' @keywords internal #' @keywords internal
#' @export #' @export
CandleReader <- function(csv) { CandleReader <- function(csv) {
@@ -2687,7 +2694,14 @@ RenkoTrailingStop <- function(block_size) {
.wk_obj("renko_trailing_stop", ptr, "RenkoTrailingStop") .wk_obj("renko_trailing_stop", ptr, "RenkoTrailingStop")
} }
#' Resampler indicator #' Resample candles to a higher timeframe
#'
#' Aggregates a stream of candles into higher-timeframe bars. Feed candles with
#' [update()] (it returns a completed higher-timeframe bar, or `NULL` while the
#' current bar is still open) and emit the final, still-open bar with [flush()].
#'
#' @param timeframe Integer number of input candles per higher-timeframe bar.
#' @return A `wickra_indicator` resampler.
#' @keywords internal #' @keywords internal
#' @export #' @export
Resampler <- function(timeframe) { Resampler <- function(timeframe) {
@@ -3487,7 +3501,15 @@ Thrusting <- function() {
.wk_obj("thrusting", ptr, "Thrusting") .wk_obj("thrusting", ptr, "Thrusting")
} }
#' TickAggregator indicator #' Aggregate trade ticks into time-bucketed candles
#'
#' Builds OHLCV candles from a stream of trade ticks. Feed ticks with [push()],
#' which returns the candles closed by that tick.
#'
#' @param bucket Time-bucket width, in the same unit as the tick timestamps.
#' @param gap_fill Logical; if `TRUE`, empty buckets with no trades are still
#' emitted (carried forward) instead of skipped.
#' @return A `wickra_indicator` tick aggregator; feed it ticks with [push()].
#' @keywords internal #' @keywords internal
#' @export #' @export
TickAggregator <- function(bucket, gap_fill) { TickAggregator <- function(bucket, gap_fill) {
@@ -4151,6 +4173,13 @@ Zlema <- function(period) {
#' 15 = 1M). `base_url` overrides the endpoint (`NULL` = production). Not #' 15 = 1M). `base_url` overrides the endpoint (`NULL` = production). Not
#' available in the wasm (r-universe/webR) build, which has no raw sockets. #' available in the wasm (r-universe/webR) build, which has no raw sockets.
#' #'
#' @param symbols Comma-separated trading symbols (case-insensitive), e.g.
#' `"btcusdt,ethusdt"`.
#' @param interval Integer interval code `0:15` (`0` = 1s, `1` = 1m, ...,
#' `12` = 1d, `13` = 3d, `14` = 1w, `15` = 1M).
#' @param base_url Optional endpoint override; `NULL` uses production.
#' @return A `wickra_binance_feed`; poll it with [binance_next()] and close it
#' with [binance_close()].
#' @keywords internal #' @keywords internal
#' @export #' @export
BinanceFeed <- function(symbols, interval, base_url = NULL) { BinanceFeed <- function(symbols, interval, base_url = NULL) {
@@ -4165,6 +4194,10 @@ BinanceFeed <- function(symbols, interval, base_url = NULL) {
#' `high`, `low`, `close`, `volume`, `open_time`, `is_closed`) when an event #' `high`, `low`, `close`, `volume`, `open_time`, `is_closed`) when an event
#' arrives, or `NULL` on timeout. Errors once the stream is closed. #' arrives, or `NULL` on timeout. Errors once the stream is closed.
#' #'
#' @param feed A `wickra_binance_feed` created by [BinanceFeed()].
#' @param timeout_ms Poll timeout in milliseconds.
#' @return A named list (`symbol`, `open`, `high`, `low`, `close`, `volume`,
#' `open_time`, `is_closed`) for an event, or `NULL` on timeout.
#' @keywords internal #' @keywords internal
#' @export #' @export
binance_next <- function(feed, timeout_ms = 1000) { binance_next <- function(feed, timeout_ms = 1000) {
@@ -4173,6 +4206,8 @@ binance_next <- function(feed, timeout_ms = 1000) {
#' Close a Binance feed #' Close a Binance feed
#' #'
#' @param feed A `wickra_binance_feed` created by [BinanceFeed()].
#' @return `NULL`, invisibly.
#' @keywords internal #' @keywords internal
#' @export #' @export
binance_close <- function(feed) { binance_close <- function(feed) {
@@ -4190,6 +4225,14 @@ binance_close <- function(feed) {
#' `volume`, `timestamp`. Blocks until the response arrives. Not available in the #' `volume`, `timestamp`. Blocks until the response arrives. Not available in the
#' wasm (r-universe/webR) build, which has no raw sockets. #' wasm (r-universe/webR) build, which has no raw sockets.
#' #'
#' @param symbol Trading symbol (case-insensitive), e.g. `"btcusdt"`.
#' @param interval Integer interval code `0:15` (see [BinanceFeed()]).
#' @param limit Number of klines to fetch (`1:1000`).
#' @param start_ms,end_ms Optional inclusive Unix-millisecond bounds; a negative
#' value means unset.
#' @param base_url Optional host override; `NULL` uses production.
#' @return An `n x 6` numeric matrix with columns `open`, `high`, `low`,
#' `close`, `volume`, `timestamp`.
#' @keywords internal #' @keywords internal
#' @export #' @export
fetch_binance_klines <- function(symbol, interval, limit, start_ms = -1, fetch_binance_klines <- function(symbol, interval, limit, start_ms = -1,
+1 -1
View File
@@ -151,7 +151,7 @@ name.wickra_indicator <- function(object) {
#' @param timestamp Trade timestamp, in the same unit as the aggregator bucket. #' @param timestamp Trade timestamp, in the same unit as the aggregator bucket.
#' @return A numeric matrix with six named columns (possibly zero rows). #' @return A numeric matrix with six named columns (possibly zero rows).
#' @examples #' @examples
#' agg <- TickAggregator(1000) #' agg <- TickAggregator(1000, FALSE)
#' push(agg, 100, 1, 0) #' push(agg, 100, 1, 0)
#' push(agg, 102, 1, 1000) # closes the first bucket #' push(agg, 102, 1, 1000) # closes the first bucket
#' @export #' @export
+12 -3
View File
@@ -1,8 +1,17 @@
<p align="center">
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![r-universe](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/r-universe.svg)](https://wickra-lib.r-universe.dev)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](https://github.com/wickra-lib/wickra#license)
# Wickra — R <img src="man/figures/logo.png" align="right" height="120" alt="Wickra logo" /> # Wickra — R <img src="man/figures/logo.png" align="right" height="120" alt="Wickra logo" />
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml) ---
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license) > **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
**Streaming-first technical indicators for R, over the Wickra C ABI hub via `.Call`.** **Streaming-first technical indicators for R, over the Wickra C ABI hub via `.Call`.**
+22 -4
View File
@@ -14,6 +14,26 @@ set -e
inc="" inc=""
lib="" lib=""
# A freshly-cut GitHub release can briefly return 404 while its assets propagate
# across the CDN, and a transient network blip should not fail the build either.
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
# on the first miss.
wickra_download() {
_url="$1"
_dest="$2"
_attempt=1
while [ "${_attempt}" -le 6 ]; do
if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
return 0
fi
echo "wickra: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating — retrying in 20s..."
sleep 20
_attempt=$((_attempt + 1))
done
echo "wickra: failed to download ${_url} after 6 attempts"
return 1
}
# WebAssembly (r-universe / webR): there is no prebuilt wasm C ABI to download, # WebAssembly (r-universe / webR): there is no prebuilt wasm C ABI to download,
# but the build image ships cargo (/usr/local/cargo/bin) and emscripten # but the build image ships cargo (/usr/local/cargo/bin) and emscripten
# (EMSDK on PATH), so build the C ABI staticlib from source for # (EMSDK on PATH), so build the C ABI staticlib from source for
@@ -26,8 +46,7 @@ if [ "$(uname -s)" = "Emscripten" ]; then
echo "wickra: building C ABI from source for wasm32-unknown-emscripten (v${version})" echo "wickra: building C ABI from source for wasm32-unknown-emscripten (v${version})"
build=$(mktemp -d) build=$(mktemp -d)
url="https://github.com/wickra-lib/wickra/archive/refs/tags/v${version}.tar.gz" url="https://github.com/wickra-lib/wickra/archive/refs/tags/v${version}.tar.gz"
"${R_HOME}/bin/Rscript" -e "download.file('${url}', '${build}/src.tar.gz', mode = 'wb', quiet = TRUE)" \ wickra_download "${url}" "${build}/src.tar.gz" || exit 1
|| { echo "wickra: failed to download source ${url}"; exit 1; }
"${R_HOME}/bin/Rscript" -e "untar('${build}/src.tar.gz', exdir = '${build}')" "${R_HOME}/bin/Rscript" -e "untar('${build}/src.tar.gz', exdir = '${build}')"
root="${build}/wickra-${version}" root="${build}/wickra-${version}"
rustup target add wasm32-unknown-emscripten 2>/dev/null || true rustup target add wasm32-unknown-emscripten 2>/dev/null || true
@@ -73,8 +92,7 @@ else
esac esac
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz" url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
echo "wickra: downloading C ABI ${triple} for v${version}" echo "wickra: downloading C ABI ${triple} for v${version}"
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \ wickra_download "${url}" "src/wickra-c.tar.gz" || exit 1
|| { echo "wickra: failed to download ${url}"; exit 1; }
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')" "${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
inc="src/wickra-c/wickra-c-${triple}/include" inc="src/wickra-c/wickra-c-${triple}/include"
lib="src/wickra-c/wickra-c-${triple}/lib" lib="src/wickra-c/wickra-c-${triple}/lib"
+21 -2
View File
@@ -10,6 +10,26 @@
# WICKRA_LIB_DIR to build against a locally built C ABI instead (dev override). # WICKRA_LIB_DIR to build against a locally built C ABI instead (dev override).
set -e set -e
# A freshly-cut GitHub release can briefly return 404 while its assets propagate
# across the CDN, and a transient network blip should not fail the build either.
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
# on the first miss.
wickra_download() {
_url="$1"
_dest="$2"
_attempt=1
while [ "${_attempt}" -le 6 ]; do
if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
return 0
fi
echo "wickra: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating — retrying in 20s..."
sleep 20
_attempt=$((_attempt + 1))
done
echo "wickra: failed to download ${_url} after 6 attempts"
return 1
}
if [ -n "${WICKRA_INCLUDE_DIR}" ] && [ -n "${WICKRA_LIB_DIR}" ]; then if [ -n "${WICKRA_INCLUDE_DIR}" ] && [ -n "${WICKRA_LIB_DIR}" ]; then
echo "wickra: using C ABI from WICKRA_INCLUDE_DIR / WICKRA_LIB_DIR (dev override)" echo "wickra: using C ABI from WICKRA_INCLUDE_DIR / WICKRA_LIB_DIR (dev override)"
inc="${WICKRA_INCLUDE_DIR}" inc="${WICKRA_INCLUDE_DIR}"
@@ -24,8 +44,7 @@ else
esac esac
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz" url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
echo "wickra: downloading C ABI ${triple} for v${version}" echo "wickra: downloading C ABI ${triple} for v${version}"
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \ wickra_download "${url}" "src/wickra-c.tar.gz" || exit 1
|| { echo "wickra: failed to download ${url}"; exit 1; }
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')" "${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
inc="src/wickra-c/wickra-c-${triple}/include" inc="src/wickra-c/wickra-c-${triple}/include"
lib="src/wickra-c/wickra-c-${triple}/lib" lib="src/wickra-c/wickra-c-${triple}/lib"
+1 -1
View File
@@ -4,7 +4,7 @@
\alias{AwesomeOscillatorHistogram} \alias{AwesomeOscillatorHistogram}
\title{AwesomeOscillatorHistogram indicator} \title{AwesomeOscillatorHistogram indicator}
\usage{ \usage{
AwesomeOscillatorHistogram(fast, slow, sma_period) AwesomeOscillatorHistogram(fast, slow, lookback)
} }
\description{ \description{
AwesomeOscillatorHistogram indicator AwesomeOscillatorHistogram indicator
+29
View File
@@ -0,0 +1,29 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{BinanceFeed}
\alias{BinanceFeed}
\title{Connect to a live Binance kline feed}
\usage{
BinanceFeed(symbols, interval, base_url = NULL)
}
\arguments{
\item{symbols}{Comma-separated trading symbols (case-insensitive), e.g.
\code{"btcusdt,ethusdt"}.}
\item{interval}{Integer interval code \code{0:15} (\code{0} = 1s, \code{1} = 1m, ...,
\code{12} = 1d, \code{13} = 3d, \code{14} = 1w, \code{15} = 1M).}
\item{base_url}{Optional endpoint override; \code{NULL} uses production.}
}
\value{
A \code{wickra_binance_feed}; poll it with \code{\link[=binance_next]{binance_next()}} and close it
with \code{\link[=binance_close]{binance_close()}}.
}
\description{
Opens a live Binance kline stream for one or more comma-separated \code{symbols}
(case-insensitive) at the given \code{interval} code (an integer \code{0:15}, the same
order as the other bindings: 0 = 1s, 1 = 1m, ... 12 = 1d, 13 = 3d, 14 = 1w,
15 = 1M). \code{base_url} overrides the endpoint (\code{NULL} = production). Not
available in the wasm (r-universe/webR) build, which has no raw sockets.
}
\keyword{internal}
+20
View File
@@ -0,0 +1,20 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{CandleReader}
\alias{CandleReader}
\title{Parse OHLCV candles from a CSV string}
\usage{
CandleReader(csv)
}
\arguments{
\item{csv}{A length-one character string of CSV text (a header row followed
by OHLCV data rows).}
}
\value{
A \code{wickra_indicator} candle reader; read its candles with \code{\link[=read]{read()}}.
}
\description{
Builds a reader over an in-memory CSV string with a header row and OHLCV
columns. Pass the result to \code{\link[=read]{read()}} to get every parsed candle.
}
\keyword{internal}
+20
View File
@@ -0,0 +1,20 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Resampler}
\alias{Resampler}
\title{Resample candles to a higher timeframe}
\usage{
Resampler(timeframe)
}
\arguments{
\item{timeframe}{Integer number of input candles per higher-timeframe bar.}
}
\value{
A \code{wickra_indicator} resampler.
}
\description{
Aggregates a stream of candles into higher-timeframe bars. Feed candles with
\code{\link[=update]{update()}} (it returns a completed higher-timeframe bar, or \code{NULL} while the
current bar is still open) and emit the final, still-open bar with \code{\link[=flush]{flush()}}.
}
\keyword{internal}
+22
View File
@@ -0,0 +1,22 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{TickAggregator}
\alias{TickAggregator}
\title{Aggregate trade ticks into time-bucketed candles}
\usage{
TickAggregator(bucket, gap_fill)
}
\arguments{
\item{bucket}{Time-bucket width, in the same unit as the tick timestamps.}
\item{gap_fill}{Logical; if \code{TRUE}, empty buckets with no trades are still
emitted (carried forward) instead of skipped.}
}
\value{
A \code{wickra_indicator} tick aggregator; feed it ticks with \code{\link[=push]{push()}}.
}
\description{
Builds OHLCV candles from a stream of trade ticks. Feed ticks with \code{\link[=push]{push()}},
which returns the candles closed by that tick.
}
\keyword{internal}
+18
View File
@@ -0,0 +1,18 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{binance_close}
\alias{binance_close}
\title{Close a Binance feed}
\usage{
binance_close(feed)
}
\arguments{
\item{feed}{A \code{wickra_binance_feed} created by \code{\link[=BinanceFeed]{BinanceFeed()}}.}
}
\value{
\code{NULL}, invisibly.
}
\description{
Close a Binance feed
}
\keyword{internal}
+23
View File
@@ -0,0 +1,23 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{binance_next}
\alias{binance_next}
\title{Poll a Binance feed for the next kline event}
\usage{
binance_next(feed, timeout_ms = 1000)
}
\arguments{
\item{feed}{A \code{wickra_binance_feed} created by \code{\link[=BinanceFeed]{BinanceFeed()}}.}
\item{timeout_ms}{Poll timeout in milliseconds.}
}
\value{
A named list (\code{symbol}, \code{open}, \code{high}, \code{low}, \code{close}, \code{volume},
\code{open_time}, \code{is_closed}) for an event, or \code{NULL} on timeout.
}
\description{
Waits up to \code{timeout_ms} milliseconds. Returns a named list (\code{symbol}, \code{open},
\code{high}, \code{low}, \code{close}, \code{volume}, \code{open_time}, \code{is_closed}) when an event
arrives, or \code{NULL} on timeout. Errors once the stream is closed.
}
\keyword{internal}
+41
View File
@@ -0,0 +1,41 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{fetch_binance_klines}
\alias{fetch_binance_klines}
\title{Fetch historical Binance klines over REST}
\usage{
fetch_binance_klines(
symbol,
interval,
limit,
start_ms = -1,
end_ms = -1,
base_url = NULL
)
}
\arguments{
\item{symbol}{Trading symbol (case-insensitive), e.g. \code{"btcusdt"}.}
\item{interval}{Integer interval code \code{0:15} (see \code{\link[=BinanceFeed]{BinanceFeed()}}).}
\item{limit}{Number of klines to fetch (\code{1:1000}).}
\item{start_ms, end_ms}{Optional inclusive Unix-millisecond bounds; a negative
value means unset.}
\item{base_url}{Optional host override; \code{NULL} uses production.}
}
\value{
An \verb{n x 6} numeric matrix with columns \code{open}, \code{high}, \code{low},
\code{close}, \code{volume}, \code{timestamp}.
}
\description{
Downloads up to \code{limit} (\code{1:1000}) historical klines for \code{symbol} at the given
\code{interval} code (an integer \code{0:15}, the same order as the other bindings).
\code{start_ms}/\code{end_ms} are optional inclusive Unix-millisecond bounds (a negative
value means unset); \code{base_url} overrides the host (\code{NULL} = production). Returns
an \verb{n x 6} numeric matrix with columns \code{open}, \code{high}, \code{low}, \code{close},
\code{volume}, \code{timestamp}. Blocks until the response arrives. Not available in the
wasm (r-universe/webR) build, which has no raw sockets.
}
\keyword{internal}
+25
View File
@@ -0,0 +1,25 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/methods.R
\name{flush.wickra_indicator}
\alias{flush.wickra_indicator}
\title{Flush a resampler's final candle}
\usage{
\method{flush}{wickra_indicator}(con)
}
\arguments{
\item{con}{A \code{wickra_indicator} created by \code{\link[=Resampler]{Resampler()}}.}
}
\value{
A named numeric vector (\code{open}, \code{high}, \code{low}, \code{close}, \code{volume},
\code{timestamp}), or \code{NULL} if nothing is pending.
}
\description{
Emit the final, still-open candle a \code{\link[=Resampler]{Resampler()}} is aggregating (the partial
higher-timeframe bar that no later input has closed yet). Extends the base
generic \code{\link[base:flush]{base::flush()}}.
}
\examples{
r <- Resampler(5)
for (t in 0:6) update(r, 100 + t, 101 + t, 99 + t, 100 + t, 10, t)
flush(r)
}
+26
View File
@@ -0,0 +1,26 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/methods.R
\name{is_ready}
\alias{is_ready}
\alias{is_ready.wickra_indicator}
\title{Whether an indicator has consumed enough input to emit a value}
\usage{
is_ready(object)
\method{is_ready}{wickra_indicator}(object)
}
\arguments{
\item{object}{A \code{wickra_indicator}.}
}
\value{
A single logical.
}
\description{
Not available for the alt-chart bar builders, which have no warmup.
}
\examples{
sma <- Sma(3)
is_ready(sma) # FALSE
for (x in c(1, 2, 3)) update(sma, x)
is_ready(sma) # TRUE
}
+24
View File
@@ -0,0 +1,24 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/methods.R
\name{name}
\alias{name}
\alias{name.wickra_indicator}
\title{Canonical name of an indicator}
\usage{
name(object)
\method{name}{wickra_indicator}(object)
}
\arguments{
\item{object}{A \code{wickra_indicator}.}
}
\value{
A single character string.
}
\description{
Returns the stable, human-readable name of the indicator (the same name
reported by every other Wickra binding), e.g. \code{"SMA"} for \code{\link[=Sma]{Sma()}}.
}
\examples{
name(Sma(14)) # "SMA"
}
+33
View File
@@ -0,0 +1,33 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/methods.R
\name{push}
\alias{push}
\alias{push.wickra_indicator}
\title{Push a trade tick into a tick aggregator}
\usage{
push(object, price, size, timestamp)
\method{push}{wickra_indicator}(object, price, size, timestamp)
}
\arguments{
\item{object}{A \code{wickra_indicator} created by \code{\link[=TickAggregator]{TickAggregator()}}.}
\item{price}{Trade price.}
\item{size}{Trade size (volume).}
\item{timestamp}{Trade timestamp, in the same unit as the aggregator bucket.}
}
\value{
A numeric matrix with six named columns (possibly zero rows).
}
\description{
Feeds one trade tick to a \code{\link[=TickAggregator]{TickAggregator()}} and returns the candles it
closed as a numeric matrix with columns \code{open}, \code{high}, \code{low}, \code{close},
\code{volume}, \code{timestamp} (zero rows while the open bar merely grows).
}
\examples{
agg <- TickAggregator(1000, FALSE)
push(agg, 100, 1, 0)
push(agg, 102, 1, 1000) # closes the first bucket
}
+25
View File
@@ -0,0 +1,25 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/methods.R
\name{read}
\alias{read}
\alias{read.wickra_indicator}
\title{Read every candle parsed by a CSV candle reader}
\usage{
read(object)
\method{read}{wickra_indicator}(object)
}
\arguments{
\item{object}{A \code{wickra_indicator} created by \code{\link[=CandleReader]{CandleReader()}}.}
}
\value{
A numeric matrix with six named columns (zero rows for an empty CSV).
}
\description{
Returns all the candles a \code{\link[=CandleReader]{CandleReader()}} parsed from its CSV, as a numeric
matrix with columns \code{open}, \code{high}, \code{low}, \code{close}, \code{volume}, \code{timestamp}.
}
\examples{
r <- CandleReader("timestamp,open,high,low,close,volume\n0,100,101,99,100.5,10\n")
read(r)
}
+6 -6
View File
@@ -7,12 +7,12 @@
\format{ \format{
A data frame with 250 rows and 6 columns: A data frame with 250 rows and 6 columns:
\describe{ \describe{
\item{date}{Trading date (\code{Date}).} \item{date}{Trading date (\code{Date}).}
\item{open}{Opening price.} \item{open}{Opening price.}
\item{high}{Session high.} \item{high}{Session high.}
\item{low}{Session low.} \item{low}{Session low.}
\item{close}{Closing price.} \item{close}{Closing price.}
\item{volume}{Traded volume.} \item{volume}{Traded volume.}
} }
} }
\usage{ \usage{
+24
View File
@@ -0,0 +1,24 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/methods.R
\name{warmup_period}
\alias{warmup_period}
\alias{warmup_period.wickra_indicator}
\title{Number of updates an indicator needs before it produces a value}
\usage{
warmup_period(object)
\method{warmup_period}{wickra_indicator}(object)
}
\arguments{
\item{object}{A \code{wickra_indicator}.}
}
\value{
A single integer: the warmup period.
}
\description{
Not available for the alt-chart bar builders (\code{\link[=RenkoBars]{RenkoBars()}}, \code{\link[=KagiBars]{KagiBars()}},
\code{\link[=PointAndFigureBars]{PointAndFigureBars()}}, …), which have no warmup.
}
\examples{
warmup_period(Sma(14)) # 14
}
+3 -2
View File
@@ -18,16 +18,17 @@ Useful links:
\itemize{ \itemize{
\item \url{https://github.com/wickra-lib/wickra} \item \url{https://github.com/wickra-lib/wickra}
\item \url{https://docs.wickra.org} \item \url{https://docs.wickra.org}
\item \url{https://wickra-lib.r-universe.dev}
\item Report bugs at \url{https://github.com/wickra-lib/wickra/issues} \item Report bugs at \url{https://github.com/wickra-lib/wickra/issues}
} }
} }
\author{ \author{
\strong{Maintainer}: Wickra contributors \email{support@wickra.org} \strong{Maintainer}: kingchenc \email{support@wickra.org}
Authors: Authors:
\itemize{ \itemize{
\item Wickra contributors \email{support@wickra.org} \item kingchenc \email{support@wickra.org}
} }
} }
+12 -4
View File
@@ -1,9 +1,17 @@
<p align="center">
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![npm](https://img.shields.io/npm/v/wickra-wasm.svg?logo=npm&color=red)](https://www.npmjs.com/package/wickra-wasm)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](https://github.com/wickra-lib/wickra#license)
# Wickra — WASM # Wickra — WASM
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml) ---
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![npm](https://img.shields.io/npm/v/wickra-wasm.svg?logo=npm&color=red)](https://www.npmjs.com/package/wickra-wasm) > **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license)
**Streaming-first technical indicators in the browser. `npm install **Streaming-first technical indicators in the browser. `npm install
wickra-wasm` — pure WebAssembly, runs anywhere a modern JS engine does.** wickra-wasm` — pure WebAssembly, runs anywhere a modern JS engine does.**
+1 -1
View File
@@ -27,7 +27,7 @@ workspace = true
# (rayon) feature on — the WASM binding needs a rayon-free build and the data # (rayon) feature on — the WASM binding needs a rayon-free build and the data
# layer never uses the parallel batch path. Native bindings re-enable `parallel` # layer never uses the parallel batch path. Native bindings re-enable `parallel`
# through their own wickra-core dependency (cargo unifies the features). # through their own wickra-core dependency (cargo unifies the features).
wickra-core = { path = "../wickra-core", version = "0.9.2", default-features = false } wickra-core = { path = "../wickra-core", version = "0.9.9", default-features = false }
thiserror = { workspace = true } thiserror = { workspace = true }
csv = "1.3" csv = "1.3"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
+2 -2
View File
@@ -6,7 +6,7 @@
<groupId>org.wickra.examples</groupId> <groupId>org.wickra.examples</groupId>
<artifactId>wickra-examples</artifactId> <artifactId>wickra-examples</artifactId>
<version>0.9.4</version> <version>0.9.9</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Wickra Java examples</name> <name>Wickra Java examples</name>
@@ -21,7 +21,7 @@
<dependency> <dependency>
<groupId>org.wickra</groupId> <groupId>org.wickra</groupId>
<artifactId>wickra</artifactId> <artifactId>wickra</artifactId>
<version>0.9.4</version> <version>0.9.9</version>
</dependency> </dependency>
</dependencies> </dependencies>
+7 -7
View File
@@ -14,7 +14,7 @@
}, },
"../../bindings/node": { "../../bindings/node": {
"name": "wickra", "name": "wickra",
"version": "0.9.4", "version": "0.9.9",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"devDependencies": { "devDependencies": {
"@napi-rs/cli": "^2.18.0" "@napi-rs/cli": "^2.18.0"
@@ -23,12 +23,12 @@
"node": ">= 20" "node": ">= 20"
}, },
"optionalDependencies": { "optionalDependencies": {
"wickra-darwin-arm64": "0.9.4", "wickra-darwin-arm64": "0.9.9",
"wickra-darwin-x64": "0.9.4", "wickra-darwin-x64": "0.9.9",
"wickra-linux-arm64-gnu": "0.9.4", "wickra-linux-arm64-gnu": "0.9.9",
"wickra-linux-x64-gnu": "0.9.4", "wickra-linux-x64-gnu": "0.9.9",
"wickra-win32-arm64-msvc": "0.9.4", "wickra-win32-arm64-msvc": "0.9.9",
"wickra-win32-x64-msvc": "0.9.4" "wickra-win32-x64-msvc": "0.9.9"
} }
}, },
"node_modules/wickra": { "node_modules/wickra": {
+33
View File
@@ -0,0 +1,33 @@
# lychee external-link checker config (see .github/workflows/links.yml).
# Only http(s) URLs are checked; relative/internal links are skipped via the
# scheme filter and --root-dir resolution. Loopback and private addresses are
# skipped too.
max_retries = 3
retry_wait_time = 2
timeout = 20
# Treat these as success: OK, partial content, and rate-limited (transient).
accept = [200, 206, 429]
scheme = ["https", "http"]
exclude_all_private = true
# Known false positives (the URLs are valid; lychee just can't verify them at
# check time):
# - crates.io and npmjs.com return 403/404 to non-browser requests
# (anti-scraping); the package pages are live in a browser.
# - GitHub serves 404 for /stargazers and /network/members to anonymous clients
# (anti-scraping). The README social-footer badges link there; the pages are
# live in a browser.
# - the CHANGELOG version-compare links point at the release tag that is created
# *after* the bump is merged. ci.yml runs on push/PR (never on the tag), so the
# tag never exists when lychee runs and the compare URL 404s. One pattern
# covers every future version — no per-release exclude needed.
exclude = [
'crates\.io/crates/',
'www\.npmjs\.com/package/',
'github\.com/wickra-lib/wickra/compare/',
'github\.com/wickra-lib/wickra/stargazers',
'github\.com/wickra-lib/wickra/network/members',
]