Skip to content

Commit f774812

Browse files
committed
feat: render multiline classic syntax and release beta through CI
1 parent b7b5d35 commit f774812

28 files changed

Lines changed: 553 additions & 121 deletions

‎.github/workflows/ci.yml‎

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,46 @@ jobs:
4545
RESULT: ${{ needs.test.result }}
4646
run: test "$RESULT" = success
4747

48+
publish:
49+
name: Publish beta package
50+
needs: verify
51+
if: github.ref_type == 'tag' && startsWith(github.ref_name, 'v')
52+
runs-on: ubuntu-latest
53+
environment: npm
54+
permissions:
55+
contents: read
56+
id-token: write
57+
steps:
58+
- uses: actions/checkout@v4
59+
with:
60+
fetch-depth: 0
61+
- uses: actions/setup-node@v4
62+
with:
63+
node-version: 24
64+
registry-url: https://registry.npmjs.org
65+
- run: npm ci
66+
- run: node scripts/validate-release.mjs
67+
- run: npm run build
68+
- run: npm run test:package
69+
- name: Publish verified beta with provenance
70+
run: npm publish --tag beta --access public --provenance
71+
env:
72+
# Used only to bootstrap the first package publication, then removed.
73+
NODE_AUTH_TOKEN: ${{ secrets.NPM_BOOTSTRAP_TOKEN }}
74+
4875
deploy:
4976
name: Deploy website
50-
needs: verify
51-
if: github.event_name != 'pull_request'
77+
needs: [verify, publish]
78+
if: always() && needs.verify.result == 'success' && github.event_name != 'pull_request' && ((github.ref_type == 'tag' && needs.publish.result == 'success') || (github.ref_type != 'tag' && needs.publish.result == 'skipped'))
5279
runs-on: ubuntu-latest
5380
environment:
54-
name: ${{ github.ref == 'refs/heads/main' && 'production' || 'preview' }}
81+
name: ${{ (github.ref == 'refs/heads/main' || github.ref_type == 'tag') && 'production' || 'preview' }}
5582
url: ${{ steps.deploy.outputs.url }}
5683
env:
5784
VERCEL_ORG_ID: ${{ vars.VERCEL_ORG_ID }}
5885
VERCEL_PROJECT_ID: ${{ vars.VERCEL_PROJECT_ID }}
5986
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
60-
DEPLOY_ENVIRONMENT: ${{ github.ref == 'refs/heads/main' && 'production' || 'preview' }}
87+
DEPLOY_ENVIRONMENT: ${{ (github.ref == 'refs/heads/main' || github.ref_type == 'tag') && 'production' || 'preview' }}
6188
steps:
6289
- uses: actions/checkout@v4
6390
- uses: actions/setup-node@v4

‎README.md‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
A structured JavaScript data inspector for React: inspect the value you actually have.
44

5-
**Alpha package, not yet published to npm.** [Website](https://react-data-inspector.nipesolutions.com) · [Playground](https://react-data-inspector.nipesolutions.com/playground) · [Documentation](https://react-data-inspector.nipesolutions.com/docs). Run `npm install && npm run dev` locally. See [release readiness](docs/release-readiness.md) before production adoption.
5+
**Beta release channel.** [Website](https://react-data-inspector.nipesolutions.com) · [Playground](https://react-data-inspector.nipesolutions.com/playground) · [Documentation](https://react-data-inspector.nipesolutions.com/docs). Run `npm install && npm run dev` locally. See [release readiness](docs/release-readiness.md) before production adoption.
66

77
```tsx
88
import { DataInspector } from '@nipe-solutions/react-data-inspector'
@@ -11,7 +11,11 @@ import '@nipe-solutions/react-data-inspector/styles.css'
1111
;<DataInspector value={data} />
1212
```
1313

14-
Until publication, run `npm run build && npm pack` and install the generated tarball in your application.
14+
Install the beta release:
15+
16+
```sh
17+
npm install @nipe-solutions/react-data-inspector@beta
18+
```
1519

1620
## Why this exists
1721

@@ -49,7 +53,7 @@ Prefer quoted keys and object-viewer syntax? Set `presentation="classic"`; see [
4953

5054
See the [compiled customization examples](examples/customization.tsx), [API reference](docs/api.md), [architecture and type matrix](docs/architecture.md), and [performance methodology](benchmarks/README.md).
5155

52-
The alpha is read-only; editing is not part of the public API. Getters are not evaluated, promises are not awaited, functions are not executed, and WeakMap/WeakSet contents remain opaque. Collection paths are not presented as JSON Pointers.
56+
The beta is read-only; editing is not part of the public API. Getters are not evaluated, promises are not awaited, functions are not executed, and WeakMap/WeakSet contents remain opaque. Collection paths are not presented as JSON Pointers.
5357

5458
## Development
5559

‎benchmarks/presentation.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const cases: Record<string, Omit<DataInspectorProps, 'presentation'>> = {
3838
const results = Object.entries(cases).map(([name, props]) => {
3939
const timings = { inspector: [] as number[], classic: [] as number[] }
4040
const rowCounts = { inspector: 0, classic: 0 }
41+
const closingLines = { inspector: 0, classic: 0 }
4142
for (let iteration = -1; iteration < samples; iteration++) {
4243
const order =
4344
iteration % 2 === 0
@@ -50,6 +51,9 @@ const results = Object.entries(cases).map(([name, props]) => {
5051
)
5152
const elapsed = performance.now() - start
5253
rowCounts[presentation] = (html.match(/data-rdi-node=/g) ?? []).length
54+
closingLines[presentation] = (
55+
html.match(/data-rdi-closing=/g) ?? []
56+
).length
5357
if (iteration >= 0) timings[presentation].push(elapsed)
5458
}
5559
}
@@ -66,6 +70,11 @@ const results = Object.entries(cases).map(([name, props]) => {
6670
return {
6771
name,
6872
dataRows: rowCounts.inspector,
73+
visualLines: {
74+
inspector: rowCounts.inspector + closingLines.inspector,
75+
classic: rowCounts.classic + closingLines.classic,
76+
},
77+
closingLines,
6978
inspector: summarize(timings.inspector),
7079
classic: summarize(timings.classic),
7180
}
@@ -82,7 +91,7 @@ process.stdout.write(
8291
cpu: cpus()[0]?.model,
8392
},
8493
methodology:
85-
'Paired in-process React SSR; one warmup per mode and fixture, ten measured samples, alternating mode order. Dataset construction excluded. Each render creates the same model and visible rows. No client windowing, scrolling, or browser timings. Deep fixture reaches the default maximum depth (100); wide and 500k cases use default grouping. Open-range fixture explicitly expands the first 10k range and first 100-value subrange. Customization, themes, and actions use defaults. Samples are descriptive, not timing assertions.',
94+
'Paired in-process React SSR; one warmup per mode and fixture, ten measured samples, alternating mode order. Dataset construction excluded. Each render creates the same model and data rows. Classic adds separate decorative closing lines; visual-line counts are reported independently. No client windowing, scrolling, or browser timings. Deep fixture reaches the default maximum depth (100); wide and 500k cases use default grouping. Open-range fixture explicitly expands the first 10k range and first 100-value subrange. Customization, themes, and actions use defaults. Samples are descriptive, not timing assertions.',
8695
results,
8796
},
8897
null,

‎docs/api.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,6 @@ The canonical [styling reference](https://react-data-inspector.nipesolutions.com
9999

100100
## Presentation
101101

102-
`presentation="inspector"` is the default. `presentation="classic"` changes built-in visual notation using quoted property keys and balanced inline container delimiters. It adds no closing-delimiter rows or selectable synthetic punctuation. Both presentations share paths, graph identity, search, selection, expansion, actions, grouping, virtualization, and SSR behavior.
102+
`presentation="inspector"` is the default. `presentation="classic"` changes built-in visual notation using quoted property keys and multiline container delimiters. Closing-delimiter lines are decorative and aria-hidden; they add visual offsets but no selectable data nodes. Both presentations share paths, graph identity, search, selection, expansion, actions, grouping, virtualization, and SSR behavior.
103103

104104
Classic output is not serialized JSON or executable JavaScript. Non-JSON type summaries and separately addressed Map key/value rows retain their meaning. See [presentation modes](https://react-data-inspector.nipesolutions.com/guides/presentation) for examples and customization boundaries.

‎docs/delivery-audit.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ This audit maps the product deliverables to the implementation and honest releas
3535
| 29. Limitations | [Architecture](architecture.md) and [readiness](release-readiness.md) |
3636
| 30. Roadmap | Inspection-first; editing/continuation/integration after audited core |
3737
| 31. Naming | Verified NIPE conventions, public GitHub repository and unpublished npm candidate |
38-
| 32. Readiness | **PRIVATE PREVIEW READY**; no public-beta or stable claim |
38+
| 32. Readiness | **Beta distribution**; outstanding manual production-qualification audits |
3939

4040
## Mandatory customization scenarios
4141

@@ -55,6 +55,6 @@ Cycle and shared-reference tests distinguish semantics without recursion; getter
5555

5656
## Accessibility audit
5757

58-
Keyboard-only behavior, collapse/focus restoration, selection, search, actions, RTL/mobile and windowed active descendants have automated interaction coverage and live browser inspection. Axe passes the default and dark examples. No human screen-reader audit was performed. Editing accessibility is not applicable to this read-only alpha. See the public-beta blockers before describing the project as production-ready.
58+
Keyboard-only behavior, collapse/focus restoration, selection, search, actions, RTL/mobile and windowed active descendants have automated interaction coverage and live browser inspection. Axe passes the default and dark examples. No human screen-reader audit was performed. Editing accessibility is not applicable to this read-only beta. See the remaining production-qualification work before describing the project as production-ready.
5959

6060
The dedicated [playground](playground.md) now includes externally updated data, typed-value scenarios, styling controls, lazy children and opt-in performance measurements. Standalone live examples are verified against the packed package.

‎docs/deployment.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The website uses the `react-data-inspector` project in the NIPE Solutions Vercel
1313

1414
The GitHub `VERCEL_TOKEN` secret is scoped to this project and expires on 2027-09-07. Rotate it before expiry through Vercel and update the GitHub secret. `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` are repository variables. Optional diagnostic artifact uploads are non-blocking when GitHub storage is unavailable; tests, builds and packaging remain required.
1515

16-
The website deployment does not publish the npm package or change its alpha classification. Application secrets are unnecessary for this static site. Keep `.vercel/` local and ignored.
16+
Version-tag builds publish the beta npm package after both React matrix jobs pass, then deploy the website. Ordinary branch pushes deploy the site without publishing packages. Application secrets are unnecessary for this static site. Keep `.vercel/` local and ignored.
1717

1818
## Domain
1919

@@ -31,4 +31,4 @@ Check the custom hostname, a direct `/playground` URL, JavaScript/CSS asset resp
3131

3232
`website/articles.ts` is the shared route and documentation registry. Article Markdown feeds navigation, rendered HTML and the sitemap; the API article imports `docs/api.md` directly. Each route gets a title, description, canonical URL, OpenGraph and social metadata. `social.svg` is the source for the 1200 × 630 social PNG. `npm run test:website` checks static metadata, internal links and compiles the React Data Inspector documentation snippets. Browser tests run against the production build, including JavaScript-disabled documentation and hydration.
3333

34-
Registry publication is verified on each website build; network/registry errors fail the build instead of publishing stale installation claims. After an npm release, trigger the Verify workflow on main to refresh installation copy. The website does not publish packages.
34+
Registry publication is verified on each website build; network/registry errors fail the build instead of publishing stale installation claims. After successful npm publication, the same workflow rebuilds the website against registry metadata. A failed publication prevents the release deployment. See [releasing](releasing.md).

‎docs/release-readiness.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Release readiness
22

3-
Classification: **PRIVATE PREVIEW READY**
3+
Distribution: **beta**. Manual production-qualification audits remain open.
44

5-
Assessed 2026-09-07. Version: 0.1.0-alpha.0. The package is not published to npm. Website hosting and automatic deployment are configured separately; see [deployment](deployment.md).
5+
Assessed 2026-09-07. Version: 0.1.0-beta.0. Beta publication is performed by the verified version-tag workflow; check the [npm beta channel](https://www.npmjs.com/package/@nipe-solutions/react-data-inspector?activeTab=versions) and [release workflow](https://github.com/NIPE-Solutions/react-data-inspector/actions/workflows/ci.yml) for registry status. See [deployment](deployment.md).
66

77
## Verified
88

@@ -29,20 +29,20 @@ Opening the 500,000-item array produces 51 first-level model rows with defaults.
2929

3030
The forced-GC experiment observed all 50 discarded model roots collected. It does not establish absence of leaks in mounted React components, browser heaps or application-held callback contexts. No frame-loss or retained-browser-heap claim is made.
3131

32-
## Public-beta blockers
32+
## Remaining production-qualification work
3333

3434
1. Perform and record actual VoiceOver/Safari and NVDA/Firefox or Chrome navigation, selection, search, actions and virtualization audits. Keyboard automation and axe are insufficient.
3535
2. Dogfood through the public API in an application such as source metadata/job payload inspection. No application integration has been performed.
3636
3. Audit mounted-browser retained heaps across repeated input replacement/unmount, and scrolling frame timing on representative hardware.
3737
4. Validate current desktop/mobile Safari and current evergreen browser versions beyond the locally available pinned WebKit.
38-
5. Review the deliberately limited alpha contracts: uniform-height virtualization, first 10,000 Map/Set entries, indexed-only arrays, bounded search/reveal and discovery-scoped reference targets.
38+
5. Review the deliberately limited beta contracts: uniform-height virtualization, first 10,000 Map/Set entries, indexed-only arrays, bounded search/reveal and discovery-scoped reference targets.
3939

4040
## Deferred features
4141

4242
Editing, add/remove proposals, JSON Patch conversion, collection continuation, prototype inspection and specialized binary/DOM views are not implemented. There is no editing prop that implies otherwise. See the current [public API](api.md) and [limitations](https://react-data-inspector.nipesolutions.com/limitations).
4343

4444
## Naming and publication
4545

46-
The public GitHub repository is `NIPE-Solutions/react-data-inspector`, matching this checkout's origin. The npm registry returned 404 for `@nipe-solutions/react-data-inspector` on 2026-09-07. The name follows neighboring NIPE packages; it is not reserved and publication permission has not been proven by a publish attempt.
46+
The public GitHub repository and npm package are `NIPE-Solutions/react-data-inspector` and `@nipe-solutions/react-data-inspector`. The first beta is `0.1.0-beta.0`, published with dist-tag `beta`; a beta version does not claim stable API or completion of the manual audits above.
4747

48-
`react-data-inspector.nipesolutions.com` follows the NIPE docs-host pattern. Its GoDaddy CNAME points to the Vercel project in the NIPE Solutions team. GitHub Actions deploys `website/dist` from `main` after both React verification jobs pass. The repository is public; the npm package remains unpublished. Website publication does not raise the library release classification.
48+
GitHub Actions checks React 18/19, builds the package, publishes a matching version tag, and deploys the website after publication so the real npm installation command is visible. Future publication uses package-scoped trusted publishing. See [release process](releasing.md).

‎docs/releasing.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Beta releases
2+
3+
The package uses versions such as `0.1.0-beta.0` and the npm `beta` dist-tag. It does not promote prereleases to `latest`.
4+
5+
1. Update `package.json` and the lockfile with `npm version 0.1.0-beta.N --no-git-tag-version`.
6+
2. Commit the reviewed change to `main`.
7+
3. Push a matching tag: `git tag v0.1.0-beta.N` then `git push origin v0.1.0-beta.N`.
8+
9+
The Verify workflow runs the complete React 18.3.1/19 matrix, including unit, browser, SSR, package and website checks. Its publication job requires the tag to equal the package version, the lockfile to match, the commit to belong to main, and the version to be absent from npm. Publication uses public access, `beta`, and provenance. Existing versions are never overwritten; bump the version for another release.
10+
11+
Configure npm trusted publishing for organization `NIPE-Solutions`, repository `react-data-inspector`, workflow `ci.yml`, environment `npm`, with direct publish allowed. GitHub-hosted runners supply OIDC credentials. The first package creation may require the temporary `NPM_BOOTSTRAP_TOKEN` secret because no package settings exist yet; revoke and delete it after configuring trusted publishing. Never commit credentials.
12+
13+
A successful tag publication is followed by a production website build, which checks npm and displays the real installation command. Failed publication blocks that release deployment. Ordinary main pushes continue to deploy verified website updates without publishing a package.
14+
15+
The beta channel is a release designation. It does not imply that the manual screen-reader, current mobile Safari, dogfooding and retained-browser-heap audits in [release readiness](release-readiness.md) are complete.

‎package-lock.json‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nipe-solutions/react-data-inspector",
3-
"version": "0.1.0-alpha.0",
3+
"version": "0.1.0-beta.0",
44
"description": "A structured JavaScript data inspector for React.",
55
"type": "module",
66
"license": "MIT",
@@ -36,7 +36,7 @@
3636
},
3737
"publishConfig": {
3838
"access": "public",
39-
"tag": "alpha",
39+
"tag": "beta",
4040
"provenance": true
4141
},
4242
"scripts": {

0 commit comments

Comments
 (0)