From 8101234bee97fbca91f61766b6796f67ec5de2e9 Mon Sep 17 00:00:00 2001 From: Nik Graf Date: Tue, 5 Aug 2025 21:54:03 +0200 Subject: [PATCH 1/2] remove typesync --- CLAUDE.md | 3 - CONTRIBUTING.md | 20 +- .../.cursor/rules/cli-app.mdc | 55 - apps/typesync/.cursor/rules/typesync-app.mdc | 56 - apps/typesync/.envrc | 1 - apps/typesync/CHANGELOG.md | 8 - apps/typesync/LICENSE | 21 - apps/typesync/README.md | 70 - apps/typesync/client/index.html | 29 - .../SchemaBuilder/PropertyCombobox.tsx | 135 - .../SchemaBuilder/SchemaBrowser.tsx | 113 - .../SchemaBuilder/TypeNameCombobox.tsx | 124 - .../SchemaBuilder/TypeSelect.tsx | 132 - .../App/CreateAppForm/useCreateAppForm.tsx | 28 - .../Components/App/Schema/SchemaPreview.tsx | 156 - .../client/src/Components/App/Schema/utils.ts | 124 - .../client/src/Components/App/StatusBadge.tsx | 12 - .../client/src/Components/AppsNavbar.tsx | 98 - .../client/src/Components/CmdPalette.tsx | 285 -- .../FormComponents/ErrorMessages.tsx | 17 - .../src/Components/FormComponents/Input.tsx | 55 - .../Components/FormComponents/RadioGroup.tsx | 37 - .../FormComponents/SubmitButton.tsx | 53 - .../Components/FormComponents/TextArea.tsx | 44 - .../src/Components/FormComponents/index.ts | 5 - .../client/src/Components/InlineCode.tsx | 7 - .../client/src/Components/Loading.tsx | 7 - apps/typesync/client/src/Providers.tsx | 26 - apps/typesync/client/src/clients/graphql.ts | 4 - apps/typesync/client/src/clients/router.tsx | 56 - apps/typesync/client/src/constants.ts | 1 - apps/typesync/client/src/context/form.ts | 8 - apps/typesync/client/src/generated/gql.ts | 52 - apps/typesync/client/src/generated/graphql.ts | 1768 --------- apps/typesync/client/src/generated/index.ts | 1 - .../typesync/client/src/hooks/useAppQuery.tsx | 204 - .../typesync/client/src/hooks/useCWDQuery.tsx | 54 - apps/typesync/client/src/hooks/useOSQuery.tsx | 34 - .../src/hooks/useSchemaBrowserQuery.tsx | 269 -- .../typesync/client/src/images/react_logo.png | Bin 5347 -> 0 bytes .../client/src/images/vitejs_logo.png | Bin 53648 -> 0 bytes apps/typesync/client/src/index.css | 6 - apps/typesync/client/src/main.tsx | 12 - apps/typesync/client/src/routeTree.gen.ts | 95 - apps/typesync/client/src/routes/__root.tsx | 104 - .../client/src/routes/apps/$appId/details.tsx | 278 -- .../client/src/routes/apps/create.tsx | 854 ---- apps/typesync/client/src/routes/index.tsx | 129 - apps/typesync/client/src/schema.ts | 165 - apps/typesync/client/src/utils/classnames.ts | 3 - apps/typesync/client/src/utils/mapper.ts | 26 - apps/typesync/client/src/vite-env.d.ts | 1 - apps/typesync/domain/Domain.ts | 53 - apps/typesync/flake.nix | 22 - apps/typesync/graphql.codegen.ts | 37 - apps/typesync/package.json | 94 - apps/typesync/scripts/copy-client-dist.ts | 19 - apps/typesync/scripts/copy-package-json.ts | 36 - apps/typesync/src/Api.ts | 184 - apps/typesync/src/Cli.ts | 15 - apps/typesync/src/Database.ts | 323 -- apps/typesync/src/Domain.ts | 201 - apps/typesync/src/Generator.ts | 419 -- apps/typesync/src/Server.ts | 63 - apps/typesync/src/Utils.ts | 171 - apps/typesync/src/bin.ts | 16 - .../src/migrations/0001_create_table__app.ts | 17 - .../0002_create_table__app_events.ts | 18 - .../0003_create_table__app_schema.ts | 19 - ..._create_table__app_schema_type_property.ts | 23 - ..._update_table_property_relationTypeName.ts | 9 - apps/typesync/src/subcommands/studio.ts | 111 - apps/typesync/test/Generator.test.ts | 80 - apps/typesync/test/Utils.test.ts | 152 - apps/typesync/tsconfig.base.json | 42 - apps/typesync/tsconfig.client.json | 20 - apps/typesync/tsconfig.domain.json | 11 - apps/typesync/tsconfig.json | 10 - apps/typesync/tsconfig.scripts.json | 19 - apps/typesync/tsconfig.src.json | 11 - apps/typesync/tsconfig.test.json | 10 - apps/typesync/tsup.config.ts | 29 - apps/typesync/vite.config.ts | 33 - apps/typesync/vitest.config.ts | 12 - biome.jsonc | 1 - packages/hypergraph/src/mapping/Mapping.ts | 2 +- packages/typesync/CHANGELOG.md | 16 - packages/typesync/LICENSE | 21 - packages/typesync/README.md | 77 - packages/typesync/package.json | 48 - packages/typesync/src/Mapping.ts | 771 ---- packages/typesync/src/Utils.ts | 156 - packages/typesync/src/index.ts | 2 - packages/typesync/test/Mapping.test.ts | 430 --- packages/typesync/test/Utils.test.ts | 46 - packages/typesync/tsconfig.build.json | 8 - packages/typesync/tsconfig.json | 5 - packages/typesync/tsconfig.src.json | 8 - packages/typesync/tsconfig.test.json | 11 - packages/typesync/vitest.config.ts | 6 - pnpm-lock.yaml | 3438 +---------------- tsconfig.base.json | 5 +- tsconfig.build.json | 3 +- tsconfig.json | 2 - vitest.config.ts | 2 +- vitest.shared.ts | 1 - 106 files changed, 82 insertions(+), 13101 deletions(-) delete mode 100644 apps/create-hypergraph-app/.cursor/rules/cli-app.mdc delete mode 100644 apps/typesync/.cursor/rules/typesync-app.mdc delete mode 100644 apps/typesync/.envrc delete mode 100644 apps/typesync/CHANGELOG.md delete mode 100644 apps/typesync/LICENSE delete mode 100644 apps/typesync/README.md delete mode 100644 apps/typesync/client/index.html delete mode 100644 apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/PropertyCombobox.tsx delete mode 100644 apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/SchemaBrowser.tsx delete mode 100644 apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/TypeNameCombobox.tsx delete mode 100644 apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/TypeSelect.tsx delete mode 100644 apps/typesync/client/src/Components/App/CreateAppForm/useCreateAppForm.tsx delete mode 100644 apps/typesync/client/src/Components/App/Schema/SchemaPreview.tsx delete mode 100644 apps/typesync/client/src/Components/App/Schema/utils.ts delete mode 100644 apps/typesync/client/src/Components/App/StatusBadge.tsx delete mode 100644 apps/typesync/client/src/Components/AppsNavbar.tsx delete mode 100644 apps/typesync/client/src/Components/CmdPalette.tsx delete mode 100644 apps/typesync/client/src/Components/FormComponents/ErrorMessages.tsx delete mode 100644 apps/typesync/client/src/Components/FormComponents/Input.tsx delete mode 100644 apps/typesync/client/src/Components/FormComponents/RadioGroup.tsx delete mode 100644 apps/typesync/client/src/Components/FormComponents/SubmitButton.tsx delete mode 100644 apps/typesync/client/src/Components/FormComponents/TextArea.tsx delete mode 100644 apps/typesync/client/src/Components/FormComponents/index.ts delete mode 100644 apps/typesync/client/src/Components/InlineCode.tsx delete mode 100644 apps/typesync/client/src/Components/Loading.tsx delete mode 100644 apps/typesync/client/src/Providers.tsx delete mode 100644 apps/typesync/client/src/clients/graphql.ts delete mode 100644 apps/typesync/client/src/clients/router.tsx delete mode 100644 apps/typesync/client/src/constants.ts delete mode 100644 apps/typesync/client/src/context/form.ts delete mode 100644 apps/typesync/client/src/generated/gql.ts delete mode 100644 apps/typesync/client/src/generated/graphql.ts delete mode 100644 apps/typesync/client/src/generated/index.ts delete mode 100644 apps/typesync/client/src/hooks/useAppQuery.tsx delete mode 100644 apps/typesync/client/src/hooks/useCWDQuery.tsx delete mode 100644 apps/typesync/client/src/hooks/useOSQuery.tsx delete mode 100644 apps/typesync/client/src/hooks/useSchemaBrowserQuery.tsx delete mode 100644 apps/typesync/client/src/images/react_logo.png delete mode 100644 apps/typesync/client/src/images/vitejs_logo.png delete mode 100644 apps/typesync/client/src/index.css delete mode 100644 apps/typesync/client/src/main.tsx delete mode 100644 apps/typesync/client/src/routeTree.gen.ts delete mode 100644 apps/typesync/client/src/routes/__root.tsx delete mode 100644 apps/typesync/client/src/routes/apps/$appId/details.tsx delete mode 100644 apps/typesync/client/src/routes/apps/create.tsx delete mode 100644 apps/typesync/client/src/routes/index.tsx delete mode 100644 apps/typesync/client/src/schema.ts delete mode 100644 apps/typesync/client/src/utils/classnames.ts delete mode 100644 apps/typesync/client/src/utils/mapper.ts delete mode 100644 apps/typesync/client/src/vite-env.d.ts delete mode 100644 apps/typesync/domain/Domain.ts delete mode 100644 apps/typesync/flake.nix delete mode 100644 apps/typesync/graphql.codegen.ts delete mode 100644 apps/typesync/package.json delete mode 100644 apps/typesync/scripts/copy-client-dist.ts delete mode 100644 apps/typesync/scripts/copy-package-json.ts delete mode 100644 apps/typesync/src/Api.ts delete mode 100644 apps/typesync/src/Cli.ts delete mode 100644 apps/typesync/src/Database.ts delete mode 100644 apps/typesync/src/Domain.ts delete mode 100644 apps/typesync/src/Generator.ts delete mode 100644 apps/typesync/src/Server.ts delete mode 100644 apps/typesync/src/Utils.ts delete mode 100755 apps/typesync/src/bin.ts delete mode 100644 apps/typesync/src/migrations/0001_create_table__app.ts delete mode 100644 apps/typesync/src/migrations/0002_create_table__app_events.ts delete mode 100644 apps/typesync/src/migrations/0003_create_table__app_schema.ts delete mode 100644 apps/typesync/src/migrations/0004_create_table__app_schema_type_property.ts delete mode 100644 apps/typesync/src/migrations/0005_update_table_property_relationTypeName.ts delete mode 100644 apps/typesync/src/subcommands/studio.ts delete mode 100644 apps/typesync/test/Generator.test.ts delete mode 100644 apps/typesync/test/Utils.test.ts delete mode 100644 apps/typesync/tsconfig.base.json delete mode 100644 apps/typesync/tsconfig.client.json delete mode 100644 apps/typesync/tsconfig.domain.json delete mode 100644 apps/typesync/tsconfig.json delete mode 100644 apps/typesync/tsconfig.scripts.json delete mode 100644 apps/typesync/tsconfig.src.json delete mode 100644 apps/typesync/tsconfig.test.json delete mode 100644 apps/typesync/tsup.config.ts delete mode 100644 apps/typesync/vite.config.ts delete mode 100644 apps/typesync/vitest.config.ts delete mode 100644 packages/typesync/CHANGELOG.md delete mode 100644 packages/typesync/LICENSE delete mode 100644 packages/typesync/README.md delete mode 100644 packages/typesync/package.json delete mode 100644 packages/typesync/src/Mapping.ts delete mode 100644 packages/typesync/src/Utils.ts delete mode 100644 packages/typesync/src/index.ts delete mode 100644 packages/typesync/test/Mapping.test.ts delete mode 100644 packages/typesync/test/Utils.test.ts delete mode 100644 packages/typesync/tsconfig.build.json delete mode 100644 packages/typesync/tsconfig.json delete mode 100644 packages/typesync/tsconfig.src.json delete mode 100644 packages/typesync/tsconfig.test.json delete mode 100644 packages/typesync/vitest.config.ts diff --git a/CLAUDE.md b/CLAUDE.md index 2f0265fc..7d26c300 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,6 @@ Hypergraph is a local-first framework for building web3 consumer applications th # Run specific apps cd apps/events && pnpm dev # Events demo app cd apps/server && pnpm dev # Backend sync server -cd apps/typesync && pnpm dev # TypeSync development cd apps/connect && pnpm dev # Geo Connect auth app ``` @@ -49,12 +48,10 @@ pnpm clean # Clean all build artifacts - **packages/** - Core libraries - `hypergraph/` - Main SDK with entity management, encryption, spaces, and inboxes - `hypergraph-react/` - React hooks and components - - `typesync/` - Schema management utilities - **apps/** - Complete applications - `server/` - Backend sync server (Express + Prisma + SQLite/PostgreSQL) - `events/` - Demo app showcasing the framework (Vite + React) - `connect/` - Geo Connect authentication app - - `typesync/` - CLI and web interface for schema development - `create-hypergraph/` - Project scaffolding tool - `next-example/` - Next.js integration example - **docs/** - Docusaurus documentation site diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1ed9530..f08e1355 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,24 +29,6 @@ cd apps/server pnpm prisma migrate dev # this will also generate the Prisma client ``` -To develop the Typesync CLI, you can run: - -```sh -cd apps/typesync -pnpm dev -``` - -To develop the Typesync frontend run: - -```sh -# open the vite.config.ts and comment out the server object that specifies the port to be 3000 -cd apps/typesync -pnpm run dev:cli -# in another tab -cd apps/typesync -pnpm dev:client -``` - To develop the create-hypergraph, run: ```sh @@ -89,7 +71,7 @@ pnpm up --interactive --latest -r ## Publishing -Update the version in the `package.json` files (hypergraph, hypergraph-react, typesync) +Update the version in the `package.json` files (hypergraph, hypergraph-react) ```sh pnpm changeset version diff --git a/apps/create-hypergraph-app/.cursor/rules/cli-app.mdc b/apps/create-hypergraph-app/.cursor/rules/cli-app.mdc deleted file mode 100644 index e0e16b60..00000000 --- a/apps/create-hypergraph-app/.cursor/rules/cli-app.mdc +++ /dev/null @@ -1,55 +0,0 @@ ---- -description: Create Hypergraph App CLI patterns and conventions -globs: ["src/**/*.ts"] -alwaysApply: false ---- - -# Create Hypergraph App CLI Rules - -## CLI Architecture -- Use Effect CLI for command-line interface -- Implement proper subcommands -- Use descriptive command names -- Provide helpful error messages -- Implement proper help text - -## Template System -- Use structured templates for scaffolding -- Implement proper template validation -- Use consistent template structure -- Provide clear template documentation -- Support multiple template types - -## File Operations -- Use safe file system operations -- Implement proper error handling -- Validate file paths and permissions -- Use consistent file naming -- Implement proper backup strategies - -## User Experience -- Provide clear progress indicators -- Implement proper error recovery -- Use consistent output formatting -- Provide helpful suggestions -- Implement proper validation - -## Code Generation -- Generate type-safe code -- Use consistent code formatting -- Implement proper imports -- Follow established patterns -- Generate comprehensive documentation - -## Testing -- Test CLI commands thoroughly -- Mock file system operations -- Test error scenarios -- Test template generation -- Use Vitest for testing - -## Distribution -- Use proper package.json configuration -- Implement proper binary setup -- Use TypeScript for type safety -- Follow npm publishing best practices diff --git a/apps/typesync/.cursor/rules/typesync-app.mdc b/apps/typesync/.cursor/rules/typesync-app.mdc deleted file mode 100644 index c96892cf..00000000 --- a/apps/typesync/.cursor/rules/typesync-app.mdc +++ /dev/null @@ -1,56 +0,0 @@ ---- -description: TypeSync application patterns and conventions -globs: ["src/**/*.tsx", "src/**/*.ts"] -alwaysApply: false ---- - -# TypeSync App Rules - -## Technology Stack -- Use Vite for build tooling -- Use React for UI components -- Use Tailwind CSS for styling -- Use GraphQL for data fetching -- Use TypeScript for type safety - -## GraphQL Integration -- Use proper GraphQL queries -- Implement proper error handling -- Use GraphQL code generation -- Handle loading states properly -- Implement proper caching - -## Type Generation -- Generate type-safe code -- Use proper TypeScript interfaces -- Implement proper validation -- Handle complex type relationships -- Use consistent naming conventions - -## UI Components -- Use functional React components -- Implement proper TypeScript props -- Use consistent styling patterns -- Follow accessibility guidelines -- Implement responsive design - -## Data Management -- Handle GraphQL data properly -- Implement proper error states -- Use proper loading indicators -- Handle data synchronization -- Implement proper caching - -## Performance -- Optimize GraphQL queries -- Implement proper code splitting -- Use lazy loading -- Optimize bundle size -- Monitor performance - -## Testing -- Test GraphQL operations -- Test type generation -- Mock external dependencies -- Test error scenarios -- Use proper testing utilities diff --git a/apps/typesync/.envrc b/apps/typesync/.envrc deleted file mode 100644 index 3550a30f..00000000 --- a/apps/typesync/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake diff --git a/apps/typesync/CHANGELOG.md b/apps/typesync/CHANGELOG.md deleted file mode 100644 index 3e89dadb..00000000 --- a/apps/typesync/CHANGELOG.md +++ /dev/null @@ -1,8 +0,0 @@ -# @graphprotocol/hypergraph-cli - -## 0.1.0 -### Patch Changes - -- dd4746a: remove unsupported dataType Url -- Updated dependencies [dd4746a] - - @graphprotocol/typesync@0.1.0 diff --git a/apps/typesync/LICENSE b/apps/typesync/LICENSE deleted file mode 100644 index 3ddb85bf..00000000 --- a/apps/typesync/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024-present Geo Browser, PB LLC and other contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/apps/typesync/README.md b/apps/typesync/README.md deleted file mode 100644 index b1da4f36..00000000 --- a/apps/typesync/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# @graphprotocol/hypergraph-cli - -# Hypergraph command-line toolchain for scaffolding and working with Hypergraph applications. - -## Installing - -```bash -# npm -npm i -g @graphprotocol/hypergraph-cli - -# yarn -yarn global add @graphprotocol/hypergraph-cli - -# pnpm -pnpm install -g @graphprotocol/hypergraph-cli -``` - -## Running - -### Setup - -```sh -pnpm install -cd apps/server -cp .env.example .env -# add the PRIVY_APP_SECRET & PRIVY_APP_ID to the apps/server/.env file -pnpm prisma migrate dev -``` - -### Development - -```sh -pnpm build --watch -# in another tab -cd apps/events -pnpm dev -# in another tab -cd apps/server -pnpm dev -# in another tab -cd apps/typesync -pnpm build -# then, from anywhere in the repo, start Typesync -hypergraph typesync -``` - -## Commands - -- `typesync` -> runs the Hypergraph API and client UI application for viewing created application schemas, browsing the Knowledge Graph, and creating new application schemas. - - running: `hypergraph typesync` - - args: - - `port` [OPTIONAL, default = 3000] port to run the application on - - example: `hypergraph typesync --port 3001` - - `browser` [OPTION, default 'browser'] browser to open the app in, if the `--open` flag is passed - - example: `hypergraph typesync --open --browser firefox` - -## Generating & running a new app - -1. Start TypeSync: - ```bash - hypergraph typesync - ``` -2. In the UI click **Generate App** and choose a name (e.g. `awesome-app`). When the toast shows the path, the scaffold is ready and all dependencies are already installed. -3. Run it: - ```bash - cd awesome-app - pnpm dev - ``` - -No additional `pnpm install` is necessary – the generator takes care of adding the app to the workspace and installing its dependencies for you. \ No newline at end of file diff --git a/apps/typesync/client/index.html b/apps/typesync/client/index.html deleted file mode 100644 index 792a273e..00000000 --- a/apps/typesync/client/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - Graph Protocol | TypeSync - - - - -
- - - diff --git a/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/PropertyCombobox.tsx b/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/PropertyCombobox.tsx deleted file mode 100644 index ed5aef70..00000000 --- a/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/PropertyCombobox.tsx +++ /dev/null @@ -1,135 +0,0 @@ -'use client'; - -import { - Combobox, - ComboboxButton, - ComboboxInput, - type ComboboxInputProps, - ComboboxOption, - ComboboxOptions, - Label, -} from '@headlessui/react'; -import { CheckIcon, ChevronUpDownIcon } from '@heroicons/react/16/solid'; -import { useStore } from '@tanstack/react-form'; -import { Array as EffectArray, String as EffectString } from 'effect'; -import { useState } from 'react'; - -import { useFieldContext } from '../../../../context/form.js'; -import { type ExtendedProperty, usePropertiesQuery } from '../../../../hooks/useSchemaBrowserQuery.js'; -import { classnames } from '../../../../utils/classnames.js'; -import { mapKGDataTypeToPrimitiveType } from '../../../../utils/mapper.js'; -import { ErrorMessages } from '../../../FormComponents/ErrorMessages.js'; -import { InlineCode } from '../../../InlineCode.js'; - -export type PropertyCombobox = Omit & { - id: string; - label?: React.ReactNode; - propertySelected(prop: ExtendedProperty): void; -}; -export function PropertyCombobox({ id, label, propertySelected, ...rest }: Readonly) { - const field = useFieldContext(); - const value = useStore(field.store, (state) => state.value); - const errors = useStore(field.store, (state) => state.meta.errors); - const touched = useStore(field.store, (state) => state.meta.isTouched); - const hasErrors = errors.length > 0 && touched; - - const [propsFilter, setPropsFilter] = useState(''); - - const { data } = usePropertiesQuery({ - refetchOnMount: false, - refetchOnWindowFocus: false, - select(data) { - if (EffectString.isEmpty(propsFilter)) { - return data; - } - return EffectArray.filter(data, (prop) => prop.slug.includes(propsFilter.toLowerCase())); - }, - }); - const props = data ?? []; - - return ( - - value={value} - onChange={(val) => { - if (val == null) { - field.handleChange(''); - return; - } - if (typeof val === 'string') { - field.handleChange(val); - return; - } - field.handleChange(val.name || val.id); - propertySelected(val); - }} - onClose={() => setPropsFilter('')} - immediate - > - {label != null ? ( - - ) : null} -
- { - const value = event.target.value; - setPropsFilter(value); - field.handleChange(value); - }} - onBlur={() => setPropsFilter('')} - displayValue={(selectedType: string) => selectedType} - /> - - - - {props.length > 0 || EffectString.isNonEmpty(propsFilter) ? ( - - {props.map((_prop) => ( - -
-
-

- {_prop.name || _prop.id} - {mapKGDataTypeToPrimitiveType(_prop.dataType, _prop.name || _prop.id)} -

-

- {_prop.id} -

-
-

- {_prop.description} -

-
- - - -
- ))} - {EffectString.isNonEmpty(propsFilter) ? ( - - - New Property: {propsFilter} - - - ) : null} -
- ) : null} -
- {hasErrors ? : null} - - ); -} diff --git a/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/SchemaBrowser.tsx b/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/SchemaBrowser.tsx deleted file mode 100644 index 291f2cdc..00000000 --- a/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/SchemaBrowser.tsx +++ /dev/null @@ -1,113 +0,0 @@ -'use client'; - -import { Disclosure, DisclosureButton, DisclosurePanel, Input } from '@headlessui/react'; -import { ChevronDownIcon, ChevronRightIcon, PlusIcon } from '@heroicons/react/20/solid'; -import { Array as EffectArray, pipe } from 'effect'; -import { useState } from 'react'; - -import { type ExtendedSchemaBrowserType, useSchemaBrowserQuery } from '../../../../hooks/useSchemaBrowserQuery.js'; -import { mapKGDataTypeToPrimitiveType } from '../../../../utils/mapper.js'; -import { InlineCode } from '../../../InlineCode.js'; -import { Loading } from '../../../Loading.js'; - -export type SchemaBrowserProps = Readonly<{ - typeSelected(type: ExtendedSchemaBrowserType): void; -}>; -export function SchemaBrowser({ typeSelected }: SchemaBrowserProps) { - const [typeSearch, setTypeSearch] = useState(''); - - const { data: types, isLoading } = useSchemaBrowserQuery({ - refetchOnMount: false, - refetchOnWindowFocus: false, - select(data) { - if (!typeSearch) { - return data; - } - return pipe( - data, - EffectArray.filter((type) => type.slug.includes(typeSearch.toLowerCase())), - ); - }, - }); - - return ( -
-
-

- Schema Browser - {isLoading ? : null} -

-

- Browse existing schemas/types from the Knowledge Graph to add to your schema. -

-
-
-
- setTypeSearch(e.target.value || '')} - type="search" - placeholder="Search types..." - className="block min-w-0 grow py-1.5 pl-2 pr-3 rounded-md bg-white dark:bg-slate-700 data-[state=invalid]:pr-10 text-base text-gray-900 dark:text-white placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline sm:text-sm/6 focus-visible:outline-none w-full" - /> -
-
    - {(types ?? []).map((_type) => { - const properties = EffectArray.filter(_type.properties ?? [], (prop) => prop != null); - - return ( - -
    - -
    - {/* shown when the collapsible is open */} -
    -
    -
    - -
    -
    - -
      - {properties.map((prop) => ( -
    • - {prop.name || prop.id} - {prop.dataType != null ? ( - {mapKGDataTypeToPrimitiveType(prop.dataType, prop.name || prop.id)} - ) : null} -
    • - ))} -
    -
    -
    - ); - })} -
-
-
- ); -} diff --git a/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/TypeNameCombobox.tsx b/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/TypeNameCombobox.tsx deleted file mode 100644 index 590fcc9e..00000000 --- a/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/TypeNameCombobox.tsx +++ /dev/null @@ -1,124 +0,0 @@ -'use client'; - -import { - Combobox, - ComboboxButton, - ComboboxInput, - type ComboboxInputProps, - ComboboxOption, - ComboboxOptions, - Label, -} from '@headlessui/react'; -import { CheckIcon, ChevronUpDownIcon } from '@heroicons/react/16/solid'; -import { useStore } from '@tanstack/react-form'; -import { Array as EffectArray, String as EffectString } from 'effect'; -import { useState } from 'react'; - -import { useFieldContext } from '../../../../context/form.js'; -import { type ExtendedSchemaBrowserType, useSchemaBrowserQuery } from '../../../../hooks/useSchemaBrowserQuery.js'; -import { classnames } from '../../../../utils/classnames.js'; -import { ErrorMessages } from '../../../FormComponents/ErrorMessages.js'; -import { InlineCode } from '../../../InlineCode.js'; - -export type TypeNameComboboxProps = Omit & { - id: string; - label?: React.ReactNode; - typeSelected(type: ExtendedSchemaBrowserType): void; -}; -export function TypeNameCombobox({ id, label, typeSelected, ...rest }: Readonly) { - const field = useFieldContext(); - const value = useStore(field.store, (state) => state.value); - const errors = useStore(field.store, (state) => state.meta.errors); - const touched = useStore(field.store, (state) => state.meta.isTouched); - const hasErrors = errors.length > 0 && touched; - - const [typesFilter, setTypesFilter] = useState(''); - - const { data } = useSchemaBrowserQuery({ - refetchOnMount: false, - select(data) { - if (EffectString.isEmpty(typesFilter)) { - return data; - } - return EffectArray.filter(data, (type) => type.slug.includes(typesFilter.toLowerCase())); - }, - }); - const types = data ?? []; - - return ( - - value={value} - onChange={(val) => { - if (val == null) { - field.handleChange(''); - return; - } - if (typeof val === 'string') { - field.handleChange(val); - return; - } - field.handleChange(val.name || val.id); - // emit the change - typeSelected(val); - }} - onClose={() => setTypesFilter('')} - immediate - > - {label != null ? ( - - ) : null} -
- { - const value = event.target.value; - setTypesFilter(value); - field.handleChange(value); - }} - onBlur={() => setTypesFilter('')} - displayValue={(selectedType: string) => selectedType} - /> - - - - {types.length > 0 || EffectString.isNonEmpty(typesFilter) ? ( - - {types.map((_type) => ( - - - {_type.name || _type.id} - {_type.id} - - - - - - ))} - {EffectString.isNonEmpty(typesFilter) ? ( - - - New Type: {typesFilter} - - - ) : null} - - ) : null} -
- {hasErrors ? : null} - - ); -} diff --git a/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/TypeSelect.tsx b/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/TypeSelect.tsx deleted file mode 100644 index b0fcd64e..00000000 --- a/apps/typesync/client/src/Components/App/CreateAppForm/SchemaBuilder/TypeSelect.tsx +++ /dev/null @@ -1,132 +0,0 @@ -'use client'; - -import { Label, Listbox, ListboxButton, ListboxOption, ListboxOptions, type ListboxProps } from '@headlessui/react'; -import { CheckIcon, ChevronUpDownIcon } from '@heroicons/react/16/solid'; -import { Array as EffectArray, String as EffectString, pipe, Schema } from 'effect'; - -import { useFieldContext } from '../../../../context/form.js'; -import { classnames } from '../../../../utils/classnames.js'; - -class TypeOption extends Schema.Class('/hypergraph/typesync/models/TypeOption')({ - id: Schema.NonEmptyTrimmedString, - name: Schema.NonEmptyTrimmedString, -}) {} -class RelationTypeOption extends Schema.Class('/hypergraph/typesync/models/RelationTypeOption')({ - ...TypeOption.fields, - relationType: Schema.NonEmptyTrimmedString, -}) {} - -const typeOptions: Array = [ - TypeOption.make({ id: 'DefaultEntityText', name: 'Text' }), - TypeOption.make({ id: 'DefaultEntityNumber', name: 'Number' }), - TypeOption.make({ id: 'DefaultEntityBoolean', name: 'Boolean' }), - TypeOption.make({ id: 'DefaultEntityDate', name: 'Date' }), - TypeOption.make({ id: 'DefaultEntityUrl', name: 'Url' }), - TypeOption.make({ id: 'DefaultEntityPoint', name: 'Point' }), -]; - -export type TypeSelectProps = Pick & { - id: string; - name: string; - /** - * A list of types within the defined schema that the user can use as a relation - * This allows the user to specify the property as a relationship to a type in the schema - * - * @default [] - */ - schemaTypes?: Array<{ type: string; schemaTypeIdx: number }> | undefined; - - relationTypeSelected(relationType: string): void; -}; -export function TypeSelect({ - id, - name, - schemaTypes = [], - disabled = false, - relationTypeSelected, -}: Readonly) { - const field = useFieldContext(); - - const relationTypeOptions = pipe( - schemaTypes, - EffectArray.filter((_type) => EffectString.isNonEmpty(_type.type)), - EffectArray.map((_type) => - RelationTypeOption.make({ - id: `Relation(${_type})`, - name: `Relation(${_type.type})`, - relationType: _type.type, - }), - ), - ); - - return ( - { - if (value) { - if (typeof value === 'string') { - field.handleChange(value); - return; - } - field.handleChange(value.name); - relationTypeSelected(value.relationType); - } - }} - > - -
- - - {field.state.value} - - {!disabled ? ( - - - - {typeOptions.map((type) => ( - - {type.name} - - - - - ))} - {relationTypeOptions.map((type, idx) => ( - - {type.name} - - - - - ))} - -
-
- ); -} diff --git a/apps/typesync/client/src/Components/App/CreateAppForm/useCreateAppForm.tsx b/apps/typesync/client/src/Components/App/CreateAppForm/useCreateAppForm.tsx deleted file mode 100644 index efc85793..00000000 --- a/apps/typesync/client/src/Components/App/CreateAppForm/useCreateAppForm.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { createFormHook } from '@tanstack/react-form'; - -import { fieldContext, formContext } from '../../../context/form.js'; -import { - FormComponentRadioGroup, - FormComponentTextArea, - FormComponentTextField, - SubmitButton, -} from '../../FormComponents/index.js'; -import { PropertyCombobox } from './SchemaBuilder/PropertyCombobox.js'; -import { TypeNameCombobox } from './SchemaBuilder/TypeNameCombobox.js'; -import { TypeSelect } from './SchemaBuilder/TypeSelect.js'; - -export const { useAppForm } = createFormHook({ - fieldComponents: { - FormComponentTextField, - FormComponentTextArea, - FormComponentRadioGroup, - PropertyCombobox, - TypeSelect, - TypeNameCombobox, - }, - formComponents: { - SubmitButton, - }, - fieldContext, - formContext, -}); diff --git a/apps/typesync/client/src/Components/App/Schema/SchemaPreview.tsx b/apps/typesync/client/src/Components/App/Schema/SchemaPreview.tsx deleted file mode 100644 index 5eb3fd3b..00000000 --- a/apps/typesync/client/src/Components/App/Schema/SchemaPreview.tsx +++ /dev/null @@ -1,156 +0,0 @@ -'use client'; - -import { useQuery } from '@tanstack/react-query'; -import type { CSSProperties } from 'react'; -import { codeToTokens, type ThemedToken } from 'shiki'; - -import type { AppSchema } from '../../../schema.js'; -import { classnames } from '../../../utils/classnames.js'; -import * as Utils from './utils.js'; - -enum FontStyle { - NotSet = -1, - None = 0, - Italic = 1, - Bold = 2, - Underline = 4, - Strikethrough = 8, -} - -type CodeChunk = ThemedToken; -type CodeLine = { chunks: Array; style: 'added' | 'deleted' | null }; - -export function SchemaPreview({ schema }: Readonly<{ schema: AppSchema }>) { - const { code, hash } = Utils.buildAppSchemaFormCode(schema); - const { data } = useQuery({ - queryKey: ['App', 'schema', 'preview', hash] as const, - async queryFn() { - const tokens = await codeToTokens(code, { - lang: 'typescript', - theme: 'github-dark-dimmed', - }); - - return tokens.tokens.map((lineTokens) => { - const lineContent = lineTokens.map((token) => token.content).join(''); - - if (!lineContent) { - return { chunks: [], style: null }; - } - - const lineChunks: Array = []; - let currentTokenIndex = 0; - let currentToken = lineTokens[currentTokenIndex]; - let currentChunk: CodeChunk = { - ...currentToken, - content: '', - }; - let currentOffset = currentChunk.offset; - - for (let characterIndex = 0; characterIndex < lineContent.length; characterIndex++) { - const character = lineContent[characterIndex]; - const moveToNextToken = currentOffset >= currentToken.offset + currentToken.content.length; - if (moveToNextToken) { - lineChunks.push(currentChunk); - if (moveToNextToken) { - currentTokenIndex++; - currentToken = lineTokens[currentTokenIndex]; - } - currentChunk = { ...currentToken, content: character }; - } else { - currentChunk.content += character; - } - currentOffset++; - } - lineChunks.push(currentChunk); - - return { - chunks: lineChunks, - style: null, - }; - }); - }, - }); - - const lines = data ?? []; - - return ( -
-
-        
-          {lines.flatMap((line, lineIndex) => {
-            const key = `schema_preview_line__${lineIndex}`;
-            return (
-              
-                
-                
-                  {line.chunks.map((chunk, chunkIndex) => {
-                    const fontStyle = chunk.fontStyle as number | undefined;
-                    const chunkClasses = [
-                      fontStyle === FontStyle.Bold ? 'font-bold' : null,
-                      fontStyle === FontStyle.Italic ? 'italic' : null,
-                      fontStyle === FontStyle.Underline ? 'underline' : null,
-                    ];
-                    const chunkStyle: CSSProperties = {
-                      color: chunk.color,
-                      backgroundColor: chunk.bgColor,
-                    };
-                    let chunkContent = chunk.content;
-                    if ((line.style === 'added' || line.style === 'deleted') && chunkIndex === 0) {
-                      /**
-                       * Replace whitespaces between the initial `+` or `-` character and the content of the line with non-breaking spaces,
-                       * to prevent wrapping there. Also replace the `-` character by an actual minus symbol (`−`) to prevent wrapping right
-                       * after it in Chrome (other browsers seem to understand that it's not a hyphen).
-                       */
-                      chunkContent = chunkContent.replace(
-                        /^([+-])\s+/,
-                        (match, plusOrMinus: string) =>
-                          (plusOrMinus === '-' ? '−' : plusOrMinus) + '\u00A0'.repeat(match.length - 1),
-                      );
-                    }
-
-                    const chunkKey = `line_chunk__${chunkIndex}`;
-
-                    return (
-                      
-                        {chunkContent}
-                      
-                    );
-                  })}
-                
-              
-            );
-          })}
-        
-      
-
- ); -} diff --git a/apps/typesync/client/src/Components/App/Schema/utils.ts b/apps/typesync/client/src/Components/App/Schema/utils.ts deleted file mode 100644 index 52d85fa4..00000000 --- a/apps/typesync/client/src/Components/App/Schema/utils.ts +++ /dev/null @@ -1,124 +0,0 @@ -import type { AppSchema } from '../../../schema.js'; - -function fieldToEntityString({ - name, - type_name, - nullable = false, - optional = false, - description, -}: AppSchema['types'][number]['properties'][number]): string { - // Add JSDoc comment if description exists - const jsDoc = description ? ` /** ${description} */\n` : ''; - - // Convert type to Entity type - const entityType = (() => { - switch (true) { - case type_name === 'Text': - return 'Type.Text'; - case type_name === 'Number': - return 'Type.Number'; - case type_name === 'Boolean': - return 'Type.Boolean'; - case type_name === 'Date': - return 'Type.Date'; - case type_name === 'Point': - return 'Type.Point'; - case type_name.startsWith('Relation'): - // renders the type as `Type.Relation(Entity)` - return `Type.${type_name}`; - default: - // how to handle complex types - return 'Type.Text'; - } - })(); - - let derivedEntityType = entityType; - if (optional) { - derivedEntityType = `Schema.NullishOr(${derivedEntityType})`; - } else if (nullable) { - derivedEntityType = `Schema.NullOr(${entityType})`; - } - - return `${jsDoc} ${name}: ${derivedEntityType}`; -} - -function typeDefinitionToString(type: { - name: string; - properties: ReadonlyArray; -}): string | null { - if (!type.name) { - return null; - } - const fields = type.properties.filter((_prop) => _prop.name != null && _prop.name.length > 0); - if (fields.length === 0) { - return null; - } - - const fieldStrings = fields.map(fieldToEntityString); - - const capitalizedName = type.name.charAt(0).toUpperCase() + type.name.slice(1); - return `export class ${capitalizedName} extends Entity.Class<${capitalizedName}>('${capitalizedName}')({ -${fieldStrings.join(',\n')} -}) {}`; -} - -/** - * Take the input schema and create a typescript code string representation to render in the preview - * - * @example - * ```ts - * const schema: AppSchemaForm = { - * types: [ - * { - * name: "Event", - * fields: [ - * { name: 'name', type: Text, description: 'Name of the event' }, - * { name: 'description', type: Schema.NullOr(Text) } - * ] - * } - * ] - * } - * - * const { code } = buildAppSchemaFormCode(schema) - * - * expect(code).toEqual(` - * import { Entity } from '@graphprotocol/hypergraph'; - * - * export class Event extends Entity.Class('Event')({ - * // Name of the event - * name: string; - * description: string | null; - * }) {} - * `) - * ``` - * - * @param schema the app schema being built by the user - * @returns a typescript string representation of the schema as well as a 20bit hash to pass to the useQuery hook - */ -export function buildAppSchemaFormCode(schema: AppSchema): Readonly<{ code: string; hash: string }> { - const fileCommentStatement = '// src/schema.ts'; - const importStatement = `import { Entity, Type } from '@graphprotocol/hypergraph';\nimport * as Schema from 'effect/Schema';`; - const typeDefinitions = schema.types - .map(typeDefinitionToString) - .filter((def) => def != null) - .join('\n\n'); - const code = [fileCommentStatement, importStatement, typeDefinitions].join('\n\n'); - - const byteArray = new TextEncoder().encode(code); - - // Use a simple but deterministic hashing algorithm - let hash = 0; - for (let i = 0; i < byteArray.length; i++) { - hash = (hash << 5) - hash + byteArray[i]; - hash = hash & hash; // Convert to 32-bit integer - } - - // Convert to hex string and ensure it's 20 bytes (40 characters) - const hexHash = Math.abs(hash).toString(16).padStart(40, '0'); - const generatedHash = hexHash.slice(0, 40); - - return { - code, - hash: generatedHash, - } as const; -} diff --git a/apps/typesync/client/src/Components/App/StatusBadge.tsx b/apps/typesync/client/src/Components/App/StatusBadge.tsx deleted file mode 100644 index 288333bc..00000000 --- a/apps/typesync/client/src/Components/App/StatusBadge.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import type { App } from '../../schema.js'; - -export function AppStatusBadge(props: Readonly<{ status: App['status'] }>) { - return ( - - {props.status.replaceAll('_', ' ')} - - ); -} diff --git a/apps/typesync/client/src/Components/AppsNavbar.tsx b/apps/typesync/client/src/Components/AppsNavbar.tsx deleted file mode 100644 index 0db9c12b..00000000 --- a/apps/typesync/client/src/Components/AppsNavbar.tsx +++ /dev/null @@ -1,98 +0,0 @@ -'use client'; - -import { ChevronDoubleLeftIcon, ChevronDoubleRightIcon, PlusIcon } from '@heroicons/react/20/solid'; -import { Link } from '@tanstack/react-router'; -import { atom, useAtom } from 'jotai'; - -import { useAppsSuspenseQuery } from '../hooks/useAppQuery.js'; -import { classnames } from '../utils/classnames.js'; - -export const navbarExpandedAtom = atom(false); - -export function AppSpacesNavbar() { - const { data: apps } = useAppsSuspenseQuery(); - - const [navbarExpanded, setNavbarExpanded] = useAtom(navbarExpandedAtom); - - return ( - - ); -} diff --git a/apps/typesync/client/src/Components/CmdPalette.tsx b/apps/typesync/client/src/Components/CmdPalette.tsx deleted file mode 100644 index b35cc51e..00000000 --- a/apps/typesync/client/src/Components/CmdPalette.tsx +++ /dev/null @@ -1,285 +0,0 @@ -'use client'; - -import { - Combobox, - ComboboxInput, - ComboboxOption, - ComboboxOptions, - Dialog, - DialogBackdrop, - DialogPanel, -} from '@headlessui/react'; -import { CodeBracketIcon, MagnifyingGlassIcon } from '@heroicons/react/20/solid'; -import { DocumentPlusIcon, FolderIcon } from '@heroicons/react/24/outline'; -import { useQuery } from '@tanstack/react-query'; -import { Link, useRouter } from '@tanstack/react-router'; -import { Array as EffectArray, Schema } from 'effect'; -import { atom, useAtom } from 'jotai'; -import { useEffect, useState } from 'react'; - -import { fetchApps } from '../hooks/useAppQuery.js'; -import { useOSQuery } from '../hooks/useOSQuery.js'; -import { Loading } from './Loading.js'; - -class SearchResult extends Schema.Class('SearchResult')({ - id: Schema.Union(Schema.NonEmptyTrimmedString, Schema.Positive), - type: Schema.Literal('entity', 'app'), - name: Schema.NonEmptyTrimmedString, - slug: Schema.NonEmptyTrimmedString, -}) {} - -async function search(): Promise> { - return await fetchApps().then((apps) => - EffectArray.map(apps, (app) => - SearchResult.make({ - id: app.id, - type: 'app', - name: app.name, - slug: `${app.id}${app.name}${app.description || ''}${app.directory || ''}`, - }), - ), - ); -} - -export const cmdPaletteOpenAtom = atom(false); - -export function CmdPalette() { - const router = useRouter(); - const { data: os } = useOSQuery(); - const [cmdPaletteOpen, setCmdPaletteOpen] = useAtom(cmdPaletteOpenAtom); - - const [query, setQuery] = useState(''); - - const { data, isLoading } = useQuery({ - queryKey: ['Space', 'search'] as const, - async queryFn() { - return await search(); - }, - select(data) { - if (!query) { - return data; - } - - const normalizedQuery = query.toLocaleLowerCase(); - return data.filter((result) => result.slug.includes(normalizedQuery)); - }, - }); - const results = data ?? []; - - // listen for the user to type cmd/ctrl+k and set the cmdPaletteOpen atom to true - useEffect(() => { - const handleKeyDown = (event: KeyboardEvent) => { - if (os == null) { - return; - } - // Check for Cmd+K (Mac) or Ctrl+K (Windows/Linux) - const modifier = os === 'MacOS' ? event.metaKey : event.ctrlKey; - - if (modifier && event.key === 'k') { - event.preventDefault(); // Prevent default browser behavior - setCmdPaletteOpen(true); - } - }; - - // Add event listener - window.addEventListener('keydown', handleKeyDown); - - // Cleanup function - return () => { - window.removeEventListener('keydown', handleKeyDown); - }; - }, [setCmdPaletteOpen, os]); - - // if the user types cmd/ctrl+N with the command palette open, navigate to the create new apps page - useEffect(() => { - const handleKeyDown = (event: KeyboardEvent) => { - if (os == null || !cmdPaletteOpen) { - return; - } - // Check for Cmd+K (Mac) or Ctrl+K (Windows/Linux) - const modifier = os === 'MacOS' ? event.metaKey : event.ctrlKey; - - if (modifier && event.key === 'N') { - event.preventDefault(); // Prevent default browser behavior - void router.navigate({ to: '/apps/create' }); - } - }; - - // Add event listener - window.addEventListener('keydown', handleKeyDown); - - // Cleanup function - return () => { - window.removeEventListener('keydown', handleKeyDown); - }; - }, [router, cmdPaletteOpen, os]); - - return ( - { - setCmdPaletteOpen(false); - setQuery(''); - }} - > - - -
- - - onChange={(item) => { - if (item) { - if (typeof item === 'string' && item === 'create_new_app') { - void router.navigate({ to: '/apps/create' }); - } else if (item.type === 'app') { - void router.navigate({ to: '/apps/$appId/details', params: { appId: String(item.id) } }); - } - setCmdPaletteOpen(false); - } - }} - > -
- setQuery(event.target.value)} - onBlur={() => setQuery('')} - /> - {isLoading ? ( - - ) : ( -
- - {query === '' || results.length > 0 ? ( - - {query === '' && !isLoading && results.length === 0 ? ( -
-

No apps created

-

- Get started by creating a new App, building the App schema, and generating the hypergraph schema - code. Click the "Create new app" option below -

-
- ) : ( -
  • -
      - {results.map((result) => ( -
    -
  • - )} - {query === '' && !isLoading ? ( -
  • -

    Quick actions

    -
      - - -
    -
  • - ) : null} -
    - ) : null} - - {query !== '' && results.length === 0 ? ( -
    -
    - ) : null} - -
    -
    -
    - ); -} - -// biome-ignore lint/suspicious/noExplicitAny: type inference from the routes for link does not get populated for as={Link} -type UnknownLinkParams = any; - -function Option({ result }: Readonly<{ result: SearchResult }>) { - if (result.type === 'app') { - return ( - - - - ); - } - - return ( - - - - ); -} - -function OptionContent({ result }: Readonly<{ result: SearchResult }>) { - return ( - <> -
    - {result.type === 'app' ? ( -
    -
    -

    - {result.name} - - {result.type} - -

    -
    - - ); -} diff --git a/apps/typesync/client/src/Components/FormComponents/ErrorMessages.tsx b/apps/typesync/client/src/Components/FormComponents/ErrorMessages.tsx deleted file mode 100644 index d94ba83d..00000000 --- a/apps/typesync/client/src/Components/FormComponents/ErrorMessages.tsx +++ /dev/null @@ -1,17 +0,0 @@ -export function ErrorMessages({ - id, - errors, -}: Readonly<{ id: string | undefined; errors: Array }>) { - return ( -
    - {errors.map((error, idx) => { - const key = `${id}__errorMessage__${idx}`; - return ( -
    - {typeof error === 'string' ? error : error.message} -
    - ); - })} -
    - ); -} diff --git a/apps/typesync/client/src/Components/FormComponents/Input.tsx b/apps/typesync/client/src/Components/FormComponents/Input.tsx deleted file mode 100644 index 40cbb2d7..00000000 --- a/apps/typesync/client/src/Components/FormComponents/Input.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { Input, type InputProps } from '@headlessui/react'; -import { useStore } from '@tanstack/react-form'; - -import { useFieldContext } from '../../context/form.js'; -import { classnames } from '../../utils/classnames.js'; -import { ErrorMessages } from './ErrorMessages.js'; - -export type FormComponentInputProps = Omit & { - id: string; - label?: React.ReactNode; - hint?: React.ReactNode; -}; -export function FormComponentTextField({ id, label, hint, ...rest }: Readonly) { - const field = useFieldContext(); - const errors = useStore(field.store, (state) => state.meta.errors); - const touched = useStore(field.store, (state) => state.meta.isTouched); - const hasErrors = errors.length > 0 && touched; - - return ( -
    - {label != null ? ( - - ) : null} -
    -
    - { - field.handleChange(e.target.value); - rest.onChange?.(e); - }} - data-state={hasErrors ? 'invalid' : undefined} - aria-invalid={hasErrors ? 'true' : undefined} - aria-describedby={hasErrors ? `${id}-invalid` : hint != null ? `${id}-hint` : undefined} - className="block min-w-0 grow py-1.5 pl-1 pr-3 data-[state=invalid]:pr-10 text-base text-gray-900 dark:text-white data-[state=invalid]:text-red-900 dark:data-[state=invalid]:text-red-700 placeholder:text-gray-400 dark:placeholder:text-gray-500 data-[state=invalid]:placeholder:text-red-700 dark:data-[state=invalid]:placeholder:text-red-400 focus:outline sm:text-sm/6 focus-visible:outline-none" - /> -
    - {hasErrors ? : null} - {hint != null && !hasErrors ? ( -

    - {hint} -

    - ) : null} -
    -
    - ); -} diff --git a/apps/typesync/client/src/Components/FormComponents/RadioGroup.tsx b/apps/typesync/client/src/Components/FormComponents/RadioGroup.tsx deleted file mode 100644 index 30a4c9f9..00000000 --- a/apps/typesync/client/src/Components/FormComponents/RadioGroup.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Radio, RadioGroup, type RadioGroupProps, type RadioProps } from '@headlessui/react'; - -import { useFieldContext } from '../../context/form.js'; - -export type FormComponentRadioGroupProps = Omit & { - id: string; - label: React.ReactNode; - options: ReadonlyArray; -}; -export function FormComponentRadioGroup({ id, label, options, ...rest }: Readonly) { - const field = useFieldContext(); - - return ( -
    - {label} - field.handleChange(value)} - className="mt-6 grid grid-cols-1 gap-y-6 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 sm:gap-x-4" - > - {options.map((opt, idx) => { - const radioOptKey = `RadioGroup__Opt[${opt.id || idx}]`; - return ( - - ); - })} - -
    - ); -} diff --git a/apps/typesync/client/src/Components/FormComponents/SubmitButton.tsx b/apps/typesync/client/src/Components/FormComponents/SubmitButton.tsx deleted file mode 100644 index 008fccd1..00000000 --- a/apps/typesync/client/src/Components/FormComponents/SubmitButton.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { CheckIcon, ExclamationCircleIcon } from '@heroicons/react/16/solid'; - -import { useFormContext } from '../../context/form.js'; -import { classnames } from '../../utils/classnames.js'; -import { Loading } from '../Loading.js'; - -export function SubmitButton({ - status, - children, -}: Readonly<{ status: 'idle' | 'error' | 'success' | 'submitting'; children: React.ReactNode }>) { - const form = useFormContext(); - - return ( - ({ - canSubmit: state.canSubmit, - isSubmitting: state.isSubmitting, - valid: state.isValid && state.errors.length === 0, - dirty: state.isDirty, - })} - > - {({ canSubmit, isSubmitting, valid, dirty }) => ( - - )} - - ); -} diff --git a/apps/typesync/client/src/Components/FormComponents/TextArea.tsx b/apps/typesync/client/src/Components/FormComponents/TextArea.tsx deleted file mode 100644 index 79373a5c..00000000 --- a/apps/typesync/client/src/Components/FormComponents/TextArea.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Textarea, type TextareaProps } from '@headlessui/react'; -import { useStore } from '@tanstack/react-form'; - -import { useFieldContext } from '../../context/form.js'; -import { ErrorMessages } from './ErrorMessages.js'; - -export type FormComponentTextAreaProps = Omit & { - id: string; - label: React.ReactNode; - hint?: React.ReactNode; -}; -export function FormComponentTextArea({ id, label, hint, ...rest }: Readonly) { - const field = useFieldContext(); - const errors = useStore(field.store, (state) => state.meta.errors); - const hasErrors = errors.length > 0; - - return ( -
    - -
    -