diff --git a/.changeset/config.json b/.changeset/config.json index ab848d1a..f7e8ad09 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,11 +1,11 @@ { - "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", "changelog": "@changesets/cli/changelog", - "commit": false, + "commit": ["@changesets/cli/commit", { "skipCI": false }], "fixed": [], "linked": [], - "access": "restricted", + "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": [] + "ignore": ["@example/*"] } diff --git a/.deepsource.toml b/.deepsource.toml index 0af08500..c3cbc5b2 100644 --- a/.deepsource.toml +++ b/.deepsource.toml @@ -1,12 +1,12 @@ version = 1 -test_patterns = [ - "test/**/*.*", +test_patterns = ["**/*.test.*"] + +exclude_patterns = [ + "docs/**", "**/*.test.*" ] -exclude_patterns = ["docs/**"] - [[analyzers]] name = "javascript" diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 95f5d426..5ef5e42c 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,6 +1,6 @@ # These are supported funding model platforms -github: [mayank1513] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +github: [react18-tools, mayank1513] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] polar: mayank1513 patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8c2a6b39..2d5697aa 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,7 +10,6 @@ jobs: if: github.event.repository.owner.login == 'react18-tools' runs-on: ubuntu-latest permissions: - packages: write contents: write steps: - uses: actions/checkout@v4 @@ -21,13 +20,20 @@ jobs: with: registry-url: https://registry.npmjs.org node-version: 20 + - name: Setup Git + run: | + git config --global user.name "mayank1513" + git config --global user.email "mayank.srmu@gmail.com" + git fetch + git checkout main + git pull - run: npm i -g pnpm && pnpm i name: Install dependencies - name: Test run: npm test - - run: git status && git clean -f -d && git status + - run: git stash --include-untracked name: clean up working directory - - run: npx @turbo/codemod update . && pnpm update --latest -w + - run: npx @turbo/codemod update . && pnpm update --latest -r name: Update dependencies - run: pnpm build name: Build all apps to make sure it is not broken due to dependency upgrades @@ -35,11 +41,5 @@ jobs: run: pnpm test - name: Generate/update docs run: pnpm doc - - name: Setup Git - run: | - git config --global user.name "react18-tools" - git config --global user.email "mayank.srmu@gmail.com" - git fetch - git checkout main - name: Save upgraded packages back to repo run: git add . && git commit -m "upgrade deps && docs" && git push origin main diff --git a/.github/workflows/manual-publish.yml b/.github/workflows/manual-publish.yml new file mode 100644 index 00000000..624397c5 --- /dev/null +++ b/.github/workflows/manual-publish.yml @@ -0,0 +1,44 @@ +name: Manually publish to NPM - Apply changeset in the workflow. + +# publish only when package json has changed - assuming version upgrade +on: + workflow_dispatch: + +jobs: + publish: + if: github.event.repository.owner.login == 'react18-tools' + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: https://registry.npmjs.org + - name: Setup Git + run: | + git config --global user.name "mayank1513" + git config --global user.email "mayank.srmu@gmail.com" + - run: npm i -g pnpm && pnpm i + name: Install dependencies + # fail and not publish if any of the unit tests are failing + - name: Test + run: pnpm test + - name: clean up working directory + run: git status && git clean -f -d && git status + - name: Copy Readme file + run: cp ./README.md ./lib # todo: uncomment this line while rebranding + - name: Apply changesets, publish and create release, branches and tags + run: node ./scripts/manual-publish.js + env: + BRANCH: ${{ github.ref_name }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 07973245..cfb637bc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,26 +2,20 @@ name: Publish to NPM # publish only when package json has changed - assuming version upgrade on: - workflow_dispatch: push: branches: [main] - paths: "lib/r18gs/package.json" + paths: "lib/package.json" jobs: publish: # Don't run just after creating repo from template # Also avoid running after merging set-up PR - if: github.event.repository.owner.login == 'react18-tools' + if: github.run_number > 2 && github.event.repository.owner.login == 'react18-tools' runs-on: ubuntu-latest permissions: - packages: write contents: write id-token: write - defaults: - run: - working-directory: ./lib/r18gs - steps: - uses: actions/checkout@v4 with: @@ -31,46 +25,22 @@ jobs: with: node-version: 20 registry-url: https://registry.npmjs.org + - name: Setup Git + run: | + git config --global user.name "mayank1513" + git config --global user.email "mayank.srmu@gmail.com" - run: npm i -g pnpm && pnpm i name: Install dependencies # fail and not publish if any of the unit tests are failing - name: Test run: pnpm test - - name: publish to NPM - run: pnpm build && pnpm publish-package - continue-on-error: true + - name: Copy Readme file + run: cp ./README.md ./lib # will be uncommented while rebranding + - name: Apply changesets, publish and create release, branches and tags + run: node ./scripts/publish.js env: + BRANCH: ${{ github.ref_name }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} - TOKEN: ${{ secrets.GITHUB_TOKEN }} - OWNER: ${{ github.event.repository.owner.login }} - REPO: ${{ github.event.repository.name }} - - - name: Create GitHub release - run: | - v=$(node -p -e "require('./package.json').version") - gh release create $v --generate-notes --latest -n "$(sed '1,/^## /d;/^## /,$d' CHANGELOG.md)" --title "Release $v" - env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Publish canonical packages - continue-on-error: true - run: | - sed -i -e "s/.*name.*/\t\"name\": \"@mayank1513\/r18gs\",/" package.json - npm publish --provenance --access public - sed -i -e "s/.*name.*/\t\"name\": \"react18-global-store\",/" package.json - npm publish --provenance --access public - sed -i -e "s/.*name.*/\t\"name\": \"react18-store\",/" package.json - npm publish --provenance --access public - sed -i -e "s/.*name.*/\t\"name\": \"react19-global-store\",/" package.json - npm publish --provenance --access public - sed -i -e "s/.*name.*/\t\"name\": \"react19-store\",/" package.json - npm publish --provenance --access public - sed -i -e "s/.*name.*/\t\"name\": \"r19gs\",/" package.json - npm publish --provenance --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} - - - name: Mark scoped package as deprecated - run: npm deprecate @mayank1513/r18gs "Please use https://www.npmjs.com/package/r18gs instead. We initially created scoped packages to have similarities with the GitHub Public Repository (which requires packages to be scoped). We are no longer using GPR and thus deprecating all scoped packages for which corresponding un-scoped packages exist." - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 15e4a2ba..47cca655 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,9 +7,8 @@ on: - cron: "5 */8 * * *" jobs: test: + if: github.run_number != 1 runs-on: ubuntu-latest - permissions: - contents: write steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -23,12 +22,11 @@ jobs: continue-on-error: true uses: codecov/codecov-action@v4 with: - directory: ./lib/r18gs + directory: ./lib token: ${{ secrets.CODECOV_TOKEN }} - flags: r18gs - uses: paambaati/codeclimate-action@v5.0.0 continue-on-error: true env: CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} with: - coverageLocations: ./lib/r18gs/coverage/*.xml:clover + coverageLocations: ./lib/coverage/*.xml:clover diff --git a/.gitignore b/.gitignore index 3e6eed46..544fb870 100644 --- a/.gitignore +++ b/.gitignore @@ -1,39 +1,16 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -node_modules -.pnp -.pnp.js - -# testing -coverage - -# next.js -.next/ -out/ -build - -# misc .DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env -.env.local -.env.development.local -.env.test.local -.env.production.local - -# turbo +node_modules .turbo +*.log +.next +dist +dist-ssr +*.local +.env +.cache -# vercel -.vercel +# test coverage +coverage -# lock files -*lock* +# temporary files +tsup.config.bundled* diff --git a/.prettierignore b/.prettierignore index a8d4ec13..e58c2191 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,3 +3,4 @@ # ignore hbs files as prettier removes all spaces and makes it ugly *hbs docs +.vscode diff --git a/.prettierrc b/.prettierrc index 25fc6e9d..0b48ac1a 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,6 +4,5 @@ "tabWidth": 2, "arrowParens": "avoid", "jsxBracketSameLine": true, - "bracketSameLine": true, - "useTabs": true + "bracketSameLine": true } diff --git a/.tkb b/.tkb index 15ff7bec..8e0c6c8e 100644 --- a/.tkb +++ b/.tkb @@ -1,19 +1,11 @@ { "scope": "Workspace", - "tasks": { - "task-oQKhoVOKYhYaRYGvlDMj5": { - "id": "task-oQKhoVOKYhYaRYGvlDMj5", - "description": "Add support for persist and sync", - "columnId": "column-todo" - } - }, + "tasks": {}, "columns": [ { "id": "column-todo", "title": "To do", - "tasksIds": [ - "task-oQKhoVOKYhYaRYGvlDMj5" - ] + "tasksIds": [] }, { "id": "column-doing", diff --git a/.vscode/settings.json b/.vscode/settings.json index 20d656cd..36db13c4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,28 +1,13 @@ { // Formatting using Prettier by default for all languages "editor.defaultFormatter": "esbenp.prettier-vscode", - // Formatting using Prettier for JavaScript, overrides VSCode default. - "[javascript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - }, // Ensure enough terminal history is preserved when running tests. "terminal.integrated.scrollback": 10000, - // Configure todo-tree to exclude node_modules, dist, and compiled. - "todo-tree.filtering.excludeGlobs": ["**/node_modules", "**/dist", "**/compiled"], - // Match TODO-APP in addition to other TODOs. - "todo-tree.general.tags": ["BUG", "HACK", "FIXME", "TODO", "XXX", "[ ]", "[x]", "TODO-APP"], - // Disable TypeScript surveys. "typescript.surveys.enabled": false, - "grammarly.selectors": [ - { - "language": "markdown", - "scheme": "file" - } - ], "editor.tabSize": 2, "editor.wordWrap": "on", "editor.formatOnSave": true, diff --git a/FEATURED.md b/FEATURED.md new file mode 100644 index 00000000..97909ff2 --- /dev/null +++ b/FEATURED.md @@ -0,0 +1,11 @@ +# Featured packages built with this template. + +> This file is automatically generated. Please refrain from editing it directly. To add your package, update `scripts/featured.json` in alphabetical order. + +- [esbuild-plugin-react18](https://github.com/react18-tools/esbuild-plugin-react18) - An esbuild plugin for compiling libraries compatible with React 18 server and client component, Nextjs13, and Nextjs14 +- [esbuild-plugin-react18-css](https://github.com/react18-tools/esbuild-plugin-react18-css) - ESBuild plugin to handle CSS/SCSS modules, autoprefixer, etc. +- [Nextjs-Themes](https://github.com/react18-tools/nextjs-themes) - 🤟 👉 Theme with confidence and Unleash the Power of React Server Components +- [Persist-And-Sync](https://github.com/react18-tools/persist-and-sync) - Zustand middleware to easily persist and sync Zustand state between tabs / windows / iframes (Same Origin) +- [React 18 Themes](https://github.com/react18-tools/react18-themes) - 🤟 👉 Unleash the Power of React Server Components +- [React18 Global Store](https://github.com/react18-tools/react18-global-store) - A simple yet elegant, light weight, react18 global store to replace Zustand for better tree shaking. +- [Zustand Sync Tabs](https://github.com/react18-tools/zustand-sync-tabs) - Zustand middleware to easily sync Zustand state between tabs / windows / iframes (Same Origin) diff --git a/README.md b/README.md index ddb13a72..d009ad25 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# React18GlobalStore +# React18GlobalStore [![test](https://github.com/react18-tools/react18-global-store/actions/workflows/test.yml/badge.svg)](https://github.com/react18-tools/react18-global-store/actions/workflows/test.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/ec3140063acd8df82481/maintainability)](https://codeclimate.com/github/react18-tools/react18-global-store/maintainability) [![codecov](https://codecov.io/gh/react18-tools/react18-global-store/graph/badge.svg)](https://codecov.io/gh/react18-tools/react18-global-store) [![Version](https://img.shields.io/npm/v/r18gs.svg?colorB=green)](https://www.npmjs.com/package/r18gs) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/d18m/r18gs.svg)](https://www.npmjs.com/package/r18gs) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/r18gs) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/from-referrer/) @@ -68,7 +68,9 @@ Interested in hands-on courses for getting started with Turborepo? Check out [Re ## License -Licensed under the MPL 2.0 open source license. +This library is licensed under the MPL-2.0 open-source license. + +> Please consider enrolling in [our courses](https://mayank-chaudhari.vercel.app/courses) or [sponsoring](https://github.com/sponsors/mayank1513) our work.
diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..4ed0871d --- /dev/null +++ b/TODO.md @@ -0,0 +1,52 @@ +## Step-by-Step Instructions and Checklist + +- [ ] Star [this repository](https://github.com/react18-tools/turborepo-template/) for easy access and to show your support +- [x] Create a new GitHub repository using this template. + - Click the `Use this template` button at the top right -> `Create a new repository` + - Click `Create repository` and wait for the setup workflow to finish rebranding your repo. +- [ ] Install and set up Node.js and your IDE (VSCode recommended) +- [ ] Install the recommended VSCode extensions: + - [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) + - [Trello Kanban](https://marketplace.visualstudio.com/items?itemName=mayank1513.trello-kanban-task-board) +- [ ] 🌟 **Update [`sripts/rebrand.config.json`](./scripts/rebrand.config.json) if required.** +- [ ] Install `pnpm` using `npm i -g pnpm` +- [ ] Install dependencies using `pnpm` + - Run `pnpm i` to install dependencies; the `rebrand` script will automatically rebrand the repo, adjust workflows, and create a commit +- [ ] Make sure you run `node scripts/rebrand.js` from the root directory to rebrand your repo. +- [ ] Run `yarn plop`, and follow prompts to generate server or client components for your library +- [ ] 🌟 Enable [private vulnerability reporting](https://github.com/react18-tools/react18-global-store/security) +- [ ] Set up `CodeCov` + - Visit Codecov and set up your repo + - Create [repository secret](<(https://github.com/react18-tools/react18-global-store/settings/secrets/actions)>) for `CODECOV_TOKEN` +- [ ] Set up `CodeClimate` + - Visit CodeClimate and set up your repo + - Create [repository secret] for `CC_TEST_REPORTER_ID` + - Add `*.test.*` to ignore patterns on the website + - Update Code Climate badge +- [ ] Add `NPM_AUTH_TOKEN` to repository secrets to automate package publishing + - Log in to your [`npm` account](https://www.npmjs.com/login) and create an automation token + - Create a new repository secret `NPM_AUTH_TOKEN` +- [ ] Update description in `lib/package.json` +- [ ] (Optional) Add Repo Stats by visiting and setting up [repobeats](https://repobeats.axiom.co/) +- [ ] Create your library and update examples +- [ ] Update README as required +- [ ] Set up GitHub pages to deploy docs + - Go to [repo settings](https://github.com/react18-tools/react18-global-store/settings/pages) -> pages (On the left panel); Select deploy from a branch; Then Select `main` and `/docs` +- [ ] (Optional) Set up [Deepsource](https://app.deepsource.com/login) for static code analysis +- [ ] Push your changes/Create PR and see your library being automatically tested and published +- [ ] Optionally deploy your examples to Vercel. +- [ ] Feel free to star this template, contribute, and/or sponsor the [`terborepo-template`](https://github.com/react18-tools/turborepo-template) project or my [other open-source work](https://github.com/sponsors/mayank1513) +- [ ] You can also fork the [`terborepo-template`](https://github.com/react18-tools/turborepo-template/fork) and add your package to `scripts/featured.json` + - If approved, your package will be automatically added to FEATURED.md and also published on the home page of this repo. + +## Recommended Repository Settings + +Go to [repository settings] and configure the following: + +- [ ] Enable Discussions +- [ ] Enable `Always suggest updating pull request branches` +- [ ] Enable `Automatically delete head branches` + +
+ +

with 💖 by Mayank Kumar Chaudhari

diff --git a/contributing.md b/contributing.md index 87045151..f13085b9 100644 --- a/contributing.md +++ b/contributing.md @@ -1,36 +1,67 @@ -# Contributing to r18gs +# Contribution Guidelines -## Contribute +## Overview -Once you have cloned the repo. `cd` to the repo directory and use following commands. +### Included Utilities + +This template is equipped with pre-configured tools to streamline your development process: + +- Monorepo setup powered by TurboRepo + - TurboRepo is renowned for its efficient builds and caching mechanisms, minimizing unnecessary builds. +- [TypeScript](https://www.typescriptlang.org/) for static type checking +- [ESLint](https://eslint.org/) for code linting +- [Prettier](https://prettier.io) for code formatting +- Plop-based code generator for effortlessly scaffolding new components +- Automatic rebranding functionality for this template +- Workflows facilitating testing, documentation, dependency updates, and deployment of your docs and packages +- Build setup capable of creating appropriate CJS and ESM builds to support React 18 server and client component exports from the same library +- Out-of-the-box support for SCSS modules for `lib` and `packages/shared` + +### Apps and Packages + +This TurboRepo comprises the following packages/examples, all written in [TypeScript](https://www.typescriptlang.org/): + +- `@example/nextjs`: a [Next.js](https://nextjs.org/) app +- `@example/vite`: a [Vite.js](https://vitest.dev) app +- `@example/remix`: a Remix app +- `@repo/eslint-config`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`) +- `@repo/typescript-config`: `tsconfig.json`s used throughout the monorepo +- `@repo/jest-presets`: Jest presets for unit testing +- `@repo/logger`: A configurable shared logger utility +- `@repo/shared`: An internal library of components utilized by the examples +- `react18-loaders`: a React component library (The core package published to NPM) + +## Automated File Generation + +Simply execute `yarn turbo gen` and follow the prompts to automatically generate your new component along with a test file and dependency linking, adhering to best practices. ### Build -To build all apps and packages, run the following command: +To build all apps and packages, execute the following command: ```bash pnpm build ``` -### Develop +### Development -To develop all apps and packages, run the following command: +For development of all apps and packages, run: ```bash pnpm dev ``` -### Run unit tests +### Running Unit Tests -To run unit tests, run the following command: +To execute unit tests, use: ```bash pnpm test ``` -### Linting and formating +### Linting and Formatting -Before creating PR make sure lint is passing and also run formatter to properly format the code. +Before creating a PR, ensure that linting passes and format the code properly with: ```bash pnpm lint @@ -42,55 +73,12 @@ and pnpm format ``` -You can also contribute by - -1. Sponsoring -2. Check out discussion for providing any feedback or sugestions. -3. Report any issues or feature requests in issues tab - -## What's inside? - -### Utilities - -This Turborepo has some additional tools already setup for you: - -- [TypeScript](https://www.typescriptlang.org/) for static type checking -- [ESLint](https://eslint.org/) for code linting -- [Prettier](https://prettier.io) for code formatting - -### Library, Examples and Packages - -This Turborepo includes the following packages/examples: - -#### React18 Global Store library - -You will find the core library code inside lib/r18gs - -#### Examples (/examples) - -- `nextjs`: a [Next.js](https://nextjs.org/) app -- `vite`: a [Vite.js](https://vitest.dev) app -- `remix`: a [Remix](https://remix.run/) app +## Useful Resources -#### Packages (/packages) - -- `eslint-config-custom`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`) -- `tsconfig`: `tsconfig.json`s used throughout the monorepo -- `shared-ui`: An internal UI package for shared UI code - -Each package/example is 100% [TypeScript](https://www.typescriptlang.org/). - -## Automatic file generation - -- just run `yarn turbo gen` and follow the propts to auto generate your new component with test file and dependency linking -- follow best practices automatically - -## Useful Links - -Learn more about Turborepo and Next.js: +Explore more about TurboRepo and Next.js through the following links: - [React and Next.js with TypeScript](https://www.udemy.com/course/react-and-next-js-with-typescript/?referralCode=7202184A1E57C3DCA8B2) - an interactive Next.js course. -- [The Game of Chess with Next.js, React and TypeScrypt](https://www.udemy.com/course/game-of-chess-with-nextjs-react-and-typescrypt/?referralCode=851A28F10B254A8523FE) +- [The Game of Chess with Next.js, React, and TypeScript](https://www.udemy.com/course/game-of-chess-with-nextjs-react-and-typescrypt/?referralCode=851A28F10B254A8523FE) - [Tasks](https://turbo.build/repo/docs/core-concepts/monorepos/running-tasks) - [Caching](https://turbo.build/repo/docs/core-concepts/caching) - [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) @@ -98,10 +86,10 @@ Learn more about Turborepo and Next.js: - [Configuration Options](https://turbo.build/repo/docs/reference/configuration) - [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference) -> A quick tip: Delete all stale branches `git branch --merged main | grep -v '^[ *]*main$' | xargs git branch -d` +> Quick tip: Remove all stale branches with `git branch --merged main | grep -v '^[ *]*main$' | xargs git branch -d` -
+> Consider enrolling in [our courses](https://mayank-chaudhari.vercel.app/courses) or [sponsoring](https://github.com/sponsors/mayank1513) our work. -### 🤩 Don't forger to star [this repo](https://github.com/mayank1513/react18-global-store)! +

with 💖 by Mayank Kumar Chaudhari

diff --git a/devcontainer.json b/devcontainer.json new file mode 100644 index 00000000..bf721a6c --- /dev/null +++ b/devcontainer.json @@ -0,0 +1,18 @@ +{ + "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:20", + "hostRequirements": { + "memory": "8gb" + }, + "waitFor": "onCreateCommand", + "updateContentCommand": "", + "postCreateCommand": "", + "postAttachCommand": "", + "customizations": { + "codespaces": { + "openFiles": ["TODO.md", "scripts/rebrand.config.json"] + }, + "vscode": { + "extensions": ["mayank1513.trello-kanban-task-board", "esbenp.prettier-vscode"] + } + } +} diff --git a/docs/assets/highlight.css b/docs/assets/highlight.css deleted file mode 100644 index f544099d..00000000 --- a/docs/assets/highlight.css +++ /dev/null @@ -1,120 +0,0 @@ -:root { - --light-hl-0: #0000FF; - --dark-hl-0: #569CD6; - --light-hl-1: #000000; - --dark-hl-1: #D4D4D4; - --light-hl-2: #0070C1; - --dark-hl-2: #4FC1FF; - --light-hl-3: #795E26; - --dark-hl-3: #DCDCAA; - --light-hl-4: #267F99; - --dark-hl-4: #4EC9B0; - --light-hl-5: #A31515; - --dark-hl-5: #CE9178; - --light-hl-6: #098658; - --dark-hl-6: #B5CEA8; - --light-hl-7: #008000; - --dark-hl-7: #6A9955; - --light-hl-8: #AF00DB; - --dark-hl-8: #C586C0; - --light-hl-9: #001080; - --dark-hl-9: #9CDCFE; - --light-hl-10: #800000; - --dark-hl-10: #808080; - --light-hl-11: #800000; - --dark-hl-11: #569CD6; - --light-hl-12: #E50000; - --dark-hl-12: #9CDCFE; - --light-hl-13: #000000FF; - --dark-hl-13: #D4D4D4; - --light-code-background: #FFFFFF; - --dark-code-background: #1E1E1E; -} - -@media (prefers-color-scheme: light) { :root { - --hl-0: var(--light-hl-0); - --hl-1: var(--light-hl-1); - --hl-2: var(--light-hl-2); - --hl-3: var(--light-hl-3); - --hl-4: var(--light-hl-4); - --hl-5: var(--light-hl-5); - --hl-6: var(--light-hl-6); - --hl-7: var(--light-hl-7); - --hl-8: var(--light-hl-8); - --hl-9: var(--light-hl-9); - --hl-10: var(--light-hl-10); - --hl-11: var(--light-hl-11); - --hl-12: var(--light-hl-12); - --hl-13: var(--light-hl-13); - --code-background: var(--light-code-background); -} } - -@media (prefers-color-scheme: dark) { :root { - --hl-0: var(--dark-hl-0); - --hl-1: var(--dark-hl-1); - --hl-2: var(--dark-hl-2); - --hl-3: var(--dark-hl-3); - --hl-4: var(--dark-hl-4); - --hl-5: var(--dark-hl-5); - --hl-6: var(--dark-hl-6); - --hl-7: var(--dark-hl-7); - --hl-8: var(--dark-hl-8); - --hl-9: var(--dark-hl-9); - --hl-10: var(--dark-hl-10); - --hl-11: var(--dark-hl-11); - --hl-12: var(--dark-hl-12); - --hl-13: var(--dark-hl-13); - --code-background: var(--dark-code-background); -} } - -:root[data-theme='light'] { - --hl-0: var(--light-hl-0); - --hl-1: var(--light-hl-1); - --hl-2: var(--light-hl-2); - --hl-3: var(--light-hl-3); - --hl-4: var(--light-hl-4); - --hl-5: var(--light-hl-5); - --hl-6: var(--light-hl-6); - --hl-7: var(--light-hl-7); - --hl-8: var(--light-hl-8); - --hl-9: var(--light-hl-9); - --hl-10: var(--light-hl-10); - --hl-11: var(--light-hl-11); - --hl-12: var(--light-hl-12); - --hl-13: var(--light-hl-13); - --code-background: var(--light-code-background); -} - -:root[data-theme='dark'] { - --hl-0: var(--dark-hl-0); - --hl-1: var(--dark-hl-1); - --hl-2: var(--dark-hl-2); - --hl-3: var(--dark-hl-3); - --hl-4: var(--dark-hl-4); - --hl-5: var(--dark-hl-5); - --hl-6: var(--dark-hl-6); - --hl-7: var(--dark-hl-7); - --hl-8: var(--dark-hl-8); - --hl-9: var(--dark-hl-9); - --hl-10: var(--dark-hl-10); - --hl-11: var(--dark-hl-11); - --hl-12: var(--dark-hl-12); - --hl-13: var(--dark-hl-13); - --code-background: var(--dark-code-background); -} - -.hl-0 { color: var(--hl-0); } -.hl-1 { color: var(--hl-1); } -.hl-2 { color: var(--hl-2); } -.hl-3 { color: var(--hl-3); } -.hl-4 { color: var(--hl-4); } -.hl-5 { color: var(--hl-5); } -.hl-6 { color: var(--hl-6); } -.hl-7 { color: var(--hl-7); } -.hl-8 { color: var(--hl-8); } -.hl-9 { color: var(--hl-9); } -.hl-10 { color: var(--hl-10); } -.hl-11 { color: var(--hl-11); } -.hl-12 { color: var(--hl-12); } -.hl-13 { color: var(--hl-13); } -pre, code { background: var(--code-background); } diff --git a/docs/assets/icons.js b/docs/assets/icons.js deleted file mode 100644 index b79c9e89..00000000 --- a/docs/assets/icons.js +++ /dev/null @@ -1,15 +0,0 @@ -(function(svg) { - svg.innerHTML = ``; - svg.style.display = 'none'; - if (location.protocol === 'file:') { - if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateUseElements); - else updateUseElements() - function updateUseElements() { - document.querySelectorAll('use').forEach(el => { - if (el.getAttribute('href').includes('#icon-')) { - el.setAttribute('href', el.getAttribute('href').replace(/.*#/, '#')); - } - }); - } - } -})(document.body.appendChild(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))) \ No newline at end of file diff --git a/docs/assets/icons.svg b/docs/assets/icons.svg deleted file mode 100644 index 7dead611..00000000 --- a/docs/assets/icons.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/assets/main.js b/docs/assets/main.js deleted file mode 100644 index d6f13886..00000000 --- a/docs/assets/main.js +++ /dev/null @@ -1,59 +0,0 @@ -"use strict"; -"use strict";(()=>{var Ce=Object.create;var ne=Object.defineProperty;var Pe=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var _e=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var Me=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Fe=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Oe(e))!Re.call(t,i)&&i!==n&&ne(t,i,{get:()=>e[i],enumerable:!(r=Pe(e,i))||r.enumerable});return t};var De=(t,e,n)=>(n=t!=null?Ce(_e(t)):{},Fe(e||!t||!t.__esModule?ne(n,"default",{value:t,enumerable:!0}):n,t));var ae=Me((se,oe)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(n){e.console&&console.warn&&console.warn(n)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i0){var d=t.utils.clone(n)||{};d.position=[a,u],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r1&&(oe&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ol?d+=2:a==l&&(n+=r[u+1]*i[d+1],u+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}if(s.str.length==0&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}s.str.length==1&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),y=s.str.charAt(1),p;y in s.node.edges?p=s.node.edges[y]:(p=new t.TokenSet,s.node.edges[y]=p),s.str.length==1&&(p.final=!0),i.push({node:p,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),l=0;l1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,n){typeof define=="function"&&define.amd?define(n):typeof se=="object"?oe.exports=n():e.lunr=n()}(this,function(){return t})})()});var re=[];function G(t,e){re.push({selector:e,constructor:t})}var U=class{constructor(){this.alwaysVisibleMember=null;this.createComponents(document.body),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible()),document.body.style.display||(this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}createComponents(e){re.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}showPage(){document.body.style.display&&(console.log("Show page"),document.body.style.removeProperty("display"),this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}scrollToHash(){if(location.hash){console.log("Scorlling");let e=document.getElementById(location.hash.substring(1));if(!e)return;e.scrollIntoView({behavior:"instant",block:"start"})}}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e&&!e.checkVisibility()){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r}}updateIndexVisibility(){let e=document.querySelector(".tsd-index-content"),n=e?.open;e&&(e.open=!0),document.querySelectorAll(".tsd-index-section").forEach(r=>{r.style.display="block";let i=Array.from(r.querySelectorAll(".tsd-index-link")).every(s=>s.offsetParent==null);r.style.display=i?"none":"block"}),e&&(e.open=n)}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(n&&n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let r=document.createElement("p");r.classList.add("warning"),r.textContent="This member is normally hidden due to your filter settings.",n.prepend(r)}}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent="Copied!",e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent="Copy"},100)},1e3)})})}};var ie=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var de=De(ae());async function le(t,e){if(!window.searchData)return;let n=await fetch(window.searchData),r=new Blob([await n.arrayBuffer()]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();t.data=i,t.index=de.Index.load(i.index),e.classList.remove("loading"),e.classList.add("ready")}function he(){let t=document.getElementById("tsd-search");if(!t)return;let e={base:t.dataset.base+"/"},n=document.getElementById("tsd-search-script");t.classList.add("loading"),n&&(n.addEventListener("error",()=>{t.classList.remove("loading"),t.classList.add("failure")}),n.addEventListener("load",()=>{le(e,t)}),le(e,t));let r=document.querySelector("#tsd-search input"),i=document.querySelector("#tsd-search .results");if(!r||!i)throw new Error("The input field or the result list wrapper was not found");let s=!1;i.addEventListener("mousedown",()=>s=!0),i.addEventListener("mouseup",()=>{s=!1,t.classList.remove("has-focus")}),r.addEventListener("focus",()=>t.classList.add("has-focus")),r.addEventListener("blur",()=>{s||(s=!1,t.classList.remove("has-focus"))}),Ae(t,i,r,e)}function Ae(t,e,n,r){n.addEventListener("input",ie(()=>{Ve(t,e,n,r)},200));let i=!1;n.addEventListener("keydown",s=>{i=!0,s.key=="Enter"?Ne(e,n):s.key=="Escape"?n.blur():s.key=="ArrowUp"?ue(e,-1):s.key==="ArrowDown"?ue(e,1):i=!1}),n.addEventListener("keypress",s=>{i&&s.preventDefault()}),document.body.addEventListener("keydown",s=>{s.altKey||s.ctrlKey||s.metaKey||!n.matches(":focus")&&s.key==="/"&&(n.focus(),s.preventDefault())})}function Ve(t,e,n,r){if(!r.index||!r.data)return;e.textContent="";let i=n.value.trim(),s;if(i){let o=i.split(" ").map(a=>a.length?`*${a}*`:"").join(" ");s=r.index.search(o)}else s=[];for(let o=0;oa.score-o.score);for(let o=0,a=Math.min(10,s.length);o`,d=ce(l.name,i);globalThis.DEBUG_SEARCH_WEIGHTS&&(d+=` (score: ${s[o].score.toFixed(2)})`),l.parent&&(d=` - ${ce(l.parent,i)}.${d}`);let y=document.createElement("li");y.classList.value=l.classes??"";let p=document.createElement("a");p.href=r.base+l.url,p.innerHTML=u+d,y.append(p),e.appendChild(y)}}function ue(t,e){let n=t.querySelector(".current");if(!n)n=t.querySelector(e==1?"li:first-child":"li:last-child"),n&&n.classList.add("current");else{let r=n;if(e===1)do r=r.nextElementSibling??void 0;while(r instanceof HTMLElement&&r.offsetParent==null);else do r=r.previousElementSibling??void 0;while(r instanceof HTMLElement&&r.offsetParent==null);r&&(n.classList.remove("current"),r.classList.add("current"))}}function Ne(t,e){let n=t.querySelector(".current");if(n||(n=t.querySelector("li:first-child")),n){let r=n.querySelector("a");r&&(window.location.href=r.href),e.blur()}}function ce(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(K(t.substring(s,o)),`${K(t.substring(o,o+r.length))}`),s=o+r.length,o=n.indexOf(r,s);return i.push(K(t.substring(s))),i.join("")}var He={"&":"&","<":"<",">":">","'":"'",'"':"""};function K(t){return t.replace(/[&<>"'"]/g,e=>He[e])}var I=class{constructor(e){this.el=e.el,this.app=e.app}};var F="mousedown",fe="mousemove",H="mouseup",J={x:0,y:0},pe=!1,ee=!1,Be=!1,D=!1,me=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(me?"is-mobile":"not-mobile");me&&"ontouchstart"in document.documentElement&&(Be=!0,F="touchstart",fe="touchmove",H="touchend");document.addEventListener(F,t=>{ee=!0,D=!1;let e=F=="touchstart"?t.targetTouches[0]:t;J.y=e.pageY||0,J.x=e.pageX||0});document.addEventListener(fe,t=>{if(ee&&!D){let e=F=="touchstart"?t.targetTouches[0]:t,n=J.x-(e.pageX||0),r=J.y-(e.pageY||0);D=Math.sqrt(n*n+r*r)>10}});document.addEventListener(H,()=>{ee=!1});document.addEventListener("click",t=>{pe&&(t.preventDefault(),t.stopImmediatePropagation(),pe=!1)});var X=class extends I{constructor(e){super(e),this.className=this.el.dataset.toggle||"",this.el.addEventListener(H,n=>this.onPointerUp(n)),this.el.addEventListener("click",n=>n.preventDefault()),document.addEventListener(F,n=>this.onDocumentPointerDown(n)),document.addEventListener(H,n=>this.onDocumentPointerUp(n))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let n=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(n),setTimeout(()=>document.documentElement.classList.remove(n),500)}onPointerUp(e){D||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!D&&this.active&&e.target.closest(".col-sidebar")){let n=e.target.closest("a");if(n){let r=window.location.href;r.indexOf("#")!=-1&&(r=r.substring(0,r.indexOf("#"))),n.href.substring(0,r.length)==r&&setTimeout(()=>this.setActive(!1),250)}}}};var te;try{te=localStorage}catch{te={getItem(){return null},setItem(){}}}var Q=te;var ye=document.head.appendChild(document.createElement("style"));ye.dataset.for="filters";var Y=class extends I{constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),ye.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } -`,this.app.updateIndexVisibility()}fromLocalStorage(){let e=Q.getItem(this.key);return e?e==="true":this.el.checked}setLocalStorage(e){Q.setItem(this.key,e.toString()),this.value=e,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),this.app.filterChanged(),this.app.updateIndexVisibility()}};var Z=class extends I{constructor(e){super(e),this.summary=this.el.querySelector(".tsd-accordion-summary"),this.icon=this.summary.querySelector("svg"),this.key=`tsd-accordion-${this.summary.dataset.key??this.summary.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`;let n=Q.getItem(this.key);this.el.open=n?n==="true":this.el.open,this.el.addEventListener("toggle",()=>this.update());let r=this.summary.querySelector("a");r&&r.addEventListener("click",()=>{location.assign(r.href)}),this.update()}update(){this.icon.style.transform=`rotate(${this.el.open?0:-90}deg)`,Q.setItem(this.key,this.el.open.toString())}};function ge(t){let e=Q.getItem("tsd-theme")||"os";t.value=e,ve(e),t.addEventListener("change",()=>{Q.setItem("tsd-theme",t.value),ve(t.value)})}function ve(t){document.documentElement.dataset.theme=t}var Le;function be(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",xe),xe())}async function xe(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let n=await(await fetch(window.navigationData)).arrayBuffer(),r=new Blob([n]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();Le=t.dataset.base+"/",t.innerHTML="";for(let s of i)we(s,t,[]);window.app.createComponents(t),window.app.showPage(),window.app.ensureActivePageVisible()}function we(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-index-accordion`:"tsd-index-accordion",s.dataset.key=i.join("$");let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.innerHTML='',Ee(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let l=a.appendChild(document.createElement("ul"));l.className="tsd-nested-navigation";for(let u of t.children)we(u,l,i)}else Ee(t,r,t.class)}function Ee(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));r.href=Le+t.path,n&&(r.className=n),location.pathname===r.pathname&&r.classList.add("current"),t.kind&&(r.innerHTML=``),r.appendChild(document.createElement("span")).textContent=t.text}else e.appendChild(document.createElement("span")).textContent=t.text}G(X,"a[data-toggle]");G(Z,".tsd-index-accordion");G(Y,".tsd-filter-item input[type=checkbox]");var Se=document.getElementById("tsd-theme");Se&&ge(Se);var je=new U;Object.defineProperty(window,"app",{value:je});he();be();})(); -/*! Bundled license information: - -lunr/lunr.js: - (** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - *) - (*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Set - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.tokenizer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Vector - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.stemmer - * Copyright (C) 2020 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - *) - (*! - * lunr.stopWordFilter - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.trimmer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.TokenSet - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Builder - * Copyright (C) 2020 Oliver Nightingale - *) -*/ diff --git a/docs/assets/navigation.js b/docs/assets/navigation.js deleted file mode 100644 index ddec113b..00000000 --- a/docs/assets/navigation.js +++ /dev/null @@ -1 +0,0 @@ -window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA6XWW2+bMBQH8O/ivJKtl7RTo2lS9pI9dNoWpu2hqpCBU7DiGuRLk2rad5+Cy834wtpX+PuHzzHY3P1BEo4SrdFWkRwEilCNZYnW6LHKFQXxXl9/V8pHiiK0JyxH64sIZSWhOQeG1ncdsUl+KJLtk1hiLnvpCXOC04E1yo3ly4u/Ued9Tm7hCTguCCuS71QVhAkPa4tP9PuBT1gOx2nFzeVZBeuH+IRFF9HQ6vxmdXm2GkwiBhlLLGGTSVL5rUnUY0rgG178fK4hRI6SLtFo1YNizRxay9Ky69Wo17W5fO1kattCufoNXBAhv9XNs/3WYhJ21VbrYIDrU691kpfAm0olTAJ/wJmFHQ8xnnJ17Ztpv54map1zs7bD1VWSUMt6NJdnlfuxqYth+smlJG0imQXeEiGBAe85+VzbsDZoqGc3H86vhpvRV3X69IKcjoWw3TYOSrttHGQgq3gelpqYFYtQRrEQp7EiXxKxhKMehYbbiUpFxkk6o5t91D734Utj7p5DUt8L1e/aO4fSODNDtO2cBthHQt4vTBW4re52yClolWI6em36809bXcRzomYcsIQvVbW3ffva6TOTj96EdCtClE6FMZWaL5nDa4MekjAifxNZTv4aTNIIekglYLeNZ6GTqPdoPBBZLp3n4+lu8j+HpGeeTnNhG+Q65/Qq2KofuTrmaejB38oRdvD28v4fxirZ58cKAAA=" \ No newline at end of file diff --git a/docs/assets/search.js b/docs/assets/search.js deleted file mode 100644 index 5dd85e3d..00000000 --- a/docs/assets/search.js +++ /dev/null @@ -1 +0,0 @@ -window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAAA+09247bOJb/4jxsHjSKeNMl6G6gZx96F5jFzk4Wsw+ZoKByybYQW3JLclVqgvz74vBmHkqU6fRMP81TMRLPhed+SMr5uhn6l3Hz/uPXzee2e9q8p8mmq0/N5v3ml0v71IybZHMZjpv3m1P/dDk24zv1OD1Mp+Mm2WyP9Tg24+b9ZvMtMTjYFcnPD/9zabefHz5M9TBZXM/10NaPDjY0bQF3sjnXQ9NNV7YWqf3x4U/NczPU+7bbP/z5eNm33RgmujT7TtpX0m331HyZCUs+XZVVzgModpduO7V9Z5CEUDnsKQRL3J09WRj+zsFVr2B5d26GsR2nELYH/X4dq8gt3j+r+f99luu1aNtuaoZdvV3AjCHWpeJzfeWBZPQq/fG1234n6TcaNoq+hyDIztQP9b75bo4s+G9kyrFPX+1XC/U5ChtAlF6uFneZ2uPcauXTdevKqoKIK54PzTQ1w8/D/n9fz1eZTq9niw3NWGdcMbVK7MNUT83PUjohas6U+8jlQrCr7zw8TCtL8om8sdNXaHmAKyv9a328NEGR2rf3rc+J5/tj/1gf//LLh4UgrmjYGXfK8GrV26Gpp+bD5XE7tI/NsGDdipI377fSk+Z2i5ic9Bsp/Ufff75BB6b8NpNX2XPRCtSrf5KJO8jjTFszGgi6bddOkXRSPfc2sVQz9g9ZniSrMf6B3ENfMRxYeN/9+6Hu9tFcOPN/bwEY0kYI7C4hWMYDFVg7/V87HfzS0Xcbb953e+hlbP7yy4cYirOZd/qrJfnSToc/hMpBePkQUxPOoswC4wiZmrXONGIt0lhuk3ujxzfCg0vcgOulLS77ZVVpiJmXWK39AwXg03zjPrhHFC6cu+Yre5xUnGX8Rq0174je+BPjmpoFckvV1jI9PPP7CHq5boGQnfGdBJbboaWe7c1s7mqtvUL0Rk+nqF0nfS+ZcMQLxqA3SzB3OdA1+v0g26iuPv4UaCoezISH31YQuTWrm9Ac/HFFa+qwvNJyXB5Hr34NUL3O/G7i0dk7TDauWLtSd+D/KYzYisoM6PewliJkK+r6r8vk5swAq2rW76omh+TdKtKLCq/6T+04Nd1tEzXzfteVI6J3r90u7dunRMf39183zxAu+27zfkNTllabZLNrm+MTbLcq5pLNtj+dAOcn/e6vzXbqB5ihprzLNsnHLGEiJaL49Cn5aCDkC/lATiOb5CNZmgYvaMJSUrCEJSQlPOFJluYkT4T+myck5SVPioSkWZUnpX5eJVnK8zwhWZKlVcESQuSMhFA9gzAzMDiJQUryJEuLkiSkMNClIk8q9ZdmeiolegY1eKnBSw1eavBS4DbLy4QW5onhlwJiUZGEGcyMKFKMJjRlLGFMU2IGLzN4WW4GgFdQkTCFlyes0q844OWUJpzoOdxwzJl5xROS0kwkXGgBcMBc5izhhRYoNxxzwFwQkYhMvxJSFpQmgponTIMLwCwymgiDWYAsKBeJKMwAMLMyT4RRXm4w54bnnJqBkXJupJFbkwCeGSNJbqSclwaPkUZhMBfEPDHSKAzmwmAuDOYi10oqDOai1BIrQH9VWSWl0V9J9EpLmpA0r3hSGg2W3DwRSsdlbt4UWm+lEXOpLa4yeCttFxWVFEVSadeouBZ2ZfitjF1Uht/K+oeRBMkyLVKSEfvMOklmvSSzbpJZP8k0gasvU/DlrFjyZiq9maZFXki3pURIty0KKt2VlspbGWCGRVIqXZGkRV6BK5KUUQEeR1JBS/CmLK1yDp5BUuBKmj+AM1BLVjJl9VRwZfV5xpSxyydCD6TZcqJME2KJkEZPKJgmqIUr0+ScKUMECtIQmbE24CKXIaIQyrZoCbaRpVUJpqGmSouQaqeaYWkIsChpAHKO9IZKgDZJyoRRkBRKJj2kIAnJpFVQCGuZeUaIHVE7AtFkELhklCuyIiEyzKm3uWaZyEAH4iGktM8qA0stDWppyHgn8cmAp0bcvhWGZ5rbUWHf2nVQS0PGPZA+YUZVhElvZyIhMvhJCGbXwYSFyO1bS0OZgMRcmWfcrkOaAyifcCsrbmlwuw4uDBYZCasyITISSga4XQa3JEQGrl0UCRFWVMLYChGWhLAkVEQUCRF2FcKSEJaEMFZE8kybCMktidyuIrckcksit6uQ1iplm1tJyegopZzbZRRWUjJASl4Kq/HC0iisNgprVUVunxWGrvQF9czSKK1dl3YdpV1HaS235IbnUhgspcpLIiEqYjLAYmVVWllVlkZlaVSWRsV02KmsqCpLorLqqArtrqSyJCqzDCrdE9ijGbHPjMZpxuwzbkfCjnI7KuyotCNLwzo5JUYd1Do5JZYGsTSsk1NiaRBLg5Rq4ZQYSVGa2ZFdBrUkqCVhfZxSS4JaEsbHrwmBQdSnZcKyNMtylBAYqgJ5eKJ8BX5FRJInNAUmioSmGYQPAgPwZJlTigLyArzSWQBgeKZfcWYGHNAUifRv+UAWkoRAoaMHMsTmVSJdGp4IIMWrEuob/YSZATcDg1DWNxK8MIPSDCo9OTeYS6KhZPjPwNa5eUQsfSKRZ6V0Wf2oNNiprSApMwBU1pBqRO1bZp9xOxJqdNWGkHkc0KaZEEgbAqktB92wfCnh52hiIScWS/ot0MRSTiyXMJa6hChBOiVPeCoyLs2ZpVXFrzgqYB9MYE6scnFAGRzCQaBLgRxE8zQnDHcm8E4aGgQhXsGgElAMQD2jkhNLIUBD4gCrqaT6aJoXPKGsSri0TMozOwLrKkmRUE7tM6ZGDlOyJ+J8aWXynTNVFlxcLE6leKr0Ur4oL4LdlEhnBC8RqWAcT+V4qpBTFzVJsBURaUa8WpyK7YhIQxKLfaV8B/LOcxUhoCjKpQKIAOdSAypIwlMO/xbQX5a0Sqhg6plDSZqb4IuUSk0JpFbovzJAFLmmJKBqlaMKirkKNJ0VzMEvTVGIRfyVxg/plJXShGTBxlKRkURaQFrxMoG7KDzNoTAWhR2VauTU5cqYwabSrChxYY7bcUrCGqbYxKg0MbGoNopNjLIVrNjEqDSxfFHDFJsYFStYsYlRaWL54kaDfKd0ViRVwlLI1tJuKDR2OYg9h1q6tKOK6WmQ7NUzmoPjQoCl0DHDyCEPpgnV9UI0ke/+leB+1wRHS53hiNDtRJaQIiXc840SG5FMLHIrZ65Fk1lyCg1ullZMNbi8FEpnPCuVzgolfDBcKXNaCLMhUih5ghJK/UBmlayADpOmrIIGU/0t5aYKV0ItVMsI/1btITQrUlIM0pCUVF7lMiHpaVLc0J4oKQMtKrs+mAcVIZXtqpK3zJISixoxO+J2JMwo5waL7D0qCINyGWqkVuiEWpaF/Zjh8MTkdiFZLCTkOyBTllSKHv5K0UPrJcMoDCQnXOSwI0NTBtKCUicVMGKw7IJV2kJLcAFBzTwpMogS0JDpZ2VmR/ZZBZgzXsruQT2DTkGPcm5HwFORgYFUZiT1q0bEjqgdMTVyJEJXhIejMGPhmoDhKMx4uCZgOAozEU4uDEdhlofLQIYTPSvC9RfDJSMrw8GVYQ9m0kuLxaQu3zkdiTJKstiSYKPkMmdCMbEwFedMvqItjrXFV3Im97onqa1isZbgWFt8JWdyrC0utVUsVvcca4sXK1iVtuTxwnMzTM3Tf6pjho8fN5vk6+ZBnzrY45av366nC++/boh6QtUfrv6U6k+l3xX6r/z3t29APnNxwzbabewKkLiA+Q047jKg4X94d6CYOFlDoqCoD1WJ20DmsMcRIi8s2IYY7swimf4r1F+W6b9Gtuavnsf1PK5W53Kh6NeIdH6PAkm2pLpkw5zl1Q+/yrv1o7qC70jUWWOIte22GUekylUtIBNQwO3jEclW3LDQBVuot0OPueA3pLSE5OnJxcAirKl+em7H2uM/j7Co+nhES2b3c3scmvrpFVlGEZIc0vZx7BHU9ZafB+Vq6tR3e2QatIiA6hAIjyHUISXwKkowy1ZuMb7rB8SICBmHy8j5jBgJLXdFQ+fzsW2esO+WMRoacKyJsadhf5GP3WWWIatylzlircaAXKb+VE/ttj4ePfsLRXG0uue6Pfo+Q4KgDuHHn75u+0s3ffvh3SMK4au+rmEfjtdPeeztRjd5OAGdBoLdYz0e0IJXrVPD4HVWq26D4/Jj0zW7dtvWR2y9ocDkiqqZXpqmwykrGFczB/Di2VBoiUv8ImuAY7GbfG69EHHDyzBk12Neg3aAwEbsXFnIuzwgbC1FyI9dqGPreaQIBcBwENn2p3PfeXiqG3joPApaPGgdYjW0+LXEIl/jO+mTzZBO4xfE5KouZ1ie2vF8rF99LOVqYWiwdLtju8VLK1ZlZAFHrKAY+/Pk4cu5G6caFqQ+PEEsRcSpbd9Nddu1ONtC078MuspKf+pxCAivD8FdsLkFYwDxgBqUZosbudt1laFuJi/pBcsv1wr11XI36uROHK9mgdyoEC1YYvmhu5wem+Gnt38zV139fMpWYyHCBf3CT28/Nzg/BitDOuPmCUfhmHAj4Q7yYx5XjleaZtHzxKZgR8xssFpbaCE0Av3NkkueO+TLdfLXL6xcBJmDINQgSQStX6HGqOsyTv0JESQR6fWp2dWXI3aSmLbMQJ8bXObCFYTbRNvt5Ft7MKMguN2uGZpuix0sKJ6FaK+DM1pviGPigj2jjLDa2GmQvusn9eWUm24jmo0mxSGT3KhcXJ9r2umA7Q4u8Nwm2ckvDbHVRRSyTXeoPXXAFaMIuPGCe4NwTedATVtEKQ/BuJS+1KczLtGLiDZEg+FAEmEozZdzj7ceggVWuMRpvkxDvZ1w9Ah6pQO4q4+4KIQ7MDdFtGvq6TL42o8IHrvmBXdNt+Wzaz1dxGyzYens2mH0yuXV+jzZ0Hwe53e4k47J8AaRQXAZpgMWdoQ97gYcpcuYCliD6u+fEPhddR7RxRUpw8WWoVIf28lrgyKWt2+waiJq13377PV3RUifrgJVVTrssYs62ywbkgeS7B5+2wJJMYJL/RMhVyAnnWcBQgf607x3ClqrQ+3QHM+7yxGngYim8NB4Oy4R8j+0ey9l0BhN+/UZi4tzxhIXN+Kxix76F9jpQFkifku2Tb32OCKgtU9NN7U7ZPY8wjjaHa5lVsWHF9meTs1TW08N3oGCS4632T35ySYYgRbkg3wuuJ0XjsP6N1zcQuyKZMMcdS94hl8Ywa2Qa7cT2rYCKH8TiUdkOA3X/h0nx3zVo3C4v6LA+6DBc6IlXVscOGgVIV37wPDR38KWH3VOKgzTS8I7e1tiWUTN1XajFyxJcAcZSXycvKMBEuNICqz201xwBw7Bqk+UsGidro2Fmsa2e+63M5pwxB6jluf+s28TN/wf2RUuu8QNc1poabwOI3gM6Gpn+jd80hWRJrwtgKDb3dxw+9y8YuIRZeN1yxsbcESzeWwfh3rAwTXC7o/2Cz7XmpwtGR7ys2O/9UJU8NxDC8kJqsd+325xYAy6jQN2qj/jk8f7T6FPdVfvvfVGeN2p7vDWUBYRHU64AyfBDTYXpn9qd94pFNywvw14OU6t1wLS4P48AvR3KajTOm54KLedXu1u8Nvz0J+9DfeIxO5gWEAQUZzBe++8LgjlBKOu8eQbLAvC7u2fZQT3vRcSZNe/4EwTsZXQnVE/xSJCWXfxMlMVoZN+h10j5Bsr+9heThN3nEj13Vb/Co2rU6cFoSFrNJA/fsVZPItw7r7zzkVj9nZwYx2U07wi7Ycnvw+JOHiTUJ6xB288rClntnGWx1AHKG/nJCIm9S9eeROx+3mut5/rvXcIe1uH53qY2u3lWGPRZhEhF0BxoGYRYfNcexdYYixgMZTY3+BwObjGMXtZgs130xFD+hDkaXYeRILN3Ry8N7874tqZc9SuTYqFygKNxkMQVKBzkn3Wv7HiSsHJQ9RIQQSkkCxgQzfH4Mut22JYumrgNG366hedH43g5hHHNfPrJyfswDF3cmY/0enK1SnUggpR8J/epu9YunTuQoMX1Fwu/PwTccx7HppdM/hBK6IoPQ/Ns7ebFCwnEJhfQwSvtlEPKg0cY8RIRsLrnvfZK4mDh9ozBF7fQYKbgzPIJYsN7v070PIOIdLpbREPpMQ7kSxCnRII7gtM75Z4DaZOuogCNgfwfm1EiB+aevTKkvBxqQu281L1eo9joH69tENz8i9vkOCtQQQ8XQbEabBqIz6Ut1sSNF6nHJhtLDtbLHy+34tC7Ajz3A43fldubM714HUdwX0I4sL9evFP4mjQBhdyLSCYnawGW3NXUqO35R88kvB2gFfOIMZmmuXqYKtH5nBvz/UwNm03vW3SqR72zZQ+wy+0ptPQnnAGi2gXxmZaKyEivGxsptHvJcN9fbgsmklJYq1np0LUuTS8IXorloU6hPllB/j6cFWH+gKEA14P+/nVcvfGhmlq2AoXfgIO9iiubA/95ejtv0VUdf6uZrDYdw2hPbVeHU2CJxLL+mNzdLjFCleEDuDn9nyeySoibI/9ydsBj+jnxnOzbXev/t5bsKx3Qf17+DHeBjDeNkTEgf3cv2KOiuKi0eRfKQqeqvsMjal3ly9ir9P+nrnbUzr+HLoKdoXGhh33lYXppcwRsTkzXyraJQ28g0xiLhtJOE8iJNirLxw5AYLZ5agYuze/W4d3VoMuXyyAepe5nDaUzz8p8VBscWEW026p39l3k7lzuBa6fgZAXtkSbEecemWqHz2ooGRcqEONM2HwDu79H/JMB3xL5C5X9i855DH02gGHHBbR4UwH7/TmrpDjVl/T4YIxBW+YueTbk1euBUOys8c7oW9m7vsEy5NszCH+NLT7vb9BR4L3vt3lDRfvLtMqkP7ET8Niew4ePbqQ6BzGu7wdvn0VW6xNF/8IIrhTsIbl9dz8+LeNuuCLC9mIlDS9nnucjiKa1EvX/ooVEfz6KXy4dOm6Br6Q8w7igr08oj+13m59RMV9Gb0UGvRnlxS+PBe8gnHTnS+jfyIcEU0uY3N6vV7Y1vfQZ/mcBC/a+Lj8Fnb9Qic2NIPg7eImDI35uuoyNh4Hwc+4yDxuKOi3C7fxg+qfQTsX4RfwBI9fVswYo11iLmL7T2EJ3OUgTqy6dg2hTVWLcFb+hhP/beOdHbNHb1/Ar8V61wZp8A6gD4dv5wSPGgJU/+5zHUvXK33ca/5LhZ3jJHJPATdFN24U2drHx/Lj1/nOQjBoEA/YO1MIrXslr0g08/7dMUUyP10woPq/qcGNZUSMfm4Gz1Ii9hCfW/wNeYS/vdSeYMNfrzhAzXHrdcsRGfblgK+ykuDHFAtXgV5a71g6+JGTy6e/68vcQ+H7DmMAl3fQFN4BxGC9d7UseJ3fg1uMgM6pGltwwWUUbz+qAcGJKqItfa3xvnLwEzVHVK/9Bcvpe6Pta3/xzrzjwt6nZHNuz82x7ZrN+4+fvn37fwqWi7LfcAAA"; \ No newline at end of file diff --git a/docs/assets/style.css b/docs/assets/style.css deleted file mode 100644 index 778b9492..00000000 --- a/docs/assets/style.css +++ /dev/null @@ -1,1412 +0,0 @@ -:root { - /* Light */ - --light-color-background: #f2f4f8; - --light-color-background-secondary: #eff0f1; - --light-color-warning-text: #222; - --light-color-background-warning: #e6e600; - --light-color-icon-background: var(--light-color-background); - --light-color-accent: #c5c7c9; - --light-color-active-menu-item: var(--light-color-accent); - --light-color-text: #222; - --light-color-text-aside: #6e6e6e; - --light-color-link: #1f70c2; - - --light-color-ts-keyword: #056bd6; - --light-color-ts-project: #b111c9; - --light-color-ts-module: var(--light-color-ts-project); - --light-color-ts-namespace: var(--light-color-ts-project); - --light-color-ts-enum: #7e6f15; - --light-color-ts-enum-member: var(--light-color-ts-enum); - --light-color-ts-variable: #4760ec; - --light-color-ts-function: #572be7; - --light-color-ts-class: #1f70c2; - --light-color-ts-interface: #108024; - --light-color-ts-constructor: var(--light-color-ts-class); - --light-color-ts-property: var(--light-color-ts-variable); - --light-color-ts-method: var(--light-color-ts-function); - --light-color-ts-call-signature: var(--light-color-ts-method); - --light-color-ts-index-signature: var(--light-color-ts-property); - --light-color-ts-constructor-signature: var(--light-color-ts-constructor); - --light-color-ts-parameter: var(--light-color-ts-variable); - /* type literal not included as links will never be generated to it */ - --light-color-ts-type-parameter: #a55c0e; - --light-color-ts-accessor: var(--light-color-ts-property); - --light-color-ts-get-signature: var(--light-color-ts-accessor); - --light-color-ts-set-signature: var(--light-color-ts-accessor); - --light-color-ts-type-alias: #d51270; - /* reference not included as links will be colored with the kind that it points to */ - - --light-external-icon: url("data:image/svg+xml;utf8,"); - --light-color-scheme: light; - - /* Dark */ - --dark-color-background: #2b2e33; - --dark-color-background-secondary: #1e2024; - --dark-color-background-warning: #bebe00; - --dark-color-warning-text: #222; - --dark-color-icon-background: var(--dark-color-background-secondary); - --dark-color-accent: #9096a2; - --dark-color-active-menu-item: #5d5d6a; - --dark-color-text: #f5f5f5; - --dark-color-text-aside: #dddddd; - --dark-color-link: #00aff4; - - --dark-color-ts-keyword: #3399ff; - --dark-color-ts-project: #e358ff; - --dark-color-ts-module: var(--dark-color-ts-project); - --dark-color-ts-namespace: var(--dark-color-ts-project); - --dark-color-ts-enum: #f4d93e; - --dark-color-ts-enum-member: var(--dark-color-ts-enum); - --dark-color-ts-variable: #798dff; - --dark-color-ts-function: #a280ff; - --dark-color-ts-class: #8ac4ff; - --dark-color-ts-interface: #6cff87; - --dark-color-ts-constructor: var(--dark-color-ts-class); - --dark-color-ts-property: var(--dark-color-ts-variable); - --dark-color-ts-method: var(--dark-color-ts-function); - --dark-color-ts-call-signature: var(--dark-color-ts-method); - --dark-color-ts-index-signature: var(--dark-color-ts-property); - --dark-color-ts-constructor-signature: var(--dark-color-ts-constructor); - --dark-color-ts-parameter: var(--dark-color-ts-variable); - /* type literal not included as links will never be generated to it */ - --dark-color-ts-type-parameter: #e07d13; - --dark-color-ts-accessor: var(--dark-color-ts-property); - --dark-color-ts-get-signature: var(--dark-color-ts-accessor); - --dark-color-ts-set-signature: var(--dark-color-ts-accessor); - --dark-color-ts-type-alias: #ff6492; - /* reference not included as links will be colored with the kind that it points to */ - - --dark-external-icon: url("data:image/svg+xml;utf8,"); - --dark-color-scheme: dark; -} - -@media (prefers-color-scheme: light) { - :root { - --color-background: var(--light-color-background); - --color-background-secondary: var(--light-color-background-secondary); - --color-background-warning: var(--light-color-background-warning); - --color-warning-text: var(--light-color-warning-text); - --color-icon-background: var(--light-color-icon-background); - --color-accent: var(--light-color-accent); - --color-active-menu-item: var(--light-color-active-menu-item); - --color-text: var(--light-color-text); - --color-text-aside: var(--light-color-text-aside); - --color-link: var(--light-color-link); - - --color-ts-keyword: var(--light-color-ts-keyword); - --color-ts-module: var(--light-color-ts-module); - --color-ts-namespace: var(--light-color-ts-namespace); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-enum-member: var(--light-color-ts-enum-member); - --color-ts-variable: var(--light-color-ts-variable); - --color-ts-function: var(--light-color-ts-function); - --color-ts-class: var(--light-color-ts-class); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-constructor: var(--light-color-ts-constructor); - --color-ts-property: var(--light-color-ts-property); - --color-ts-method: var(--light-color-ts-method); - --color-ts-call-signature: var(--light-color-ts-call-signature); - --color-ts-index-signature: var(--light-color-ts-index-signature); - --color-ts-constructor-signature: var( - --light-color-ts-constructor-signature - ); - --color-ts-parameter: var(--light-color-ts-parameter); - --color-ts-type-parameter: var(--light-color-ts-type-parameter); - --color-ts-accessor: var(--light-color-ts-accessor); - --color-ts-get-signature: var(--light-color-ts-get-signature); - --color-ts-set-signature: var(--light-color-ts-set-signature); - --color-ts-type-alias: var(--light-color-ts-type-alias); - - --external-icon: var(--light-external-icon); - --color-scheme: var(--light-color-scheme); - } -} - -@media (prefers-color-scheme: dark) { - :root { - --color-background: var(--dark-color-background); - --color-background-secondary: var(--dark-color-background-secondary); - --color-background-warning: var(--dark-color-background-warning); - --color-warning-text: var(--dark-color-warning-text); - --color-icon-background: var(--dark-color-icon-background); - --color-accent: var(--dark-color-accent); - --color-active-menu-item: var(--dark-color-active-menu-item); - --color-text: var(--dark-color-text); - --color-text-aside: var(--dark-color-text-aside); - --color-link: var(--dark-color-link); - - --color-ts-keyword: var(--dark-color-ts-keyword); - --color-ts-module: var(--dark-color-ts-module); - --color-ts-namespace: var(--dark-color-ts-namespace); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-enum-member: var(--dark-color-ts-enum-member); - --color-ts-variable: var(--dark-color-ts-variable); - --color-ts-function: var(--dark-color-ts-function); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-constructor: var(--dark-color-ts-constructor); - --color-ts-property: var(--dark-color-ts-property); - --color-ts-method: var(--dark-color-ts-method); - --color-ts-call-signature: var(--dark-color-ts-call-signature); - --color-ts-index-signature: var(--dark-color-ts-index-signature); - --color-ts-constructor-signature: var( - --dark-color-ts-constructor-signature - ); - --color-ts-parameter: var(--dark-color-ts-parameter); - --color-ts-type-parameter: var(--dark-color-ts-type-parameter); - --color-ts-accessor: var(--dark-color-ts-accessor); - --color-ts-get-signature: var(--dark-color-ts-get-signature); - --color-ts-set-signature: var(--dark-color-ts-set-signature); - --color-ts-type-alias: var(--dark-color-ts-type-alias); - - --external-icon: var(--dark-external-icon); - --color-scheme: var(--dark-color-scheme); - } -} - -html { - color-scheme: var(--color-scheme); -} - -body { - margin: 0; -} - -:root[data-theme="light"] { - --color-background: var(--light-color-background); - --color-background-secondary: var(--light-color-background-secondary); - --color-background-warning: var(--light-color-background-warning); - --color-warning-text: var(--light-color-warning-text); - --color-icon-background: var(--light-color-icon-background); - --color-accent: var(--light-color-accent); - --color-active-menu-item: var(--light-color-active-menu-item); - --color-text: var(--light-color-text); - --color-text-aside: var(--light-color-text-aside); - --color-link: var(--light-color-link); - - --color-ts-keyword: var(--light-color-ts-keyword); - --color-ts-module: var(--light-color-ts-module); - --color-ts-namespace: var(--light-color-ts-namespace); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-enum-member: var(--light-color-ts-enum-member); - --color-ts-variable: var(--light-color-ts-variable); - --color-ts-function: var(--light-color-ts-function); - --color-ts-class: var(--light-color-ts-class); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-constructor: var(--light-color-ts-constructor); - --color-ts-property: var(--light-color-ts-property); - --color-ts-method: var(--light-color-ts-method); - --color-ts-call-signature: var(--light-color-ts-call-signature); - --color-ts-index-signature: var(--light-color-ts-index-signature); - --color-ts-constructor-signature: var( - --light-color-ts-constructor-signature - ); - --color-ts-parameter: var(--light-color-ts-parameter); - --color-ts-type-parameter: var(--light-color-ts-type-parameter); - --color-ts-accessor: var(--light-color-ts-accessor); - --color-ts-get-signature: var(--light-color-ts-get-signature); - --color-ts-set-signature: var(--light-color-ts-set-signature); - --color-ts-type-alias: var(--light-color-ts-type-alias); - - --external-icon: var(--light-external-icon); - --color-scheme: var(--light-color-scheme); -} - -:root[data-theme="dark"] { - --color-background: var(--dark-color-background); - --color-background-secondary: var(--dark-color-background-secondary); - --color-background-warning: var(--dark-color-background-warning); - --color-warning-text: var(--dark-color-warning-text); - --color-icon-background: var(--dark-color-icon-background); - --color-accent: var(--dark-color-accent); - --color-active-menu-item: var(--dark-color-active-menu-item); - --color-text: var(--dark-color-text); - --color-text-aside: var(--dark-color-text-aside); - --color-link: var(--dark-color-link); - - --color-ts-keyword: var(--dark-color-ts-keyword); - --color-ts-module: var(--dark-color-ts-module); - --color-ts-namespace: var(--dark-color-ts-namespace); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-enum-member: var(--dark-color-ts-enum-member); - --color-ts-variable: var(--dark-color-ts-variable); - --color-ts-function: var(--dark-color-ts-function); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-constructor: var(--dark-color-ts-constructor); - --color-ts-property: var(--dark-color-ts-property); - --color-ts-method: var(--dark-color-ts-method); - --color-ts-call-signature: var(--dark-color-ts-call-signature); - --color-ts-index-signature: var(--dark-color-ts-index-signature); - --color-ts-constructor-signature: var( - --dark-color-ts-constructor-signature - ); - --color-ts-parameter: var(--dark-color-ts-parameter); - --color-ts-type-parameter: var(--dark-color-ts-type-parameter); - --color-ts-accessor: var(--dark-color-ts-accessor); - --color-ts-get-signature: var(--dark-color-ts-get-signature); - --color-ts-set-signature: var(--dark-color-ts-set-signature); - --color-ts-type-alias: var(--dark-color-ts-type-alias); - - --external-icon: var(--dark-external-icon); - --color-scheme: var(--dark-color-scheme); -} - -.always-visible, -.always-visible .tsd-signatures { - display: inherit !important; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - line-height: 1.2; -} - -h1 > a:not(.link), -h2 > a:not(.link), -h3 > a:not(.link), -h4 > a:not(.link), -h5 > a:not(.link), -h6 > a:not(.link) { - text-decoration: none; - color: var(--color-text); -} - -h1 { - font-size: 1.875rem; - margin: 0.67rem 0; -} - -h2 { - font-size: 1.5rem; - margin: 0.83rem 0; -} - -h3 { - font-size: 1.25rem; - margin: 1rem 0; -} - -h4 { - font-size: 1.05rem; - margin: 1.33rem 0; -} - -h5 { - font-size: 1rem; - margin: 1.5rem 0; -} - -h6 { - font-size: 0.875rem; - margin: 2.33rem 0; -} - -.uppercase { - text-transform: uppercase; -} - -dl, -menu, -ol, -ul { - margin: 1em 0; -} - -dd { - margin: 0 0 0 40px; -} - -.container { - max-width: 1700px; - padding: 0 2rem; -} - -/* Footer */ -footer { - border-top: 1px solid var(--color-accent); - padding-top: 1rem; - padding-bottom: 1rem; - max-height: 3.5rem; -} -.tsd-generator { - margin: 0 1em; -} - -.container-main { - margin: 0 auto; - /* toolbar, footer, margin */ - min-height: calc(100vh - 41px - 56px - 4rem); -} - -@keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@keyframes fade-out { - from { - opacity: 1; - visibility: visible; - } - to { - opacity: 0; - } -} -@keyframes fade-in-delayed { - 0% { - opacity: 0; - } - 33% { - opacity: 0; - } - 100% { - opacity: 1; - } -} -@keyframes fade-out-delayed { - 0% { - opacity: 1; - visibility: visible; - } - 66% { - opacity: 0; - } - 100% { - opacity: 0; - } -} -@keyframes pop-in-from-right { - from { - transform: translate(100%, 0); - } - to { - transform: translate(0, 0); - } -} -@keyframes pop-out-to-right { - from { - transform: translate(0, 0); - visibility: visible; - } - to { - transform: translate(100%, 0); - } -} -body { - background: var(--color-background); - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", - Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; - font-size: 16px; - color: var(--color-text); -} - -a { - color: var(--color-link); - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -a.external[target="_blank"] { - background-image: var(--external-icon); - background-position: top 3px right; - background-repeat: no-repeat; - padding-right: 13px; -} - -code, -pre { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - padding: 0.2em; - margin: 0; - font-size: 0.875rem; - border-radius: 0.8em; -} - -pre { - position: relative; - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; - padding: 10px; - border: 1px solid var(--color-accent); -} -pre code { - padding: 0; - font-size: 100%; -} -pre > button { - position: absolute; - top: 10px; - right: 10px; - opacity: 0; - transition: opacity 0.1s; - box-sizing: border-box; -} -pre:hover > button, -pre > button.visible { - opacity: 1; -} - -blockquote { - margin: 1em 0; - padding-left: 1em; - border-left: 4px solid gray; -} - -.tsd-typography { - line-height: 1.333em; -} -.tsd-typography ul { - list-style: square; - padding: 0 0 0 20px; - margin: 0; -} -.tsd-typography .tsd-index-panel h3, -.tsd-index-panel .tsd-typography h3, -.tsd-typography h4, -.tsd-typography h5, -.tsd-typography h6 { - font-size: 1em; -} -.tsd-typography h5, -.tsd-typography h6 { - font-weight: normal; -} -.tsd-typography p, -.tsd-typography ul, -.tsd-typography ol { - margin: 1em 0; -} -.tsd-typography table { - border-collapse: collapse; - border: none; -} -.tsd-typography td, -.tsd-typography th { - padding: 6px 13px; - border: 1px solid var(--color-accent); -} -.tsd-typography thead, -.tsd-typography tr:nth-child(even) { - background-color: var(--color-background-secondary); -} - -.tsd-breadcrumb { - margin: 0; - padding: 0; - color: var(--color-text-aside); -} -.tsd-breadcrumb a { - color: var(--color-text-aside); - text-decoration: none; -} -.tsd-breadcrumb a:hover { - text-decoration: underline; -} -.tsd-breadcrumb li { - display: inline; -} -.tsd-breadcrumb li:after { - content: " / "; -} - -.tsd-comment-tags { - display: flex; - flex-direction: column; -} -dl.tsd-comment-tag-group { - display: flex; - align-items: center; - overflow: hidden; - margin: 0.5em 0; -} -dl.tsd-comment-tag-group dt { - display: flex; - margin-right: 0.5em; - font-size: 0.875em; - font-weight: normal; -} -dl.tsd-comment-tag-group dd { - margin: 0; -} -code.tsd-tag { - padding: 0.25em 0.4em; - border: 0.1em solid var(--color-accent); - margin-right: 0.25em; - font-size: 70%; -} -h1 code.tsd-tag:first-of-type { - margin-left: 0.25em; -} - -dl.tsd-comment-tag-group dd:before, -dl.tsd-comment-tag-group dd:after { - content: " "; -} -dl.tsd-comment-tag-group dd pre, -dl.tsd-comment-tag-group dd:after { - clear: both; -} -dl.tsd-comment-tag-group p { - margin: 0; -} - -.tsd-panel.tsd-comment .lead { - font-size: 1.1em; - line-height: 1.333em; - margin-bottom: 2em; -} -.tsd-panel.tsd-comment .lead:last-child { - margin-bottom: 0; -} - -.tsd-filter-visibility h4 { - font-size: 1rem; - padding-top: 0.75rem; - padding-bottom: 0.5rem; - margin: 0; -} -.tsd-filter-item:not(:last-child) { - margin-bottom: 0.5rem; -} -.tsd-filter-input { - display: flex; - width: fit-content; - width: -moz-fit-content; - align-items: center; - user-select: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - cursor: pointer; -} -.tsd-filter-input input[type="checkbox"] { - cursor: pointer; - position: absolute; - width: 1.5em; - height: 1.5em; - opacity: 0; -} -.tsd-filter-input input[type="checkbox"]:disabled { - pointer-events: none; -} -.tsd-filter-input svg { - cursor: pointer; - width: 1.5em; - height: 1.5em; - margin-right: 0.5em; - border-radius: 0.33em; - /* Leaving this at full opacity breaks event listeners on Firefox. - Don't remove unless you know what you're doing. */ - opacity: 0.99; -} -.tsd-filter-input input[type="checkbox"]:focus + svg { - transform: scale(0.95); -} -.tsd-filter-input input[type="checkbox"]:focus:not(:focus-visible) + svg { - transform: scale(1); -} -.tsd-checkbox-background { - fill: var(--color-accent); -} -input[type="checkbox"]:checked ~ svg .tsd-checkbox-checkmark { - stroke: var(--color-text); -} -.tsd-filter-input input:disabled ~ svg > .tsd-checkbox-background { - fill: var(--color-background); - stroke: var(--color-accent); - stroke-width: 0.25rem; -} -.tsd-filter-input input:disabled ~ svg > .tsd-checkbox-checkmark { - stroke: var(--color-accent); -} - -.tsd-theme-toggle { - padding-top: 0.75rem; -} -.tsd-theme-toggle > h4 { - display: inline; - vertical-align: middle; - margin-right: 0.75rem; -} - -.tsd-hierarchy { - list-style: square; - margin: 0; -} -.tsd-hierarchy .target { - font-weight: bold; -} - -.tsd-full-hierarchy:not(:last-child) { - margin-bottom: 1em; - padding-bottom: 1em; - border-bottom: 1px solid var(--color-accent); -} -.tsd-full-hierarchy, -.tsd-full-hierarchy ul { - list-style: none; - margin: 0; - padding: 0; -} -.tsd-full-hierarchy ul { - padding-left: 1.5rem; -} -.tsd-full-hierarchy a { - padding: 0.25rem 0 !important; - font-size: 1rem; - display: inline-flex; - align-items: center; - color: var(--color-text); -} - -.tsd-panel-group.tsd-index-group { - margin-bottom: 0; -} -.tsd-index-panel .tsd-index-list { - list-style: none; - line-height: 1.333em; - margin: 0; - padding: 0.25rem 0 0 0; - overflow: hidden; - display: grid; - grid-template-columns: repeat(3, 1fr); - column-gap: 1rem; - grid-template-rows: auto; -} -@media (max-width: 1024px) { - .tsd-index-panel .tsd-index-list { - grid-template-columns: repeat(2, 1fr); - } -} -@media (max-width: 768px) { - .tsd-index-panel .tsd-index-list { - grid-template-columns: repeat(1, 1fr); - } -} -.tsd-index-panel .tsd-index-list li { - -webkit-page-break-inside: avoid; - -moz-page-break-inside: avoid; - -ms-page-break-inside: avoid; - -o-page-break-inside: avoid; - page-break-inside: avoid; -} - -.tsd-flag { - display: inline-block; - padding: 0.25em 0.4em; - border-radius: 4px; - color: var(--color-comment-tag-text); - background-color: var(--color-comment-tag); - text-indent: 0; - font-size: 75%; - line-height: 1; - font-weight: normal; -} - -.tsd-anchor { - position: relative; - top: -100px; -} - -.tsd-member { - position: relative; -} -.tsd-member .tsd-anchor + h3 { - display: flex; - align-items: center; - margin-top: 0; - margin-bottom: 0; - border-bottom: none; -} - -.tsd-navigation.settings { - margin: 1rem 0; -} -.tsd-navigation > a, -.tsd-navigation .tsd-accordion-summary { - width: calc(100% - 0.25rem); - display: flex; - align-items: center; -} -.tsd-navigation a, -.tsd-navigation summary > span, -.tsd-page-navigation a { - display: flex; - width: calc(100% - 0.25rem); - align-items: center; - padding: 0.25rem; - color: var(--color-text); - text-decoration: none; - box-sizing: border-box; -} -.tsd-navigation a.current, -.tsd-page-navigation a.current { - background: var(--color-active-menu-item); -} -.tsd-navigation a:hover, -.tsd-page-navigation a:hover { - text-decoration: underline; -} -.tsd-navigation ul, -.tsd-page-navigation ul { - margin-top: 0; - margin-bottom: 0; - padding: 0; - list-style: none; -} -.tsd-navigation li, -.tsd-page-navigation li { - padding: 0; - max-width: 100%; -} -.tsd-nested-navigation { - margin-left: 3rem; -} -.tsd-nested-navigation > li > details { - margin-left: -1.5rem; -} -.tsd-small-nested-navigation { - margin-left: 1.5rem; -} -.tsd-small-nested-navigation > li > details { - margin-left: -1.5rem; -} - -.tsd-page-navigation ul { - padding-left: 1.75rem; -} - -#tsd-sidebar-links a { - margin-top: 0; - margin-bottom: 0.5rem; - line-height: 1.25rem; -} -#tsd-sidebar-links a:last-of-type { - margin-bottom: 0; -} - -a.tsd-index-link { - padding: 0.25rem 0 !important; - font-size: 1rem; - line-height: 1.25rem; - display: inline-flex; - align-items: center; - color: var(--color-text); -} -.tsd-accordion-summary { - list-style-type: none; /* hide marker on non-safari */ - outline: none; /* broken on safari, so just hide it */ -} -.tsd-accordion-summary::-webkit-details-marker { - display: none; /* hide marker on safari */ -} -.tsd-accordion-summary, -.tsd-accordion-summary a { - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - - cursor: pointer; -} -.tsd-accordion-summary a { - width: calc(100% - 1.5rem); -} -.tsd-accordion-summary > * { - margin-top: 0; - margin-bottom: 0; - padding-top: 0; - padding-bottom: 0; -} -.tsd-index-accordion .tsd-accordion-summary > svg { - margin-left: 0.25rem; -} -.tsd-index-content > :not(:first-child) { - margin-top: 0.75rem; -} -.tsd-index-heading { - margin-top: 1.5rem; - margin-bottom: 0.75rem; -} - -.tsd-kind-icon { - margin-right: 0.5rem; - width: 1.25rem; - height: 1.25rem; - min-width: 1.25rem; - min-height: 1.25rem; -} -.tsd-kind-icon path { - transform-origin: center; - transform: scale(1.1); -} -.tsd-signature > .tsd-kind-icon { - margin-right: 0.8rem; -} - -.tsd-panel { - margin-bottom: 2.5rem; -} -.tsd-panel.tsd-member { - margin-bottom: 4rem; -} -.tsd-panel:empty { - display: none; -} -.tsd-panel > h1, -.tsd-panel > h2, -.tsd-panel > h3 { - margin: 1.5rem -1.5rem 0.75rem -1.5rem; - padding: 0 1.5rem 0.75rem 1.5rem; -} -.tsd-panel > h1.tsd-before-signature, -.tsd-panel > h2.tsd-before-signature, -.tsd-panel > h3.tsd-before-signature { - margin-bottom: 0; - border-bottom: none; -} - -.tsd-panel-group { - margin: 4rem 0; -} -.tsd-panel-group.tsd-index-group { - margin: 2rem 0; -} -.tsd-panel-group.tsd-index-group details { - margin: 2rem 0; -} - -#tsd-search { - transition: background-color 0.2s; -} -#tsd-search .title { - position: relative; - z-index: 2; -} -#tsd-search .field { - position: absolute; - left: 0; - top: 0; - right: 2.5rem; - height: 100%; -} -#tsd-search .field input { - box-sizing: border-box; - position: relative; - top: -50px; - z-index: 1; - width: 100%; - padding: 0 10px; - opacity: 0; - outline: 0; - border: 0; - background: transparent; - color: var(--color-text); -} -#tsd-search .field label { - position: absolute; - overflow: hidden; - right: -40px; -} -#tsd-search .field input, -#tsd-search .title, -#tsd-toolbar-links a { - transition: opacity 0.2s; -} -#tsd-search .results { - position: absolute; - visibility: hidden; - top: 40px; - width: 100%; - margin: 0; - padding: 0; - list-style: none; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); -} -#tsd-search .results li { - background-color: var(--color-background); - line-height: initial; - padding: 4px; -} -#tsd-search .results li:nth-child(even) { - background-color: var(--color-background-secondary); -} -#tsd-search .results li.state { - display: none; -} -#tsd-search .results li.current:not(.no-results), -#tsd-search .results li:hover:not(.no-results) { - background-color: var(--color-accent); -} -#tsd-search .results a { - display: flex; - align-items: center; - padding: 0.25rem; - box-sizing: border-box; -} -#tsd-search .results a:before { - top: 10px; -} -#tsd-search .results span.parent { - color: var(--color-text-aside); - font-weight: normal; -} -#tsd-search.has-focus { - background-color: var(--color-accent); -} -#tsd-search.has-focus .field input { - top: 0; - opacity: 1; -} -#tsd-search.has-focus .title, -#tsd-search.has-focus #tsd-toolbar-links a { - z-index: 0; - opacity: 0; -} -#tsd-search.has-focus .results { - visibility: visible; -} -#tsd-search.loading .results li.state.loading { - display: block; -} -#tsd-search.failure .results li.state.failure { - display: block; -} - -#tsd-toolbar-links { - position: absolute; - top: 0; - right: 2rem; - height: 100%; - display: flex; - align-items: center; - justify-content: flex-end; -} -#tsd-toolbar-links a { - margin-left: 1.5rem; -} -#tsd-toolbar-links a:hover { - text-decoration: underline; -} - -.tsd-signature { - margin: 0 0 1rem 0; - padding: 1rem 0.5rem; - border: 1px solid var(--color-accent); - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - font-size: 14px; - overflow-x: auto; -} - -.tsd-signature-keyword { - color: var(--color-ts-keyword); - font-weight: normal; -} - -.tsd-signature-symbol { - color: var(--color-text-aside); - font-weight: normal; -} - -.tsd-signature-type { - font-style: italic; - font-weight: normal; -} - -.tsd-signatures { - padding: 0; - margin: 0 0 1em 0; - list-style-type: none; -} -.tsd-signatures .tsd-signature { - margin: 0; - border-color: var(--color-accent); - border-width: 1px 0; - transition: background-color 0.1s; -} -.tsd-description .tsd-signatures .tsd-signature { - border-width: 1px; -} - -ul.tsd-parameter-list, -ul.tsd-type-parameter-list { - list-style: square; - margin: 0; - padding-left: 20px; -} -ul.tsd-parameter-list > li.tsd-parameter-signature, -ul.tsd-type-parameter-list > li.tsd-parameter-signature { - list-style: none; - margin-left: -20px; -} -ul.tsd-parameter-list h5, -ul.tsd-type-parameter-list h5 { - font-size: 16px; - margin: 1em 0 0.5em 0; -} -.tsd-sources { - margin-top: 1rem; - font-size: 0.875em; -} -.tsd-sources a { - color: var(--color-text-aside); - text-decoration: underline; -} -.tsd-sources ul { - list-style: none; - padding: 0; -} - -.tsd-page-toolbar { - position: sticky; - z-index: 1; - top: 0; - left: 0; - width: 100%; - color: var(--color-text); - background: var(--color-background-secondary); - border-bottom: 1px var(--color-accent) solid; - transition: transform 0.3s ease-in-out; -} -.tsd-page-toolbar a { - color: var(--color-text); - text-decoration: none; -} -.tsd-page-toolbar a.title { - font-weight: bold; -} -.tsd-page-toolbar a.title:hover { - text-decoration: underline; -} -.tsd-page-toolbar .tsd-toolbar-contents { - display: flex; - justify-content: space-between; - height: 2.5rem; - margin: 0 auto; -} -.tsd-page-toolbar .table-cell { - position: relative; - white-space: nowrap; - line-height: 40px; -} -.tsd-page-toolbar .table-cell:first-child { - width: 100%; -} -.tsd-page-toolbar .tsd-toolbar-icon { - box-sizing: border-box; - line-height: 0; - padding: 12px 0; -} - -.tsd-widget { - display: inline-block; - overflow: hidden; - opacity: 0.8; - height: 40px; - transition: - opacity 0.1s, - background-color 0.2s; - vertical-align: bottom; - cursor: pointer; -} -.tsd-widget:hover { - opacity: 0.9; -} -.tsd-widget.active { - opacity: 1; - background-color: var(--color-accent); -} -.tsd-widget.no-caption { - width: 40px; -} -.tsd-widget.no-caption:before { - margin: 0; -} - -.tsd-widget.options, -.tsd-widget.menu { - display: none; -} -input[type="checkbox"] + .tsd-widget:before { - background-position: -120px 0; -} -input[type="checkbox"]:checked + .tsd-widget:before { - background-position: -160px 0; -} - -img { - max-width: 100%; -} - -.tsd-anchor-icon { - display: inline-flex; - align-items: center; - margin-left: 0.5rem; - vertical-align: middle; - color: var(--color-text); -} - -.tsd-anchor-icon svg { - width: 1em; - height: 1em; - visibility: hidden; -} - -.tsd-anchor-link:hover > .tsd-anchor-icon svg { - visibility: visible; -} - -.deprecated { - text-decoration: line-through !important; -} - -.warning { - padding: 1rem; - color: var(--color-warning-text); - background: var(--color-background-warning); -} - -.tsd-kind-project { - color: var(--color-ts-project); -} -.tsd-kind-module { - color: var(--color-ts-module); -} -.tsd-kind-namespace { - color: var(--color-ts-namespace); -} -.tsd-kind-enum { - color: var(--color-ts-enum); -} -.tsd-kind-enum-member { - color: var(--color-ts-enum-member); -} -.tsd-kind-variable { - color: var(--color-ts-variable); -} -.tsd-kind-function { - color: var(--color-ts-function); -} -.tsd-kind-class { - color: var(--color-ts-class); -} -.tsd-kind-interface { - color: var(--color-ts-interface); -} -.tsd-kind-constructor { - color: var(--color-ts-constructor); -} -.tsd-kind-property { - color: var(--color-ts-property); -} -.tsd-kind-method { - color: var(--color-ts-method); -} -.tsd-kind-call-signature { - color: var(--color-ts-call-signature); -} -.tsd-kind-index-signature { - color: var(--color-ts-index-signature); -} -.tsd-kind-constructor-signature { - color: var(--color-ts-constructor-signature); -} -.tsd-kind-parameter { - color: var(--color-ts-parameter); -} -.tsd-kind-type-literal { - color: var(--color-ts-type-literal); -} -.tsd-kind-type-parameter { - color: var(--color-ts-type-parameter); -} -.tsd-kind-accessor { - color: var(--color-ts-accessor); -} -.tsd-kind-get-signature { - color: var(--color-ts-get-signature); -} -.tsd-kind-set-signature { - color: var(--color-ts-set-signature); -} -.tsd-kind-type-alias { - color: var(--color-ts-type-alias); -} - -/* if we have a kind icon, don't color the text by kind */ -.tsd-kind-icon ~ span { - color: var(--color-text); -} - -* { - scrollbar-width: thin; - scrollbar-color: var(--color-accent) var(--color-icon-background); -} - -*::-webkit-scrollbar { - width: 0.75rem; -} - -*::-webkit-scrollbar-track { - background: var(--color-icon-background); -} - -*::-webkit-scrollbar-thumb { - background-color: var(--color-accent); - border-radius: 999rem; - border: 0.25rem solid var(--color-icon-background); -} - -/* mobile */ -@media (max-width: 769px) { - .tsd-widget.options, - .tsd-widget.menu { - display: inline-block; - } - - .container-main { - display: flex; - } - html .col-content { - float: none; - max-width: 100%; - width: 100%; - } - html .col-sidebar { - position: fixed !important; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - z-index: 1024; - top: 0 !important; - bottom: 0 !important; - left: auto !important; - right: 0 !important; - padding: 1.5rem 1.5rem 0 0; - width: 75vw; - visibility: hidden; - background-color: var(--color-background); - transform: translate(100%, 0); - } - html .col-sidebar > *:last-child { - padding-bottom: 20px; - } - html .overlay { - content: ""; - display: block; - position: fixed; - z-index: 1023; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.75); - visibility: hidden; - } - - .to-has-menu .overlay { - animation: fade-in 0.4s; - } - - .to-has-menu .col-sidebar { - animation: pop-in-from-right 0.4s; - } - - .from-has-menu .overlay { - animation: fade-out 0.4s; - } - - .from-has-menu .col-sidebar { - animation: pop-out-to-right 0.4s; - } - - .has-menu body { - overflow: hidden; - } - .has-menu .overlay { - visibility: visible; - } - .has-menu .col-sidebar { - visibility: visible; - transform: translate(0, 0); - display: flex; - flex-direction: column; - gap: 1.5rem; - max-height: 100vh; - padding: 1rem 2rem; - } - .has-menu .tsd-navigation { - max-height: 100%; - } -} - -/* one sidebar */ -@media (min-width: 770px) { - .container-main { - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); - grid-template-areas: "sidebar content"; - margin: 2rem auto; - } - - .col-sidebar { - grid-area: sidebar; - } - .col-content { - grid-area: content; - padding: 0 1rem; - } -} -@media (min-width: 770px) and (max-width: 1399px) { - .col-sidebar { - max-height: calc(100vh - 2rem - 42px); - overflow: auto; - position: sticky; - top: 42px; - padding-top: 1rem; - } - .site-menu { - margin-top: 1rem; - } -} - -/* two sidebars */ -@media (min-width: 1200px) { - .container-main { - grid-template-columns: minmax(0, 1fr) minmax(0, 2.5fr) minmax(0, 20rem); - grid-template-areas: "sidebar content toc"; - } - - .col-sidebar { - display: contents; - } - - .page-menu { - grid-area: toc; - padding-left: 1rem; - } - .site-menu { - grid-area: sidebar; - } - - .site-menu { - margin-top: 1rem 0; - } - - .page-menu, - .site-menu { - max-height: calc(100vh - 2rem - 42px); - overflow: auto; - position: sticky; - top: 42px; - } -} diff --git a/docs/functions/index.index.html b/docs/functions/index.index.html deleted file mode 100644 index d0053d87..00000000 --- a/docs/functions/index.index.html +++ /dev/null @@ -1,12 +0,0 @@ -index | React18 Global Store
  • Use this hook similar to useState hook. -The difference is that you need to pass a -unique key - unique across the app to make -this state accessible to all client components.

    -

    Type Parameters

    • T

    Parameters

    • key: string

      Unique key to identify the store.

      -
    • Optional value: ValueType<T>

      Initial value of the store.

      -

    Returns [T, SetStateAction<T>]

      -
    • A tuple (Ordered sequance of values) containing the state and a function to set the state.
    • -
    -

    Example

    const [state, setState] = useRGS<number>("counter", 1);
    -
    -
\ No newline at end of file diff --git a/docs/functions/plugins_persist.persist.html b/docs/functions/plugins_persist.persist.html deleted file mode 100644 index 90b671dd..00000000 --- a/docs/functions/plugins_persist.persist.html +++ /dev/null @@ -1,3 +0,0 @@ -persist | React18 Global Store
\ No newline at end of file diff --git a/docs/functions/utils.createHook.html b/docs/functions/utils.createHook.html deleted file mode 100644 index bab931cf..00000000 --- a/docs/functions/utils.createHook.html +++ /dev/null @@ -1,2 +0,0 @@ -createHook | React18 Global Store
\ No newline at end of file diff --git a/docs/functions/utils.createSetter.html b/docs/functions/utils.createSetter.html deleted file mode 100644 index c01d8397..00000000 --- a/docs/functions/utils.createSetter.html +++ /dev/null @@ -1,2 +0,0 @@ -createSetter | React18 Global Store
\ No newline at end of file diff --git a/docs/functions/utils.createSubcriber.html b/docs/functions/utils.createSubcriber.html deleted file mode 100644 index bb25b5c4..00000000 --- a/docs/functions/utils.createSubcriber.html +++ /dev/null @@ -1,2 +0,0 @@ -createSubcriber | React18 Global Store
\ No newline at end of file diff --git a/docs/functions/utils.initWithPlugins.html b/docs/functions/utils.initWithPlugins.html deleted file mode 100644 index 6c270a27..00000000 --- a/docs/functions/utils.initWithPlugins.html +++ /dev/null @@ -1,2 +0,0 @@ -initWithPlugins | React18 Global Store
  • Initialize the named store when invoked for the first time.

    -

    Type Parameters

    • T

    Parameters

    • key: string
    • Optional value: ValueType<T>
    • plugins: Plugin<T>[] = []
    • doNotInit: boolean = false

    Returns void

\ No newline at end of file diff --git a/docs/functions/utils.useRGSWithPlugins.html b/docs/functions/utils.useRGSWithPlugins.html deleted file mode 100644 index 94e48cba..00000000 --- a/docs/functions/utils.useRGSWithPlugins.html +++ /dev/null @@ -1,14 +0,0 @@ -useRGSWithPlugins | React18 Global Store
  • Use this hook similar to useState hook. -The difference is that you need to pass a -unique key - unique across the app to make -this state accessible to all client components.

    -

    Type Parameters

    • T

    Parameters

    • key: string

      Unique key to identify the store.

      -
    • Optional value: ValueType<T>

      Initial value of the store.

      -
    • Optional plugins: Plugin<T>[]

      Plugins to be applied to the store.

      -
    • doNotInit: boolean = false

      Do not initialize the store. Useful when you want to initialize the store later. Note that the setter function is not available until the store is initialized.

      -

    Returns [T, SetStateAction<T>]

      -
    • A tuple (Ordered sequance of values) containing the state and a function to set the state.
    • -
    -

    Example

    const [state, setState] = useRGS<number>("counter", 1);
    -
    -
\ No newline at end of file diff --git a/docs/functions/with_plugins.create.html b/docs/functions/with_plugins.create.html deleted file mode 100644 index 39270326..00000000 --- a/docs/functions/with_plugins.create.html +++ /dev/null @@ -1,10 +0,0 @@ -create | React18 Global Store
  • Creates a store with plugins.

    -

    Type Parameters

    • T

    Parameters

    • key: string

      Unique key to identify the store.

      -
    • Optional value: T

      Initial value of the store.

      -
    • Optional plugins: Plugin<T>[]

      Plugins to be applied to the store.

      -

    Returns (() => [T, SetStateAction<T>])

      -
    • A hook function that returns a tuple (Ordered sequence of values) containing the state and a function to set the state.
    • -
    -

    Example

    // in hook file, e.g., store.ts
    export const useMyRGS = create<type>(key, value, plugins);

    // in component file
    const [state, setState] = useMyRGS(); -
    -
\ No newline at end of file diff --git a/docs/functions/with_plugins.withPlugins.html b/docs/functions/with_plugins.withPlugins.html deleted file mode 100644 index 4878e349..00000000 --- a/docs/functions/with_plugins.withPlugins.html +++ /dev/null @@ -1,4 +0,0 @@ -withPlugins | React18 Global Store
  • Creates a hook similar to useRGS, but with plugins to be applied on first invocation.

    -

    Type Parameters

    • T

    Parameters

    • plugins: Plugin<T>[]

      Plugins to be applied to the store.

      -

    Returns (<U>(key, value?, doNotInit?) => [U, SetStateAction<U>])

    A hook that automatically initializes the store (if not already initialized) with the given plugins.

    -
\ No newline at end of file diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 7c316f02..00000000 --- a/docs/index.html +++ /dev/null @@ -1,33 +0,0 @@ -React18 Global Store

React18 Global Store

React18GlobalStore

test Maintainability codecov Version Downloads npm bundle size Gitpod ready-to-code

-

Motivation

I've developed fantastic libraries leveraging React18 features using Zustand, and they performed admirably. However, when attempting to import from specific folders for better tree-shaking, the libraries encountered issues. Each import resulted in a separate Zustand store being created, leading to increased package size.

-

As a solution, I set out to create a lightweight, bare minimum store that facilitates shared state even when importing components from separate files, optimizing tree-shaking.

-

Features

✅ Full TypeScript Support

-

✅ Unleash the full power of React18 Server components

-

✅ Compatible with all build systems/tools/frameworks for React18

-

✅ Documented with Typedoc (Docs)

-

✅ Examples for Next.js, Vite, and Remix

-

Simple Global State Shared Across Multiple Components

Utilize this hook similarly to the useState hook. However, ensure to pass a unique key, unique across the app, to identify and make this state accessible to all client components.

-
const [state, setState] = useRGS<number>("counter", 1);
-
-

or

-
const [state, setState] = useRGS<number>("counter", () => 1);
-
-
-

For detailed instructions, see Getting Started

-
-

Using Plugins

Enhance the functionality of the store by leveraging either the create function, withPlugins function, or the useRGSWithPlugins hook from r18gs/dist/with-plugins, enabling features such as storing to local storage, among others.

-
// store.ts
import { create } from "r18gs/dist/with-plugins";
import { persist } from "r18gs/dist/plugins"; /** You can create your own plugin or import third-party plugins */

export const useMyPersistentCounterStore = create<number>("persistent-counter", 0, [persist()]); -
-

Now, you can utilize useMyPersistentCounterStore similarly to useState without specifying an initial value.

-
const [persistedCount, setPersistedCount] = useMyPersistentCounterStore();
-
-
-

For detailed instructions, see Leveraging Plugins

-
-

Contributing

See contributing.md

-

🤩 Don't forget to star this repo!

Interested in hands-on courses for getting started with Turborepo? Check out React and Next.js with TypeScript and The Game of Chess with Next.js, React and TypeScript

-

Repo Stats

-

License

Licensed under the MPL 2.0 open source license.

-
- -

with 💖 by Mayank Kumar Chaudhari

\ No newline at end of file diff --git a/docs/interfaces/plugins_persist.PersistOptions.html b/docs/interfaces/plugins_persist.PersistOptions.html deleted file mode 100644 index 4395c940..00000000 --- a/docs/interfaces/plugins_persist.PersistOptions.html +++ /dev/null @@ -1,7 +0,0 @@ -PersistOptions | React18 Global Store
interface PersistOptions {
    storage?: "local" | "session" | "cookie";
    sync?: boolean;
}

Properties

Properties

storage?: "local" | "session" | "cookie"

Default Value

local
-
-
sync?: boolean

Default Value

true
-
-
\ No newline at end of file diff --git a/docs/md-docs/1.getting-started.md b/docs/md-docs/1.getting-started.md deleted file mode 100644 index e951f864..00000000 --- a/docs/md-docs/1.getting-started.md +++ /dev/null @@ -1,94 +0,0 @@ -# Quick Start - -Welcome to the quick guide for using this library. - -## Installation - -To get started, you can install the package via your preferred package manager. Here are a few examples: - -```bash -$ pnpm add r18gs -``` - -or - -```bash -$ npm install r18gs -``` - -or - -```bash -$ yarn add r18gs -``` - -## Usage - -Utilize this hook similarly to the `useState` hook. However, ensure to pass a unique key, unique across the app, to identify and make this state accessible to all client components. - -```tsx -const [state, setState] = useRGS("counter", 1); -``` - -You can access the same state across all client-side components using a unique key. - -> It's advisable to store your keys in a separate file to prevent typos and unnecessary conflicts. - -### Initializing the state with a function - -In some cases you might want to initialize the state with a function, for example, when reading from `localStorage`. We support initializer function as well. - -```tsx -const [state, setState] = useRGS("counter", () => - typeof localStorage === "undefined" ? 1 : localStorage.getItem("counter") ?? 1, -); -``` - -### Example - -```tsx -// constants/global-states.ts -export const COUNTER = "counter"; -``` - -```tsx -// components/display.tsx -"use client"; - -import useRGS from "r18gs"; -import { COUNTER } from "../constants/global-states"; - -export default function Display() { - const [count] = useRGS(COUNTER); - return ( -
-

Client Component 2

- {count} -
- ); -} -``` - -```tsx -// components/counter.tsx -"use client"; - -import useRGS from "r18gs"; -import { COUNTER } from "../constants/global-states"; - -export default function Counter() { - const [count, setCount] = useRGS(COUNTER, 0); - return ( -
-

Client Component 1

- { - setCount(parseInt(e.target.value.trim())); - }} - type="number" - value={count} - /> -
- ); -} -``` diff --git a/docs/md-docs/2.leveraging-plugins.md b/docs/md-docs/2.leveraging-plugins.md deleted file mode 100644 index e8bd53c2..00000000 --- a/docs/md-docs/2.leveraging-plugins.md +++ /dev/null @@ -1,64 +0,0 @@ -# Leveraging Plugins - -Enhance your store's functionality by utilizing either the `create` function, `withPlugins` function, or the `useRGSWithPlugins` hook from `r18gs/dist/with-plugins`. This enables features such as storing to local storage, among others. - -## Creating a Store with the `create` Function - -```tsx -// store.ts -import { create } from "r18gs/dist/with-plugins"; -import { persist } from "r18gs/dist/plugins"; /** You can create your own plugin or import third-party plugins */ - -export const useMyPersistentCounterStore = create("persistent-counter", 0, [persist()]); -``` - -Now you can utilize `useMyPersistentCounterStore` similar to `useState` without specifying an initial value. - -```tsx -// inside your component -const [persistedCount, setPersistedCount] = useMyPersistentCounterStore(); -``` - -## Utilizing the `useRGSWithPlugins` Hook - -This function is beneficial if your requirements dictate that your `key` and/or initial value will depend on some props, etc. Or for some other reason you want to initialize the store from within a component (You need to use some variables available inside the component). - -```tsx -import { useRGSWithPlugins } from "r18gs/dist/with-plugin"; - -export function MyComponent(props: MyComponentProps) { - const [state, setState] = useRGSWithPlugins( - props.key, - props.initialVal, - props.plugins, - props.doNotInit, - ); - // ... -} -``` - -### `doNotInit` - -In some cases, you may not want to initialize the store immediately. In such cases, you can pass the fourth argument (`doNotInit`) as `true`. The default value is false. - -- When this argument is set to `true`, the store is created, but the setter function is set to null. Thus, you can access the initial value set by the first component that triggered this hook. However, it cannot be modified until the store is initialized, i.e., the hook is invoked by a component setting `doNotInit` to false (or skipping this argument). - -**Use case**: When you need that the store be used in many components, however, it should be initialized in a particular component only. - -## Creating a Custom Hook using the `withPlugins` Higher-Order Function - -This is a utility function that will be very helpful when you want to use the `useRGSWithPlugins` hook with the same plugins in multiple components. - -```ts -// custom hook file, e.g., store.ts -export const useMyRGS = withPlugins([plugin1, plugin2, ...]); -``` - -```tsx -export function MyComponent(props: MyComponentProps) { - const [state, setState] = useMyRGS(props.key, props.initialVal, props.doNotInit); - // ... -} -``` - -You can also create your own plugins. Refer to [Creating Plugins](./3.creating-plugins.md). diff --git a/docs/md-docs/3.creating-plugins.md b/docs/md-docs/3.creating-plugins.md deleted file mode 100644 index b7d3cbd8..00000000 --- a/docs/md-docs/3.creating-plugins.md +++ /dev/null @@ -1 +0,0 @@ -# Creating Plugins diff --git a/docs/modules/Guides.html b/docs/modules/Guides.html deleted file mode 100644 index 5ebe5f18..00000000 --- a/docs/modules/Guides.html +++ /dev/null @@ -1,3 +0,0 @@ -Guides | React18 Global Store
\ No newline at end of file diff --git a/docs/modules/index.html b/docs/modules/index.html deleted file mode 100644 index a9afbdbc..00000000 --- a/docs/modules/index.html +++ /dev/null @@ -1,5 +0,0 @@ -index | React18 Global Store

References

Functions

References

Re-exports Plugin
Re-exports SetStateAction
Re-exports SetterArgType
\ No newline at end of file diff --git a/docs/modules/plugins.html b/docs/modules/plugins.html deleted file mode 100644 index 1323b11e..00000000 --- a/docs/modules/plugins.html +++ /dev/null @@ -1,3 +0,0 @@ -plugins | React18 Global Store

References

References

Re-exports PersistOptions
Re-exports persist
\ No newline at end of file diff --git a/docs/modules/plugins_persist.html b/docs/modules/plugins_persist.html deleted file mode 100644 index bf17356d..00000000 --- a/docs/modules/plugins_persist.html +++ /dev/null @@ -1,3 +0,0 @@ -plugins/persist | React18 Global Store

Index

Interfaces

Functions

\ No newline at end of file diff --git a/docs/modules/utils._internal_.html b/docs/modules/utils._internal_.html deleted file mode 100644 index 280615c8..00000000 --- a/docs/modules/utils._internal_.html +++ /dev/null @@ -1,6 +0,0 @@ -<internal> | React18 Global Store
\ No newline at end of file diff --git a/docs/modules/utils.html b/docs/modules/utils.html deleted file mode 100644 index 65426f1e..00000000 --- a/docs/modules/utils.html +++ /dev/null @@ -1,12 +0,0 @@ -utils | React18 Global Store
\ No newline at end of file diff --git a/docs/modules/with_plugins.html b/docs/modules/with_plugins.html deleted file mode 100644 index b2c95d3c..00000000 --- a/docs/modules/with_plugins.html +++ /dev/null @@ -1,4 +0,0 @@ -with-plugins | React18 Global Store

References

Functions

References

Re-exports useRGSWithPlugins
\ No newline at end of file diff --git a/docs/types/utils.Plugin.html b/docs/types/utils.Plugin.html deleted file mode 100644 index 382c1451..00000000 --- a/docs/types/utils.Plugin.html +++ /dev/null @@ -1 +0,0 @@ -Plugin | React18 Global Store
Plugin<T>: {
    init?: ((key, value, mutate) => void);
    onChange?: ((key, value?) => void);
}

Type Parameters

  • T

Type declaration

  • Optional init?: ((key, value, mutate) => void)
      • (key, value, mutate): void
      • Parameters

        • key: string
        • value: T | undefined
        • mutate: Mutate<T>

        Returns void

  • Optional onChange?: ((key, value?) => void)
      • (key, value?): void
      • Parameters

        • key: string
        • Optional value: T

        Returns void

\ No newline at end of file diff --git a/docs/types/utils.SetStateAction.html b/docs/types/utils.SetStateAction.html deleted file mode 100644 index 2316b84c..00000000 --- a/docs/types/utils.SetStateAction.html +++ /dev/null @@ -1 +0,0 @@ -SetStateAction | React18 Global Store

Type alias SetStateAction<T>

SetStateAction<T>: ((value) => void)

Type Parameters

  • T

Type declaration

\ No newline at end of file diff --git a/docs/types/utils.SetterArgType.html b/docs/types/utils.SetterArgType.html deleted file mode 100644 index 71d660b3..00000000 --- a/docs/types/utils.SetterArgType.html +++ /dev/null @@ -1 +0,0 @@ -SetterArgType | React18 Global Store

Type alias SetterArgType<T>

SetterArgType<T>: T | ((prevState) => T)

Type Parameters

  • T

Type declaration

    • (prevState): T
    • Parameters

      • prevState: T

      Returns T

\ No newline at end of file diff --git a/docs/types/utils.ValueType.html b/docs/types/utils.ValueType.html deleted file mode 100644 index 6ba2b2cc..00000000 --- a/docs/types/utils.ValueType.html +++ /dev/null @@ -1 +0,0 @@ -ValueType | React18 Global Store

Type alias ValueType<T>

ValueType<T>: T | (() => T)

Type Parameters

  • T

Type declaration

    • (): T
    • Returns T

\ No newline at end of file diff --git a/docs/types/utils._internal_.Listener.html b/docs/types/utils._internal_.Listener.html deleted file mode 100644 index a9cf6af2..00000000 --- a/docs/types/utils._internal_.Listener.html +++ /dev/null @@ -1 +0,0 @@ -Listener | React18 Global Store
Listener: (() => void)

Type declaration

    • (): void
    • Returns void

\ No newline at end of file diff --git a/docs/types/utils._internal_.Mutate.html b/docs/types/utils._internal_.Mutate.html deleted file mode 100644 index d4ed74bf..00000000 --- a/docs/types/utils._internal_.Mutate.html +++ /dev/null @@ -1 +0,0 @@ -Mutate | React18 Global Store
Mutate<T>: ((value?) => void)

Type Parameters

  • T

Type declaration

    • (value?): void
    • Parameters

      • Optional value: T

      Returns void

\ No newline at end of file diff --git a/docs/types/utils._internal_.RGS.html b/docs/types/utils._internal_.RGS.html deleted file mode 100644 index a7c3c544..00000000 --- a/docs/types/utils._internal_.RGS.html +++ /dev/null @@ -1 +0,0 @@ -RGS | React18 Global Store
\ No newline at end of file diff --git a/docs/types/utils._internal_.Record.html b/docs/types/utils._internal_.Record.html deleted file mode 100644 index cf6f7856..00000000 --- a/docs/types/utils._internal_.Record.html +++ /dev/null @@ -1,2 +0,0 @@ -Record | React18 Global Store
Record<K, T>: {
    [P in K]: T
}

Construct a type with a set of properties K of type T

-

Type Parameters

  • K extends keyof any
  • T
\ No newline at end of file diff --git a/docs/types/utils._internal_.Subscriber.html b/docs/types/utils._internal_.Subscriber.html deleted file mode 100644 index c44ba8d6..00000000 --- a/docs/types/utils._internal_.Subscriber.html +++ /dev/null @@ -1 +0,0 @@ -Subscriber | React18 Global Store
Subscriber: ((l) => (() => void))

Type declaration

    • (l): (() => void)
    • Parameters

      Returns (() => void)

        • (): void
        • Returns void

\ No newline at end of file diff --git a/docs/variables/Guides.A_Quick_Start.html b/docs/variables/Guides.A_Quick_Start.html deleted file mode 100644 index 2a758477..00000000 --- a/docs/variables/Guides.A_Quick_Start.html +++ /dev/null @@ -1,24 +0,0 @@ -A_Quick_Start | React18 Global Store

Variable A_Quick_StartConst

A_Quick_Start: "Quick Start" = "Quick Start"

Quick Start

Welcome to the quick guide for using this library.

-

Installation

To get started, you can install the package via your preferred package manager. Here are a few examples:

-
$ pnpm add r18gs
-
-

or

-
$ npm install r18gs
-
-

or

-
$ yarn add r18gs
-
-

Usage

Utilize this hook similarly to the useState hook. However, ensure to pass a unique key, unique across the app, to identify and make this state accessible to all client components.

-
const [state, setState] = useRGS<number>("counter", 1);
-
-

You can access the same state across all client-side components using a unique key.

-
-

It's advisable to store your keys in a separate file to prevent typos and unnecessary conflicts.

-
-

Example

// constants/global-states.ts
export const COUNTER = "counter"; -
-
// components/display.tsx
"use client";

import useRGS from "r18gs";
import { COUNTER } from "../constants/global-states";

export default function Display() {
const [count] = useRGS<number>(COUNTER);
return (
<div>
<h2>Client Component 2</h2>
<b>{count}</b>
</div>
);
} -
-
// components/counter.tsx
"use client";

import useRGS from "r18gs";
import { COUNTER } from "../constants/global-states";

export default function Counter() {
const [count, setCount] = useRGS(COUNTER, 0);
return (
<div>
<h2>Client Component 1</h2>
<input
onChange={e => {
setCount(parseInt(e.target.value.trim()));
}}
type="number"
value={count}
/>
</div>
);
} -
-
\ No newline at end of file diff --git a/docs/variables/Guides.B_Leveraging_Plugins.html b/docs/variables/Guides.B_Leveraging_Plugins.html deleted file mode 100644 index 4b93706e..00000000 --- a/docs/variables/Guides.B_Leveraging_Plugins.html +++ /dev/null @@ -1,21 +0,0 @@ -B_Leveraging_Plugins | React18 Global Store

Variable B_Leveraging_PluginsConst

B_Leveraging_Plugins: "Leveraging Plugins" = "Leveraging Plugins"

Leveraging Plugins

Enhance your store's functionality by utilizing either the create function, withPlugins function, or the useRGSWithPlugins hook from r18gs/dist/with-plugins. This enables features such as storing to local storage, among others.

-

Creating a Store with the create Function

// store.ts
import { create } from "r18gs/dist/with-plugins";
import { persist } from "r18gs/dist/plugins"; // You can create your own plugin or import third-party plugins

export const useMyPersistentCounterStore = create<number>("persistent-counter", 0, [persist()]); -
-

Now you can utilize useMyPersistentCounterStore similar to useState without specifying an initial value.

-
// inside your component
const [persistedCount, setPersistedCount] = useMyPersistentCounterStore(); -
-

Utilizing the useRGSWithPlugins Hook

This function is beneficial if your requirements dictate that your key and/or initial value will depend on some props, etc. Or for some other reason you want to initialize the store from within a component (You need to use some variables available inside the component).

-
import { useRGSWithPlugins } from "r18gs/dist/with-plugin";

export function MyComponent(props: MyComponentProps) {
const [state, setState] = useRGSWithPlugins(
props.key,
props.initialVal,
props.plugins,
props.doNotInit,
);
// ...
} -
-

doNotInit

In some cases, you may not want to initialize the store immediately. In such cases, you can pass the fourth argument (doNotInit) as true. The default value is false.

-
    -
  • When this argument is set to true, the store is created, but the setter function is set to null. Thus, you can access the initial value set by the first component that triggered this hook. However, it cannot be modified until the store is initialized, i.e., the hook is invoked by a component setting doNotInit to false (or skipping this argument).
  • -
-

Use case*: When you need that the store be used in many components, however, it should be initialized in a particular component only.

-

Creating a Custom Hook using the withPlugins Higher-Order Function

This is a utility function that will be very helpful when you want to use the useRGSWithPlugins hook with the same plugins in multiple components.

-
// custom hook file, e.g., store.ts
export const useMyRGS = withPlugins([plugin1, plugin2, ...]); -
-
export function MyComponent(props: MyComponentProps) {
const [state, setState] = useMyRGS(props.key, props.initialVal, props.doNotInit);
// ...
} -
-

You can also create your own plugins. Refer to Creating Plugins.

-
\ No newline at end of file diff --git a/docs/variables/utils.globalRGS.html b/docs/variables/utils.globalRGS.html deleted file mode 100644 index 7c528cf7..00000000 --- a/docs/variables/utils.globalRGS.html +++ /dev/null @@ -1 +0,0 @@ -globalRGS | React18 Global Store

Variable globalRGSConst

globalRGS: Record<string, undefined | RGS> = globalThisForBetterMinification.rgs
\ No newline at end of file diff --git a/examples/nextjs/.eslintrc.js b/examples/nextjs/.eslintrc.js index 1d9773ea..6582db49 100644 --- a/examples/nextjs/.eslintrc.js +++ b/examples/nextjs/.eslintrc.js @@ -1,3 +1,8 @@ +/** @type {import("eslint").Linter.Config} */ module.exports = { - extends: ["custom/next"], + extends: ["@repo/eslint-config/next.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, }; diff --git a/examples/nextjs/.gitignore b/examples/nextjs/.gitignore deleted file mode 100644 index 1437c53f..00000000 --- a/examples/nextjs/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# vercel -.vercel diff --git a/examples/nextjs/CHANGELOG.md b/examples/nextjs/CHANGELOG.md deleted file mode 100644 index eff4862e..00000000 --- a/examples/nextjs/CHANGELOG.md +++ /dev/null @@ -1,171 +0,0 @@ -# nextjs-example - -## 0.0.16 - -### Patch Changes - -- Updated dependencies - - r18gs@1.1.1 - - shared-ui@0.0.0 - -## 0.0.15 - -### Patch Changes - -- Updated dependencies - - r18gs@1.1.0 - - shared-ui@0.0.0 - -## 0.0.14 - -### Patch Changes - -- Updated dependencies - - r18gs@1.0.2 - - shared-ui@0.0.0 - -## 0.0.13 - -### Patch Changes - -- Updated dependencies - - r18gs@1.0.1 - - shared-ui@0.0.0 - -## 0.0.12 - -### Patch Changes - -- Updated dependencies -- Updated dependencies -- Updated dependencies -- Updated dependencies - - r18gs@1.0.0 - - shared-ui@0.0.0 - -## 0.0.11 - -### Patch Changes - -- Updated dependencies [81b9d3f] -- Updated dependencies - - r18gs@0.2.0 - - shared-ui@0.0.0 - -## 0.0.10 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.4 - - shared-ui@0.0.0 - -## 0.0.9 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.3 - - shared-ui@0.0.0 - -## 0.0.8 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.2 - - shared-ui@0.0.0 - -## 0.0.7 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.1 - - shared-ui@0.0.0 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.0 - - shared-ui@0.0.0 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.5 - - shared-ui@0.0.0 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.4 - - shared-ui@0.0.0 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.3 - - shared-ui@0.0.0 - -## 0.0.2 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.2 - - shared-ui@0.0.0 - -## 0.0.1 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.1 - - shared-ui@0.0.0 - -## 1.0.5 - -### Patch Changes - -- Updated dependencies - - @mayank1513/fork-me@2.0.1 - - shared-ui@1.0.1 - -## 1.0.4 - -### Patch Changes - -- Support Next.js 14 -- Updated dependencies - - @mayank1513/fork-me@2.0.0 - -## 1.0.3 - -### Patch Changes - -- Updated dependencies - - @mayank1513/fork-me@1.1.2 - -## 1.0.2 - -### Patch Changes - -- Fix CSS modules -- Updated dependencies - - @mayank1513/fork-me@1.1.1 - -## 1.0.1 - -### Patch Changes - -- Updated dependencies - - @mayank1513/fork-me@1.1.0 diff --git a/examples/nextjs/README.md b/examples/nextjs/README.md deleted file mode 100644 index 1626d340..00000000 --- a/examples/nextjs/README.md +++ /dev/null @@ -1,28 +0,0 @@ -## Getting Started - -First, run the development server: - -```bash -yarn dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -To create [API routes](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) add an `api/` directory to the `app/` directory with a `route.ts` file. For individual endpoints, create a subfolder in the `api` directory, as `api/hello/route.ts` would map to [http://localhost:3000/api/hello](http://localhost:3000/api/hello). - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - Learn about Next.js features and API. -- [Learn Next.js](https://www.udemy.com/course/react-and-next-js-with-typescript/?referralCode=7202184A1E57C3DCA8B2) - an interactive Next.js course. - -You can check out [the Turbo Template GitHub repository](https://github.com/mayank1513/turborepo-template/) - your feedback and contributions are welcome! - -### 🤩 Don't forget to start this repo! - -
- -

with 💖 by Mayank Kumar Chaudhari

diff --git a/examples/nextjs/app/favicon.ico b/examples/nextjs/app/favicon.ico deleted file mode 100644 index 71e4bd71..00000000 Binary files a/examples/nextjs/app/favicon.ico and /dev/null differ diff --git a/examples/nextjs/app/layout.tsx b/examples/nextjs/app/layout.tsx deleted file mode 100644 index 5e45229a..00000000 --- a/examples/nextjs/app/layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { ServerTarget } from "nthul-lite/server"; -import { Inter } from "next/font/google"; -import { SharedRootLayout } from "shared-ui"; - -const inter = Inter({ subsets: ["latin"] }); - -export default function RootLayout({ children }: { children: React.ReactNode }): JSX.Element { - return ( - - - - {children} - - - ); -} diff --git a/examples/nextjs/app/page.tsx b/examples/nextjs/app/page.tsx deleted file mode 100644 index c4377b2f..00000000 --- a/examples/nextjs/app/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Home(): JSX.Element { - return

Next.js Example

; -} diff --git a/examples/nextjs/cache/config.json b/examples/nextjs/cache/config.json index cb01ad90..a544f0f8 100644 --- a/examples/nextjs/cache/config.json +++ b/examples/nextjs/cache/config.json @@ -1,6 +1,6 @@ { "telemetry": { - "notifiedAt": "1701772138754", + "notifiedAt": "1715050199607", "enabled": false } } \ No newline at end of file diff --git a/examples/nextjs/next.config.js b/examples/nextjs/next.config.js index b4b8f818..da1bb770 100644 --- a/examples/nextjs/next.config.js +++ b/examples/nextjs/next.config.js @@ -1,4 +1,3 @@ module.exports = { - reactStrictMode: true, - transpilePackages: [""], + reactStrictMode: true, }; diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index c2072914..98980d6e 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -1,30 +1,33 @@ { - "name": "nextjs-example", - "version": "0.0.16", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint", - "postinstall": "next telemetry disable" - }, - "dependencies": { - "@mayank1513/fork-me": "^2.1.2", - "next": "^14.2.3", - "nthul-lite": "^0.2.3", - "r18gs": "workspace:*", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "shared-ui": "workspace:*" - }, - "devDependencies": { - "@next/eslint-plugin-next": "^14.2.3", - "@types/node": "^20.14.1", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "eslint-config-custom": "workspace:*", - "tsconfig": "workspace:*", - "typescript": "^5.4.5" - } -} + "name": "@example/nextjs", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "next build", + "clean": "rm -rf .next", + "dev": "next dev -p 3002", + "lint": "next lint", + "typecheck": "tsc --noEmit", + "start": "next start" + }, + "dependencies": { + "@repo/logger": "workspace:*", + "@repo/shared": "workspace:*", + "next": "^14.2.4", + "nextjs-darkmode": "^1.0.2", + "nextjs-themes": "^3.1.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react18-loaders": "latest", + "r18gs": "workspace:*" + }, + "devDependencies": { + "@next/eslint-plugin-next": "^14.2.4", + "@repo/eslint-config": "workspace:*", + "@repo/typescript-config": "workspace:*", + "@types/node": "^20.14.2", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "typescript": "^5.4.5" + } +} \ No newline at end of file diff --git a/examples/nextjs/public/favicon.ico b/examples/nextjs/public/favicon.ico new file mode 100644 index 00000000..af984505 Binary files /dev/null and b/examples/nextjs/public/favicon.ico differ diff --git a/examples/nextjs/src/app/layout.tsx b/examples/nextjs/src/app/layout.tsx new file mode 100644 index 00000000..2137b73d --- /dev/null +++ b/examples/nextjs/src/app/layout.tsx @@ -0,0 +1,24 @@ +import "./styles.css"; +import "react18-loaders/dist/index.css"; +import { Core } from "nextjs-darkmode"; +import { Layout } from "@repo/shared/dist/server"; +import { GlobalLoader, Header } from "@repo/shared"; +import { Inter } from "next/font/google"; + +const inter = Inter({ subsets: ["latin"] }); + +/** Root layout. */ +export default function RootLayout({ children }: { children: React.ReactNode }): JSX.Element { + return ( + + + + +
+ {children} + + + + + ); +} diff --git a/examples/nextjs/src/app/page.tsx b/examples/nextjs/src/app/page.tsx new file mode 100644 index 00000000..4882e715 --- /dev/null +++ b/examples/nextjs/src/app/page.tsx @@ -0,0 +1,15 @@ +import { LandingPage } from "@repo/shared/dist/server"; +import { Demo } from "@repo/shared"; + +export const metadata = { + title: "React18 Global Store", +}; + +/** next.js landing page */ +export default function Page(): JSX.Element { + return ( + + + + ); +} diff --git a/examples/nextjs/src/app/styles.css b/examples/nextjs/src/app/styles.css new file mode 100644 index 00000000..c519c220 --- /dev/null +++ b/examples/nextjs/src/app/styles.css @@ -0,0 +1,13 @@ +@import "nextjs-darkmode/css"; +@import "@repo/shared/dist/global.css"; +@import "@repo/shared/dist"; +@import "react18-loaders/dist"; + +html { + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-tap-highlight-color: transparent; + line-height: 1.5; + tab-size: 4; +} diff --git a/examples/nextjs/tsconfig.json b/examples/nextjs/tsconfig.json index 644ee04f..aaddcaa8 100644 --- a/examples/nextjs/tsconfig.json +++ b/examples/nextjs/tsconfig.json @@ -1,8 +1,13 @@ { - "extends": "tsconfig/nextjs.json", + "exclude": ["node_modules"], + "extends": "@repo/typescript-config/nextjs.json", "compilerOptions": { - "plugins": [{ "name": "next" }] + "outDir": "dist", + "plugins": [ + { + "name": "next" + } + ] }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": ["src", "next.config.js", "next-env.d.ts", ".next/types/**/*.ts"] } diff --git a/examples/nextjs/turbo.json b/examples/nextjs/turbo.json new file mode 100644 index 00000000..bca04ff0 --- /dev/null +++ b/examples/nextjs/turbo.json @@ -0,0 +1,13 @@ +{ + "extends": [ + "//" + ], + "tasks": { + "build": { + "outputs": [ + ".next/**", + "!.next/cache/**" + ] + } + } +} diff --git a/examples/remix/.eslintrc.cjs b/examples/remix/.eslintrc.cjs deleted file mode 100644 index 613caf73..00000000 --- a/examples/remix/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import('eslint').Linter.Config} */ -module.exports = { - extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], -}; diff --git a/examples/remix/.eslintrc.js b/examples/remix/.eslintrc.js new file mode 100644 index 00000000..b86550f3 --- /dev/null +++ b/examples/remix/.eslintrc.js @@ -0,0 +1,8 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + extends: ["@repo/eslint-config/remix.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, +}; diff --git a/examples/remix/.gitignore b/examples/remix/.gitignore index 1998c294..42ec5e40 100644 --- a/examples/remix/.gitignore +++ b/examples/remix/.gitignore @@ -1 +1,11 @@ -.cache \ No newline at end of file +node_modules + +.cache +.env +.vercel +.output + +build +public/build +api/index.js* +api/_assets* diff --git a/examples/remix/CHANGELOG.md b/examples/remix/CHANGELOG.md deleted file mode 100644 index b90a290e..00000000 --- a/examples/remix/CHANGELOG.md +++ /dev/null @@ -1,142 +0,0 @@ -# remix-example - -## 0.0.16 - -### Patch Changes - -- Updated dependencies - - r18gs@1.1.1 - - shared-ui@0.0.0 - -## 0.0.15 - -### Patch Changes - -- Updated dependencies - - r18gs@1.1.0 - - shared-ui@0.0.0 - -## 0.0.14 - -### Patch Changes - -- Updated dependencies - - r18gs@1.0.2 - - shared-ui@0.0.0 - -## 0.0.13 - -### Patch Changes - -- Updated dependencies - - r18gs@1.0.1 - - shared-ui@0.0.0 - -## 0.0.12 - -### Patch Changes - -- Updated dependencies -- Updated dependencies -- Updated dependencies -- Updated dependencies - - r18gs@1.0.0 - - shared-ui@0.0.0 - -## 0.0.11 - -### Patch Changes - -- 81b9d3f: Make the library extensible with plugins -- Updated dependencies [81b9d3f] -- Updated dependencies - - r18gs@0.2.0 - - shared-ui@0.0.0 - -## 0.0.10 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.4 - - shared-ui@0.0.0 - -## 0.0.9 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.3 - - shared-ui@0.0.0 - -## 0.0.8 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.2 - - shared-ui@0.0.0 - -## 0.0.7 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.1 - - shared-ui@0.0.0 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.0 - - shared-ui@0.0.0 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.5 - - shared-ui@0.0.0 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.4 - - shared-ui@0.0.0 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.3 - - shared-ui@0.0.0 - -## 0.0.2 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.2 - - shared-ui@0.0.0 - -## 0.0.1 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.1 - - shared-ui@0.0.0 - -## null - -### Patch Changes - -- Updated dependencies - - @mayank1513/fork-me@2.0.1 - - shared-ui@1.0.1 diff --git a/examples/remix/README.md b/examples/remix/README.md new file mode 100644 index 00000000..944936b3 --- /dev/null +++ b/examples/remix/README.md @@ -0,0 +1,34 @@ +# Welcome to Remix! + +- [Remix Docs](https://remix.run/docs) + +## Deployment + +After having run the `create-remix` command and selected "Vercel" as a deployment target, you only need to [import your Git repository](https://vercel.com/new) into Vercel, and it will be deployed. + +If you'd like to avoid using a Git repository, you can also deploy the directory by running [Vercel CLI](https://vercel.com/cli): + +```sh +npm i -g vercel +vercel +``` + +It is generally recommended to use a Git repository, because future commits will then automatically be deployed by Vercel, through its [Git Integration](https://vercel.com/docs/concepts/git). + +## Development + +To run your Remix app locally, make sure your project's local dependencies are installed: + +```sh +npm install +``` + +Afterwards, start the Remix development server like so: + +```sh +npm run dev +``` + +Open up [http://localhost:3000](http://localhost:3000) and you should be ready to go! + +If you're used to using the `vercel dev` command provided by [Vercel CLI](https://vercel.com/cli) instead, you can also use that, but it's not needed. diff --git a/examples/remix/app/entry.client.tsx b/examples/remix/app/entry.client.tsx new file mode 100644 index 00000000..4a0775b2 --- /dev/null +++ b/examples/remix/app/entry.client.tsx @@ -0,0 +1,23 @@ +import { RemixBrowser } from "@remix-run/react"; +import { startTransition, StrictMode } from "react"; +import { hydrateRoot } from "react-dom/client"; + +/** Hydration */ +function hydrate(): void { + startTransition(() => { + hydrateRoot( + document, + + + , + ); + }); +} + +if (typeof requestIdleCallback === "function") { + requestIdleCallback(hydrate); +} else { + // Safari doesn't support requestIdleCallback + // https://caniuse.com/requestidlecallback + setTimeout(hydrate, 1); +} diff --git a/examples/remix/app/entry.server.tsx b/examples/remix/app/entry.server.tsx new file mode 100644 index 00000000..a66506f8 --- /dev/null +++ b/examples/remix/app/entry.server.tsx @@ -0,0 +1,14 @@ +import handleRequest from "@vercel/remix-entry-server"; +import { RemixServer } from "@remix-run/react"; +import type { EntryContext } from "@remix-run/server-runtime"; + +/** Server entry */ +export default function entry( + request: Request, + responseStatusCode: number, + responseHeaders: Headers, + remixContext: EntryContext, +): Promise { + const remixServer = ; + return handleRequest(request, responseStatusCode, responseHeaders, remixServer); +} diff --git a/examples/remix/app/root.tsx b/examples/remix/app/root.tsx index 4ebdb015..7245812d 100644 --- a/examples/remix/app/root.tsx +++ b/examples/remix/app/root.tsx @@ -1,29 +1,42 @@ -import { cssBundleHref } from "@remix-run/css-bundle"; -import type { LinksFunction } from "@remix-run/node"; +import type { MetaFunction, LinksFunction } from "@remix-run/node"; import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react"; -import { SharedRootLayout } from "shared-ui"; +import { Analytics } from "@vercel/analytics/react"; +import styles from "./styles.css"; +import { Layout } from "@repo/shared/dist/server"; +import { Core } from "nextjs-darkmode"; +import { Header } from "@repo/shared"; -export const links: LinksFunction = () => [ - ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), +/** Page metadata */ +export const meta: MetaFunction = () => [ + { + charset: "utf-8", + title: "Blog | React18 Global Store", + viewport: "width=device-width,initial-scale=1", + }, ]; -export default function App() { - return ( - - - - - - - - - - - - - - - - - ); +/** Add links to head */ +export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }]; + +/** Remix app root */ +export default function App(): JSX.Element { + return ( + + + + + + + + +
+ + + + + + + + + ); } diff --git a/examples/remix/app/routes/_index.tsx b/examples/remix/app/routes/_index.tsx index 7e84feff..55f230e6 100644 --- a/examples/remix/app/routes/_index.tsx +++ b/examples/remix/app/routes/_index.tsx @@ -1,3 +1,11 @@ -export default function Home() { - return

Remix Example

; +import { Demo } from "@repo/shared"; +import { LandingPage } from "@repo/shared/dist/server"; + +/** Remix App */ +export default function Index(): JSX.Element { + return ( + + + + ); } diff --git a/examples/remix/app/styles.css b/examples/remix/app/styles.css new file mode 100644 index 00000000..cb687b23 --- /dev/null +++ b/examples/remix/app/styles.css @@ -0,0 +1,68 @@ +@import "nextjs-darkmode/css"; +@import "@repo/shared/dist/global.css"; +@import "@repo/shared/dist"; +@import "react18-loaders/dist"; + +html { + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + Segoe UI, + Roboto, + Helvetica Neue, + Arial, + sans-serif; + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-tap-highlight-color: transparent; + line-height: 1.5; + tab-size: 4; +} + +body { + margin: 0; +} + +.container { + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1.5rem; + max-width: 100%; + margin: 0 auto; + padding: 0 16px; + text-align: center; +} + +.title { + font-size: 3rem; + font-weight: 700; + margin: 0; +} + +.title span { + display: inline-block; + background-image: linear-gradient(to right, #3b82f6, #ef4444); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.description { + color: #9ca3af; + font-weight: 500; +} + +.description a { + color: #3b82f6; + text-decoration: none; +} + +.description a:hover { + text-decoration: underline; +} diff --git a/examples/remix/package.json b/examples/remix/package.json index bef77336..d201a43e 100644 --- a/examples/remix/package.json +++ b/examples/remix/package.json @@ -1,37 +1,38 @@ { - "name": "remix-example", - "version": "0.0.16", - "private": true, - "sideEffects": false, - "type": "module", - "scripts": { - "build": "remix build", - "dev": "remix dev --manual", - "start": "remix-serve ./build/index.js", - "typecheck": "tsc" - }, - "dependencies": { - "@mayank1513/fork-me": "^2.1.2", - "@remix-run/css-bundle": "^2.9.2", - "@remix-run/node": "^2.9.2", - "@remix-run/react": "^2.9.2", - "@remix-run/serve": "^2.9.2", - "isbot": "5.1.9", - "nthul-lite": "^0.2.3", - "r18gs": "workspace:*", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "shared-ui": "workspace:*" - }, - "devDependencies": { - "@remix-run/dev": "^2.9.2", - "@remix-run/eslint-config": "^2.9.2", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "eslint": "^9.4.0", - "typescript": "^5.4.5" - }, - "engines": { - "node": ">=18.0.0" - } -} + "name": "@example/remix", + "version": "0.0.0", + "private": true, + "sideEffects": false, + "scripts": { + "build": "remix build", + "dev": "remix dev", + "typecheck": "tsc --noEmit", + "lint": "eslint app/" + }, + "dependencies": { + "@remix-run/node": "^2.9.2", + "@remix-run/react": "^2.9.2", + "@remix-run/serve": "^2.9.2", + "@remix-run/server-runtime": "^2.9.2", + "@repo/shared": "workspace:*", + "@vercel/analytics": "^1.3.1", + "@vercel/remix-entry-server": "^0.1.1", + "nextjs-darkmode": "^1.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react18-loaders": "latest", + "react18-themes": "^3.1.0", + "r18gs": "workspace:*" + }, + "devDependencies": { + "@remix-run/dev": "^2.9.2", + "@repo/eslint-config": "workspace:*", + "@repo/typescript-config": "workspace:*", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "typescript": "^5.4.5" + }, + "engines": { + "node": ">=18" + } +} \ No newline at end of file diff --git a/examples/remix/public/favicon.ico b/examples/remix/public/favicon.ico new file mode 100644 index 00000000..8830cf68 Binary files /dev/null and b/examples/remix/public/favicon.ico differ diff --git a/examples/remix/remix.config.js b/examples/remix/remix.config.js index 2afd6649..5bdbfd78 100644 --- a/examples/remix/remix.config.js +++ b/examples/remix/remix.config.js @@ -1,9 +1,9 @@ /** @type {import('@remix-run/dev').AppConfig} */ -export default { - ignoredRouteFiles: ["**/.*"], - serverDependenciesToBundle: ["@mayank1513/fork-me", "shared-ui"], - // appDirectory: "app", - // assetsBuildDirectory: "public/build", - // publicPath: "/build/", - // serverBuildPath: "build/index.js", +module.exports = { + ignoredRouteFiles: ["**/.*"], + serverModuleFormat: "cjs", + // appDirectory: "app", + // assetsBuildDirectory: "public/build", + // serverBuildPath: "build/index.js", + // publicPath: "/build/", }; diff --git a/examples/remix/remix.env.d.ts b/examples/remix/remix.env.d.ts index dcf8c45e..5c938f10 100644 --- a/examples/remix/remix.env.d.ts +++ b/examples/remix/remix.env.d.ts @@ -1,2 +1,2 @@ /// -/// +/// diff --git a/examples/remix/server.js b/examples/remix/server.js new file mode 100644 index 00000000..3b02013a --- /dev/null +++ b/examples/remix/server.js @@ -0,0 +1,4 @@ +import { createRequestHandler } from "@remix-run/server-runtime"; +import * as build from "@remix-run/dev/server-build"; + +export default createRequestHandler({ build, mode: process.env.NODE_ENV }); diff --git a/examples/remix/tsconfig.json b/examples/remix/tsconfig.json index 28cce918..2770e9c0 100644 --- a/examples/remix/tsconfig.json +++ b/examples/remix/tsconfig.json @@ -1,22 +1,18 @@ { - "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"], + "extends": "@repo/typescript-config/remix.json", "compilerOptions": { - "lib": ["DOM", "DOM.Iterable", "ES2022"], - "isolatedModules": true, - "esModuleInterop": true, - "jsx": "react-jsx", - "moduleResolution": "Bundler", - "resolveJsonModule": true, - "target": "ES2022", - "strict": true, - "allowJs": true, - "forceConsistentCasingInFileNames": true, - "baseUrl": ".", + "rootDir": ".", + "outDir": "dist", "paths": { "~/*": ["./app/*"] - }, - - // Remix takes care of building everything in `remix build`. - "noEmit": true - } + } + }, + "include": [ + "remix.env.d.ts", + "**/*.ts", + "**/*.tsx", + "server.js", + "remix.config.js" + ], + "exclude": ["node_modules", "build"] } diff --git a/examples/remix/turbo.json b/examples/remix/turbo.json new file mode 100644 index 00000000..e96fb0bb --- /dev/null +++ b/examples/remix/turbo.json @@ -0,0 +1,13 @@ +{ + "extends": [ + "//" + ], + "tasks": { + "build": { + "outputs": [ + "build/**", + "public/build/**" + ] + } + } +} diff --git a/examples/vite/.eslintrc.cjs b/examples/vite/.eslintrc.cjs deleted file mode 100644 index f63fe7dc..00000000 --- a/examples/vite/.eslintrc.cjs +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:react-hooks/recommended", - ], - ignorePatterns: ["dist", ".eslintrc.cjs"], - parser: "@typescript-eslint/parser", - plugins: ["react-refresh"], - rules: { - "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], - }, -}; diff --git a/examples/vite/.eslintrc.js b/examples/vite/.eslintrc.js new file mode 100644 index 00000000..d83112c0 --- /dev/null +++ b/examples/vite/.eslintrc.js @@ -0,0 +1,8 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + extends: ["@repo/eslint-config/react.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, +}; diff --git a/examples/vite/.gitignore b/examples/vite/.gitignore deleted file mode 100644 index 5a079d55..00000000 --- a/examples/vite/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# vercel -.vercel - -# vite -dist diff --git a/examples/vite/CHANGELOG.md b/examples/vite/CHANGELOG.md deleted file mode 100644 index b8d10792..00000000 --- a/examples/vite/CHANGELOG.md +++ /dev/null @@ -1,170 +0,0 @@ -# vite-example - -## 0.0.16 - -### Patch Changes - -- Updated dependencies - - r18gs@1.1.1 - - shared-ui@0.0.0 - -## 0.0.15 - -### Patch Changes - -- Updated dependencies - - r18gs@1.1.0 - - shared-ui@0.0.0 - -## 0.0.14 - -### Patch Changes - -- Updated dependencies - - r18gs@1.0.2 - - shared-ui@0.0.0 - -## 0.0.13 - -### Patch Changes - -- Updated dependencies - - r18gs@1.0.1 - - shared-ui@0.0.0 - -## 0.0.12 - -### Patch Changes - -- Updated dependencies -- Updated dependencies -- Updated dependencies -- Updated dependencies - - r18gs@1.0.0 - - shared-ui@0.0.0 - -## 0.0.11 - -### Patch Changes - -- Updated dependencies [81b9d3f] -- Updated dependencies - - r18gs@0.2.0 - - shared-ui@0.0.0 - -## 0.0.10 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.4 - - shared-ui@0.0.0 - -## 0.0.9 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.3 - - shared-ui@0.0.0 - -## 0.0.8 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.2 - - shared-ui@0.0.0 - -## 0.0.7 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.1 - - shared-ui@0.0.0 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies - - r18gs@0.1.0 - - shared-ui@0.0.0 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.5 - - shared-ui@0.0.0 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.4 - - shared-ui@0.0.0 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.3 - - shared-ui@0.0.0 - -## 0.0.2 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.2 - - shared-ui@0.0.0 - -## 0.0.1 - -### Patch Changes - -- Updated dependencies - - r18gs@0.0.1 - - shared-ui@0.0.0 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies - - @mayank1513/fork-me@2.0.1 - - shared-ui@1.0.1 - -## 0.0.4 - -### Patch Changes - -- Support Next.js 14 -- Updated dependencies - - @mayank1513/fork-me@2.0.0 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies - - @mayank1513/fork-me@1.1.2 - -## 0.0.2 - -### Patch Changes - -- Updated dependencies - - @mayank1513/fork-me@1.1.1 - -## 0.0.1 - -### Patch Changes - -- Updated dependencies - - @mayank1513/fork-me@1.1.0 diff --git a/examples/vite/README.md b/examples/vite/README.md deleted file mode 100644 index 603a1359..00000000 --- a/examples/vite/README.md +++ /dev/null @@ -1,25 +0,0 @@ -## Getting Started - -First, run the development server: - -```bash -yarn dev -``` - -Open [http://localhost:3001](http://localhost:3001) with your browser to see the result. -Edit `src/App.tsx` and save to test HMR - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - Learn about Next.js features and API. -- [Learn Next.js](https://www.udemy.com/course/react-and-next-js-with-typescript/?referralCode=7202184A1E57C3DCA8B2) - an interactive Next.js course. - -You can check out [the Turbo Template GitHub repository](https://github.com/mayank1513/turborepo-template/) - your feedback and contributions are welcome! - -### 🤩 Don't forget to start this repo! - -
- -

with 💖 by Mayank Kumar Chaudhari

diff --git a/examples/vite/index.html b/examples/vite/index.html index ef80c79b..978f2d53 100644 --- a/examples/vite/index.html +++ b/examples/vite/index.html @@ -1,13 +1,12 @@ - - - - - Vite + React + TS - - -
- - + + + + Admin | Turborepo Template + + +
+ + diff --git a/examples/vite/package.json b/examples/vite/package.json index 14a0d2cb..62493385 100644 --- a/examples/vite/package.json +++ b/examples/vite/package.json @@ -1,32 +1,31 @@ { - "name": "vite-example", - "private": true, - "version": "0.0.16", - "type": "module", - "scripts": { - "dev": "vite --port 3001", - "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" - }, - "dependencies": { - "@mayank1513/fork-me": "^2.1.2", - "nthul-lite": "^0.2.3", - "r18gs": "workspace:*", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "shared-ui": "workspace:*" - }, - "devDependencies": { - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^7.12.0", - "@typescript-eslint/parser": "^7.12.0", - "@vitejs/plugin-react-swc": "^3.7.0", - "eslint": "^9.4.0", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.7", - "typescript": "^5.4.5", - "vite": "^5.2.12" - } -} + "name": "@example/vite", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "vite build", + "start": "vite preview", + "clean": "rm -rf dist", + "dev": "vite --host 0.0.0.0 --port 3001 --clearScreen false", + "typecheck": "tsc --noEmit", + "lint": "eslint src/" + }, + "dependencies": { + "@repo/shared": "workspace:*", + "nextjs-darkmode": "^1.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react18-loaders": "latest", + "react18-themes": "^3.1.0", + "r18gs": "workspace:*" + }, + "devDependencies": { + "@repo/eslint-config": "workspace:*", + "@repo/typescript-config": "workspace:*", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "typescript": "^5.4.5", + "vite": "^5.3.1" + } +} \ No newline at end of file diff --git a/examples/vite/public/favicon.ico b/examples/vite/public/favicon.ico new file mode 100644 index 00000000..3a3c34a2 Binary files /dev/null and b/examples/vite/public/favicon.ico differ diff --git a/examples/vite/public/vite.svg b/examples/vite/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/examples/vite/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/vite/src/App.tsx b/examples/vite/src/App.tsx deleted file mode 100644 index 21bf2947..00000000 --- a/examples/vite/src/App.tsx +++ /dev/null @@ -1,5 +0,0 @@ -function App() { - return

Vite + React + TS Example

; -} - -export default App; diff --git a/examples/vite/src/app/index.tsx b/examples/vite/src/app/index.tsx new file mode 100644 index 00000000..f9b4a4b1 --- /dev/null +++ b/examples/vite/src/app/index.tsx @@ -0,0 +1,25 @@ +import React from "react"; +import "./styles.css"; +import { Bars1 } from "react18-loaders/dist/server"; +import { LoaderContainer } from "react18-loaders"; +import { LandingPage, Layout } from "@repo/shared/dist/server"; +import { Core } from "nextjs-darkmode"; +import { Demo, Header } from "@repo/shared"; + +/** Vite App */ +function App(): JSX.Element { + return ( + + +
+ + + + + + + + ); +} + +export default App; diff --git a/examples/vite/src/app/styles.css b/examples/vite/src/app/styles.css new file mode 100644 index 00000000..ca59aa6a --- /dev/null +++ b/examples/vite/src/app/styles.css @@ -0,0 +1,45 @@ +@import "react18-loaders/dist"; +@import "nextjs-darkmode/css"; +@import "@repo/shared/dist/global.css"; +@import "@repo/shared/dist"; + +.container { + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1.5rem; + max-width: 100%; + margin: 0 auto; + padding: 0 16px; + text-align: center; +} + +.title { + font-size: 3rem; + font-weight: 700; + margin: 0; +} + +.title span { + display: inline-block; + background-image: linear-gradient(to right, #3b82f6, #ef4444); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.description { + color: #9ca3af; + font-weight: 500; +} + +.description a { + color: #3b82f6; + text-decoration: none; +} + +.description a:hover { + text-decoration: underline; +} diff --git a/examples/vite/src/index.css b/examples/vite/src/index.css new file mode 100644 index 00000000..efb82277 --- /dev/null +++ b/examples/vite/src/index.css @@ -0,0 +1,22 @@ +html { + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + Segoe UI, + Roboto, + Helvetica Neue, + Arial, + sans-serif; + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-tap-highlight-color: transparent; + line-height: 1.5; + tab-size: 4; +} + +body { + margin: 0; +} diff --git a/examples/vite/src/main.tsx b/examples/vite/src/main.tsx index 684a45aa..9657f6dd 100644 --- a/examples/vite/src/main.tsx +++ b/examples/vite/src/main.tsx @@ -1,15 +1,16 @@ import React from "react"; -import ReactDOM from "react-dom/client"; -import App from "./App.tsx"; -import { SharedRootLayout } from "shared-ui"; +import { createRoot } from "react-dom/client"; +import App from "./app"; +import "./index.css"; -const rootElement = document.getElementById("root"); -if (!rootElement) throw new Error("Root element not found"); - -ReactDOM.createRoot(rootElement).render( - - - - - , -); +const el = document.getElementById("root"); +if (el) { + const root = createRoot(el); + root.render( + + + , + ); +} else { + throw new Error("Could not find root element"); +} diff --git a/examples/vite/src/vite-env.d.ts b/examples/vite/src/vite-env.d.ts deleted file mode 100644 index 11f02fe2..00000000 --- a/examples/vite/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/examples/vite/tsconfig.json b/examples/vite/tsconfig.json index 483d7b4d..c64bb08c 100644 --- a/examples/vite/tsconfig.json +++ b/examples/vite/tsconfig.json @@ -1,24 +1,9 @@ { - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + "exclude": ["node_modules"], + "extends": "@repo/typescript-config/vite.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "dist" + }, + "include": ["src", "vite.config.ts"] } diff --git a/examples/vite/tsconfig.node.json b/examples/vite/tsconfig.node.json deleted file mode 100644 index 42872c59..00000000 --- a/examples/vite/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/examples/vite/turbo.json b/examples/vite/turbo.json new file mode 100644 index 00000000..52e8c763 --- /dev/null +++ b/examples/vite/turbo.json @@ -0,0 +1,12 @@ +{ + "extends": [ + "//" + ], + "tasks": { + "build": { + "outputs": [ + "dist/**" + ] + } + } +} diff --git a/examples/vite/vite.config.ts b/examples/vite/vite.config.ts index 41114b5e..58676f78 100644 --- a/examples/vite/vite.config.ts +++ b/examples/vite/vite.config.ts @@ -1,7 +1,6 @@ +import react from "@vitejs/plugin-react"; import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react-swc"; -// https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], + plugins: [react()], }); diff --git a/lib/.eslintrc.js b/lib/.eslintrc.js new file mode 100644 index 00000000..d83112c0 --- /dev/null +++ b/lib/.eslintrc.js @@ -0,0 +1,8 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + extends: ["@repo/eslint-config/react.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, +}; diff --git a/lib/r18gs/CHANGELOG.md b/lib/CHANGELOG.md similarity index 100% rename from lib/r18gs/CHANGELOG.md rename to lib/CHANGELOG.md diff --git a/lib/README.md b/lib/README.md new file mode 100644 index 00000000..810ec09a --- /dev/null +++ b/lib/README.md @@ -0,0 +1,130 @@ +# R18gs + +[![test](https://github.com/react18-tools/react18-global-store/actions/workflows/test.yml/badge.svg)](https://github.com/react18-tools/react18-global-store/actions/workflows/test.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/aa896ec14c570f3bb274/maintainability)](https://codeclimate.com/github/react18-tools/react18-global-store/maintainability) [![codecov](https://codecov.io/gh/react18-tools/react18-global-store/graph/badge.svg)](https://codecov.io/gh/react18-tools/react18-global-store) [![Version](https://img.shields.io/npm/v/r18gs.svg?colorB=green)](https://www.npmjs.com/package/r18gs) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/d18m/r18gs.svg)](https://www.npmjs.com/package/r18gs) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/r18gs) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/from-referrer/) + +R18gs is a comprehensive library designed to unlock the full potential of React 18 server components. It provides customizable loading animation components and a fullscreen loader container, seamlessly integrating with React and Next.js. + +✅ Fully Treeshakable (import from `r18gs/client/loader-container`) + +✅ Fully TypeScript Supported + +✅ Leverages the power of React 18 Server components + +✅ Compatible with all React 18 build systems/tools/frameworks + +✅ Documented with [Typedoc](https://react18-tools.github.io/react18-global-store) ([Docs](https://react18-tools.github.io/react18-global-store)) + +✅ Examples for Next.js, Vite, and Remix + +> Please consider starring [this repository](https://github.com/react18-tools/react18-global-store) and sharing it with your friends. + +## Getting Started + +### Installation + +```bash +$ pnpm add r18gs +``` + +**_or_** + +```bash +$ npm install r18gs +``` + +**_or_** + +```bash +$ yarn add r18gs +``` + +## Want Lite Version? [![npm bundle size](https://img.shields.io/bundlephobia/minzip/r18gs-lite)](https://www.npmjs.com/package/r18gs-lite) [![Version](https://img.shields.io/npm/v/r18gs-lite.svg?colorB=green)](https://www.npmjs.com/package/r18gs-lite) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/d18m/r18gs-lite.svg)](https://www.npmjs.com/package/r18gs-lite) + +```bash +$ pnpm add r18gs-lite +``` + +**or** + +```bash +$ npm install r18gs-lite +``` + +**or** + +```bash +$ yarn add r18gs-lite +``` + +> You need `r18gs` as a peer-dependency + +### Import Styles + +You can import styles globally or within specific components. + +```css +/* globals.css */ +@import "r18gs/dist"; +``` + +```tsx +// layout.tsx +import "r18gs/dist/index.css"; +``` + +For selective imports: + +```css +/* globals.css */ +@import "r18gs/dist/client"; /** required if you are using LoaderContainer */ +@import "r18gs/dist/server/bars/bars1"; +``` + +### Usage + +Using loaders is straightforward. + +```tsx +import { Bars1 } from "r18gs/dist/server/bars/bars1"; + +export default function MyComponent() { + return someCondition ? : <>Something else...; +} +``` + +For detailed API and options, refer to [the API documentation](https://react18-tools.github.io/react18-global-store). + +**Using LoaderContainer** + +`LoaderContainer` is a fullscreen component. You can add this component directly in your layout and then use `useLoader` hook to toggle its visibility. + +```tsx +// layout.tsx + + ... +``` + +```tsx +// some other page or component +import { useLoader } from "r18gs/dist/hooks"; + +export default MyComponent() { + const { setLoading } = useLoader(); + useCallback(()=>{ + setLoading(true); + ...do some work + setLoading(false); + }, []) + ... +} +``` + +## License + +This library is licensed under the MPL-2.0 open-source license. + +> Please consider enrolling in [our courses](https://mayank-chaudhari.vercel.app/courses) or [sponsoring](https://github.com/sponsors/mayank1513) our work. + +
+ +

with 💖 by Mayank Kumar Chaudhari

diff --git a/lib/package.json b/lib/package.json new file mode 100644 index 00000000..1c7a3651 --- /dev/null +++ b/lib/package.json @@ -0,0 +1,95 @@ +{ + "name": "r18gs", + "author": "Mayank Kumar Chaudhari ", + "private": false, + "version": "1.1.1", + "description": "A simple yet elegant, light weight, react18 global store to replace Zustand for better tree shaking.", + "license": "MPL-2.0", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "repository": "github:react18-tools/react18-global-store", + "bugs": "https://github.com/react18-tools/react18-global-store/issues", + "homepage": "https://react18-global-store.vercel.app/", + "sideEffects": false, + "files": [ + "dist/**" + ], + "scripts": { + "build": "tsup && tsc -p tsconfig-build.json", + "clean": "rm -rf dist", + "dev": "tsup --watch && tsc -p tsconfig-build.json -w", + "typecheck": "tsc --noEmit", + "lint": "eslint src/", + "test": "vitest run --coverage" + }, + "devDependencies": { + "@repo/eslint-config": "workspace:*", + "@repo/jest-presets": "workspace:*", + "@repo/typescript-config": "workspace:*", + "@testing-library/react": "^16.0.0", + "@types/node": "^20.14.2", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "@vitest/coverage-v8": "^1.6.0", + "esbuild-plugin-react18": "0.2.4", + "esbuild-plugin-react18-css": "^0.0.4", + "jsdom": "^24.1.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "tsup": "^8.1.0", + "typescript": "^5.4.5", + "vite-tsconfig-paths": "^4.3.2", + "vitest": "^1.6.0" + }, + "peerDependencies": { + "@types/react": "16.8 - 19", + "react": "16.8 - 19" + }, + "peerDependenciesMeta": { + "next": { + "optional": true + } + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/react18-tools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/mayank1513" + } + ], + "keywords": [ + "React", + "React 18", + "React 19", + "Next.js", + "Next.js 14", + "Next.js 15", + "React Server Components", + "Highly Customizable", + "State-of-the-Art", + "Broad Compatibility", + "Frontend Development", + "UI Components", + "Web Development", + "Progressive", + "Modern Design", + "Seamless Integration", + "react18-global-store", + "Next.js Framework", + "Next.js 13", + "React 18 Features", + "Zustand Alternative for simple need", + "Zen Store", + "React Global Store", + "React Server-Side Components", + "React Client-Side Components", + "TypeScript Support", + "Mayank1513", + "Turborepo Template" + ] +} diff --git a/lib/r18gs/.eslintrc.js b/lib/r18gs/.eslintrc.js deleted file mode 100644 index 05ac2b2b..00000000 --- a/lib/r18gs/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ["custom/react-internal"], -}; diff --git a/lib/r18gs/.gitignore b/lib/r18gs/.gitignore deleted file mode 100644 index 06435e20..00000000 --- a/lib/r18gs/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# tsup build -dist diff --git a/lib/r18gs/README.md b/lib/r18gs/README.md deleted file mode 100644 index ddb13a72..00000000 --- a/lib/r18gs/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# React18GlobalStore - -[![test](https://github.com/react18-tools/react18-global-store/actions/workflows/test.yml/badge.svg)](https://github.com/react18-tools/react18-global-store/actions/workflows/test.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/ec3140063acd8df82481/maintainability)](https://codeclimate.com/github/react18-tools/react18-global-store/maintainability) [![codecov](https://codecov.io/gh/react18-tools/react18-global-store/graph/badge.svg)](https://codecov.io/gh/react18-tools/react18-global-store) [![Version](https://img.shields.io/npm/v/r18gs.svg?colorB=green)](https://www.npmjs.com/package/r18gs) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/d18m/r18gs.svg)](https://www.npmjs.com/package/r18gs) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/r18gs) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/from-referrer/) - -## Motivation - -I've developed fantastic libraries leveraging React18 features using Zustand, and they performed admirably. However, when attempting to import from specific folders for better tree-shaking, the libraries encountered issues. Each import resulted in a separate Zustand store being created, leading to increased package size. - -As a solution, I set out to create a lightweight, bare minimum store that facilitates shared state even when importing components from separate files, optimizing tree-shaking. - -## Features - -✅ Full TypeScript Support - -✅ Unleash the full power of React18 Server components - -✅ Compatible with all build systems/tools/frameworks for React18 - -✅ Documented with [Typedoc](https://react18-tools.github.io/react18-global-store) ([Docs](https://react18-tools.github.io/react18-global-store)) - -✅ Examples for Next.js, Vite, and Remix - -## Simple Global State Shared Across Multiple Components - -Utilize this hook similarly to the `useState` hook. However, ensure to pass a unique key, unique across the app, to identify and make this state accessible to all client components. - -```tsx -const [state, setState] = useRGS("counter", 1); -``` - -**_or_** - -```tsx -const [state, setState] = useRGS("counter", () => 1); -``` - -> For detailed instructions, see [Getting Started](./md-docs/1.getting-started.md) - -## Using Plugins - -Enhance the functionality of the store by leveraging either the `create` function, `withPlugins` function, or the `useRGSWithPlugins` hook from `r18gs/dist/with-plugins`, enabling features such as storing to local storage, among others. - -```tsx -// store.ts -import { create } from "r18gs/dist/with-plugins"; -import { persist } from "r18gs/dist/plugins"; /** You can create your own plugin or import third-party plugins */ - -export const useMyPersistentCounterStore = create("persistent-counter", 0, [persist()]); -``` - -Now, you can utilize `useMyPersistentCounterStore` similarly to `useState` without specifying an initial value. - -```tsx -const [persistedCount, setPersistedCount] = useMyPersistentCounterStore(); -``` - -> For detailed instructions, see [Leveraging Plugins](./md-docs/2.leveraging-plugins.md) - -## Contributing - -See [contributing.md](/contributing.md) - -### 🤩 Don't forget to star [this repo](https://github.com/mayank1513/react18-global-store)! - -Interested in hands-on courses for getting started with Turborepo? Check out [React and Next.js with TypeScript](https://mayank-chaudhari.vercel.app/courses/react-and-next-js-with-typescript) and [The Game of Chess with Next.js, React and TypeScript](https://www.udemy.com/course/game-of-chess-with-nextjs-react-and-typescript/?referralCode=851A28F10B254A8523FE) - -![Repo Stats](https://repobeats.axiom.co/api/embed/ec3e74d795ed805a0fce67c0b64c3f08872e7945.svg "Repobeats analytics image") - -## License - -Licensed under the MPL 2.0 open source license. - -
- -

with 💖 by Mayank Kumar Chaudhari

diff --git a/lib/r18gs/package.json b/lib/r18gs/package.json deleted file mode 100644 index cc9f74a9..00000000 --- a/lib/r18gs/package.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "r18gs", - "author": "Mayank Kumar Chaudhari ", - "private": false, - "version": "1.1.1", - "description": "A simple yet elegant, light weight, react18 global store to replace Zustand for better tree shaking.", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "module": "./dist/index.mjs", - "files": [ - "dist/**" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/react18-tools/react18-global-store.git" - }, - "bugs": { - "url": "https://github.com/react18-tools/react18-global-store/issues" - }, - "homepage": "https://react18-global-store.vercel.app/", - "sideEffects": false, - "license": "MPL-2.0", - "scripts": { - "test": "vitest run --coverage", - "build": "tsup src && tsc -p tsconfig-build.json", - "doc": "cp ../../README.md . && typedoc && cp -r ../../md-docs ../../docs/", - "publish-package": "cp ../../README.md . && npm publish --provenance --access public", - "lint": "eslint ." - }, - "devDependencies": { - "@testing-library/react": "^16.0.0", - "@turbo/gen": "^2.0.1", - "@types/node": "^20.14.1", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@vitejs/plugin-react": "^4.3.0", - "@vitest/coverage-v8": "^1.6.0", - "eslint-config-custom": "workspace:*", - "jsdom": "^24.1.0", - "octokit": "^4.0.2", - "react": "^18.3.1", - "tsconfig": "workspace:*", - "tsup": "^8.1.0", - "typedoc": "^0.25.13", - "typedoc-plugin-mdn-links": "^3.1.28", - "typedoc-plugin-missing-exports": "^2.2.0", - "typedoc-plugin-rename-defaults": "^0.7.0", - "typedoc-plugin-zod": "^1.1.2", - "typescript": "^5.4.5", - "vite-tsconfig-paths": "^4.3.2", - "vitest": "^1.6.0" - }, - "peerDependencies": { - "@types/react": "16.8 - 18", - "react": "16.8 - 18" - }, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mayank1513" - }, - "https://pages.razorpay.com/mayank1513" - ], - "keywords": [ - "react18-global-store", - "nextjs", - "nextjs13", - "nextjs14", - "react", - "react18", - "zustand", - "zen-store", - "react-global-store", - "react-server-components", - "react-client-components", - "typescript", - "javascript", - "mayank1513", - "turborepo-trmplate" - ] -} diff --git a/lib/r18gs/src/Guides.ts b/lib/r18gs/src/Guides.ts deleted file mode 100644 index b7c4d750..00000000 --- a/lib/r18gs/src/Guides.ts +++ /dev/null @@ -1,155 +0,0 @@ -/** -# Quick Start - -Welcome to the quick guide for using this library. - -## Installation - -To get started, you can install the package via your preferred package manager. Here are a few examples: - -```bash -$ pnpm add r18gs -``` - -or - -```bash -$ npm install r18gs -``` - -or - -```bash -$ yarn add r18gs -``` - -## Usage - -Utilize this hook similarly to the `useState` hook. However, ensure to pass a unique key, unique across the app, to identify and make this state accessible to all client components. - -```tsx -const [state, setState] = useRGS("counter", 1); -``` - -You can access the same state across all client-side components using a unique key. - -> It's advisable to store your keys in a separate file to prevent typos and unnecessary conflicts. - -### Example - -```tsx -// constants/global-states.ts -export const COUNTER = "counter"; -``` - -```tsx -// components/display.tsx -"use client"; - -import useRGS from "r18gs"; -import { COUNTER } from "../constants/global-states"; - -export default function Display() { - const [count] = useRGS(COUNTER); - return ( -
-

Client Component 2

- {count} -
- ); -} -``` - -```tsx -// components/counter.tsx -"use client"; - -import useRGS from "r18gs"; -import { COUNTER } from "../constants/global-states"; - -export default function Counter() { - const [count, setCount] = useRGS(COUNTER, 0); - return ( -
-

Client Component 1

- { - setCount(parseInt(e.target.value.trim())); - }} - type="number" - value={count} - /> -
- ); -} -``` - */ -export const A_Quick_Start = "Quick Start"; - -/** - * # Leveraging Plugins - -Enhance your store's functionality by utilizing either the `create` function, `withPlugins` function, or the `useRGSWithPlugins` hook from `r18gs/dist/with-plugins`. This enables features such as storing to local storage, among others. - -## Creating a Store with the `create` Function - -```tsx -// store.ts -import { create } from "r18gs/dist/with-plugins"; -import { persist } from "r18gs/dist/plugins"; // You can create your own plugin or import third-party plugins - -export const useMyPersistentCounterStore = create("persistent-counter", 0, [persist()]); -``` - -Now you can utilize `useMyPersistentCounterStore` similar to `useState` without specifying an initial value. - -```tsx -// inside your component -const [persistedCount, setPersistedCount] = useMyPersistentCounterStore(); -``` - -## Utilizing the `useRGSWithPlugins` Hook - -This function is beneficial if your requirements dictate that your `key` and/or initial value will depend on some props, etc. Or for some other reason you want to initialize the store from within a component (You need to use some variables available inside the component). - -```tsx -import { useRGSWithPlugins } from "r18gs/dist/with-plugin"; - -export function MyComponent(props: MyComponentProps) { - const [state, setState] = useRGSWithPlugins( - props.key, - props.initialVal, - props.plugins, - props.doNotInit, - ); - // ... -} -``` - -### `doNotInit` - -In some cases, you may not want to initialize the store immediately. In such cases, you can pass the fourth argument (`doNotInit`) as `true`. The default value is false. - -- When this argument is set to `true`, the store is created, but the setter function is set to null. Thus, you can access the initial value set by the first component that triggered this hook. However, it cannot be modified until the store is initialized, i.e., the hook is invoked by a component setting `doNotInit` to false (or skipping this argument). - -**Use case**: When you need that the store be used in many components, however, it should be initialized in a particular component only. - -## Creating a Custom Hook using the `withPlugins` Higher-Order Function - -This is a utility function that will be very helpful when you want to use the `useRGSWithPlugins` hook with the same plugins in multiple components. - -```ts -// custom hook file, e.g., store.ts -export const useMyRGS = withPlugins([plugin1, plugin2, ...]); -``` - -```tsx -export function MyComponent(props: MyComponentProps) { - const [state, setState] = useMyRGS(props.key, props.initialVal, props.doNotInit); - // ... -} -``` - -You can also create your own plugins. Refer to [Creating Plugins](./3.creating-plugins.md). - */ -export const B_Leveraging_Plugins = "Leveraging Plugins"; diff --git a/lib/r18gs/src/plugins/persist.ts b/lib/r18gs/src/plugins/persist.ts deleted file mode 100644 index 29f75477..00000000 --- a/lib/r18gs/src/plugins/persist.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Plugin } from ".."; - -export interface PersistOptions { - /** @defaultValue true */ - sync?: boolean; - /** @defaultValue local */ - storage?: "local" | "session" | "cookie"; -} - -/** get stored item */ -const getItem = (key: string, options?: PersistOptions) => { - const cookie = document.cookie.split("; ").find(c => c.startsWith(key)); - switch (options?.storage) { - case "cookie": - return cookie?.split("=")[1]; - case "session": - return sessionStorage.getItem(key); - default: - return localStorage.getItem(key); - } -}; - -/** set item to persistant store */ -const setItem = (key: string, value: string, options?: PersistOptions) => { - switch (options?.storage) { - case "cookie": - document.cookie = `${key}=${value}; max-age=31536000; SameSite=Strict;`; - if (options.sync ?? true) sessionStorage.setItem(key, value); - return; - case "session": - sessionStorage.setItem(key, value); - return; - default: - localStorage.setItem(key, value); - } -}; -/** - * A plugin that persists and syncs RGS store between tabs. - * - * @returns A plugin that persists and syncs a value between tabs. - */ -export const persist = (options?: PersistOptions): Plugin => { - return { - init(key, _, mutate) { - if (typeof window === "undefined") return; - const persistedValue = getItem(key, options); - const newVal = JSON.parse(persistedValue || "{}").val; - if (newVal) mutate(newVal); - - if (options?.sync ?? true) { - addEventListener("storage", e => { - if (e.key === key && e.newValue) { - const newVal = JSON.parse(e.newValue).val; - if (newVal !== undefined) mutate(newVal); - } - }); - } - }, - onChange(key, value) { - if (typeof window !== "undefined") { - setItem(key, JSON.stringify({ val: value }), options); - } - }, - }; -}; diff --git a/lib/r18gs/src/utils.ts b/lib/r18gs/src/utils.ts deleted file mode 100644 index f35cd979..00000000 --- a/lib/r18gs/src/utils.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { useSyncExternalStore } from "react"; - -type Listener = () => void; -type Subscriber = (l: Listener) => () => void; - -export type SetterArgType = T | ((prevState: T) => T); -export type SetStateAction = (value: SetterArgType) => void; -export type ValueType = T | (() => T); - -/** - * This is a hack to reduce lib size + readability + not encouraging direct access to globalThis - */ -const [VALUE, LISTENERS, SETTER, SUBSCRIBER] = [0, 1, 2, 3, 4]; -type RGS = [unknown, Listener[], SetStateAction | null, Subscriber]; - -declare global { - // eslint-disable-next-line no-var -- var required for global declaration. - // skipcq: JS-0102, JS-0239 - var rgs: Record; -} - -const globalThisForBetterMinification = globalThis; -globalThisForBetterMinification.rgs = {}; -export const globalRGS = globalThisForBetterMinification.rgs; - -/** trigger all listeners */ -const triggerListeners = (rgs: RGS) => - (rgs[LISTENERS] as Listener[]).forEach(listener => listener()); - -/** craete subscriber function to subscribe to the store. */ -export const createSubcriber = (key: string): Subscriber => { - return listener => { - const rgs = globalRGS[key] as RGS; - (rgs[LISTENERS] as Listener[]).push(listener); - return () => { - rgs[LISTENERS] = (rgs[LISTENERS] as Listener[]).filter(l => l !== listener); - }; - }; -}; - -/** setter function to set the state. */ -export const createSetter = (key: string): SetStateAction => { - return val => { - const rgs = globalRGS[key] as RGS; - rgs[VALUE] = typeof val === "function" ? val(rgs[VALUE] as T) : val; - (rgs[LISTENERS] as Listener[]).forEach(listener => listener()); - }; -}; - -/** Extract coomon create hook logic to utils */ -export const createHook = (key: string): [T, SetStateAction] => { - const rgs = globalRGS[key] as RGS; - /** This function is called by react to get the current stored value. */ - const getSnapshot = () => rgs[VALUE] as T; - const val = useSyncExternalStore(rgs[SUBSCRIBER] as Subscriber, getSnapshot, getSnapshot); - return [val, rgs[SETTER] as SetStateAction]; -}; - -type Mutate = (value?: T) => void; - -export type Plugin = { - init?: (key: string, value: T | undefined, mutate: Mutate) => void; - onChange?: (key: string, value?: T) => void; -}; - -let allExtentionsInitialized = false; -/** Initialize extestions - wait for previous plugins's promise to be resolved before processing next */ -const initPlugins = async (key: string, plugins: Plugin[]) => { - const rgs = globalRGS[key] as RGS; - /** Mutate function to update the value */ - const mutate: Mutate = newValue => { - rgs[VALUE] = newValue; - triggerListeners(rgs); - }; - for (const plugin of plugins) { - /** Next plugins initializer will get the new value if updated by previous one */ - await plugin.init?.(key, rgs[VALUE] as T, mutate); - } - allExtentionsInitialized = true; -}; - -/** Initialize the named store when invoked for the first time. */ -export const initWithPlugins = ( - key: string, - value?: ValueType, - plugins: Plugin[] = [], - doNotInit = false, -) => { - value = value instanceof Function ? value() : value; - if (doNotInit) { - /** You will not have access to the setter until initialized */ - globalRGS[key] = [value, [], null, createSubcriber(key)]; - return; - } - /** setter function to set the state. */ - const setterWithPlugins: SetStateAction = val => { - /** Do not allow mutating the store before all extentions are initialized */ - if (!allExtentionsInitialized) return; - const rgs = globalRGS[key] as RGS; - rgs[VALUE] = val instanceof Function ? val(rgs[VALUE] as T) : val; - triggerListeners(rgs); - plugins.forEach(plugin => plugin.onChange?.(key, rgs[VALUE] as T)); - }; - - const rgs = globalRGS[key]; - if (rgs) { - rgs[VALUE] = value; - rgs[SETTER] = setterWithPlugins; - } else globalRGS[key] = [value, [], setterWithPlugins, createSubcriber(key)]; - initPlugins(key, plugins); -}; - -/** - * Use this hook similar to `useState` hook. - * The difference is that you need to pass a - * unique key - unique across the app to make - * this state accessible to all client components. - * - * @example - * ```tsx - * const [state, setState] = useRGS("counter", 1); - * ``` - * - * @param key - Unique key to identify the store. - * @param value - Initial value of the store. - * @param plugins - Plugins to be applied to the store. - * @param doNotInit - Do not initialize the store. Useful when you want to initialize the store later. Note that the setter function is not available until the store is initialized. - * @returns - A tuple (Ordered sequance of values) containing the state and a function to set the state. - */ -export const useRGSWithPlugins = ( - key: string, - value?: ValueType, - plugins?: Plugin[], - doNotInit = false, -): [T, SetStateAction] => { - if (!globalRGS[key]?.[SETTER]) initWithPlugins(key, value, plugins, doNotInit); - return createHook(key); -}; diff --git a/lib/r18gs/tsconfig-build.json b/lib/r18gs/tsconfig-build.json deleted file mode 100644 index fd87a4f2..00000000 --- a/lib/r18gs/tsconfig-build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "tsconfig/react-library.json", - "compilerOptions": { - "outDir": "dist", - "emitDeclarationOnly": true, - "declarationMap": false - }, - "include": ["src"], - "exclude": ["dist", "build", "node_modules", "**/*.test.*", "**/*.spec.*"] -} diff --git a/lib/r18gs/tsconfig.json b/lib/r18gs/tsconfig.json deleted file mode 100644 index fd5dc9fa..00000000 --- a/lib/r18gs/tsconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "tsconfig/react-library.json", - "include": ["."], - "exclude": ["dist", "build", "node_modules"] -} diff --git a/lib/r18gs/tsup.config.ts b/lib/r18gs/tsup.config.ts deleted file mode 100644 index ba544fb6..00000000 --- a/lib/r18gs/tsup.config.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { defineConfig } from "tsup"; -import fs from "node:fs"; - -export default defineConfig(options => ({ - format: ["cjs", "esm"], - target: "es2015", - sourcemap: false, - clean: true, - bundle: true, - minify: !options.watch, - esbuildPlugins: [ - { - name: "improve-minify", - setup(build) { - build.onLoad({ filter: /Guides.ts/ }, () => ({ contents: " ", loader: "ts" })); - - build.onLoad({ filter: /utils.ts/ }, args => { - let contents = fs.readFileSync(args.path, "utf8"); - const lines = contents.split("\n"); - const hackLine = lines.find(line => line.startsWith("const [VALUE,")); - - if (!hackLine) return { contents, loader: "ts" }; - /** remove hackLine */ - contents = contents.replace(hackLine, ""); - - /** clean up */ - const tokens = hackLine - .replace("const", "") - .split("=")[0] - .trim() - .replace(/\]|\[/g, "") - .split(",") - .map((t, i) => ({ token: t.trim(), i })); - - tokens.sort((a, b) => b.token.length - a.token.length); - - for (const t of tokens) { - contents = contents.replace(new RegExp(`${t.token}`, "g"), t.i + ""); - } - return { contents, loader: "ts" }; - }); - }, - }, - ], -})); diff --git a/lib/r18gs/typedoc.config.js b/lib/r18gs/typedoc.config.js deleted file mode 100644 index 7ed20189..00000000 --- a/lib/r18gs/typedoc.config.js +++ /dev/null @@ -1,21 +0,0 @@ -/** @type {import('typedoc').TypeDocOptions} */ -module.exports = { - name: "React18 Global Store", - entryPoints: ["./src"], - exclude: ["**/*.test.tsx"], - entryPointStrategy: "Expand", - out: "../../docs", - commentStyle: "all", - searchInComments: true, - hideGenerator: true, - githubPages: false, - navigationLinks: { - GitHub: "https://github.com/react18-tools/react18-global-store", - }, - plugin: [ - "typedoc-plugin-mdn-links", - "typedoc-plugin-rename-defaults", - "typedoc-plugin-missing-exports", - "typedoc-plugin-zod", - ], -}; diff --git a/lib/r18gs/vitest.config.ts b/lib/r18gs/vitest.config.ts deleted file mode 100644 index 2d58bcf9..00000000 --- a/lib/r18gs/vitest.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { defineConfig } from "vitest/config"; -import react from "@vitejs/plugin-react"; -import tsconfigPaths from "vite-tsconfig-paths"; - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [react(), tsconfigPaths()], - test: { - environment: "jsdom", - globals: true, - setupFiles: [], - coverage: { - include: ["src/**"], - exclude: ["src/Guides.ts"], - reporter: ["text", "json", "clover", "html"], - }, - }, -}); diff --git a/lib/r18gs/src/index.ts b/lib/src/index.ts similarity index 67% rename from lib/r18gs/src/index.ts rename to lib/src/index.ts index 8ac4319a..cfb4b274 100644 --- a/lib/r18gs/src/index.ts +++ b/lib/src/index.ts @@ -20,16 +20,19 @@ export type { SetterArgType, SetStateAction, Plugin } from "./utils"; * @param value - Initial value of the store. * @returns - A tuple (Ordered sequance of values) containing the state and a function to set the state. */ -export default (key: string, value?: ValueType): [T, SetStateAction] => { - /** Initialize the named store when invoked for the first time. */ - if (!globalRGS[key]) - globalRGS[key] = [ - // @ts-expect-error -- ok - typeof value === "function" ? value() : value, - [], - createSetter(key), - createSubcriber(key), - ]; +const useRGS = (key: string, value?: ValueType): [T, SetStateAction] => { + /** Initialize the named store when invoked for the first time. */ + if (!globalRGS[key]) + globalRGS[key] = [ + // @ts-expect-error -- ok + typeof value === "function" ? value() : value, + [], + createSetter(key), + createSubcriber(key), + ]; - return createHook(key); + return createHook(key); }; + +export default useRGS; +export { useRGS }; diff --git a/lib/r18gs/src/plugins/index.ts b/lib/src/plugins/index.ts similarity index 100% rename from lib/r18gs/src/plugins/index.ts rename to lib/src/plugins/index.ts diff --git a/lib/src/plugins/persist.ts b/lib/src/plugins/persist.ts new file mode 100644 index 00000000..fc6cb464 --- /dev/null +++ b/lib/src/plugins/persist.ts @@ -0,0 +1,65 @@ +import { Plugin } from ".."; + +export interface PersistOptions { + /** @defaultValue true */ + sync?: boolean; + /** @defaultValue local */ + storage?: "local" | "session" | "cookie"; +} + +/** get stored item */ +const getItem = (key: string, options?: PersistOptions) => { + const cookie = document.cookie.split("; ").find(c => c.startsWith(key)); + switch (options?.storage) { + case "cookie": + return cookie?.split("=")[1]; + case "session": + return sessionStorage.getItem(key); + default: + return localStorage.getItem(key); + } +}; + +/** set item to persistant store */ +const setItem = (key: string, value: string, options?: PersistOptions) => { + switch (options?.storage) { + case "cookie": + document.cookie = `${key}=${value}; max-age=31536000; SameSite=Strict;`; + if (options.sync ?? true) sessionStorage.setItem(key, value); + return; + case "session": + sessionStorage.setItem(key, value); + return; + default: + localStorage.setItem(key, value); + } +}; +/** + * A plugin that persists and syncs RGS store between tabs. + * + * @returns A plugin that persists and syncs a value between tabs. + */ +export const persist = (options?: PersistOptions): Plugin => { + return { + init(key, _, mutate) { + if (typeof window === "undefined") return; + const persistedValue = getItem(key, options); + const newVal = JSON.parse(persistedValue || "{}").val; + if (newVal) mutate(newVal); + + if (options?.sync ?? true) { + addEventListener("storage", e => { + if (e.key === key && e.newValue) { + const newVal = JSON.parse(e.newValue).val; + if (newVal !== undefined) mutate(newVal); + } + }); + } + }, + onChange(key, value) { + if (typeof window !== "undefined") { + setItem(key, JSON.stringify({ val: value }), options); + } + }, + }; +}; diff --git a/lib/src/utils.ts b/lib/src/utils.ts new file mode 100644 index 00000000..1ee02f7d --- /dev/null +++ b/lib/src/utils.ts @@ -0,0 +1,138 @@ +import { useSyncExternalStore } from "react"; + +type Listener = () => void; +type Subscriber = (l: Listener) => () => void; + +export type SetterArgType = T | ((prevState: T) => T); +export type SetStateAction = (value: SetterArgType) => void; +export type ValueType = T | (() => T); + +/** + * This is a hack to reduce lib size + readability + not encouraging direct access to globalThis + */ +const [VALUE, LISTENERS, SETTER, SUBSCRIBER] = [0, 1, 2, 3, 4]; +type RGS = [unknown, Listener[], SetStateAction | null, Subscriber]; + +declare global { + // eslint-disable-next-line no-var -- var required for global declaration. + // skipcq: JS-0102, JS-0239 + var rgs: Record; +} + +const globalThisForBetterMinification = globalThis; +globalThisForBetterMinification.rgs = {}; +export const globalRGS = globalThisForBetterMinification.rgs; + +/** trigger all listeners */ +const triggerListeners = (rgs: RGS) => + (rgs[LISTENERS] as Listener[]).forEach(listener => listener()); + +/** craete subscriber function to subscribe to the store. */ +export const createSubcriber = (key: string): Subscriber => { + return listener => { + const rgs = globalRGS[key] as RGS; + (rgs[LISTENERS] as Listener[]).push(listener); + return () => { + rgs[LISTENERS] = (rgs[LISTENERS] as Listener[]).filter(l => l !== listener); + }; + }; +}; + +/** setter function to set the state. */ +export const createSetter = (key: string): SetStateAction => { + return val => { + const rgs = globalRGS[key] as RGS; + rgs[VALUE] = typeof val === "function" ? val(rgs[VALUE] as T) : val; + (rgs[LISTENERS] as Listener[]).forEach(listener => listener()); + }; +}; + +/** Extract coomon create hook logic to utils */ +export const createHook = (key: string): [T, SetStateAction] => { + const rgs = globalRGS[key] as RGS; + /** This function is called by react to get the current stored value. */ + const getSnapshot = () => rgs[VALUE] as T; + const val = useSyncExternalStore(rgs[SUBSCRIBER] as Subscriber, getSnapshot, getSnapshot); + return [val, rgs[SETTER] as SetStateAction]; +}; + +type Mutate = (value?: T) => void; + +export type Plugin = { + init?: (key: string, value: T | undefined, mutate: Mutate) => void; + onChange?: (key: string, value?: T) => void; +}; + +let allExtentionsInitialized = false; +/** Initialize extestions - wait for previous plugins's promise to be resolved before processing next */ +const initPlugins = async (key: string, plugins: Plugin[]) => { + const rgs = globalRGS[key] as RGS; + /** Mutate function to update the value */ + const mutate: Mutate = newValue => { + rgs[VALUE] = newValue; + triggerListeners(rgs); + }; + for (const plugin of plugins) { + /** Next plugins initializer will get the new value if updated by previous one */ + await plugin.init?.(key, rgs[VALUE] as T, mutate); + } + allExtentionsInitialized = true; +}; + +/** Initialize the named store when invoked for the first time. */ +export const initWithPlugins = ( + key: string, + value?: ValueType, + plugins: Plugin[] = [], + doNotInit = false, +) => { + value = value instanceof Function ? value() : value; + if (doNotInit) { + /** You will not have access to the setter until initialized */ + globalRGS[key] = [value, [], null, createSubcriber(key)]; + return; + } + /** setter function to set the state. */ + const setterWithPlugins: SetStateAction = val => { + /** Do not allow mutating the store before all extentions are initialized */ + if (!allExtentionsInitialized) return; + const rgs = globalRGS[key] as RGS; + rgs[VALUE] = val instanceof Function ? val(rgs[VALUE] as T) : val; + triggerListeners(rgs); + plugins.forEach(plugin => plugin.onChange?.(key, rgs[VALUE] as T)); + }; + + const rgs = globalRGS[key]; + if (rgs) { + rgs[VALUE] = value; + rgs[SETTER] = setterWithPlugins; + } else globalRGS[key] = [value, [], setterWithPlugins, createSubcriber(key)]; + initPlugins(key, plugins); +}; + +/** + * Use this hook similar to `useState` hook. + * The difference is that you need to pass a + * unique key - unique across the app to make + * this state accessible to all client components. + * + * @example + * ```tsx + * const [state, setState] = useRGS("counter", 1); + * ``` + * + * @param key - Unique key to identify the store. + * @param value - Initial value of the store. + * @param plugins - Plugins to be applied to the store. + * @param doNotInit - Do not initialize the store. Useful when you want to initialize the store later. Note that the setter function is not available until the store is initialized. + * @returns - A tuple (Ordered sequance of values) containing the state and a function to set the state. + */ +export const useRGSWithPlugins = ( + key: string, + value?: ValueType, + plugins?: Plugin[], + doNotInit = false, +): [T, SetStateAction] => { + if (!globalRGS[key]?.[SETTER]) initWithPlugins(key, value, plugins, doNotInit); + return createHook(key); +}; diff --git a/lib/r18gs/src/with-plugins.ts b/lib/src/with-plugins.ts similarity index 59% rename from lib/r18gs/src/with-plugins.ts rename to lib/src/with-plugins.ts index 804a293a..b3c4f523 100644 --- a/lib/r18gs/src/with-plugins.ts +++ b/lib/src/with-plugins.ts @@ -21,11 +21,11 @@ import type { Plugin, SetStateAction } from "./utils"; * @returns - A hook function that returns a tuple (Ordered sequence of values) containing the state and a function to set the state. */ export const create = ( - key: string, - value?: T, - plugins?: Plugin[], + key: string, + value?: T, + plugins?: Plugin[], ): (() => [T, SetStateAction]) => { - return () => useRGSWithPlugins(key, value, plugins); + return () => useRGSWithPlugins(key, value, plugins); }; /** @@ -35,24 +35,24 @@ export const create = ( * @returns A hook that automatically initializes the store (if not already initialized) with the given plugins. */ export const withPlugins = ( - plugins: Plugin[], + plugins: Plugin[], ): ((key: string, value?: U, doNotInit?: boolean) => [U, SetStateAction]) => { - /** - * Creates a hook similar to useRGS, with plugins applied on first invocation. - * - * @param key - Unique key to identify the store. - * @param value - Initial value of the store. - * @param doNotInit - If true, the store won't be initialized immediately. Defaults to false. Useful when you want to initialize the store later. Note that the setter function is not available until the store is initialized. - * @returns A tuple containing the state value and its setter function. - */ - const hookWithPlugins = ( - key: string, - value?: U, - doNotInit = false, - ): [U, SetStateAction] => - useRGSWithPlugins(key, value, plugins as unknown as Plugin[], doNotInit); + /** + * Creates a hook similar to useRGS, with plugins applied on first invocation. + * + * @param key - Unique key to identify the store. + * @param value - Initial value of the store. + * @param doNotInit - If true, the store won't be initialized immediately. Defaults to false. Useful when you want to initialize the store later. Note that the setter function is not available until the store is initialized. + * @returns A tuple containing the state value and its setter function. + */ + const hookWithPlugins = ( + key: string, + value?: U, + doNotInit = false, + ): [U, SetStateAction] => + useRGSWithPlugins(key, value, plugins as unknown as Plugin[], doNotInit); - return hookWithPlugins; + return hookWithPlugins; }; export { useRGSWithPlugins }; diff --git a/lib/r18gs/tests/create.test.tsx b/lib/tests/create.test.tsx similarity index 100% rename from lib/r18gs/tests/create.test.tsx rename to lib/tests/create.test.tsx diff --git a/lib/r18gs/tests/plugins/persist.test.tsx b/lib/tests/plugins/persist.test.tsx similarity index 100% rename from lib/r18gs/tests/plugins/persist.test.tsx rename to lib/tests/plugins/persist.test.tsx diff --git a/lib/r18gs/tests/use-rgs.test.tsx b/lib/tests/use-rgs.test.tsx similarity index 100% rename from lib/r18gs/tests/use-rgs.test.tsx rename to lib/tests/use-rgs.test.tsx diff --git a/lib/tsconfig-build.json b/lib/tsconfig-build.json new file mode 100644 index 00000000..66cc4082 --- /dev/null +++ b/lib/tsconfig-build.json @@ -0,0 +1,12 @@ +{ + // using tsc for type declarations as "Note that declaration files generated by any tool other than tsc are not guaranteed to be error-free, so it's a good idea to test the output with tsc" - https://tsup.egoist.dev/#generate-declaration-file + "extends": "@repo/typescript-config/react-library.json", + "compilerOptions": { + "outDir": "dist", + "noEmit": false, + "emitDeclarationOnly": true, + "declarationMap": false + }, + "include": ["src"], + "exclude": ["dist", "node_modules", "**/*.test.*", "**/*.spec.*"] +} diff --git a/lib/tsconfig.json b/lib/tsconfig.json new file mode 100644 index 00000000..9430b2f8 --- /dev/null +++ b/lib/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@repo/typescript-config/react-library.json", + "compilerOptions": { + "lib": ["dom", "ES2015"], + "types": ["vitest", "node"] + }, + "include": ["."], + "exclude": ["dist", "build", "node_modules"] +} diff --git a/lib/tsup.config.ts b/lib/tsup.config.ts new file mode 100644 index 00000000..c09a8bc1 --- /dev/null +++ b/lib/tsup.config.ts @@ -0,0 +1,18 @@ +import { defineConfig, type Options } from "tsup"; +import react18Plugin from "esbuild-plugin-react18"; +import cssPlugin from "esbuild-plugin-react18-css"; + +export default defineConfig( + (options: Options) => + ({ + format: ["cjs", "esm"], + target: "es2019", + entry: ["./src"], + sourcemap: false, + clean: !options.watch, + bundle: true, + minify: !options.watch, + esbuildPlugins: [react18Plugin(), cssPlugin({ generateScopedName: "[folder]__[local]" })], + ...options, + }) as Options, +); diff --git a/lib/turbo.json b/lib/turbo.json new file mode 100644 index 00000000..52e8c763 --- /dev/null +++ b/lib/turbo.json @@ -0,0 +1,12 @@ +{ + "extends": [ + "//" + ], + "tasks": { + "build": { + "outputs": [ + "dist/**" + ] + } + } +} diff --git a/lib/vitest.config.ts b/lib/vitest.config.ts new file mode 100644 index 00000000..2b92a076 --- /dev/null +++ b/lib/vitest.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from "vitest/config"; +import react from "@vitejs/plugin-react"; +import tsconfigPaths from "vite-tsconfig-paths"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react(), tsconfigPaths()], + test: { + environment: "jsdom", + globals: true, + setupFiles: [], + coverage: { + include: ["src/**"], + reporter: ["text", "json", "clover", "html"], + }, + }, +}); diff --git a/package.json b/package.json index c59a0579..a8693df2 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,35 @@ { "private": true, "scripts": { - "build": "turbo run build", - "dev": "turbo run dev", - "test": "turbo run test", - "doc": "turbo run doc", - "lint": "turbo run lint", - "format": "prettier --write \"**/*.{ts,tsx,js,jsx,md,css,scss}\"" + "build": "turbo build", + "clean": "turbo clean", + "dev": "turbo dev", + "doc": "node scripts/doc.js && typedoc", + "format": "prettier --write \"**/*.{ts,tsx,md,css,scss}\"", + "lint": "turbo lint", + "test": "turbo test", + "typecheck": "turbo typecheck", + "preinstall": "node scripts/update-pm.js" }, "devDependencies": { "@changesets/cli": "^2.27.5", - "eslint": "^9.5.0", + "@repo/typescript-config": "workspace:*", + "plop": "^4.0.1", "prettier": "^3.3.2", - "tsconfig": "workspace:*", - "turbo": "^2.0.4" + "turbo": "^2.0.4", + "typedoc": "^0.25.13", + "typedoc-plugin-extras": "^3.0.0", + "typedoc-plugin-inline-sources": "^1.0.2", + "typedoc-plugin-mdn-links": "^3.1.30", + "typedoc-plugin-missing-exports": "^2.3.0", + "typedoc-plugin-rename-defaults": "^0.7.0", + "typedoc-plugin-zod": "^1.1.2", + "@types/node": "^20.14.2", + "enquirer": "^2.4.1" }, - "name": "r18gs", - "packageManager": "pnpm@9.1.4" -} + "packageManager": "pnpm@9.3.0", + "engines": { + "node": ">=18" + }, + "name": "turborepo-template" +} \ No newline at end of file diff --git a/packages/eslint-config-custom/README.md b/packages/config-eslint/README.md similarity index 100% rename from packages/eslint-config-custom/README.md rename to packages/config-eslint/README.md diff --git a/packages/config-eslint/index.js b/packages/config-eslint/index.js new file mode 100644 index 00000000..c667cd10 --- /dev/null +++ b/packages/config-eslint/index.js @@ -0,0 +1,34 @@ +const { resolve } = require("node:path"); + +const project = resolve(process.cwd(), "tsconfig.json"); + +/** @type {import("eslint").Linter.Config} */ +module.exports = { + extends: ["eslint:recommended", "prettier", "eslint-config-turbo"], + plugins: ["only-warn"], + globals: { + React: true, + JSX: true, + }, + env: { + node: true, + }, + settings: { + "import/resolver": { + typescript: { + project, + }, + }, + }, + ignorePatterns: [ + // Ignore dotfiles + ".*.js", + "node_modules/", + "dist/", + ], + overrides: [ + { + files: ["*.js?(x)", "*.ts?(x)"], + }, + ], +}; diff --git a/packages/config-eslint/next.js b/packages/config-eslint/next.js new file mode 100644 index 00000000..e2ca3886 --- /dev/null +++ b/packages/config-eslint/next.js @@ -0,0 +1,43 @@ +const { resolve } = require("node:path"); + +const project = resolve(process.cwd(), "tsconfig.json"); + +/* + * This is a custom ESLint configuration for use with + * Next.js apps. + * + * This config extends the Vercel Engineering Style Guide. + * For more information, see https://github.com/vercel/style-guide + * + */ + +module.exports = { + extends: [ + "@vercel/style-guide/eslint/node", + "@vercel/style-guide/eslint/typescript", + "@vercel/style-guide/eslint/browser", + "@vercel/style-guide/eslint/react", + "@vercel/style-guide/eslint/next", + "eslint-config-turbo", + ].map(require.resolve), + parserOptions: { + project, + }, + globals: { + React: true, + JSX: true, + }, + plugins: ["only-warn"], + settings: { + "import/resolver": { + typescript: { + project, + }, + }, + }, + ignorePatterns: [".*.js", "node_modules/", "dist/"], + // add rules configurations here + rules: { + "import/no-default-export": "off", + }, +}; diff --git a/packages/config-eslint/package.json b/packages/config-eslint/package.json new file mode 100644 index 00000000..83235c05 --- /dev/null +++ b/packages/config-eslint/package.json @@ -0,0 +1,13 @@ +{ + "name": "@repo/eslint-config", + "license": "MIT", + "version": "0.0.0", + "private": true, + "devDependencies": { + "@vercel/style-guide": "^6.0.0", + "eslint-config-turbo": "^2.0.4", + "eslint-plugin-mdx": "^3.1.5", + "eslint-plugin-only-warn": "^1.1.0", + "eslint-plugin-storybook": "^0.8.0" + } +} \ No newline at end of file diff --git a/packages/config-eslint/react.js b/packages/config-eslint/react.js new file mode 100644 index 00000000..16f46ee9 --- /dev/null +++ b/packages/config-eslint/react.js @@ -0,0 +1,39 @@ +const { resolve } = require("node:path"); + +const project = resolve(process.cwd(), "tsconfig.json"); + +/* + * This is a custom ESLint configuration for use a library + * that utilizes React. + * + * This config extends the Vercel Engineering Style Guide. + * For more information, see https://github.com/vercel/style-guide + * + */ + +module.exports = { + extends: [ + "@vercel/style-guide/eslint/browser", + "@vercel/style-guide/eslint/typescript", + "@vercel/style-guide/eslint/react", + ].map(require.resolve), + parserOptions: { + project, + }, + globals: { + JSX: true, + }, + plugins: ["only-warn"], + settings: { + "import/resolver": { + typescript: { + project, + }, + }, + }, + ignorePatterns: ["node_modules/", "dist/", ".eslintrc.js", "**/*.css"], + // add rules configurations here + rules: { + "import/no-default-export": "off", + }, +}; diff --git a/packages/config-eslint/remix.js b/packages/config-eslint/remix.js new file mode 100644 index 00000000..bd351154 --- /dev/null +++ b/packages/config-eslint/remix.js @@ -0,0 +1,43 @@ +const { resolve } = require("node:path"); + +const project = resolve(process.cwd(), "tsconfig.json"); + +/* + * This is a custom ESLint configuration for use a library + * that utilizes React. + * + * This config extends the Vercel Engineering Style Guide. + * For more information, see https://github.com/vercel/style-guide + * + */ + +module.exports = { + extends: [ + "@vercel/style-guide/eslint/browser", + "@vercel/style-guide/eslint/typescript", + "@vercel/style-guide/eslint/react", + ].map(require.resolve), + parserOptions: { + project, + }, + env: { + browser: true, + node: true, + }, + plugins: ["only-warn"], + globals: { + JSX: true, + }, + settings: { + "import/resolver": { + typescript: { + project, + }, + }, + }, + ignorePatterns: ["node_modules/", "dist/", ".eslintrc.js", "**/*.css"], + // add rules configurations here + rules: { + "import/no-default-export": "off", + }, +}; diff --git a/packages/config-eslint/server.js b/packages/config-eslint/server.js new file mode 100644 index 00000000..f84343f2 --- /dev/null +++ b/packages/config-eslint/server.js @@ -0,0 +1,46 @@ +const { resolve } = require("node:path"); + +const project = resolve(process.cwd(), "tsconfig.json"); + +/* + * This is a custom ESLint configuration for use server side + * typescript packages. + * + * This config extends the Vercel Engineering Style Guide. + * For more information, see https://github.com/vercel/style-guide + * + */ + +module.exports = { + extends: ["@vercel/style-guide/eslint/node", "@vercel/style-guide/eslint/typescript"].map( + require.resolve, + ), + parserOptions: { + project, + }, + env: { + node: true, + es6: true, + }, + plugins: ["only-warn"], + settings: { + "import/resolver": { + typescript: { + project, + }, + }, + }, + overrides: [ + { + files: ["**/__tests__/**/*"], + env: { + jest: true, + }, + }, + ], + ignorePatterns: [".*.js", "node_modules/", "dist/"], + // add rules configurations here + rules: { + "import/no-default-export": "off", + }, +}; diff --git a/packages/tsconfig/base.json b/packages/config-typescript/base.json similarity index 81% rename from packages/tsconfig/base.json rename to packages/config-typescript/base.json index 837bec34..56d01edd 100644 --- a/packages/tsconfig/base.json +++ b/packages/config-typescript/base.json @@ -7,14 +7,17 @@ "declarationMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, + "allowImportingTsExtensions": true, "inlineSources": false, "isolatedModules": true, - "moduleResolution": "node", + "module": "ESNext", + "moduleResolution": "Bundler", "noUnusedLocals": false, "noUnusedParameters": false, "preserveWatchOutput": true, "skipLibCheck": true, "strict": true, + "noEmit": true, "strictNullChecks": true }, "exclude": ["node_modules"] diff --git a/packages/tsconfig/nextjs.json b/packages/config-typescript/nextjs.json similarity index 82% rename from packages/tsconfig/nextjs.json rename to packages/config-typescript/nextjs.json index d5010a1b..b6ef83f8 100644 --- a/packages/tsconfig/nextjs.json +++ b/packages/config-typescript/nextjs.json @@ -13,9 +13,6 @@ "module": "esnext", "noEmit": true, "resolveJsonModule": true, - "strict": false, "target": "es5" - }, - "include": ["src", "next-env.d.ts"], - "exclude": ["node_modules"] + } } diff --git a/packages/tsconfig/package.json b/packages/config-typescript/package.json similarity index 74% rename from packages/tsconfig/package.json rename to packages/config-typescript/package.json index 6efb83e1..ac9f0b12 100644 --- a/packages/tsconfig/package.json +++ b/packages/config-typescript/package.json @@ -1,9 +1,9 @@ { - "name": "tsconfig", + "name": "@repo/typescript-config", "version": "0.0.0", "private": true, "license": "MIT", "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/config-typescript/react-app.json b/packages/config-typescript/react-app.json new file mode 100644 index 00000000..6af13474 --- /dev/null +++ b/packages/config-typescript/react-app.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Next.js", + "extends": "./base.json", + "compilerOptions": { + "allowJs": true, + "declaration": false, + "declarationMap": false, + "incremental": true, + "jsx": "preserve", + "lib": ["dom", "dom.iterable", "esnext"], + "module": "esnext", + "noEmit": true, + "resolveJsonModule": true, + "target": "es5" + } +} diff --git a/packages/tsconfig/react-library.json b/packages/config-typescript/react-library.json similarity index 84% rename from packages/tsconfig/react-library.json rename to packages/config-typescript/react-library.json index 36b62be3..3cf2d7a2 100644 --- a/packages/tsconfig/react-library.json +++ b/packages/config-typescript/react-library.json @@ -3,9 +3,10 @@ "display": "React Library", "extends": "./base.json", "compilerOptions": { - "jsx": "react-jsx", "lib": ["ES2015", "DOM"], "module": "ESNext", - "target": "es6" + "target": "ES6", + "jsx": "react-jsx", + "noEmit": true } } diff --git a/packages/config-typescript/remix.json b/packages/config-typescript/remix.json new file mode 100644 index 00000000..a4b843ea --- /dev/null +++ b/packages/config-typescript/remix.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Remix", + "extends": "./base.json", + "compilerOptions": { + "lib": ["DOM", "DOM.Iterable", "ES2019"], + "isolatedModules": true, + "esModuleInterop": true, + "jsx": "react-jsx", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "target": "ES2019", + "strict": true, + "allowJs": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": "." + } +} diff --git a/packages/config-typescript/vite.json b/packages/config-typescript/vite.json new file mode 100644 index 00000000..46c2e55b --- /dev/null +++ b/packages/config-typescript/vite.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "./base.json", + "Display": "Vite", + "compilerOptions": { + "allowJs": false, + "esModuleInterop": false, + "jsx": "react", + "lib": ["dom", "dom.iterable", "esnext"], + "module": "ESNext", + "noEmit": true, + "resolveJsonModule": true, + "skipLibCheck": false, + "target": "ESNext", + "types": ["vite/client"] + } +} diff --git a/packages/eslint-config-custom/CHANGELOG.md b/packages/eslint-config-custom/CHANGELOG.md deleted file mode 100644 index 08f8a0f2..00000000 --- a/packages/eslint-config-custom/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# eslint-config-custom - -## 0.0.1 - -### Patch Changes - -- Support Next.js 14 diff --git a/packages/eslint-config-custom/library.js b/packages/eslint-config-custom/library.js deleted file mode 100644 index db32ca2c..00000000 --- a/packages/eslint-config-custom/library.js +++ /dev/null @@ -1,33 +0,0 @@ -const { resolve } = require("node:path"); - -const project = resolve(process.cwd(), "tsconfig.json"); - -/* - * This is a custom ESLint configuration for use with - * typescript packages. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * - */ - -module.exports = { - extends: ["@vercel/style-guide/eslint/node", "@vercel/style-guide/eslint/typescript"].map( - require.resolve, - ), - parserOptions: { - project, - }, - globals: { - React: true, - JSX: true, - }, - settings: { - "import/resolver": { - typescript: { - project, - }, - }, - }, - ignorePatterns: ["node_modules/", "dist/"], -}; diff --git a/packages/eslint-config-custom/next.js b/packages/eslint-config-custom/next.js deleted file mode 100644 index 3cee3392..00000000 --- a/packages/eslint-config-custom/next.js +++ /dev/null @@ -1,43 +0,0 @@ -const { resolve } = require("node:path"); - -const project = resolve(process.cwd(), "tsconfig.json"); - -/* - * This is a custom ESLint configuration for use with - * Next.js apps. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * - */ - -module.exports = { - extends: [ - "@vercel/style-guide/eslint/node", - "@vercel/style-guide/eslint/typescript", - "@vercel/style-guide/eslint/browser", - "@vercel/style-guide/eslint/react", - "@vercel/style-guide/eslint/next", - "eslint-config-turbo", - ].map(require.resolve), - parserOptions: { - project, - }, - globals: { - React: true, - JSX: true, - }, - settings: { - "import/resolver": { - typescript: { - project, - }, - }, - }, - ignorePatterns: ["node_modules/", "dist/"], - // add rules configurations here - rules: { - "import/no-default-export": "off", - "unicorn/filename-case": "off", - }, -}; diff --git a/packages/eslint-config-custom/package.json b/packages/eslint-config-custom/package.json deleted file mode 100644 index 4d338ef8..00000000 --- a/packages/eslint-config-custom/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "eslint-config-custom", - "license": "MIT", - "version": "0.0.1", - "private": true, - "devDependencies": { - "@vercel/style-guide": "^6.0.0", - "eslint-config-turbo": "^2.0.1" - } -} diff --git a/packages/eslint-config-custom/react-internal.js b/packages/eslint-config-custom/react-internal.js deleted file mode 100644 index d944fe95..00000000 --- a/packages/eslint-config-custom/react-internal.js +++ /dev/null @@ -1,40 +0,0 @@ -const { resolve } = require("node:path"); - -const project = resolve(process.cwd(), "tsconfig.json"); - -/* - * This is a custom ESLint configuration for use with - * internal (bundled by their consumer) libraries - * that utilize React. - * - * This config extends the Vercel Engineering Style Guide. - * For more information, see https://github.com/vercel/style-guide - * - */ - -module.exports = { - extends: [ - "@vercel/style-guide/eslint/browser", - "@vercel/style-guide/eslint/typescript", - "@vercel/style-guide/eslint/react", - ].map(require.resolve), - parserOptions: { - project, - }, - globals: { - JSX: true, - }, - settings: { - "import/resolver": { - typescript: { - project, - }, - }, - }, - ignorePatterns: ["node_modules/", "dist/", ".eslintrc.js"], - // add rules configurations here - rules: { - "import/no-default-export": "off", - "@typescript-eslint/explicit-function-return-type": "off", - }, -}; diff --git a/packages/jest-presets/browser/jest-preset.js b/packages/jest-presets/browser/jest-preset.js new file mode 100644 index 00000000..3173ffd6 --- /dev/null +++ b/packages/jest-presets/browser/jest-preset.js @@ -0,0 +1,14 @@ +module.exports = { + roots: [""], + testEnvironment: "jsdom", + transform: { + "^.+\\.tsx?$": "ts-jest", + }, + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + modulePathIgnorePatterns: [ + "/test/__fixtures__", + "/node_modules", + "/dist", + ], + preset: "ts-jest", +}; diff --git a/packages/jest-presets/node/jest-preset.js b/packages/jest-presets/node/jest-preset.js new file mode 100644 index 00000000..b6c25930 --- /dev/null +++ b/packages/jest-presets/node/jest-preset.js @@ -0,0 +1,13 @@ +module.exports = { + roots: [""], + transform: { + "^.+\\.tsx?$": "ts-jest", + }, + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + modulePathIgnorePatterns: [ + "/test/__fixtures__", + "/node_modules", + "/dist", + ], + preset: "ts-jest", +}; diff --git a/packages/jest-presets/package.json b/packages/jest-presets/package.json new file mode 100644 index 00000000..2e41bb45 --- /dev/null +++ b/packages/jest-presets/package.json @@ -0,0 +1,16 @@ +{ + "name": "@repo/jest-presets", + "version": "0.0.0", + "private": true, + "license": "MIT", + "files": [ + "browser/jest-preset.js", + "node/jest-preset.js" + ], + "dependencies": { + "ts-jest": "^29.1.5" + }, + "devDependencies": { + "jest-environment-jsdom": "^29.7.0" + } +} \ No newline at end of file diff --git a/packages/logger/.eslintrc.js b/packages/logger/.eslintrc.js new file mode 100644 index 00000000..49f67f37 --- /dev/null +++ b/packages/logger/.eslintrc.js @@ -0,0 +1,11 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + extends: ["@repo/eslint-config/index.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, + env: { + jest: true, + }, +}; diff --git a/packages/logger/package.json b/packages/logger/package.json new file mode 100644 index 00000000..f11abd8c --- /dev/null +++ b/packages/logger/package.json @@ -0,0 +1,30 @@ +{ + "name": "@repo/logger", + "version": "0.0.0", + "private": true, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist/**" + ], + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "lint": "eslint src/", + "typecheck": "tsc --noEmit", + "test": "jest" + }, + "jest": { + "preset": "@repo/jest-presets/node" + }, + "devDependencies": { + "@repo/eslint-config": "workspace:*", + "@repo/jest-presets": "workspace:*", + "@repo/typescript-config": "workspace:*", + "@types/jest": "^29.5.12", + "@types/node": "^20.14.2", + "jest": "^29.7.0", + "tsup": "^8.1.0", + "typescript": "^5.4.5" + } +} \ No newline at end of file diff --git a/packages/logger/src/__tests__/log.test.ts b/packages/logger/src/__tests__/log.test.ts new file mode 100644 index 00000000..e196fcc9 --- /dev/null +++ b/packages/logger/src/__tests__/log.test.ts @@ -0,0 +1,11 @@ +import { log } from ".."; + +jest.spyOn(global.console, "log"); + +describe("@repo/logger", () => { + it("prints a message", () => { + log("hello"); + // eslint-disable-next-line no-console -- testing console + expect(console.log).toBeCalledWith("LOGGER: ", "hello"); + }); +}); diff --git a/packages/logger/src/index.ts b/packages/logger/src/index.ts new file mode 100644 index 00000000..d573ddf4 --- /dev/null +++ b/packages/logger/src/index.ts @@ -0,0 +1,4 @@ +export const log = (...args: unknown[]): void => { + // eslint-disable-next-line no-console -- logger + console.log("LOGGER: ", ...args); +}; diff --git a/packages/logger/tsconfig.json b/packages/logger/tsconfig.json new file mode 100644 index 00000000..a7f4e490 --- /dev/null +++ b/packages/logger/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@repo/typescript-config/base.json", + "compilerOptions": { + "lib": ["ES2015"], + "outDir": "./dist", + "types": ["jest", "node"] + }, + "include": ["."], + "exclude": ["node_modules", "dist"], +} diff --git a/packages/logger/tsup.config.ts b/packages/logger/tsup.config.ts new file mode 100644 index 00000000..be508ff5 --- /dev/null +++ b/packages/logger/tsup.config.ts @@ -0,0 +1,9 @@ +import { defineConfig, type Options } from "tsup"; + +export default defineConfig((options: Options) => ({ + entryPoints: ["src/index.ts"], + clean: true, + dts: true, + format: ["cjs"], + ...options, +})); diff --git a/packages/logger/turbo.json b/packages/logger/turbo.json new file mode 100644 index 00000000..52e8c763 --- /dev/null +++ b/packages/logger/turbo.json @@ -0,0 +1,12 @@ +{ + "extends": [ + "//" + ], + "tasks": { + "build": { + "outputs": [ + "dist/**" + ] + } + } +} diff --git a/packages/shared-ui/.eslintrc.js b/packages/shared-ui/.eslintrc.js deleted file mode 100644 index 05ac2b2b..00000000 --- a/packages/shared-ui/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ["custom/react-internal"], -}; diff --git a/packages/shared-ui/hooks/use-persistant-counter.ts b/packages/shared-ui/hooks/use-persistant-counter.ts deleted file mode 100644 index 18fdf006..00000000 --- a/packages/shared-ui/hooks/use-persistant-counter.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { create } from "r18gs/dist/with-plugins"; -import { persist } from "r18gs/dist/plugins"; - -export const useMyPersistentCounterStore = create("persistent-counter", 1, [persist()]); diff --git a/packages/shared-ui/index.ts b/packages/shared-ui/index.ts deleted file mode 100644 index 3bd16e17..00000000 --- a/packages/shared-ui/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./src"; diff --git a/packages/shared-ui/package.json b/packages/shared-ui/package.json deleted file mode 100644 index 298eb621..00000000 --- a/packages/shared-ui/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "shared-ui", - "author": "Mayank Kumar Chaudhari ", - "private": true, - "version": "0.0.0", - "description": "Shared UI Package", - "main": "./index.ts", - "types": "./index.ts", - "scripts": { - "lint": "eslint ." - }, - "devDependencies": { - "@mayank1513/fork-me": "^2.1.2", - "@types/node": "^20.14.1", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "eslint-config-custom": "workspace:*", - "next": "^14.2.3", - "r18gs": "workspace:*", - "react": "^18.3.1", - "tsconfig": "workspace:*", - "typescript": "5.4.5" - }, - "dependencies": { - "eslint": "^9.4.0", - "nthul-lite": "^0.2.3" - } -} diff --git a/packages/shared-ui/src/cards/card.tsx b/packages/shared-ui/src/cards/card.tsx deleted file mode 100644 index ac1b091b..00000000 --- a/packages/shared-ui/src/cards/card.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import styles from "./cards.module.css"; - -interface CardProps { - href: string; - title: string; - description: string; -} - -export function Card({ href, title, description }: CardProps) { - return ( - -

- {title} -> -

-

{description}

-
- ); -} diff --git a/packages/shared-ui/src/cards/cards.module.css b/packages/shared-ui/src/cards/cards.module.css deleted file mode 100644 index 050430d1..00000000 --- a/packages/shared-ui/src/cards/cards.module.css +++ /dev/null @@ -1,75 +0,0 @@ -.cards { - display: flex; - justify-content: space-evenly; - flex-wrap: wrap; - gap: 25px; - width: var(--max-width); - max-width: 95vw; -} - -.card { - all: unset; - display: flex; - flex-direction: column; - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0.1); - cursor: pointer; - transition: - background 200ms, - border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-top: 0; - text-align: start; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - width: 34ch; - text-align: start; -} - -.card nav { - display: flex; - gap: 15px; - padding-top: 10px; -} - -.card nav select { - flex-grow: 1; -} - -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -/* Mobile and Tablet */ -@media (max-width: 1023px) { - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } -} diff --git a/packages/shared-ui/src/cards/index.tsx b/packages/shared-ui/src/cards/index.tsx deleted file mode 100644 index c2a91604..00000000 --- a/packages/shared-ui/src/cards/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import styles from "./cards.module.css"; -import { StarMeCard } from "./star-me-card"; -import { Card } from "./card"; - -const cards = [ - { - href: "https://react18-tools.github.io/r18gs/", - title: "Docs", - description: "Explore the official docs.", - }, - { - href: "https://github.com/react18-tools/r18gs", - title: "More Examples", - description: "Explore more examples on official GitHub Repo.", - }, -]; - -export function Cards() { - return ( -
- {cards.map(card => ( - - ))} - -
- ); -} diff --git a/packages/shared-ui/src/cards/star-me-card.tsx b/packages/shared-ui/src/cards/star-me-card.tsx deleted file mode 100644 index e4c68510..00000000 --- a/packages/shared-ui/src/cards/star-me-card.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { StarMe } from "@mayank1513/fork-me"; -import styles from "./cards.module.css"; - -export function StarMeCard() { - return ( - -

- Star this repo -> -

-

Star this repo for your new library!

-
- ); -} diff --git a/packages/shared-ui/src/common/logo.tsx b/packages/shared-ui/src/common/logo.tsx deleted file mode 100644 index 9a336de6..00000000 --- a/packages/shared-ui/src/common/logo.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import type { HTMLProps } from "react"; - -export function Logo(props: HTMLProps) { - return r18gs; -} diff --git a/packages/shared-ui/src/common/select.tsx b/packages/shared-ui/src/common/select.tsx deleted file mode 100644 index bbacd8fb..00000000 --- a/packages/shared-ui/src/common/select.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { HTMLProps, ReactNode } from "react"; - -export interface SelectOptionsProps { - value: string; - children: ReactNode; -} - -interface SelectProps extends HTMLProps { - options: string[] | SelectOptionsProps[]; -} - -export function Select({ options, ...props }: SelectProps) { - const renderOptions = options.map(option => - typeof option === "string" ? { value: option, children: option } : option, - ); - return ( - - ); -} diff --git a/packages/shared-ui/src/constants/global-states.ts b/packages/shared-ui/src/constants/global-states.ts deleted file mode 100644 index 6c534d24..00000000 --- a/packages/shared-ui/src/constants/global-states.ts +++ /dev/null @@ -1 +0,0 @@ -export const COUNTER = "counter"; diff --git a/packages/shared-ui/src/declaration.d.ts b/packages/shared-ui/src/declaration.d.ts deleted file mode 100644 index a1421d73..00000000 --- a/packages/shared-ui/src/declaration.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module "*.module.css" { - const classNames: Record; - export = classNames; -} diff --git a/packages/shared-ui/src/globals.css b/packages/shared-ui/src/globals.css deleted file mode 100644 index a88be8e2..00000000 --- a/packages/shared-ui/src/globals.css +++ /dev/null @@ -1,115 +0,0 @@ -* { - box-sizing: border-box; -} - -:root { - --max-width: 1100px; - --border-radius: 12px; - --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", - "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", "Fira Mono", "Droid Sans Mono", - "Courier New", monospace; - --bg-color: #fff; - --text-color: #000; - - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); - - --callout-rgb: 238, 240, 241; - --callout-border-rgb: 172, 175, 176; - --card-rgb: 180, 185, 188; - --card-border-rgb: 131, 134, 135; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); -} - -/* dark themes */ -.dark, -.dark ~ * { - --bg-color: #000; - --text-color: #fff; -} - -.dark, -.dark ~ * { - --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); -} - -/* light themes */ - -.light, -.light ~ * { - --bg-color: #fff; - --text-color: #000; -} - -html { - padding: 0; - margin: 0; -} - -body, -#root { - padding: 0; - margin: 0; - min-height: 100vh; - display: flex; - flex-direction: column; -} - -main, -footer { - background: var(--bg-color); - color: var(--text-color); -} - -main { - flex-grow: 1; -} - -footer { - text-align: center; - padding: 10px; -} - -a { - color: inherit; - text-decoration: none; -} - -.grow { - flex-grow: 1; -} diff --git a/packages/shared-ui/src/index.ts b/packages/shared-ui/src/index.ts deleted file mode 100644 index 1c2c847f..00000000 --- a/packages/shared-ui/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./root-layout"; diff --git a/packages/shared-ui/src/root-layout.module.css b/packages/shared-ui/src/root-layout.module.css deleted file mode 100644 index d2eb0df6..00000000 --- a/packages/shared-ui/src/root-layout.module.css +++ /dev/null @@ -1,153 +0,0 @@ -.main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 3rem 0; - min-height: calc(100vh - 55px); -} - -.description { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: nowrap !important; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); - padding: 10px; - padding-right: 100px; - position: sticky; - top: 0; - backdrop-filter: blur(3px); -} - -.description a { - display: flex; - align-items: center; - justify-content: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - flex-wrap: wrap; - padding: 3rem; - gap: 20px 50px; -} - -.center > div { - position: relative; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; - pointer-events: none; -} - -.center::after { - background: var(--primary-glow); - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ""; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; - display: flex; - justify-content: center; - align-items: center; - margin-left: 16px; - transform: translateZ(0); - border-radius: var(--border-radius); - overflow: hidden; - box-shadow: 0px 2px 8px -1px #0000001a; - padding: 2px; -} -.logo p { - background: var(--bg-color); -} -.logo::before, -.logo::after { - content: " "; - position: absolute; - z-index: -1; -} - -/* Conic Gradient Animation */ -.logo::before { - animation: 3s rotate infinite linear; - width: 800%; - height: 800%; - background: var(--tile-border); -} - -/* Inner Square */ -.logo::after { - inset: 0; - padding: 1px; - border-radius: var(--border-radius); - background: linear-gradient( - to bottom right, - rgba(var(--tile-start-rgb), 1), - rgba(var(--tile-end-rgb), 1) - ); - background-clip: content-box; -} - -.by { - display: flex; - gap: 20px; -} - -/* Mobile and Tablet */ -@media (max-width: 800px) { - .center { - padding: 4rem; - } - .description { - padding: 30px; - padding-right: 100px; - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} diff --git a/packages/shared-ui/src/root-layout.tsx b/packages/shared-ui/src/root-layout.tsx deleted file mode 100644 index 171001ae..00000000 --- a/packages/shared-ui/src/root-layout.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import "./globals.css"; -import "nthul-lite/styles.css"; -import { ThemeSwitcher } from "nthul-lite/client/theme-switcher"; -import { ForkMe } from "@mayank1513/fork-me/server"; -import type { HTMLProps } from "react"; -import styles from "./root-layout.module.css"; -import { Cards } from "./cards"; -import { Description } from "./root/description"; -import { Hero } from "./root/hero"; -import { Footer } from "./root/footer"; - -export type SharedRootLayoutProps = HTMLProps; - -export function SharedRootLayout({ children, className = "", ...props }: SharedRootLayoutProps) { - return ( - <> - -
- - {children} - - -
-