Skip to content

feat: add official Flutter SDK (usenavii) with SVG parity to @usenavii/core - #5

Merged
uxderrick merged 22 commits into
uxderrick:mainfrom
404khai:main
Aug 23, 2026
Merged

uxderrick merged 22 commits into
uxderrick:mainfrom
404khai:main

Conversation

@404khai

@404khai 404khai commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an official Flutter / Dart SDK for Navii as packages/flutter (pub package name: usenavii).

This is a faithful Dart port of @usenavii/core plus thin widgets mirroring @usenavii/react-native — not a hosted-API wrapper and not a JS/WASM bridge. Same seed + same options → byte-identical SVG as the TypeScript engine.

Architecture

  • Engine: packages/flutter/lib/src/core/ (port of packages/core)
  • Widgets: Navii / NaviiGroup via flutter_svg (SvgPicture.string)
  • Versioning: independent SemVer on pub.dev (out of npm lockstep)
  • Current version: 0.1.0-dev.1 (parity target: @usenavii/core 0.9.x)

Features

Engine API (re-exported from package:usenavii/usenavii.dart)

  • createAvatar, selectAvatar, renderAvatar / renderAvatarInner
  • renderGroup / renderGroupTiles
  • build(BuildSpec) for non-seeded composition
  • Packs: builtInPacks, packRegistry, resolvePacks
  • Primitives: sha256Hex, cyrb53, createRng, seed / seedFromEmail / normalizeEmail
  • random() helper

Flutter widgets

  • Navii — required seed; props map to engine options (styleHint → engine style); Semantics via alt ?? title
  • NaviiGroup — overlapping stack with +N counter; empty seeds → zero-size widget (RN returns null)
  • animated accepted but painted statically in v1 (same as React Native — CSS keyframes do not run in flutter_svg)

Example + docs

CI / publish

  • .github/workflows/flutter.yml — flutter pub get / analyze / test / dart pub publish --dry-run on packages/flutter/**
  • Flutter explicitly excluded from .github/workflows/release.yml npm matrix (five JS packages only)
  • LICENSE, package CHANGELOG.md, .pubignore, root CHANGELOG version-mapping table
  • CONTRIBUTING.md documents the Flutter lockstep exception

Parity / testing

Golden fixtures exported from @usenavii/core assert string-identical SVG for:

  • Primitives (sha256, PRNG, seed helpers)
  • selectAvatar specs
  • createAvatar / renderAvatar
  • renderGroup / renderGroupTiles + dimensions
  • build(BuildSpec)
  • Packs registry + pack-affected SVG output
  • Widget tests: determinism, layout size, empty group, README snippet smoke tests
cd packages/flutter
flutter pub get
flutter analyze --no-fatal-infos
flutter test

cd example && flutter run -d chrome   # or -d macos
dart pub publish --dry-run             # from packages/flutter (clean tree)

Non-goals (intentional)

  • No package.json in packages/flutter (keeps pnpm / npm release CI clean)
  • Not added to the npm publish matrix
  • Animation remains static in the Flutter widget for v1 (engine still emits CSS when animated: true for string parity)

Test plan

  • flutter test green under packages/flutter
  • flutter analyze --no-fatal-infos green
  • dart pub publish --dry-run succeeds on a clean tree
  • Example runs: cd packages/flutter/example && flutter run -d chrome
  • Confirm .github/workflows/release.yml still publishes only core / react / react-native / vue / svelte
  • Spot-check: same seed in Node @usenavii/core and Dart createAvatar → identical SVG
  • Root README lists usenavii / Flutter package

Notes

  • PRNG draw order matches core (new variants append only).
  • Prefer stable ids as seeds (user.id → UUID → email), never Date.now() or display names.

404khai and others added 18 commits July 27, 2026 22:03
feat(flutter): add SDK scaffold
Add faithful Dart ports of sha256, cyrb53/createRng, and seed helpers so
Flutter matches @usenavii/core hashing and PRNG streams before select/render.
feat(flutter): port Phase 2 primitives with TS fixture parity
Resolve AvatarSpec from seed+options matching @usenavii/core, including
mood, style hints, and built-in packs, locked by cross-language fixtures.
feat(flutter): port Phase 3 selectAvatar with TS spec parity
Add Dart parts/render pipeline so createAvatar matches @usenavii/core
byte-for-byte on golden seeds (mood, packs, animated, sizes).
feat(flutter): port Phase 4 createAvatar with SVG parity
Port renderGroup/renderGroupTiles and build(BuildSpec) from @usenavii/core
with byte-identical SVG goldens. Packs registry/SVG parity covered; unblocks
NaviiGroup tile rendering ahead of Phase 6 widget polish.
feat(flutter): Phase 5 group stacks, build(), packs parity
Ship drop-in Flutter widgets mirroring @usenavii/react-native: SvgPicture
rendering, Semantics (alt ?? title), group stack layout, and widget tests for
determinism, size, empty seeds, and README usage snippets.
feat(flutter): Phase 6 Navii / NaviiGroup widgets
Add packages/flutter/example (seed, size, mood, NaviiGroup) with web/macOS
targets, list usenavii in the root README Packages table, and document how to
run the demo.
feat(flutter): Phase 7 example app and docs surface
Add flutter.yml (analyze/test/dry-run), document Flutter’s exclusion from the
npm release matrix, and ship LICENSE/CHANGELOG/.pubignore for usenavii on
pub.dev.
chore(flutter): Phase 8 CI workflow and pub.dev publish path
Paint the overflow chip with a Flutter-centered disc instead of SvgPicture.
flutter_svg ignores dominant-baseline, which left engine counter text sitting
high; renderGroupTiles SVG strings stay TS-identical for goldens.
fix(flutter): center NaviiGroup +N counter under flutter_svg
@404khai

404khai commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Hi @uxderrick, would appreciate it if you could review and merge. I am planning on implementing it into my Flutter manga reader app

@uxderrick
uxderrick merged commit 3d4530a into uxderrick:main Aug 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants