chore(release): prepare runtime packages 0.1.0

This commit is contained in:
smontlouis 2026-08-17 18:15:45 +02:00
parent 2386b78817
commit 2ba720e059
14 changed files with 548 additions and 41 deletions

11
.changeset/README.md Normal file
View File

@ -0,0 +1,11 @@
# Changesets
Every user-visible package change must include a changeset created with `pnpm changeset`.
The three runtime packages use one fixed version while the public API stabilizes. Select:
- `patch` for compatible fixes and documentation corrections;
- `minor` for compatible features and for breaking changes while the version is below `1.0.0`;
- `major` only after the packages have reached `1.0.0`.
Merging the generated release pull request publishes the versions recorded in that pull request.

13
.changeset/config.json Normal file
View File

@ -0,0 +1,13 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [
["@bible-strong/avatar-core", "@bible-strong/avatar-react", "@bible-strong/avatar-web"]
],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}

50
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,50 @@
name: Release
on:
push:
branches:
- main
permissions:
contents: write
pull-requests: write
id-token: write
concurrency:
group: release
cancel-in-progress: false
jobs:
release:
name: Version or publish packages
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: '24.15.0'
registry-url: 'https://registry.npmjs.org'
- name: Install pnpm
run: npm install --global pnpm@10.34.5
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Validate project
run: pnpm check
- name: Create release pull request or publish
uses: changesets/action@v1
with:
publish: pnpm release
version: pnpm version-packages
title: 'chore(release): publish runtime packages'
commit: 'chore(release): publish runtime packages'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

40
docs/PUBLISHING.md Normal file
View File

@ -0,0 +1,40 @@
# Publishing the runtime packages
The runtime is published as three public npm packages:
- `@bible-strong/avatar-core` contains the validation, playback and renderer-neutral scene APIs;
- `@bible-strong/avatar-react` depends on core and provides the React 19 integration;
- `@bible-strong/avatar-web` depends on core and provides the direct DOM/ESM integration.
All three packages keep the same version during the `0.x` stabilization period. Semantic Versioning
is applied as follows:
- a compatible fix increments the patch version (`0.1.0` to `0.1.1`);
- a compatible feature increments the minor version (`0.1.0` to `0.2.0`);
- a breaking change also increments the minor version while below `1.0.0`;
- after `1.0.0`, a breaking change increments the major version.
## Normal release flow
1. Add a changeset to every pull request that changes a published API with `pnpm changeset`.
2. Merge changes into `main`.
3. The release workflow updates or creates a release pull request containing version and changelog
changes.
4. Review and merge that release pull request.
5. The workflow validates, builds and publishes every unpublished version to npm.
Publication uses npm trusted publishing through GitHub Actions OIDC. It does not require a stored
`NPM_TOKEN`. Each npm package must trust the `release.yml` workflow in the
`smontlouis/bible-strong-avatar-lab` repository.
## Local verification
Run the complete project checks and verify real consumer projects against packed tarballs:
```sh
pnpm check
pnpm packages:smoke
```
Do not run `npm publish` from an individual package for routine releases. The initial `0.1.0`
bootstrap publication is the only manual release.

View File

@ -31,6 +31,9 @@
"format:check": "prettier --check .",
"packages:build": "pnpm --filter './packages/*' build",
"packages:smoke": "node scripts/smoke-packages.mjs",
"changeset": "changeset",
"version-packages": "changeset version",
"release": "pnpm packages:build && changeset publish",
"check": "pnpm engine:check && pnpm format:check && pnpm typecheck && pnpm test && pnpm packages:build && pnpm build"
},
"dependencies": {
@ -52,6 +55,7 @@
"devDependencies": {
"@babel/core": "^7.29.0",
"@babel/parser": "^7.28.6",
"@changesets/cli": "^3.0.0",
"@rolldown/plugin-babel": "^0.2.3",
"@tailwindcss/vite": "^4.3.3",
"@testing-library/react": "^16.3.2",

View File

@ -76,5 +76,5 @@ Application integrations are kept in separate packages: `@bible-strong/avatar-re
React 19, while `@bible-strong/avatar-web` mounts the same definition directly into the DOM. Both
depend on this package and use the same playback and scene implementation.
This package is private while copyright ownership, Apache-2.0 relicensing and repository metadata
are confirmed. Local tarballs are for verification only and must not be published.
The package follows Semantic Versioning. While it remains below `1.0.0`, breaking API changes
increment the minor version and fixes increment the patch version.

View File

@ -2,8 +2,24 @@
"name": "@bible-strong/avatar-core",
"version": "0.1.0",
"description": "Framework-independent runtime for Bible Strong procedural avatars.",
"keywords": [
"avatar",
"svg",
"animation",
"renderer",
"typescript"
],
"author": "Stéphane Montlouis-Calixte",
"license": "AGPL-3.0-only",
"private": true,
"homepage": "https://github.com/smontlouis/bible-strong-avatar-lab#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/smontlouis/bible-strong-avatar-lab.git",
"directory": "packages/avatar-core"
},
"bugs": {
"url": "https://github.com/smontlouis/bible-strong-avatar-lab/issues"
},
"type": "module",
"sideEffects": false,
"files": [
@ -36,8 +52,12 @@
},
"scripts": {
"build": "vite build --config vite.config.ts && tsc -p tsconfig.build.json",
"prepack": "pnpm build",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"ajv": "^8.20.0"
},

View File

@ -9,9 +9,6 @@ dependencies; `@bible-strong/avatar-core` is installed as a normal dependency.
pnpm add @bible-strong/avatar-react react react-dom
```
The packages are currently private. This registry command will work after publication; use the
workspace packages or locally packed tarballs for development verification in the meantime.
Import the package stylesheet once in the application entry point:
```tsx
@ -123,6 +120,6 @@ that reference changes.
The stylesheet exposes `.bs-avatar` and `.bs-avatar__svg`. Consumer `className` and `style` are
applied to the outer wrapper.
The public component never exposes Studio IDs or document types. This package is private while
copyright ownership, Apache-2.0 relicensing and repository metadata are confirmed. Local tarballs
are for verification only and must not be published.
The public component never exposes Studio IDs or document types. The package follows Semantic
Versioning. While it remains below `1.0.0`, breaking API changes increment the minor version and
fixes increment the patch version.

View File

@ -2,8 +2,24 @@
"name": "@bible-strong/avatar-react",
"version": "0.1.0",
"description": "React 19 renderer for Bible Strong procedural avatars.",
"keywords": [
"avatar",
"svg",
"animation",
"react",
"typescript"
],
"author": "Stéphane Montlouis-Calixte",
"license": "AGPL-3.0-only",
"private": true,
"homepage": "https://github.com/smontlouis/bible-strong-avatar-lab#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/smontlouis/bible-strong-avatar-lab.git",
"directory": "packages/avatar-react"
},
"bugs": {
"url": "https://github.com/smontlouis/bible-strong-avatar-lab/issues"
},
"type": "module",
"sideEffects": [
"**/*.css"
@ -22,8 +38,12 @@
},
"scripts": {
"build": "vite build --config vite.config.ts && tsc -p tsconfig.build.json",
"prepack": "pnpm build",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"@bible-strong/avatar-core": "workspace:^"
},

View File

@ -0,0 +1,10 @@
Copyright (C) 2026 Stéphane Montlouis-Calixte
This program is free software: you can redistribute it and/or modify it under the terms of the GNU
Affero General Public License as published by the Free Software Foundation, version 3.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
The complete license text is available at <https://www.gnu.org/licenses/agpl-3.0.txt>.

View File

@ -24,5 +24,5 @@ avatar.stop()
For a browser project without a bundler, load an ESM build through an import map or CDN and fetch
the definition JSON before calling `createAvatar`.
This package is private while copyright ownership, Apache-2.0 relicensing and repository metadata
are confirmed. Local tarballs are for verification only and must not be published.
The package follows Semantic Versioning. While it remains below `1.0.0`, breaking API changes
increment the minor version and fixes increment the patch version.

View File

@ -2,8 +2,25 @@
"name": "@bible-strong/avatar-web",
"version": "0.1.0",
"description": "Framework-independent DOM renderer for Bible Strong procedural avatars.",
"keywords": [
"avatar",
"svg",
"animation",
"dom",
"esm",
"typescript"
],
"author": "Stéphane Montlouis-Calixte",
"license": "AGPL-3.0-only",
"private": true,
"homepage": "https://github.com/smontlouis/bible-strong-avatar-lab#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/smontlouis/bible-strong-avatar-lab.git",
"directory": "packages/avatar-web"
},
"bugs": {
"url": "https://github.com/smontlouis/bible-strong-avatar-lab/issues"
},
"type": "module",
"sideEffects": false,
"files": [
@ -19,8 +36,12 @@
},
"scripts": {
"build": "vite build --config vite.config.ts && tsc -p tsconfig.build.json",
"prepack": "pnpm build",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"@bible-strong/avatar-core": "workspace:^"
},

354
pnpm-lock.yaml generated
View File

@ -57,12 +57,15 @@ importers:
'@babel/parser':
specifier: ^7.28.6
version: 7.29.8
'@changesets/cli':
specifier: ^3.0.0
version: 3.0.0
'@rolldown/plugin-babel':
specifier: ^0.2.3
version: 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))
version: 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))
'@tailwindcss/vite':
specifier: ^4.3.3
version: 4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))
version: 4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))
'@testing-library/react':
specifier: ^16.3.2
version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@ -77,7 +80,7 @@ importers:
version: 19.2.4(@types/react@19.2.18)
'@vitejs/plugin-react':
specifier: ^6.0.2
version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))
version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))
babel-plugin-react-compiler:
specifier: ^1.0.0
version: 1.0.0
@ -98,10 +101,10 @@ importers:
version: 6.0.3
vite:
specifier: ^8.0.13
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
vitest:
specifier: ^4.1.10
version: 4.1.10(@types/node@24.13.3)(jsdom@30.0.1)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))
version: 4.1.10(@types/node@24.13.3)(jsdom@30.0.1)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))
examples/react-vite-consumer:
dependencies:
@ -113,7 +116,7 @@ importers:
version: link:../../packages/avatar-react
'@vitejs/plugin-react':
specifier: ^6.0.2
version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))
version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))
react:
specifier: 19.2.3
version: 19.2.3
@ -125,7 +128,7 @@ importers:
version: 6.0.3
vite:
specifier: ^8.0.13
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
devDependencies:
'@types/react':
specifier: ^19.2.14
@ -145,7 +148,7 @@ importers:
version: 6.0.3
vite:
specifier: ^8.0.13
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
packages/avatar-core:
dependencies:
@ -158,7 +161,7 @@ importers:
version: 6.0.3
vite:
specifier: ^8.0.13
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
packages/avatar-react:
dependencies:
@ -183,7 +186,7 @@ importers:
version: 6.0.3
vite:
specifier: ^8.0.13
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
packages/avatar-web:
dependencies:
@ -196,7 +199,7 @@ importers:
version: 6.0.3
vite:
specifier: ^8.0.13
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
packages:
@ -310,6 +313,75 @@ packages:
resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
hasBin: true
'@changesets/apply-release-plan@8.0.0':
resolution: {integrity: sha512-kUd2pbf1w5/AYmBMb0Tt+rkIPCjFJdT0SZMrkOjJT/WV/QbtmvkyB5jkV0oaNPheavprZk+SfUiozUti7TIL2w==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/assemble-release-plan@7.0.0':
resolution: {integrity: sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/changelog-git@1.0.0':
resolution: {integrity: sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/cli@3.0.0':
resolution: {integrity: sha512-V7Gm+GP5OT3mJinMI2YcJD/JyO/a4WChnaMCCzTRhWHgu1zhtsyY7zCjP6n5W6zsgSjJKs+yPmvtREvE0F2g8A==}
engines: {node: ^22.11 || ^24 || >=26, npm: '>=10.9.0', pnpm: '>=10.0.0', yarn: '>=4.5.2'}
hasBin: true
'@changesets/config@4.0.0':
resolution: {integrity: sha512-mw95/YrkOuhZZxfnVAA4bSXOFUi+KlhzOBTM8C4x777NhUU6HWIl9Z+K+nME+E4PVsv5NQVQwTfiHihAS1A/ow==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/errors@1.0.0':
resolution: {integrity: sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/format@0.1.2':
resolution: {integrity: sha512-Caez5XtNXCFS/G5bwyav3wuXL0tMxVd2ZGbaumWbzN08tyzO21asCw7JZhNtVsAZDCvDRUzZN+Iit9SyRITSYA==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/get-dependents-graph@3.0.0':
resolution: {integrity: sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/git@4.0.0':
resolution: {integrity: sha512-uIEswpPUgzBBqrC0qg13byNaPorzhf05LE2T+gRizEKCXvMsJC6NPJp5iNDSV/gYj4Viqh09UiOF5E7XWeH5lQ==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/parse@1.0.0':
resolution: {integrity: sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/pre@3.0.0':
resolution: {integrity: sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/read@1.0.0':
resolution: {integrity: sha512-8TdE2PwG6yArPt5Ozej83Z6iHz1G8BDBKvIEKZ455MccR4K3GNbLR2XqjBxa+5yLFnEd3xAOPXYboBg1pt8stQ==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/should-skip-package@1.0.0':
resolution: {integrity: sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/types@7.0.0':
resolution: {integrity: sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==}
engines: {node: ^22.11 || ^24 || >=26}
'@changesets/write@1.0.0':
resolution: {integrity: sha512-xCK3/4C7Z7muQB/wguE6HcbjtY9iOtaK9orZKE+7xi573cMGD8rLZz7qlo6IvK7s+SIUIKajzj1l+F1QuP97tw==}
engines: {node: ^22.11 || ^24 || >=26}
'@clack/core@1.4.3':
resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==}
engines: {node: '>= 20.12.0'}
'@clack/prompts@1.7.0':
resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==}
engines: {node: '>= 20.12.0'}
'@csstools/color-helpers@6.1.0':
resolution: {integrity: sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==}
engines: {node: '>=20.19.0'}
@ -386,9 +458,25 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@manypkg/find-root@3.1.0':
resolution: {integrity: sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==}
engines: {node: '>=20.0.0'}
'@manypkg/get-packages@3.1.0':
resolution: {integrity: sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==}
engines: {node: '>=20.0.0'}
'@manypkg/tools@2.1.2':
resolution: {integrity: sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==}
engines: {node: '>=20.0.0'}
'@oxc-project/types@0.144.0':
resolution: {integrity: sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==}
'@pnpm/deps.graph-sequencer@1100.0.1':
resolution: {integrity: sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==}
engines: {node: '>=22.13'}
'@rolldown/binding-android-arm64@1.2.4':
resolution: {integrity: sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==}
engines: {node: ^20.19.0 || >=22.12.0}
@ -769,6 +857,10 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
cac@7.0.0:
resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==}
engines: {node: '>=20.19.0'}
caniuse-lite@1.0.30001809:
resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==}
@ -848,9 +940,18 @@ packages:
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
fast-string-truncated-width@3.0.3:
resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==}
fast-string-width@3.0.2:
resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==}
fast-uri@3.1.5:
resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==}
fast-wrap-ansi@0.2.2:
resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==}
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@ -887,6 +988,13 @@ packages:
resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
human-id@4.2.0:
resolution: {integrity: sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==}
hasBin: true
import-meta-resolve@4.2.0:
resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==}
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
@ -894,6 +1002,9 @@ packages:
resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
hasBin: true
jju@1.4.0:
resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -919,6 +1030,12 @@ packages:
engines: {node: '>=6'}
hasBin: true
jsonc-parser@3.3.1:
resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
launch-editor@2.14.1:
resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==}
lightningcss-android-arm64@1.32.0:
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
engines: {node: '>= 12.0.0'}
@ -1122,6 +1239,9 @@ packages:
resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==}
engines: {node: '>=12.20.0'}
package-manager-detector@1.8.0:
resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==}
parse5@8.0.1:
resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==}
@ -1193,9 +1313,21 @@ packages:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
semver@7.8.5:
resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
engines: {node: '>=10'}
hasBin: true
shell-quote@1.10.0:
resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==}
engines: {node: '>= 0.4'}
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@ -1394,6 +1526,11 @@ packages:
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
yaml@2.9.0:
resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
engines: {node: '>= 14.6'}
hasBin: true
snapshots:
'@asamuzakjp/css-color@6.0.7':
@ -1540,6 +1677,122 @@ snapshots:
dependencies:
css-tree: 3.2.1
'@changesets/apply-release-plan@8.0.0':
dependencies:
'@changesets/config': 4.0.0
'@changesets/format': 0.1.2
'@changesets/git': 4.0.0
'@changesets/should-skip-package': 1.0.0
'@changesets/types': 7.0.0
import-meta-resolve: 4.2.0
jsonc-parser: 3.3.1
semver: 7.8.5
'@changesets/assemble-release-plan@7.0.0':
dependencies:
'@changesets/errors': 1.0.0
'@changesets/get-dependents-graph': 3.0.0
'@changesets/should-skip-package': 1.0.0
'@changesets/types': 7.0.0
semver: 7.8.5
'@changesets/changelog-git@1.0.0':
dependencies:
'@changesets/types': 7.0.0
'@changesets/cli@3.0.0':
dependencies:
'@changesets/apply-release-plan': 8.0.0
'@changesets/assemble-release-plan': 7.0.0
'@changesets/changelog-git': 1.0.0
'@changesets/config': 4.0.0
'@changesets/errors': 1.0.0
'@changesets/get-dependents-graph': 3.0.0
'@changesets/git': 4.0.0
'@changesets/pre': 3.0.0
'@changesets/read': 1.0.0
'@changesets/should-skip-package': 1.0.0
'@changesets/types': 7.0.0
'@changesets/write': 1.0.0
'@clack/prompts': 1.7.0
'@manypkg/get-packages': 3.1.0
'@pnpm/deps.graph-sequencer': 1100.0.1
cac: 7.0.0
import-meta-resolve: 4.2.0
launch-editor: 2.14.1
package-manager-detector: 1.8.0
semver: 7.8.5
tinyexec: 1.3.0
'@changesets/config@4.0.0':
dependencies:
'@changesets/get-dependents-graph': 3.0.0
'@changesets/should-skip-package': 1.0.0
'@changesets/types': 7.0.0
'@manypkg/get-packages': 3.1.0
picomatch: 4.0.5
'@changesets/errors@1.0.0': {}
'@changesets/format@0.1.2':
dependencies:
package-manager-detector: 1.8.0
tinyexec: 1.3.0
'@changesets/get-dependents-graph@3.0.0':
dependencies:
'@changesets/types': 7.0.0
semver: 7.8.5
'@changesets/git@4.0.0':
dependencies:
'@changesets/errors': 1.0.0
'@changesets/types': 7.0.0
'@manypkg/get-packages': 3.1.0
picomatch: 4.0.5
tinyexec: 1.3.0
'@changesets/parse@1.0.0':
dependencies:
'@changesets/types': 7.0.0
yaml: 2.9.0
'@changesets/pre@3.0.0':
dependencies:
'@changesets/errors': 1.0.0
'@changesets/types': 7.0.0
'@manypkg/get-packages': 3.1.0
'@changesets/read@1.0.0':
dependencies:
'@changesets/git': 4.0.0
'@changesets/parse': 1.0.0
'@changesets/types': 7.0.0
'@changesets/should-skip-package@1.0.0':
dependencies:
'@changesets/types': 7.0.0
'@changesets/types@7.0.0': {}
'@changesets/write@1.0.0':
dependencies:
'@changesets/format': 0.1.2
'@changesets/types': 7.0.0
human-id: 4.2.0
'@clack/core@1.4.3':
dependencies:
fast-wrap-ansi: 0.2.2
sisteransi: 1.0.5
'@clack/prompts@1.7.0':
dependencies:
'@clack/core': 1.4.3
fast-string-width: 3.0.2
fast-wrap-ansi: 0.2.2
sisteransi: 1.0.5
'@csstools/color-helpers@6.1.0': {}
'@csstools/css-calc@3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
@ -1602,8 +1855,25 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@manypkg/find-root@3.1.0':
dependencies:
'@manypkg/tools': 2.1.2
'@manypkg/get-packages@3.1.0':
dependencies:
'@manypkg/find-root': 3.1.0
'@manypkg/tools': 2.1.2
'@manypkg/tools@2.1.2':
dependencies:
jju: 1.4.0
tinyglobby: 0.2.17
yaml: 2.9.0
'@oxc-project/types@0.144.0': {}
'@pnpm/deps.graph-sequencer@1100.0.1': {}
'@rolldown/binding-android-arm64@1.2.4':
optional: true
@ -1646,14 +1916,14 @@ snapshots:
'@rolldown/binding-win32-x64-msvc@1.2.4':
optional: true
'@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))':
'@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))':
dependencies:
'@babel/core': 7.29.7
picomatch: 4.0.5
rolldown: 1.2.4
optionalDependencies:
'@babel/runtime': 7.29.7
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
'@rolldown/pluginutils@1.0.1': {}
@ -1720,12 +1990,12 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.3.3
'@tailwindcss/oxide-win32-x64-msvc': 4.3.3
'@tailwindcss/vite@4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))':
'@tailwindcss/vite@4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))':
dependencies:
'@tailwindcss/node': 4.3.3
'@tailwindcss/oxide': 4.3.3
tailwindcss: 4.3.3
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
'@testing-library/dom@10.4.1':
dependencies:
@ -1779,12 +2049,12 @@ snapshots:
optionalDependencies:
react: 19.2.3
'@vitejs/plugin-react@6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))':
'@vitejs/plugin-react@6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))':
dependencies:
'@rolldown/pluginutils': 1.0.1
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
optionalDependencies:
'@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))
'@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))
babel-plugin-react-compiler: 1.0.0
'@vitest/expect@4.1.10':
@ -1796,13 +2066,13 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.1.1
'@vitest/mocker@4.1.10(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))':
'@vitest/mocker@4.1.10(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))':
dependencies:
'@vitest/spy': 4.1.10
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
'@vitest/pretty-format@4.1.10':
dependencies:
@ -1863,6 +2133,8 @@ snapshots:
node-releases: 2.0.53
update-browserslist-db: 1.3.1(browserslist@4.28.8)
cac@7.0.0: {}
caniuse-lite@1.0.30001809: {}
chai@6.2.2: {}
@ -1922,8 +2194,18 @@ snapshots:
fast-deep-equal@3.1.3: {}
fast-string-truncated-width@3.0.3: {}
fast-string-width@3.0.2:
dependencies:
fast-string-truncated-width: 3.0.3
fast-uri@3.1.5: {}
fast-wrap-ansi@0.2.2:
dependencies:
fast-string-width: 3.0.2
fdir@6.5.0(picomatch@4.0.5):
optionalDependencies:
picomatch: 4.0.5
@ -1950,10 +2232,16 @@ snapshots:
transitivePeerDependencies:
- '@noble/hashes'
human-id@4.2.0: {}
import-meta-resolve@4.2.0: {}
is-potential-custom-element-name@1.0.1: {}
jiti@2.7.0: {}
jju@1.4.0: {}
js-tokens@4.0.0: {}
jsdom@30.0.1:
@ -1988,6 +2276,13 @@ snapshots:
json5@2.2.3: {}
jsonc-parser@3.3.1: {}
launch-editor@2.14.1:
dependencies:
picocolors: 1.1.1
shell-quote: 1.10.0
lightningcss-android-arm64@1.32.0:
optional: true
@ -2126,6 +2421,8 @@ snapshots:
obug@2.1.4: {}
package-manager-detector@1.8.0: {}
parse5@8.0.1:
dependencies:
entities: 8.0.0
@ -2198,8 +2495,14 @@ snapshots:
semver@6.3.1: {}
semver@7.8.5: {}
shell-quote@1.10.0: {}
siginfo@2.0.0: {}
sisteransi@1.0.5: {}
source-map-js@1.2.1: {}
stackback@0.0.2: {}
@ -2257,7 +2560,7 @@ snapshots:
dependencies:
react: 19.2.3
vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0):
vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0):
dependencies:
lightningcss: 1.33.0
picomatch: 4.0.5
@ -2268,11 +2571,12 @@ snapshots:
'@types/node': 24.13.3
fsevents: 2.3.3
jiti: 2.7.0
yaml: 2.9.0
vitest@4.1.10(@types/node@24.13.3)(jsdom@30.0.1)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)):
vitest@4.1.10(@types/node@24.13.3)(jsdom@30.0.1)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)):
dependencies:
'@vitest/expect': 4.1.10
'@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))
'@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))
'@vitest/pretty-format': 4.1.10
'@vitest/runner': 4.1.10
'@vitest/snapshot': 4.1.10
@ -2289,7 +2593,7 @@ snapshots:
tinyexec: 1.3.0
tinyglobby: 0.2.17
tinyrainbow: 3.1.1
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)
vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 24.13.3
@ -2331,3 +2635,5 @@ snapshots:
xmlchars@2.2.0: {}
yallist@3.1.1: {}
yaml@2.9.0: {}

View File

@ -17,6 +17,24 @@ import { loadStudioDocument } from '@/features/studio/studioDocument'
import { initialExpressions } from '@/features/avatar/presets'
import { createInitialSequences } from '@/features/animation/sequences'
const storedZipFileNames = (archive: Uint8Array) => {
const names: string[] = []
const decoder = new TextDecoder()
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength)
let offset = 0
while (offset + 30 <= archive.byteLength && view.getUint32(offset, true) === 0x04034b50) {
const contentLength = view.getUint32(offset + 18, true)
const nameLength = view.getUint16(offset + 26, true)
const extraLength = view.getUint16(offset + 28, true)
const nameStart = offset + 30
names.push(decoder.decode(archive.subarray(nameStart, nameStart + nameLength)))
offset = nameStart + nameLength + extraLength + contentLength
}
return names
}
describe('avatar export', () => {
const avatar = createAvatar('Strobi')
const animations = createInitialSequences().filter(item =>
@ -149,10 +167,7 @@ describe('avatar export', () => {
await generateJavaScriptEsmPackage(definition.value, 'Strobi').arrayBuffer()
)
const contents = new TextDecoder().decode(archive)
expect(contents).toContain('strobi.avatar.json')
expect(contents).toContain('index.html')
expect(contents).not.toContain('avatar.js')
expect(contents).toContain('README.md')
expect(storedZipFileNames(archive)).toEqual(['strobi.avatar.json', 'index.html', 'README.md'])
expect(contents).toContain('esm.sh/@bible-strong/avatar-web@0.1.0')
expect(contents).not.toContain('AvatarProceduralEngine')
})