Skip to content

Commit 93fd369

Browse files
committed
Docs: charter, code of conduct, testing plan, leak fixes
- Adds PROJECT_CHARTER.md, CODE_OF_CONDUCT.md, TESTING.md - Fills contact email and maintainer entries - Corrects TESTING.md sample-cases table to match the actual suite - Removes residual internal-process language from vitest.config.ts, .gitignore, CONTRIBUTING.md, tests/README.md, and the PR template
1 parent 2babf12 commit 93fd369

8 files changed

Lines changed: 220 additions & 63 deletions

File tree

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
<!--
2-
Thanks for contributing! A few quick things before you submit:
3-
4-
This repo is a public mirror — your PR will be reviewed here, applied
5-
upstream by a maintainer, and then merged in this repo. Your commit
6-
attribution stays on the PR. See CONTRIBUTING.md → "How PRs get merged"
7-
for the full flow.
8-
-->
1+
<!-- Thanks for contributing! See CONTRIBUTING.md for the full guidelines. -->
92

103
**What this changes**
114

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ coverage
88
.vite
99
deno.lock
1010

11-
# Internal-only files written by the sync script — NEVER committed.
12-
# These contain context about the public/private split and the sync model.
11+
# Local-only workspace files — never committed.
1312
.local/
1413
CLAUDE.md
1514
.claude/

CODE_OF_CONDUCT.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Code of Conduct
2+
3+
The MonkeyTab project has adopted the **Contributor Covenant, version 2.1** as its code of conduct. The full text is available at:
4+
5+
<https://www.contributor-covenant.org/version/2/1/code_of_conduct/>
6+
7+
## Why we adopted it
8+
9+
The Contributor Covenant is the most widely used open-source code of conduct. It is concise, comprehensive, well-understood by contributors across the ecosystem, and maintained centrally so it stays current. Linking to the canonical version (rather than copying it inline) means the project automatically benefits from clarifications and improvements made upstream.
10+
11+
## Scope
12+
13+
This code of conduct applies to all project spaces — the GitHub repository, issue tracker, pull requests, discussions, and any other forum the project officially uses. It also applies when an individual is officially representing the project in public spaces.
14+
15+
## Reporting concerns
16+
17+
If you observe behavior that violates this code of conduct, please report it confidentially by emailing the maintainers at **info@datasketch.co**.
18+
19+
Reports will be reviewed promptly. Reporters will not be identified to the person being reported without their consent. Maintainers will treat all reports seriously and apply enforcement consistently across the community.
20+
21+
## Enforcement
22+
23+
Maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate corrective action in response to any behavior they deem inappropriate, threatening, or unwelcoming.
24+
25+
Possible actions include (but are not limited to): a private warning, a public clarification of expectations, removal of comments or commits, temporary suspension from project spaces, or permanent removal from the community. Decisions are made by the maintainer team and are not subject to public debate, though they will be explained to the affected parties.
26+
27+
## Attribution
28+
29+
This code of conduct is based on the Contributor Covenant, version 2.1, available at <https://www.contributor-covenant.org/version/2/1/code_of_conduct/>.
30+
31+
For answers to common questions, see the Contributor Covenant FAQ at <https://www.contributor-covenant.org/faq>.
32+
33+
---
34+
35+
*Code of Conduct v0.1 · last updated 2026-04-08*

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ monkeytab/
5858
│ ├── browser/ # The @datasketch/monkeytab entry point
5959
│ └── adapters/
6060
│ └── memory/ # In-memory adapter (the default)
61-
├── tests/ # Vitest test suite — public team owned
61+
├── tests/ # Vitest test suite
6262
│ └── README.md # How to write and run tests
6363
├── examples/
6464
│ └── browser-standalone/ # Minimal demo app

PROJECT_CHARTER.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Project Charter — MonkeyTab
2+
3+
> First version. Expect this to evolve as the project and community grow. TODOs flag the parts that need a real answer before this charter is "done."
4+
5+
## Vision
6+
7+
Make tables easy to drop into any React app, so developers can give their users a real spreadsheet experience without spending weeks building one.
8+
9+
## Mission
10+
11+
MonkeyTab is an embeddable, editable React table component. Type-aware columns, spreadsheet-style keyboard navigation, copy-paste from Excel, sort/filter/search out of the box, virtualized for large datasets — installable from npm with one dependency and a peer dep on React.
12+
13+
The project's job is to make the **80% case** of "I need a good table in my React app" a single component install, while staying small enough that the **20% case** can be solved by overriding renderers, editors, and behaviors via props.
14+
15+
## Scope
16+
17+
**In scope:**
18+
19+
- The `@datasketch/monkeytab` npm package: a React component for editable tables
20+
- Built-in field types (Text, Number, Boolean, Date, SingleSelect, MultiSelect, Email, URL, Phone, Image, Attachment, Rating, Color, Computed)
21+
- Sort, filter, search, pagination, virtualization
22+
- An in-memory adapter for trivial use cases
23+
- Documentation site at <https://monkeytab.app>
24+
25+
**Out of scope (for now):**
26+
27+
- Hosted backend, multi-user collaboration, or sync — MonkeyTab renders, the host app owns the data
28+
- File-based persistence (CSV, JSON, SQLite) is on the roadmap but not in the initial release
29+
- Authentication, permissions, or organization features
30+
31+
## License
32+
33+
**MIT** — see [`LICENSE`](./LICENSE).
34+
35+
The MIT license was chosen because:
36+
37+
- It's permissive — anyone can use MonkeyTab in commercial products without copyleft obligations
38+
- It's familiar to React ecosystem contributors and is the de facto standard for React component libraries on npm
39+
- It minimizes legal friction for adoption, which is the primary success metric for a UI library
40+
- It's OSI-approved, GPL-compatible, and SPDX-recognized
41+
42+
By contributing, you agree your contributions are licensed under the same terms.
43+
44+
## Community and governance
45+
46+
- **Issues and discussions**: <https://github.com/datasketch/monkeytab/issues>
47+
- **Pull requests**: see [`CONTRIBUTING.md`](./CONTRIBUTING.md)
48+
- **Code of conduct**: see [`CODE_OF_CONDUCT.md`](./CODE_OF_CONDUCT.md)
49+
50+
**Maintainers**:
51+
52+
- JP Marin Diaz — [@jpmarindiaz](https://x.com/jpmarindiaz)
53+
54+
The project is in its early stages. All decisions about scope, design, breaking changes, and write access are currently made by JP Marin Diaz. As the contributor base and the project grow, this governance will be formalized into a multi-maintainer process with explicit criteria for new committers.
55+
56+
## Trademarks
57+
58+
"MonkeyTab" and the MonkeyTab logo are project marks. They may be used to refer to the project itself (in articles, presentations, integrations) without permission. Commercial use of the marks (selling derivative products under the MonkeyTab name) requires permission.
59+
60+
> **TODO**: formal trademark policy if/when the project is donated to a foundation or when commercial derivatives become a real concern.
61+
62+
## Charter changes
63+
64+
This charter is intentionally short. Updates happen via PR to this file. Substantial changes (scope, license, governance) should be discussed in a GitHub issue first.
65+
66+
---
67+
68+
*Charter v0.1 · MIT licensed · last updated 2026-04-08*

TESTING.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Testing
2+
3+
> First version. Captures the testing approach today (Phase 1 of the project) and links out to the working configuration. Will be expanded as the test surface grows.
4+
5+
## Strategy
6+
7+
MonkeyTab tests focus on **behavior that ships to consumers**: the public API of `@datasketch/monkeytab`, the field type registries, the in-memory adapter, and the rendering of the React components.
8+
9+
We test the source directly (via the `@monkeytab/*` aliases configured in `vitest.config.ts`) so that what's tested matches what's built. We do **not** mock — tests use real adapters, real registries, and real React renders via `@testing-library/react`.
10+
11+
The minimum bar is **15% line coverage**, enforced by `vitest.config.ts` thresholds. CI fails if coverage falls below the threshold. The current target is to grow from this floor as new tests are added.
12+
13+
> **TODO**: raise the coverage target as the test suite matures (suggested next step: 30% after a full pass on `src/core/`).
14+
15+
## Test layout
16+
17+
Tests live under [`tests/`](./tests/) and are picked up by Vitest's default glob `tests/**/*.test.{ts,tsx}`. There is no enforced sub-structure — flat files, `tests/unit/`, `tests/integration/`, and `tests/components/` are all fine. See [`tests/README.md`](./tests/README.md) for the conventions and example tests.
18+
19+
## Sample test cases
20+
21+
The test suite covers (or is targeted to cover) the following surface areas. This list is the working backlog for raising coverage past the 15% floor.
22+
23+
| Area | What to test | Status |
24+
|---|---|---|
25+
| `<MonkeyTable>` render | Mounts via React Testing Library, headers from `columns` appear, mounts cleanly with empty rows / custom render / `editable: false` | ✅ in suite |
26+
| MemoryAdapter — schema | `listBases`, `getTable`, `info()` capabilities | ✅ in suite |
27+
| MemoryAdapter — CRUD | Create → query → get → update → delete round-trip | ✅ in suite |
28+
| MemoryAdapter — pagination | `queryRecords` with `offset` + `limit` slices correctly | ✅ in suite |
29+
| MemoryAdapter — schema mutation | `createField` / `deleteField` round-trip | ✅ in suite |
30+
| MemoryAdapter — error paths | `getRecord` throws on missing record | ✅ in suite |
31+
| Bundle import smoke | `dist/monkeytab.js` exports the documented public API | ✅ in suite |
32+
| SSR safety | Bundle imports cleanly in a no-DOM Node environment | ✅ in suite |
33+
| Public type contract | `dist/index.d.ts` compiles a consumer-style file via `tsc --noEmit` | ✅ in suite |
34+
| `compareValues` (sort) | numeric ordering, string ordering, null handling, mixed types | ⚠️ TODO |
35+
| `applySort` | single-column ascending/descending, multi-column tiebreakers | ⚠️ TODO |
36+
| `applyFilter` | each FilterOperator (eq, neq, lt/lte/gt/gte, contains, is_empty, etc.) per supported field type | ⚠️ TODO |
37+
| Field type registry | direct `lookup()` and override registration assertions | ⚠️ TODO |
38+
| `<MonkeyTable>` editing | `onChange` fires with new rows on cell edit | ⚠️ TODO |
39+
| Type-aware sort labels | correct label per field type | ⚠️ TODO |
40+
| Per-column control | `editable: false`, `sortable: false`, custom `width` exercised end-to-end | ⚠️ TODO |
41+
42+
> **TODO**: each ⚠️ row is a good first issue for new contributors.
43+
44+
## Data structures under test
45+
46+
The core data shapes are defined in `src/core/types.ts` and re-exported through `src/browser/types.d.ts`. Tests import them through the `@monkeytab/core` alias rather than reaching into source paths directly.
47+
48+
Key shapes:
49+
50+
- **`FieldSpec`**`{ id, label, type, options? }` — describes a column
51+
- **`Row`**`{ id, fields: Record<string, Value>, createdAt, updatedAt }` — a single record
52+
- **`TableSpec`**`{ id, label, fields, primaryFieldId?, columnOrder?, rowOrder? }` — schema
53+
- **`FilterCondition`** / **`FilterGroup`** — query filters
54+
- **`SortSpec`** — sort directives
55+
- **`FieldOptions`** — discriminated union of per-type options (NumberFieldOptions, SingleSelectFieldOptions, etc.)
56+
57+
See [`src/browser/types.d.ts`](./src/browser/types.d.ts) for the full surface.
58+
59+
## Pull request workflow
60+
61+
Every PR must:
62+
63+
1. Pass `npm run build:check` (TypeScript strict-mode check on the source)
64+
2. Pass `npm test` (the full Vitest suite)
65+
3. Pass `npm run test:coverage` (which enforces the 15% thresholds)
66+
4. Pass `npm run build` (Vite library build, produces `dist/monkeytab.js`)
67+
68+
CI runs all four steps automatically on push and on PR. The CI status badge is in [`README.md`](./README.md). The coverage report is uploaded as a CI artifact (`coverage-report`) and can be downloaded from the Actions run page.
69+
70+
For the full PR submission flow, see [`CONTRIBUTING.md`](./CONTRIBUTING.md). The pull request template at [`.github/PULL_REQUEST_TEMPLATE.md`](./.github/PULL_REQUEST_TEMPLATE.md) is auto-applied to every new PR.
71+
72+
## Running tests locally
73+
74+
```bash
75+
npm install # one-time setup
76+
npm test # run the suite once
77+
npm run test:watch # interactive watch mode
78+
npm run test:coverage # run with coverage report (enforces 15% thresholds)
79+
npm run build:check # TypeScript type-check the source
80+
npm run build # Vite library build
81+
```
82+
83+
The HTML coverage report is generated at `coverage/index.html` after `test:coverage`. Open it in a browser to see line-by-line coverage.
84+
85+
## Reporting test failures
86+
87+
If a test fails on `main`, file a GitHub issue with:
88+
89+
- The failing test name and file
90+
- The expected vs actual output
91+
- A minimal reproduction (what command you ran, what environment)
92+
- Whether the failure is reproducible or intermittent
93+
94+
If a contributor's test catches a real bug, the failing test should be merged with the fix (so it becomes a regression check for the future).
95+
96+
---
97+
98+
*Testing v0.1 · last updated 2026-04-08*

tests/README.md

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,12 @@
11
# Tests
22

3-
This directory holds the public team's test suite for `@datasketch/monkeytab`.
3+
The Vitest test suite for `@datasketch/monkeytab`. Tests run in Node with jsdom and V8 coverage; the configuration lives in `vitest.config.ts` at the repo root.
44

5-
## Important: this directory is YOURS
5+
## Layout
66

7-
The upstream sync script (in the private workspace) **never touches
8-
`tests/`**. Whatever you put here is preserved across every sync. You
9-
can:
7+
You can structure tests however you like — `tests/unit/`, `tests/integration/`, flat files, fixtures, helpers, mocks. The runner picks up anything matching `tests/**/*.test.{ts,tsx}`.
108

11-
- Write tests in any structure (`tests/unit/`, `tests/integration/`,
12-
flat files, whatever works)
13-
- Use any test framework — the default `vitest.config.ts` is set up
14-
for Vitest with jsdom + V8 coverage
15-
- Mix `*.test.ts` and `*.test.tsx` for component tests
16-
- Add fixtures, helpers, mocks — anything not committed by upstream
17-
18-
The upstream maintainers run their own (Deno-based) tests against the
19-
private build. Your tests run in parallel against the same source code
20-
but in Node — different runtime, different test author, different blind
21-
spots. That's the point: parallel suites catch different things.
9+
`@testing-library/react` and `@testing-library/jest-dom` are preinstalled for component tests.
2210

2311
## Running tests
2412

@@ -29,14 +17,11 @@ npm run test:watch # watch mode
2917
npm run test:coverage # with V8 coverage report
3018
```
3119

32-
Coverage output goes to `./coverage/` (gitignored). The HTML report
33-
at `./coverage/index.html` is the friendliest format. The `lcov.info`
34-
file is what coverage services consume.
20+
Coverage output goes to `./coverage/` (gitignored). The HTML report at `./coverage/index.html` is the friendliest format. The `lcov.info` file is what coverage services consume.
3521

3622
## Writing tests
3723

38-
Tests can import directly from the source via the `@monkeytab/*`
39-
aliases configured in `vitest.config.ts`:
24+
Tests can import directly from the source via the `@monkeytab/*` aliases configured in `vitest.config.ts`:
4025

4126
```ts
4227
// tests/core/query-utils.test.ts
@@ -79,37 +64,20 @@ describe('<MonkeyTable>', () => {
7964
});
8065
```
8166

82-
You'll need to install `@testing-library/react` and `@testing-library/jest-dom`
83-
yourself if you want component tests — they're not in the default
84-
`devDependencies` to keep the install lean.
67+
`@testing-library/react` and `@testing-library/jest-dom` are included in the default devDependencies, so you can write component tests immediately without installing anything else.
8568

8669
## Coverage target
8770

88-
The MonkeyTab project targets **15% line coverage** as a minimum bar.
89-
Aim higher when you can — exercising the core utilities (query, sort,
90-
filter, registries, MemoryAdapter) is usually enough to get to 25–30%
91-
without touching the React layer.
71+
The MonkeyTab project targets **15% line coverage** as a minimum bar. Aim higher when you can — exercising the core utilities (query, sort, filter, registries, MemoryAdapter) is usually enough to get to 25–30% without touching the React layer.
9272

9373
## What gets covered
9474

95-
`vitest.config.ts` includes `src/**/*.{ts,tsx}` and excludes test
96-
files and type-only `.d.ts` files. Anything in `src/` is fair game,
97-
which means your tests can drive the actual implementation that ships
98-
to npm consumers.
75+
`vitest.config.ts` includes `src/**/*.{ts,tsx}` and excludes test files and type-only `.d.ts` files. Anything in `src/` is fair game.
9976

10077
## CI integration
10178

102-
If you set up CI (`.github/workflows/ci.yml`), the test job should
103-
run `npm run test:coverage` and either fail on the 15% threshold or
104-
upload the `lcov.info` to a coverage service like Codecov.
105-
106-
## A note on parallel suites
79+
`.github/workflows/ci.yml` runs `npm run test:coverage` and fails the build if any of the 15% thresholds (lines, branches, functions, statements) are not met. Coverage artifacts are uploaded by the workflow.
10780
108-
The maintainers run their own internal test suite against the full
109-
feature set in a different runtime. This public test suite is
110-
**independent** — it tests only what ships in `@datasketch/monkeytab`,
111-
written by a different team.
81+
## Reporting bugs found by tests
11282
113-
If your tests catch a bug, file it in the public repo. The maintainers
114-
will reproduce it on their side, fix it, and re-sync. Your test remains
115-
as a regression check on the public side.
83+
If a test catches a bug, file it as a GitHub issue with the failing test, expected behavior, and a minimal reproduction. Keep the failing test in your branch — it becomes the regression check once the bug is fixed.

vitest.config.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@ import { fileURLToPath } from 'node:url';
44

55
const __dirname = fileURLToPath(new URL('.', import.meta.url));
66

7-
// Test runner config for the public team's parallel test suite.
7+
// Vitest config for the @datasketch/monkeytab test suite.
88
//
9-
// The public test suite lives in ./tests/ and is owned entirely by the
10-
// datasketch team. The sync script never touches it — every team member
11-
// can write their own tests, contributors can add tests via PRs, and
12-
// nothing the upstream sync owner does will overwrite them.
13-
//
14-
// Tests can import from the synced source via @monkeytab/* aliases,
15-
// matching the workspace package names used in the source code.
9+
// Tests live in ./tests/ — see tests/README.md for conventions.
10+
// The @monkeytab/* aliases below match the package names used in
11+
// the source so tests can import without relative paths.
1612
export default defineConfig({
1713
test: {
1814
globals: true,

0 commit comments

Comments
 (0)