diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a8724e7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: MIT AND Palimpsest-0.8 +# SPDX-FileCopyrightText: 2024 Jonathan D.A. Jewell + +# Git attributes for rescript-tea + +# Auto-detect text files and normalize line endings +* text=auto + +# ReScript source files +*.res text eol=lf linguist-language=ReScript +*.resi text eol=lf linguist-language=ReScript + +# JavaScript (generated) +*.js text eol=lf +*.mjs text eol=lf + +# Configuration files +*.json text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +*.toml text eol=lf + +# Documentation +*.md text eol=lf +*.adoc text eol=lf +*.txt text eol=lf + +# Shell scripts +*.sh text eol=lf + +# Nix files +*.nix text eol=lf + +# Lock files - don't merge, always use ours +package-lock.json merge=ours + +# Binary files +*.png binary +*.jpg binary +*.gif binary +*.ico binary +*.woff binary +*.woff2 binary +*.ttf binary +*.eot binary + +# Exports for GitHub linguist +*.res linguist-language=ReScript +*.resi linguist-language=ReScript diff --git a/.well-known/funding.json b/.well-known/funding.json new file mode 100644 index 0000000..f78e3ab --- /dev/null +++ b/.well-known/funding.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://fundinglink.org/schema/v1/funding.json", + "version": "1.0.0", + "entity": { + "type": "individual", + "name": "Jonathan D.A. Jewell" + }, + "projects": [ + { + "name": "rescript-tea", + "description": "The Elm Architecture for ReScript", + "repository": "https://github.com/Hyperpolymath/rescript-tea", + "license": "MIT AND Palimpsest-0.8" + } + ], + "funding": { + "channels": [], + "plans": [] + } +} diff --git a/.well-known/security.txt b/.well-known/security.txt new file mode 100644 index 0000000..52bb66e --- /dev/null +++ b/.well-known/security.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: MIT AND Palimpsest-0.8 +# Security contact information for rescript-tea +# See: https://securitytxt.org/ + +Contact: https://github.com/Hyperpolymath/rescript-tea/security/advisories/new +Expires: 2025-12-31T23:59:59.000Z +Preferred-Languages: en +Canonical: https://github.com/Hyperpolymath/rescript-tea/.well-known/security.txt +Policy: https://github.com/Hyperpolymath/rescript-tea/blob/main/SECURITY.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..32c2316 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ + + + +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- RSR (Rhodium Standard Repositories) compliance +- Nix flake for reproducible development environment +- Justfile for task automation +- SPDX license headers on all source files + +## [0.1.0] - 2024-12-06 + +### Added +- Initial release of rescript-tea +- Core modules: + - `Tea_Cmd` - Commands for side effects + - `Tea_Sub` - Subscriptions for external events + - `Tea_App` - Application runtime with React integration + - `Tea_Html` - Type-safe HTML helpers + - `Tea_Json` - Elm-style JSON decoders + - `Tea_Test` - Testing utilities + - `Tea` - Main entry point +- Subscription types: + - `Sub.Time.every` - Timer subscriptions + - `Sub.Keyboard.downs/ups` - Keyboard events + - `Sub.Mouse.clicks/moves` - Mouse events + - `Sub.Window.resizes` - Window resize events +- Counter example demonstrating basic TEA patterns +- React hooks-based runtime implementation +- Functor-based API (`Make`, `MakeSimple`, `MakeWithDispatch`) + +### Technical Details +- Built on React 18+ with hooks +- Uses Belt library for collections +- ReScript 11+ compatibility +- ESModule output format + +[Unreleased]: https://github.com/Hyperpolymath/rescript-tea/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/Hyperpolymath/rescript-tea/releases/tag/v0.1.0 diff --git a/CODE_OF_CONDUCT.adoc b/CODE_OF_CONDUCT.adoc new file mode 100644 index 0000000..c89d828 --- /dev/null +++ b/CODE_OF_CONDUCT.adoc @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: MIT AND Palimpsest-0.8 +// SPDX-FileCopyrightText: 2024 Jonathan D.A. Jewell += Code of Conduct +:toc: + +== Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +== Our Standards + +=== Positive Behaviors + +Examples of behavior that contributes to a positive environment: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes +* Focusing on what is best for the overall community +* Using welcoming and inclusive language + +=== Unacceptable Behaviors + +Examples of unacceptable behavior: + +* The use of sexualized language or imagery, and sexual attention or advances +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information without explicit permission +* Other conduct which could reasonably be considered inappropriate + +== Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +== Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. + +== Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement. + +All complaints will be reviewed and investigated promptly and fairly. + +== Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +=== 1. Correction + +*Community Impact*: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +*Consequence*: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. + +=== 2. Warning + +*Community Impact*: A violation through a single incident or series of actions. + +*Consequence*: A warning with consequences for continued behavior. No +interaction with the people involved for a specified period of time. + +=== 3. Temporary Ban + +*Community Impact*: A serious violation of community standards. + +*Consequence*: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. + +=== 4. Permanent Ban + +*Community Impact*: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +*Consequence*: A permanent ban from any sort of public interaction within +the community. + +== Attribution + +This Code of Conduct is adapted from the https://www.contributor-covenant.org[Contributor Covenant], +version 2.1. diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc new file mode 100644 index 0000000..332665e --- /dev/null +++ b/CONTRIBUTING.adoc @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: MIT AND Palimpsest-0.8 +// SPDX-FileCopyrightText: 2024 Jonathan D.A. Jewell += Contributing to rescript-tea +:toc: +:toclevels: 2 + +Thank you for your interest in contributing to rescript-tea! + +== Getting Started + +=== Prerequisites + +* Node.js 18+ +* npm or pnpm +* ReScript compiler (installed via npm) +* Nix (optional, for reproducible development environment) + +=== Development Setup + +[source,bash] +---- +# Clone the repository +git clone https://github.com/Hyperpolymath/rescript-tea.git +cd rescript-tea + +# Install dependencies +npm install + +# Build the project +npm run build + +# Run in watch mode +npm run dev +---- + +=== Using Nix + +[source,bash] +---- +# Enter development shell +nix develop + +# Or use direnv +direnv allow +---- + +== Tri-Perimeter Contribution Framework (TPCF) + +This project follows the RSR Tri-Perimeter Contribution Framework: + +=== Perimeter 1 (Core) + +Maintainers only. Changes to: + +* Build system configuration +* Core runtime (`Tea_App.res`) +* Release management +* Security-critical code + +=== Perimeter 2 (Expert) + +Trusted contributors. Changes to: + +* Protocol extensions +* New subscription types +* Performance optimizations +* API design changes + +=== Perimeter 3 (Community) + +Open participation: + +* Documentation improvements +* Bug fixes with tests +* New examples +* Test coverage +* Issue triage + +== How to Contribute + +=== Reporting Bugs + +1. Check existing issues to avoid duplicates +2. Create a new issue with: + * Clear, descriptive title + * Steps to reproduce + * Expected vs actual behavior + * ReScript/Node.js versions + * Minimal reproduction code + +=== Suggesting Features + +1. Open a discussion or issue +2. Describe the use case +3. Explain why existing features don't suffice +4. Propose an API design (if applicable) + +=== Submitting Pull Requests + +1. Fork the repository +2. Create a feature branch: `git checkout -b feature/my-feature` +3. Make your changes +4. Add/update tests +5. Ensure all tests pass: `npm test` +6. Add SPDX headers to new files +7. Update documentation if needed +8. Submit a pull request + +=== Code Style + +* Follow existing code patterns +* Use meaningful variable names +* Keep functions small and focused +* Add type annotations for public APIs +* Document complex logic with comments + +=== SPDX Headers + +All source files must include SPDX headers: + +[source,rescript] +---- +// SPDX-License-Identifier: MIT AND Palimpsest-0.8 +// SPDX-FileCopyrightText: 2024 Your Name +---- + +=== Commit Messages + +Follow conventional commits: + +---- +type(scope): description + +[optional body] + +[optional footer] +---- + +Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` + +Examples: + +---- +feat(cmd): add Cmd.debounce for rate-limited commands +fix(sub): prevent memory leak in subscription cleanup +docs: update README with new API examples +---- + +== Testing + +[source,bash] +---- +# Run all tests +npm test + +# Run tests in watch mode +npm run test:watch +---- + +=== Writing Tests + +Use `Tea_Test` utilities: + +[source,rescript] +---- +// Test update function +let model = Tea_Test.simulate( + ~init, + ~update, + ~msgs=[Increment, Increment, Decrement], +) +assert(model.count == 1) + +// Test commands +let cmds = Tea_Test.collectCmds(~init, ~update, ~msgs=[FetchData]) +assert(Belt.Array.length(cmds) > 0) +---- + +== Documentation + +* Update README.adoc for user-facing changes +* Add JSDoc comments to public functions +* Include examples for new features +* Update CHANGELOG.md + +== Code of Conduct + +Please read and follow our link:CODE_OF_CONDUCT.adoc[Code of Conduct]. + +== License + +By contributing, you agree that your contributions will be licensed under the +project's dual MIT and Palimpsest v0.8 license. + +== Questions? + +* Open a GitHub Discussion +* Check existing documentation +* Review closed issues/PRs + +Thank you for contributing! diff --git a/FUNDING.yml b/FUNDING.yml new file mode 100644 index 0000000..cd1f1e9 --- /dev/null +++ b/FUNDING.yml @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: MIT AND Palimpsest-0.8 +# SPDX-FileCopyrightText: 2024 Jonathan D.A. Jewell + +# Funding information for rescript-tea +# See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository + +github: [] +patreon: "" +open_collective: "" +ko_fi: "" +tidelift: "" +community_bridge: "" +liberapay: "" +issuehunt: "" +lfx_crowdfunding: "" +polar: "" +buy_me_a_coffee: "" +custom: [] + +# This project is currently not accepting financial sponsorship. +# If you'd like to support the project, consider: +# - Contributing code or documentation +# - Reporting bugs +# - Helping other users +# - Spreading the word diff --git a/GOVERNANCE.adoc b/GOVERNANCE.adoc new file mode 100644 index 0000000..c0ad242 --- /dev/null +++ b/GOVERNANCE.adoc @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: MIT AND Palimpsest-0.8 +// SPDX-FileCopyrightText: 2024 Jonathan D.A. Jewell += Governance +:toc: + +== Overview + +rescript-tea follows a benevolent dictator for life (BDFL) governance model with +community input through the Tri-Perimeter Contribution Framework (TPCF). + +== Roles + +=== Project Lead (BDFL) + +* Final decision authority on project direction +* Responsible for releases and security +* Manages maintainer team +* Resolves disputes + +=== Maintainers + +* Merge permissions for all perimeters +* Code review responsibilities +* Issue triage and labeling +* Community support + +=== Contributors + +* Submit pull requests +* Report issues +* Participate in discussions +* Improve documentation + +== Decision Making + +=== Consensus Seeking + +Most decisions are made through discussion and consensus: + +1. Proposal raised (issue, discussion, or PR) +2. Community feedback period (typically 1 week) +3. Maintainer review +4. Decision documented + +=== Voting + +For significant changes without consensus: + +* Maintainers vote +* Simple majority required +* Project Lead has tie-breaking vote + +=== Fast-Track + +Security fixes and critical bugs may be merged without full consensus period. + +== Tri-Perimeter Framework + +=== Perimeter 1: Core + +*Who*: Maintainers only + +*What*: + +* Build system (flake.nix, justfile) +* Core runtime (Tea_App) +* Release process +* Security fixes + +*Process*: Direct merge after maintainer review + +=== Perimeter 2: Expert + +*Who*: Maintainers + trusted contributors + +*What*: + +* New modules +* API changes +* Performance work +* Complex features + +*Process*: PR + 2 maintainer approvals + +=== Perimeter 3: Community + +*Who*: Anyone + +*What*: + +* Documentation +* Examples +* Tests +* Bug fixes + +*Process*: PR + 1 maintainer approval + +== Becoming a Maintainer + +1. Sustained, quality contributions over 6+ months +2. Demonstrated understanding of project goals +3. Nomination by existing maintainer +4. Approval by Project Lead + +== Conflict Resolution + +1. Discussion in relevant issue/PR +2. Escalation to maintainer team +3. Final decision by Project Lead +4. Appeals via community discussion + +== Changes to Governance + +This document may be amended through the standard decision-making process. +Significant changes require community discussion period. + +== Communication + +* GitHub Issues: Bug reports, feature requests +* GitHub Discussions: Questions, ideas, community chat +* Pull Requests: Code contributions diff --git a/LICENSE-PALIMPSEST.txt b/LICENSE-PALIMPSEST.txt new file mode 100644 index 0000000..8b08950 --- /dev/null +++ b/LICENSE-PALIMPSEST.txt @@ -0,0 +1,56 @@ +Palimpsest License v0.8 + +Copyright (c) 2024 Jonathan D.A. Jewell + +This license governs use of the accompanying software. If you use the software, +you accept this license. If you do not accept the license, do not use the +software. + +1. Definitions + +"Software" means the source code, object code, documentation, and any other +materials provided under this license. + +"Derivative Work" means any work that is based on (or derived from) the +Software. + +"Commercial Use" means use of the Software for the purpose of generating +revenue or monetary compensation. + +2. Grant of Rights + +Subject to the terms of this license, the licensor grants you a worldwide, +royalty-free, non-exclusive license to: + +a) Use the Software for any purpose, including Commercial Use +b) Modify the Software and create Derivative Works +c) Distribute the Software and Derivative Works +d) Sublicense the Software + +3. Conditions + +You may exercise the rights granted above provided that you: + +a) Include a copy of this license with any distribution of the Software +b) Provide attribution to the original authors +c) Clearly mark any modifications you make to the Software +d) Do not use the name of the licensor to endorse derived products + +4. Ethical Use Clause + +You agree not to use the Software in any way that: + +a) Violates applicable laws or regulations +b) Infringes on the rights of others +c) Causes harm to individuals or communities +d) Facilitates surveillance, oppression, or discrimination + +5. Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE. + +6. Termination + +This license terminates automatically if you violate any of its terms. diff --git a/LICENSE b/LICENSE.txt similarity index 63% rename from LICENSE rename to LICENSE.txt index cd7923b..ab6ac35 100644 --- a/LICENSE +++ b/LICENSE.txt @@ -1,4 +1,11 @@ +SPDX-License-Identifier: MIT AND Palimpsest-0.8 + +This project is dual-licensed under the MIT License and Palimpsest License v0.8. +You may choose either license to govern your use of this software. + +================================================================================ MIT License +================================================================================ Copyright (c) 2024 Jonathan D.A. Jewell @@ -19,3 +26,9 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +================================================================================ +Palimpsest License v0.8 +================================================================================ + +See LICENSE-PALIMPSEST.txt for the full text of the Palimpsest License. diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000..e6e9607 --- /dev/null +++ b/README.adoc @@ -0,0 +1,306 @@ +// SPDX-License-Identifier: MIT AND Palimpsest-0.8 +// SPDX-FileCopyrightText: 2024 Jonathan D.A. Jewell += rescript-tea +:toc: macro +:toc-title: Contents +:toclevels: 3 +:icons: font +:source-highlighter: rouge +:experimental: + +The Elm Architecture (TEA) for ReScript, providing a principled way to build web applications with guaranteed state consistency, exhaustive event handling, and time-travel debugging. + +toc::[] + +== Overview + +rescript-tea implements The Elm Architecture pattern for ReScript with React integration. It provides: + +* *Single source of truth* - One model, one update pathway +* *Pure updates* - Easy to test, easy to reason about +* *Type-safe* - Compiler catches missing message handlers +* *React integration* - Uses React for rendering, compatible with existing components +* *Commands & Subscriptions* - Declarative side effects + +== Installation + +[source,bash] +---- +npm install rescript-tea +---- + +Add to your `rescript.json`: + +[source,json] +---- +{ + "bs-dependencies": ["rescript-tea", "@rescript/react"] +} +---- + +== Quick Start + +[source,rescript] +---- +open Tea + +// 1. Define your model +type model = {count: int} + +// 2. Define your messages +type msg = + | Increment + | Decrement + +// 3. Initialize your app +let init = () => ({count: 0}, Cmd.none) + +// 4. Handle updates +let update = (msg, model) => { + switch msg { + | Increment => ({count: model.count + 1}, Cmd.none) + | Decrement => ({count: model.count - 1}, Cmd.none) + } +} + +// 5. Render your view (with dispatch for event handling) +let view = (model, dispatch) => { +