├── .changeset ├── README.md └── config.json ├── .github ├── dependabot.yml └── workflows │ ├── actions │ ├── prepare │ │ └── action.yml │ └── type-check-with-cache │ │ └── action.yml │ ├── changesets-reminder.yml │ ├── changesets.yml │ ├── checks.yml │ ├── ci.yml │ ├── deploy.yml │ ├── preview-versions.yml │ ├── release-notifier.yml │ ├── scripts │ └── snapshot-versions.ts │ └── snapshot-versions.yml ├── .gitignore ├── .nvmrc ├── .prettierignore ├── .vscode ├── extensions.json ├── settings.json └── tasks.json ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── configuration ├── vite.e2e.config.ts └── vite.unit.config.ts ├── craft-unwind.md ├── documentation ├── deploy │ ├── cloudflare.md │ └── fly.md ├── features │ ├── async.md │ ├── developing │ │ ├── apps.md │ │ ├── packages.md │ │ └── services.md │ ├── graphql.md │ ├── html.md │ ├── http.md │ ├── linting.md │ ├── localization.md │ ├── performance.md │ ├── request-routing.md │ ├── routing.md │ ├── server-rendering.md │ ├── static-rendering.md │ ├── styles.md │ ├── type-checking.md │ └── workers.md ├── getting-started.md ├── integrations │ ├── hono.md │ ├── htmx.md │ ├── tailwind.md │ ├── trpc.md │ └── web-vitals.md ├── priorities.md ├── projects │ ├── README.md │ ├── apps │ │ ├── README.md │ │ ├── browser.md │ │ ├── conventions.md │ │ └── server.md │ ├── packages │ │ ├── README.md │ │ └── builds.md │ └── services │ │ └── README.md ├── technology │ ├── README.md │ ├── graphql.md │ ├── preact.md │ └── typescript.md ├── thank-you.md ├── tools.md └── versioning.md ├── integrations ├── cloudflare │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── craft.ts │ │ ├── index.ts │ │ ├── request-router.tsx │ │ ├── request-router │ │ │ ├── event.ts │ │ │ ├── fetch.ts │ │ │ └── pages.ts │ │ └── types.ts │ └── tsconfig.json ├── deno │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── craft.ts │ │ ├── index.ts │ │ └── request-router.tsx │ └── tsconfig.json ├── htmx │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── source │ │ ├── index.ts │ │ ├── request.ts │ │ └── response.ts │ ├── tsconfig.json │ └── vite.config.js ├── react-query │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── ReactQueryContext.tsx │ │ ├── index.ts │ │ ├── use-graphql-mutation.ts │ │ ├── use-graphql-query.ts │ │ └── utilities.ts │ └── tsconfig.json └── trpc │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ └── rollup.config.js │ ├── package.json │ ├── source │ ├── fetch.ts │ ├── index.ts │ └── server.ts │ └── tsconfig.json ├── package.json ├── packages ├── assets │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── attributes.ts │ │ ├── index.ts │ │ ├── manifest.ts │ │ ├── manifest │ │ │ ├── runtime.ts │ │ │ └── types.ts │ │ ├── preload.ts │ │ └── types.ts │ └── tsconfig.json ├── async │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── AsyncAction.ts │ │ ├── AsyncActionCache.ts │ │ ├── AsyncModule.ts │ │ ├── global.ts │ │ ├── index.ts │ │ └── tests │ │ │ └── e2e.test.ts │ ├── tsconfig.json │ └── vite.config.js ├── babel │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── async.ts │ │ ├── index.ts │ │ └── workers.ts │ └── tsconfig.json ├── browser │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── source │ │ ├── browser.ts │ │ ├── encoding.ts │ │ ├── headers.ts │ │ ├── index.ts │ │ ├── server.browser.ts │ │ ├── server.ts │ │ ├── shared │ │ │ └── cookies.ts │ │ ├── testing.ts │ │ └── types.ts │ ├── tsconfig.json │ └── vite.config.js ├── cli-kit │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── index.ts │ │ ├── package-manager.ts │ │ ├── prompt.ts │ │ └── template.ts │ └── tsconfig.json ├── create │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── app.ts │ │ ├── cli.ts │ │ ├── help.ts │ │ ├── index.ts │ │ ├── module.ts │ │ ├── package.ts │ │ ├── server.ts │ │ ├── shared.ts │ │ └── shared │ │ │ ├── package-manager.ts │ │ │ ├── prompts.ts │ │ │ └── tsconfig.ts │ ├── templates │ │ ├── app-basic │ │ │ ├── App.tsx │ │ │ ├── browser.tsx │ │ │ ├── features │ │ │ │ ├── home.ts │ │ │ │ └── home │ │ │ │ │ ├── Home.module.css │ │ │ │ │ ├── Home.tsx │ │ │ │ │ └── tests │ │ │ │ │ └── Home.test.tsx │ │ │ ├── foundation │ │ │ │ ├── frame.ts │ │ │ │ ├── frame │ │ │ │ │ ├── Frame.module.css │ │ │ │ │ └── Frame.tsx │ │ │ │ ├── html.ts │ │ │ │ └── html │ │ │ │ │ ├── Head.test.tsx │ │ │ │ │ └── Head.tsx │ │ │ ├── package.json │ │ │ ├── rollup.config.js │ │ │ ├── server.tsx │ │ │ ├── shared │ │ │ │ ├── context.ts │ │ │ │ └── navigation.ts │ │ │ ├── tests │ │ │ │ ├── render.ts │ │ │ │ └── render │ │ │ │ │ ├── render.tsx │ │ │ │ │ └── types.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── app-empty │ │ │ ├── App.tsx │ │ │ ├── browser.tsx │ │ │ ├── package.json │ │ │ ├── rollup.config.js │ │ │ ├── server.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── app-graphql │ │ │ ├── App.tsx │ │ │ ├── _gitignore │ │ │ ├── _prettierignore │ │ │ ├── browser.tsx │ │ │ ├── features │ │ │ │ ├── home.ts │ │ │ │ └── home │ │ │ │ │ ├── Home.module.css │ │ │ │ │ ├── Home.tsx │ │ │ │ │ ├── HomeQuery.graphql │ │ │ │ │ └── tests │ │ │ │ │ └── Home.test.tsx │ │ │ ├── foundation │ │ │ │ ├── frame.ts │ │ │ │ ├── frame │ │ │ │ │ ├── Frame.module.css │ │ │ │ │ └── Frame.tsx │ │ │ │ ├── html.ts │ │ │ │ └── html │ │ │ │ │ ├── Head.test.tsx │ │ │ │ │ └── Head.tsx │ │ │ ├── graphql │ │ │ │ └── schema.graphql │ │ │ ├── package.json │ │ │ ├── rollup.config.js │ │ │ ├── server.tsx │ │ │ ├── server │ │ │ │ └── graphql.ts │ │ │ ├── shared │ │ │ │ ├── context.ts │ │ │ │ ├── graphql.ts │ │ │ │ └── navigation.ts │ │ │ ├── tests │ │ │ │ ├── graphql.ts │ │ │ │ ├── render.ts │ │ │ │ └── render │ │ │ │ │ ├── render.tsx │ │ │ │ │ └── types.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── app-trpc │ │ │ ├── App.tsx │ │ │ ├── browser.tsx │ │ │ ├── features │ │ │ │ ├── home.ts │ │ │ │ └── home │ │ │ │ │ ├── Home.module.css │ │ │ │ │ ├── Home.tsx │ │ │ │ │ └── tests │ │ │ │ │ └── Home.test.tsx │ │ │ ├── foundation │ │ │ │ ├── frame.ts │ │ │ │ ├── frame │ │ │ │ │ ├── Frame.module.css │ │ │ │ │ └── Frame.tsx │ │ │ │ ├── html.ts │ │ │ │ └── html │ │ │ │ │ ├── Head.test.tsx │ │ │ │ │ └── Head.tsx │ │ │ ├── package.json │ │ │ ├── rollup.config.js │ │ │ ├── server.tsx │ │ │ ├── shared │ │ │ │ ├── context.ts │ │ │ │ ├── navigation.ts │ │ │ │ └── trpc.ts │ │ │ ├── tests │ │ │ │ ├── render.ts │ │ │ │ └── render │ │ │ │ │ ├── render.tsx │ │ │ │ │ └── types.ts │ │ │ ├── trpc.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── github │ │ │ └── _github │ │ │ │ └── workflows │ │ │ │ ├── actions │ │ │ │ └── prepare │ │ │ │ │ └── action.yml │ │ │ │ └── ci.yml │ │ ├── module │ │ │ ├── module.ts │ │ │ ├── package.json │ │ │ ├── rollup.config.js │ │ │ └── tsconfig.json │ │ ├── package │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── rollup.config.js │ │ │ ├── source │ │ │ │ ├── index.test.ts │ │ │ │ └── index.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── server-basic │ │ │ ├── package.json │ │ │ ├── rollup.config.js │ │ │ ├── server.ts │ │ │ └── tsconfig.json │ │ ├── vscode │ │ │ └── _vscode │ │ │ │ ├── extensions.json │ │ │ │ └── settings.json │ │ └── workspace │ │ │ ├── _gitignore │ │ │ ├── _nvmrc │ │ │ ├── _prettierignore │ │ │ ├── package.json │ │ │ └── tsconfig.json │ └── tsconfig.json ├── events │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── abort.ts │ │ ├── abort │ │ │ ├── AbortError.ts │ │ │ ├── NestedAbortController.ts │ │ │ ├── TimedAbortController.ts │ │ │ └── race.ts │ │ ├── emitter.ts │ │ ├── handler.ts │ │ ├── index.ts │ │ ├── on.ts │ │ ├── once.ts │ │ ├── signals.ts │ │ ├── sleep.ts │ │ ├── tests │ │ │ └── emitter.test.ts │ │ └── types.ts │ ├── tsconfig.json │ └── vite.config.js ├── graphql-tools │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── configuration.ts │ │ ├── index.ts │ │ ├── jest-parts.ts │ │ ├── project.ts │ │ ├── project │ │ │ ├── load.ts │ │ │ └── types.ts │ │ ├── rollup-parts.ts │ │ ├── transform.ts │ │ ├── typescript.ts │ │ ├── typescript │ │ │ ├── builder.ts │ │ │ ├── cli.ts │ │ │ ├── print.ts │ │ │ ├── print │ │ │ │ ├── document.ts │ │ │ │ ├── generate.ts │ │ │ │ ├── schema.ts │ │ │ │ └── utilities.ts │ │ │ └── types.ts │ │ └── utilities │ │ │ ├── document.ts │ │ │ └── minify.ts │ └── tsconfig.json ├── graphql │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── GraphQLCache.ts │ │ ├── GraphQLMutation.ts │ │ ├── GraphQLQuery.ts │ │ ├── ast.ts │ │ ├── fetch │ │ │ ├── fetch.ts │ │ │ ├── request.ts │ │ │ ├── stream.ts │ │ │ └── tests │ │ │ │ └── stream.test.ts │ │ ├── gql.ts │ │ ├── index.ts │ │ ├── minify.ts │ │ ├── operation.ts │ │ ├── schema.ts │ │ ├── server.ts │ │ ├── server │ │ │ ├── server.ts │ │ │ ├── tests │ │ │ │ └── server.test.ts │ │ │ └── types.ts │ │ ├── testing.ts │ │ ├── testing │ │ │ ├── controller.ts │ │ │ ├── filler.ts │ │ │ ├── tests │ │ │ │ └── testing.test.ts │ │ │ └── types.ts │ │ └── types.ts │ ├── tsconfig.json │ └── vite.config.js ├── http │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── content-security-policy.ts │ │ ├── cookies.ts │ │ ├── cross-origin-headers.ts │ │ ├── headers.ts │ │ ├── index.ts │ │ ├── method.ts │ │ ├── permissions-policy.ts │ │ ├── response-type.ts │ │ └── status-code.ts │ └── tsconfig.json ├── localize │ ├── CHANGELOG.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── formatting.ts │ │ ├── index.ts │ │ ├── request-header.ts │ │ ├── tests │ │ │ └── translation.test.ts │ │ └── translation.ts │ ├── tsconfig.json │ └── vite.config.js ├── performance │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── index.ts │ │ └── performance.ts │ └── tsconfig.json ├── preact-async │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── AsyncComponent.tsx │ │ ├── AsyncContext.tsx │ │ ├── context.ts │ │ ├── hooks │ │ │ ├── async-cache-control.ts │ │ │ ├── async-retry.ts │ │ │ ├── async.ts │ │ │ ├── cache.ts │ │ │ ├── hydration.ts │ │ │ ├── module.ts │ │ │ └── mutation.ts │ │ └── index.ts │ └── tsconfig.json ├── preact-browser │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── source │ │ ├── browser.tsx │ │ ├── components │ │ │ ├── BodyAttributes.tsx │ │ │ ├── Favicon.tsx │ │ │ ├── HTMLAttributes.tsx │ │ │ ├── Link.tsx │ │ │ ├── Meta.tsx │ │ │ ├── ThemeColor.tsx │ │ │ └── Title.tsx │ │ ├── context.ts │ │ ├── hooks │ │ │ ├── body-attributes.ts │ │ │ ├── browser-effect.ts │ │ │ ├── browser-request.ts │ │ │ ├── cookie.ts │ │ │ ├── favicon.ts │ │ │ ├── html-attributes.ts │ │ │ ├── link.ts │ │ │ ├── locale.ts │ │ │ ├── meta.ts │ │ │ ├── serialized.ts │ │ │ ├── theme-color.ts │ │ │ └── title.ts │ │ ├── index.ts │ │ ├── server.browser.ts │ │ ├── server.ts │ │ ├── server │ │ │ ├── components │ │ │ │ ├── CacheControl.tsx │ │ │ │ ├── ContentSecurityPolicy.tsx │ │ │ │ ├── CrossOriginEmbedderPolicy.tsx │ │ │ │ ├── CrossOriginOpenerPolicy.tsx │ │ │ │ ├── CrossOriginResourcePolicy.tsx │ │ │ │ ├── HTML.tsx │ │ │ │ ├── HTMLPlaceholder.tsx │ │ │ │ ├── HTMLStreamBoundary.tsx │ │ │ │ ├── NotFound.tsx │ │ │ │ ├── OpenGraph.tsx │ │ │ │ ├── PermissionsPolicy.tsx │ │ │ │ ├── ResponseCookie.tsx │ │ │ │ ├── ResponseHeader.tsx │ │ │ │ ├── ResponseStatus.tsx │ │ │ │ ├── ScriptAssets.tsx │ │ │ │ ├── ScriptAssetsPreload.tsx │ │ │ │ ├── SearchRobots.tsx │ │ │ │ ├── Serialization.tsx │ │ │ │ ├── StrictTransportSecurity.tsx │ │ │ │ ├── StyleAssets.tsx │ │ │ │ ├── StyleAssetsPreload.tsx │ │ │ │ ├── Viewport.tsx │ │ │ │ └── shared │ │ │ │ │ └── base-url.ts │ │ │ ├── hooks │ │ │ │ ├── assets.ts │ │ │ │ ├── browser-response-action.ts │ │ │ │ ├── browser-response.ts │ │ │ │ ├── cache-control.ts │ │ │ │ ├── content-security-policy.ts │ │ │ │ ├── cross-origin-embedder-policy.ts │ │ │ │ ├── cross-origin-opener-policy.ts │ │ │ │ ├── cross-origin-resource-policy.ts │ │ │ │ ├── open-graph.ts │ │ │ │ ├── permissions-policy.ts │ │ │ │ ├── redirect.ts │ │ │ │ ├── response-cookie.ts │ │ │ │ ├── response-header.ts │ │ │ │ ├── response-status.ts │ │ │ │ ├── search-robots.ts │ │ │ │ ├── serialization.ts │ │ │ │ ├── strict-transport-security.ts │ │ │ │ └── viewport.ts │ │ │ └── render.tsx │ │ └── testing.ts │ ├── tsconfig.json │ └── vite.config.js ├── preact-context │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── index.ts │ │ └── optional-context.ts │ └── tsconfig.json ├── preact-email │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── context.ts │ │ ├── hooks │ │ │ ├── email-action.ts │ │ │ ├── plain-text.ts │ │ │ ├── send-bcc.ts │ │ │ ├── send-cc.ts │ │ │ ├── send-to.ts │ │ │ ├── sender.ts │ │ │ └── subject.ts │ │ ├── index.ts │ │ ├── manager.ts │ │ ├── server.tsx │ │ └── types.ts │ └── tsconfig.json ├── preact-graphql │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── context.tsx │ │ ├── hooks │ │ │ ├── use-graphql-cache.ts │ │ │ ├── use-graphql-fetch.ts │ │ │ ├── use-graphql-mutation.ts │ │ │ ├── use-graphql-query-data.ts │ │ │ ├── use-graphql-query-refetch.ts │ │ │ └── use-graphql-query.ts │ │ ├── index.ts │ │ ├── testing.tsx │ │ └── types.ts │ └── tsconfig.json ├── preact-localize │ ├── CHANGELOG.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── Localization.tsx │ │ ├── components │ │ │ └── AlternateURL.tsx │ │ ├── context.ts │ │ ├── hooks │ │ │ ├── alternate-url.ts │ │ │ ├── formatting.ts │ │ │ └── locale.ts │ │ ├── index.ts │ │ ├── request-router.ts │ │ ├── routing.ts │ │ └── routing │ │ │ ├── LocalizedLink.tsx │ │ │ ├── LocalizedNavigation.tsx │ │ │ ├── LocalizedRouter.ts │ │ │ ├── context.ts │ │ │ ├── localization │ │ │ ├── by-locale.ts │ │ │ ├── by-path.ts │ │ │ └── by-subdomain.ts │ │ │ └── types.ts │ └── tsconfig.json ├── preact-performance │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── PerformanceContext.tsx │ │ ├── context.ts │ │ ├── hooks │ │ │ ├── navigation-event.ts │ │ │ ├── navigation.ts │ │ │ └── performance.ts │ │ └── index.ts │ └── tsconfig.json ├── preact-router │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── Router.ts │ │ ├── components │ │ │ ├── Link.test.tsx │ │ │ ├── Link.tsx │ │ │ ├── Navigation.tsx │ │ │ ├── Redirect.tsx │ │ │ └── Routes.tsx │ │ ├── context.ts │ │ ├── hooks │ │ │ ├── current-url.ts │ │ │ ├── navigate.ts │ │ │ ├── route-data.ts │ │ │ ├── route-navigation-entry.ts │ │ │ ├── router.ts │ │ │ └── routes.tsx │ │ ├── index.ts │ │ ├── route.ts │ │ ├── testing.tsx │ │ ├── tests │ │ │ ├── e2e.test.tsx │ │ │ └── utilities.tsx │ │ └── types.ts │ ├── tsconfig.json │ └── vite.config.js ├── preact-signals │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ └── index.ts │ └── tsconfig.json ├── preact-testing │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── HookRunner.tsx │ │ ├── TestRenderer.tsx │ │ ├── environment.tsx │ │ ├── index.ts │ │ ├── matchers.ts │ │ ├── matchers │ │ │ ├── components.ts │ │ │ ├── context.ts │ │ │ ├── dom.ts │ │ │ ├── props.ts │ │ │ ├── text.ts │ │ │ └── utilities.ts │ │ ├── print.ts │ │ ├── tests │ │ │ └── e2e.test.tsx │ │ └── types.ts │ ├── tsconfig.json │ └── vite.config.js ├── preact-workers │ ├── CHANGELOG.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── hooks.ts │ │ └── index.ts │ └── tsconfig.json ├── prettier │ ├── CHANGELOG.md │ ├── index.js │ └── package.json ├── quilt │ ├── CHANGELOG.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── assets.ts │ │ ├── assets │ │ │ ├── files.ts │ │ │ └── styles.ts │ │ ├── async.ts │ │ ├── browser.ts │ │ ├── browser │ │ │ └── testing.ts │ │ ├── context.ts │ │ ├── env.ts │ │ ├── events.ts │ │ ├── globals.ts │ │ ├── graphql.ts │ │ ├── graphql │ │ │ ├── server.ts │ │ │ ├── testing.ts │ │ │ └── testing │ │ │ │ ├── matchers.ts │ │ │ │ └── matchers │ │ │ │ ├── operations.ts │ │ │ │ └── utilities.ts │ │ ├── index.ts │ │ ├── localize.ts │ │ ├── modules.ts │ │ ├── navigation.ts │ │ ├── navigation │ │ │ └── testing.ts │ │ ├── performance.ts │ │ ├── request-router.ts │ │ ├── request-router │ │ │ └── node.ts │ │ ├── server.browser.ts │ │ ├── server.ts │ │ ├── signals.ts │ │ ├── testing.ts │ │ └── threads.ts │ └── tsconfig.json ├── react-dom │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── client.ts │ │ ├── index.ts │ │ ├── server.ts │ │ └── test-utils.ts │ └── tsconfig.json ├── react-testing │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── HookRunner.tsx │ │ ├── TestRenderer.tsx │ │ ├── environment.tsx │ │ ├── implementations │ │ │ ├── react-dom.ts │ │ │ ├── shared │ │ │ │ └── react.ts │ │ │ └── test-renderer.ts │ │ ├── index.ts │ │ ├── matchers.ts │ │ ├── matchers │ │ │ ├── components.ts │ │ │ ├── context.ts │ │ │ ├── dom.ts │ │ │ ├── props.ts │ │ │ ├── text.ts │ │ │ └── utilities.ts │ │ ├── preact.ts │ │ ├── print.ts │ │ ├── tests │ │ │ └── e2e.test.tsx │ │ └── types.ts │ ├── tsconfig.json │ └── vite.config.js ├── react │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── index.ts │ │ └── jsx-runtime.ts │ └── tsconfig.json ├── request-router │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── errors.ts │ │ ├── errors │ │ │ ├── ResponseRedirectError.ts │ │ │ └── ResponseShortCircuitError.ts │ │ ├── globals.ts │ │ ├── handle.ts │ │ ├── index.ts │ │ ├── node │ │ │ ├── index.ts │ │ │ ├── node.ts │ │ │ ├── static.ts │ │ │ └── types.ts │ │ ├── request.ts │ │ ├── response-helpers.ts │ │ ├── response.ts │ │ ├── router.ts │ │ ├── tests │ │ │ └── router.test.ts │ │ └── types.ts │ └── tsconfig.json ├── rollup │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── app.ts │ │ ├── constants.ts │ │ ├── features │ │ │ ├── assets.ts │ │ │ ├── async.ts │ │ │ ├── css.ts │ │ │ ├── env.ts │ │ │ ├── esnext.ts │ │ │ ├── graphql.ts │ │ │ ├── graphql │ │ │ │ └── transform.ts │ │ │ ├── node.ts │ │ │ ├── react.ts │ │ │ ├── source-code.ts │ │ │ ├── system-js.ts │ │ │ ├── typescript.ts │ │ │ └── workers.ts │ │ ├── index.ts │ │ ├── module.ts │ │ ├── package.ts │ │ ├── server.ts │ │ └── shared │ │ │ ├── browserslist.ts │ │ │ ├── magic-module.ts │ │ │ ├── project.ts │ │ │ ├── rollup.ts │ │ │ └── strings.ts │ └── tsconfig.json ├── routing │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── index.ts │ │ ├── types.ts │ │ └── utilities.ts │ ├── tsconfig.json │ └── vite.config.js ├── signals │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── index.ts │ │ ├── iterator.ts │ │ └── signal-or-value.ts │ └── tsconfig.json ├── threads │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── Thread.ts │ │ ├── ThreadAbortSignal.ts │ │ ├── ThreadSignal.ts │ │ ├── constants.ts │ │ ├── errors.ts │ │ ├── functions │ │ │ ├── ThreadFunctionsAutomatic.ts │ │ │ └── ThreadFunctionsManualMemoryManagement.ts │ │ ├── index.ts │ │ ├── memory.ts │ │ ├── nanoid.ts │ │ ├── serialization │ │ │ ├── ThreadSerializationJSON.ts │ │ │ ├── ThreadSerializationStructuredClone.ts │ │ │ └── shared.ts │ │ ├── signals.ts │ │ ├── tests │ │ │ ├── e2e.test.ts │ │ │ └── utilities.ts │ │ ├── threads │ │ │ ├── ThreadBroadcastChannel.ts │ │ │ ├── ThreadBrowserWebSocket.ts │ │ │ ├── ThreadIframe.ts │ │ │ ├── ThreadMessagePort.ts │ │ │ ├── ThreadNestedIframe.ts │ │ │ ├── ThreadServiceWorker.ts │ │ │ ├── ThreadServiceWorkerClients.ts │ │ │ ├── ThreadWebWorker.ts │ │ │ └── window │ │ │ │ ├── ThreadNestedWindow.ts │ │ │ │ ├── ThreadWindow.ts │ │ │ │ └── shared.ts │ │ ├── transfer.ts │ │ └── types.ts │ ├── tsconfig.json │ └── vite.config.js ├── typescript │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── source │ │ ├── tsconfig.json │ │ ├── tsconfig.package.json │ │ ├── tsconfig.project.json │ │ └── tsconfig.workspace.json │ ├── tsconfig.json │ └── vite.config.js ├── useful-types │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ └── index.ts │ └── tsconfig.json ├── vite │ ├── CHANGELOG.md │ ├── README.md │ ├── configuration │ │ └── rollup.config.js │ ├── package.json │ ├── source │ │ ├── app.ts │ │ ├── index.ts │ │ ├── package.ts │ │ └── shared │ │ │ ├── babel.ts │ │ │ ├── magic-module.ts │ │ │ ├── node.ts │ │ │ ├── react.ts │ │ │ ├── strings.ts │ │ │ ├── typescript.ts │ │ │ └── workers.ts │ └── tsconfig.json └── workers │ ├── CHANGELOG.md │ ├── configuration │ └── rollup.config.js │ ├── package.json │ ├── source │ ├── create │ │ ├── basic.ts │ │ └── thread.ts │ └── index.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── tests └── e2e │ ├── CHANGELOG.md │ ├── apps.test.ts │ ├── assets.test.ts │ ├── async.test.ts │ ├── browser.test.ts │ ├── common │ ├── globals.ts │ ├── images │ │ ├── lemon-tiny.png │ │ └── lemon.png │ └── tsconfig.json │ ├── environment-variables.test.ts │ ├── fixtures │ ├── basic-api │ │ ├── CHANGELOG.md │ │ ├── api.ts │ │ ├── package.json │ │ ├── rollup.config.js │ │ └── tsconfig.json │ ├── basic-app │ │ ├── App.tsx │ │ ├── CHANGELOG.md │ │ ├── browser.tsx │ │ ├── foundation │ │ │ ├── HTML.tsx │ │ │ └── Routes.tsx │ │ ├── package.json │ │ ├── rollup.config.js │ │ ├── server.tsx │ │ └── tsconfig.json │ └── empty-app │ │ ├── App.tsx │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── rollup.config.js │ │ └── tsconfig.json │ ├── integrations │ ├── htmx.test.ts │ ├── react-query.test.ts │ └── trpc.test.ts │ ├── localization.test.ts │ ├── package.json │ ├── request-router.test.ts │ ├── routing.test.ts │ ├── suspense.test.ts │ ├── threads.test.ts │ └── utilities.ts ├── tsconfig.json └── vitest.workspace.js /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.7.0/schema.json", 3 | "changelog": ["@changesets/changelog-github", {"repo": "lemonmade/quilt"}], 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "minor", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # @see https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 2 | 3 | version: 2 4 | updates: 5 | - package-ecosystem: 'npm' 6 | directory: '/' 7 | schedule: 8 | interval: 'daily' 9 | 10 | - package-ecosystem: 'github-actions' 11 | directory: '/' 12 | schedule: 13 | interval: 'daily' 14 | -------------------------------------------------------------------------------- /.github/workflows/actions/prepare/action.yml: -------------------------------------------------------------------------------- 1 | name: Prepare repo 2 | runs: 3 | using: 'composite' 4 | steps: 5 | - uses: pnpm/action-setup@v4.0.0 6 | - uses: actions/setup-node@v4 7 | with: 8 | cache: pnpm 9 | registry-url: 'https://registry.npmjs.org' 10 | node-version-file: '.nvmrc' 11 | - name: Enable Corepack 12 | run: corepack enable && pnpm -v 13 | shell: bash 14 | - name: Install dependencies 15 | run: pnpm install --frozen-lockfile 16 | shell: bash 17 | -------------------------------------------------------------------------------- /.github/workflows/actions/type-check-with-cache/action.yml: -------------------------------------------------------------------------------- 1 | name: Type Check with cache 2 | runs: 3 | using: 'composite' 4 | steps: 5 | - uses: actions/cache@v4 6 | id: typescript-cache 7 | with: 8 | path: | 9 | **/build/typescript/ 10 | **/*.tsbuildinfo 11 | key: typescript-cache-v3-${{ github.sha }} 12 | restore-keys: typescript-cache-v3- 13 | - run: pnpm run type-check 14 | shell: bash 15 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | - '!main' 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | checks: 15 | name: Checks 📝 16 | uses: ./.github/workflows/checks.yml 17 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | concurrency: 8 | group: ${{ github.workflow }}-${{ github.ref }} 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | checks: 13 | name: Checks 📝 14 | uses: ./.github/workflows/checks.yml 15 | 16 | deploy: 17 | name: Deploy 🚀 18 | needs: checks 19 | runs-on: ubuntu-latest 20 | timeout-minutes: 5 21 | steps: 22 | - uses: actions/checkout@v4 23 | - uses: ./.github/workflows/actions/prepare 24 | - uses: ./.github/workflows/actions/type-check-with-cache 25 | - run: pnpm run build 26 | - name: Deploy 27 | run: pnpm run deploy 28 | env: 29 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 30 | -------------------------------------------------------------------------------- /.github/workflows/release-notifier.yml: -------------------------------------------------------------------------------- 1 | name: Release Notifier 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | post-to-discord: 9 | name: Post to Discord 📡 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 5 12 | steps: 13 | # @see https://github.com/rjstone/discord-webhook-notify 14 | - uses: rjstone/discord-webhook-notify@v1 15 | with: 16 | severity: info 17 | color: '#1EE084' 18 | text: New release from [Quilt](https://github.com/lemonmade/quilt)! 19 | description: > 20 | **${{ github.event.release.tag_name }}** 21 | 22 | Published by [${{ github.event.release.author.login }}](${{ github.event.release.author.html_url }}) 23 | 24 | ${{ github.event.release.html_url }} 25 | footer: ${{ github.event.release.published_at }} 26 | webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }} 27 | -------------------------------------------------------------------------------- /.github/workflows/snapshot-versions.yml: -------------------------------------------------------------------------------- 1 | name: Snapshot versions 2 | 3 | on: 4 | issue_comment: 5 | types: 6 | - created 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | snapshot: 12 | name: Snapshots 📸 13 | if: github.event.issue.pull_request && (github.event.comment.body == '/snap' || github.event.comment.body == '/snapshot' || github.event.comment.body == '📸') 14 | runs-on: ubuntu-latest 15 | timeout-minutes: 5 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: ./.github/workflows/actions/prepare 19 | - name: Deploy preview versions to NPM 20 | run: pnpm typescript.run ./.github/workflows/scripts/snapshot-versions.ts 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.RELEASES_GITHUB_TOKEN }} 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | node_modules/ 3 | .quilt/ 4 | .DS_STORE 5 | packages/*/bin/ 6 | *.log 7 | tests/e2e/output/ 8 | coverage 9 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v22.14.0 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | build/ 2 | node_modules/ 3 | .quilt/ 4 | packages/*/bin/ 5 | tests/e2e/output/ 6 | pnpm-lock.yaml 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["esbenp.prettier-vscode", "GraphQL.vscode-graphql"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "cSpell.words": ["middlewares", "pnpm", "Vite"], 5 | "cSpell.ignoreWords": [ 6 | "Changesets", 7 | "browserslist", 8 | "preloadable", 9 | "unmount" 10 | ], 11 | "search.exclude": { 12 | "**/node_modules": true, 13 | "**/bower_components": true, 14 | "**/*.code-search": true, 15 | "**/build": true 16 | }, 17 | "typescript.tsdk": "node_modules/typescript/lib" 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Create a changeset", 8 | "type": "shell", 9 | "command": "pnpm changeset", 10 | "problemMatcher": [] 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Working on this repository 4 | 5 | ### Installing dependencies 6 | 7 | This project uses 8 | 9 | ### Making changes 10 | 11 | This project uses [changesets](https://github.com/changesets/changesets/blob/main/docs/intro-to-using-changesets.md) to manage package versioning. When adding a change, run `pnpm changeset`. This will prompt you to select the packages your change affects, and the type of change you are making (patch, minor, or major). This command will generate a new file in the `.changesets` directory, which you should edit to provide a detailed explanation of your changes. 12 | 13 | To publish a new version, merge the pull request created by [changesets/action](https://github.com/changesets/action) on GitHub. Robots will take care of the rest! 14 | -------------------------------------------------------------------------------- /configuration/vite.e2e.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | esbuild: { 5 | // Without this, vitest preserves `using` statements, which aren’t supported in Node. 6 | target: 'es2022', 7 | }, 8 | server: { 9 | watch: { 10 | ignored: ['./tests/e2e/output/'], 11 | }, 12 | }, 13 | test: { 14 | testTimeout: 20_000, 15 | include: ['./tests/e2e/**/*.test.ts'], 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /configuration/vite.unit.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig, configDefaults} from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | esbuild: { 5 | jsx: 'automatic', 6 | jsxImportSource: 'preact', 7 | }, 8 | resolve: { 9 | conditions: ['quilt:source'], 10 | }, 11 | test: { 12 | include: ['./**/*.test.ts', './**/*.test.tsx'], 13 | exclude: [ 14 | ...configDefaults.exclude, 15 | './tests/e2e/**', 16 | './packages/create/templates/**', 17 | ], 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /craft-unwind.md: -------------------------------------------------------------------------------- 1 | - [x] Add GraphQL support for testing 2 | - [x] Add `tsx` (or similar) for running scripts 3 | - [ ] Add GraphQL type generation 4 | - [x] Add executable creation 5 | - [x] Multi browser builds, priority of asset manifests 6 | - [x] Improve Node bundle 7 | - [x] CJS build? 8 | - [x] Fix request router entries 9 | - [x] Support CF/ Deno/ general overrides 10 | - [x] Add support for serving assets to default server in Node 11 | - [x] Add development stuff 12 | - [x] ESNext target consumption 13 | - [x] Make sure in-repo packages are aliased for dev, test, and build 14 | - [x] Add support for non-ESM server 15 | - [x] Service stuff 16 | - [x] App polyfills 17 | - [ ] Add back Preact aliasing 18 | - [x] Allow passing of `env: 'production'` to rollup plugins 19 | - [x] Re-enable app cleaning 20 | - [x] Automatic setting of Rollup output format options based on targets 21 | - [x] Add development support for async components and workers 22 | -------------------------------------------------------------------------------- /documentation/features/developing/apps.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/developing/apps.md -------------------------------------------------------------------------------- /documentation/features/developing/packages.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/developing/packages.md -------------------------------------------------------------------------------- /documentation/features/developing/services.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/developing/services.md -------------------------------------------------------------------------------- /documentation/features/graphql.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/graphql.md -------------------------------------------------------------------------------- /documentation/features/linting.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/linting.md -------------------------------------------------------------------------------- /documentation/features/performance.md: -------------------------------------------------------------------------------- 1 | # Performance 2 | 3 | ## Polyfills 4 | 5 | TODO 6 | -------------------------------------------------------------------------------- /documentation/features/request-routing.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/request-routing.md -------------------------------------------------------------------------------- /documentation/features/server-rendering.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/server-rendering.md -------------------------------------------------------------------------------- /documentation/features/static-rendering.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/static-rendering.md -------------------------------------------------------------------------------- /documentation/features/styles.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/styles.md -------------------------------------------------------------------------------- /documentation/features/type-checking.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/type-checking.md -------------------------------------------------------------------------------- /documentation/features/workers.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/features/workers.md -------------------------------------------------------------------------------- /documentation/projects/apps/README.md: -------------------------------------------------------------------------------- 1 | # Apps 2 | 3 | Quilt’s main purpose is building **small-but-mighty** web applications. 4 | -------------------------------------------------------------------------------- /documentation/projects/packages/README.md: -------------------------------------------------------------------------------- 1 | # Packages 2 | 3 | ## Entries 4 | 5 | ## Runtimes 6 | -------------------------------------------------------------------------------- /documentation/projects/services/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/projects/services/README.md -------------------------------------------------------------------------------- /documentation/technology/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/technology/README.md -------------------------------------------------------------------------------- /documentation/technology/graphql.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/technology/graphql.md -------------------------------------------------------------------------------- /documentation/technology/preact.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/technology/preact.md -------------------------------------------------------------------------------- /documentation/technology/typescript.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/technology/typescript.md -------------------------------------------------------------------------------- /documentation/thank-you.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/thank-you.md -------------------------------------------------------------------------------- /documentation/versioning.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/documentation/versioning.md -------------------------------------------------------------------------------- /integrations/cloudflare/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /integrations/cloudflare/source/index.ts: -------------------------------------------------------------------------------- 1 | export type { 2 | CloudflareRequestContext, 3 | CloudflareRequestEnvironment, 4 | } from './types.ts'; 5 | export {}; 6 | -------------------------------------------------------------------------------- /integrations/cloudflare/source/request-router.tsx: -------------------------------------------------------------------------------- 1 | export { 2 | createFetchHandler, 3 | type RequestHandlerOptions, 4 | } from './request-router/fetch.ts'; 5 | export {transformFetchEvent} from './request-router/event.ts'; 6 | export { 7 | createPagesFetchHandler, 8 | type PagesAssetOptions, 9 | type PagesRequestHandlerOptions, 10 | } from './request-router/pages.ts'; 11 | -------------------------------------------------------------------------------- /integrations/cloudflare/source/types.ts: -------------------------------------------------------------------------------- 1 | import type {} from '@quilted/quilt'; 2 | 3 | export interface CloudflareRequestEnvironment {} 4 | 5 | export interface CloudflareRequestContext extends ExecutionContext { 6 | readonly cf?: IncomingRequestCfProperties; 7 | readonly env: CloudflareRequestEnvironment; 8 | } 9 | 10 | declare module '@quilted/quilt' { 11 | interface ServerRenderRequestContext extends CloudflareRequestContext {} 12 | } 13 | 14 | declare module '@quilted/quilt/request-router' { 15 | interface RequestContext extends CloudflareRequestContext {} 16 | } 17 | 18 | // @ts-expect-error This module augmentation does work when consumed in real projects 19 | declare module '@quilted/request-router' { 20 | interface RequestContext extends CloudflareRequestContext {} 21 | } 22 | -------------------------------------------------------------------------------- /integrations/cloudflare/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "types": ["@cloudflare/workers-types"] 5 | }, 6 | "references": [ 7 | {"path": "../../packages/quilt"}, 8 | {"path": "../../packages/rollup"} 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /integrations/deno/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/deno` 2 | -------------------------------------------------------------------------------- /integrations/deno/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /integrations/deno/source/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /integrations/deno/source/request-router.tsx: -------------------------------------------------------------------------------- 1 | import {NotFoundResponse, handleRequest} from '@quilted/quilt/request-router'; 2 | import type { 3 | RequestRouter, 4 | RequestHandler, 5 | } from '@quilted/quilt/request-router'; 6 | 7 | /** 8 | * Creates a Deno request handler from a Quilt HTTP handler. 9 | * The request handler can be passed directly as handler to 10 | * `Deno.serve()`. 11 | */ 12 | export function createServeHandler( 13 | handler: RequestRouter | RequestHandler, 14 | ): (request: Request) => Promise { 15 | return async (request: Request) => { 16 | const response = 17 | (await handleRequest(handler, request)) ?? new NotFoundResponse(); 18 | return response; 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /integrations/deno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [ 4 | {"path": "../../packages/quilt"}, 5 | {"path": "../../packages/rollup"} 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /integrations/htmx/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @quilted/htmx 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [[`00cac4b`](https://github.com/lemonmade/quilt/commit/00cac4b4d01831ba654e94152d7a67a0ef75043b)]: 8 | - @quilted/request-router@0.3.0 9 | -------------------------------------------------------------------------------- /integrations/htmx/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /integrations/htmx/source/index.ts: -------------------------------------------------------------------------------- 1 | export * from './request.ts'; 2 | export * from './response.ts'; 3 | -------------------------------------------------------------------------------- /integrations/htmx/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /integrations/htmx/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /integrations/react-query/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /integrations/react-query/source/index.ts: -------------------------------------------------------------------------------- 1 | export {ReactQueryContext} from './ReactQueryContext.tsx'; 2 | export { 3 | useGraphQLQuery, 4 | useGraphQLQueryOptions, 5 | useLazyGraphQLQuery, 6 | type GraphQLQueryOptions, 7 | type LazyGraphQLQueryOptions, 8 | } from './use-graphql-query.ts'; 9 | export { 10 | useGraphQLMutation, 11 | type GraphQLMutationOptions, 12 | } from './use-graphql-mutation.ts'; 13 | -------------------------------------------------------------------------------- /integrations/react-query/source/utilities.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type GraphQLResult, 3 | type GraphQLError as GraphQLErrorType, 4 | } from '@quilted/quilt/graphql'; 5 | 6 | class GraphQLError extends Error { 7 | readonly path?: GraphQLErrorType['path']; 8 | readonly locations?: GraphQLErrorType['locations']; 9 | 10 | constructor({message, path, locations}: GraphQLErrorType) { 11 | super(message); 12 | this.path = path; 13 | this.locations = locations; 14 | } 15 | } 16 | 17 | export function throwIfError(result: GraphQLResult) { 18 | if (result.errors) { 19 | throw new GraphQLError(result.errors[0]!); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /integrations/react-query/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [ 7 | {"path": "../../packages/quilt"}, 8 | {"path": "../../packages/useful-types"} 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /integrations/trpc/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/trpc` 2 | -------------------------------------------------------------------------------- /integrations/trpc/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /integrations/trpc/source/fetch.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/integrations/trpc/source/fetch.ts -------------------------------------------------------------------------------- /integrations/trpc/source/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /integrations/trpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/assets/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/assets` 2 | -------------------------------------------------------------------------------- /packages/assets/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/assets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quilted/assets", 3 | "description": "Utilities for working with browser assets", 4 | "type": "module", 5 | "license": "MIT", 6 | "publishConfig": { 7 | "access": "public", 8 | "@quilted/registry": "https://registry.npmjs.org" 9 | }, 10 | "version": "0.1.9", 11 | "engines": { 12 | "node": ">=14.0.0" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/lemonmade/quilt.git", 17 | "directory": "packages/assets" 18 | }, 19 | "exports": { 20 | ".": { 21 | "types": "./build/typescript/index.d.ts", 22 | "quilt:source": "./source/index.ts", 23 | "quilt:esnext": "./build/esnext/index.esnext", 24 | "import": "./build/esm/index.mjs" 25 | } 26 | }, 27 | "types": "./build/typescript/index.d.ts", 28 | "sideEffects": false, 29 | "scripts": { 30 | "build": "rollup --config configuration/rollup.config.js" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/assets/source/index.ts: -------------------------------------------------------------------------------- 1 | export type { 2 | Asset, 3 | AssetLoadTiming, 4 | BrowserAssets, 5 | BrowserAssetsEntry, 6 | BrowserAssetSelector, 7 | BrowserAssetModuleSelector, 8 | } from './types.ts'; 9 | export { 10 | styleAssetAttributes, 11 | styleAssetPreloadAttributes, 12 | scriptAssetAttributes, 13 | scriptAssetPreloadAttributes, 14 | } from './attributes.ts'; 15 | export { 16 | BrowserAssetsFromManifests, 17 | type AssetBuildManifest, 18 | type AssetBuildAsset, 19 | type AssetBuildAssetType, 20 | } from './manifest.ts'; 21 | export { 22 | preloadHeader, 23 | preloadScriptAssetHeader, 24 | preloadStyleAssetHeader, 25 | } from './preload.ts'; 26 | -------------------------------------------------------------------------------- /packages/assets/source/manifest.ts: -------------------------------------------------------------------------------- 1 | export type { 2 | AssetBuildManifest, 3 | AssetBuildAsset, 4 | AssetBuildAssetType, 5 | } from './manifest/types.ts'; 6 | export {BrowserAssetsFromManifests} from './manifest/runtime.ts'; 7 | -------------------------------------------------------------------------------- /packages/assets/source/manifest/types.ts: -------------------------------------------------------------------------------- 1 | export type AssetBuildAssetType = /** style */ 1 | /** script */ 2; 2 | 3 | export interface AssetBuildManifest { 4 | key?: string; 5 | priority?: number; 6 | base?: string; 7 | attributes?: { 8 | [K in AssetBuildAssetType]?: Record; 9 | }; 10 | entries: { 11 | '.': string; 12 | [key: string]: string; 13 | }; 14 | modules: Record; 15 | assets: AssetBuildAsset[]; 16 | } 17 | 18 | export type AssetBuildAsset = [ 19 | type: AssetBuildAssetType, 20 | path: string, 21 | integrityOrIntegrity?: string, 22 | attributes?: {textContent: string; [key: string]: string | boolean | number}, 23 | ]; 24 | -------------------------------------------------------------------------------- /packages/assets/source/types.ts: -------------------------------------------------------------------------------- 1 | export interface Asset { 2 | source: string; 3 | content?: string; 4 | attributes?: Record; 5 | } 6 | 7 | export type AssetLoadTiming = 'never' | 'preload' | 'load'; 8 | 9 | export interface BrowserAssetSelector { 10 | id?: string; 11 | modules?: Iterable< 12 | BrowserAssetModuleSelector | BrowserAssetModuleSelector['id'] 13 | >; 14 | request?: Request; 15 | } 16 | 17 | export interface BrowserAssetModuleSelector { 18 | id: string; 19 | styles?: boolean; 20 | scripts?: boolean; 21 | } 22 | 23 | export interface BrowserAssets { 24 | entry(options?: BrowserAssetSelector): BrowserAssetsEntry; 25 | modules( 26 | modules: NonNullable, 27 | options?: Pick, 28 | ): BrowserAssetsEntry; 29 | } 30 | 31 | export interface BrowserAssetsEntry { 32 | styles: Asset[]; 33 | scripts: Asset[]; 34 | } 35 | -------------------------------------------------------------------------------- /packages/assets/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/async/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/async` 2 | -------------------------------------------------------------------------------- /packages/async/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/async/source/index.ts: -------------------------------------------------------------------------------- 1 | export {AsyncModulesGlobal, type AsyncModulesOptions} from './global.ts'; 2 | export { 3 | AsyncAction, 4 | AsyncActionRun, 5 | type AsyncActionPromise, 6 | type AsyncActionStatus, 7 | type AsyncActionFunction, 8 | type AsyncActionRunCache, 9 | } from './AsyncAction.ts'; 10 | export { 11 | AsyncModule, 12 | type AsyncModuleLoader, 13 | type AsyncModuleLoaderFunction, 14 | type AsyncModuleLoaderObject, 15 | } from './AsyncModule.ts'; 16 | export { 17 | AsyncActionCache, 18 | type AsyncActionCacheKey, 19 | type AsyncActionCacheEntry, 20 | type AsyncActionCacheCreateOptions, 21 | type AsyncActionCacheFindOptions, 22 | type AsyncActionCacheEntrySerialization, 23 | } from './AsyncActionCache.ts'; 24 | -------------------------------------------------------------------------------- /packages/async/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [ 4 | {"path": "../events"}, 5 | {"path": "../assets"}, 6 | {"path": "../signals"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /packages/async/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/babel/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/babel` 2 | -------------------------------------------------------------------------------- /packages/babel/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage({ 4 | commonjs: true, 5 | }); 6 | -------------------------------------------------------------------------------- /packages/babel/source/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /packages/babel/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/browser/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/react-browser` 2 | -------------------------------------------------------------------------------- /packages/browser/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/browser/source/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types.ts'; 2 | export * from './browser.ts'; 3 | -------------------------------------------------------------------------------- /packages/browser/source/server.browser.ts: -------------------------------------------------------------------------------- 1 | class NoopBrowserServerClass {} 2 | 3 | export { 4 | NoopBrowserServerClass as BrowserResponse, 5 | NoopBrowserServerClass as BrowserResponseCookies, 6 | NoopBrowserServerClass as BrowserResponseStatus, 7 | NoopBrowserServerClass as BrowserResponseTitle, 8 | NoopBrowserServerClass as BrowserResponseHeadElements, 9 | NoopBrowserServerClass as BrowserResponseElementAttributes, 10 | NoopBrowserServerClass as BrowserResponseSerializations, 11 | NoopBrowserServerClass as BrowserResponseAssets, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/browser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [ 4 | {"path": "../assets"}, 5 | {"path": "../http"}, 6 | {"path": "../signals"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /packages/browser/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/cli-kit/README.md: -------------------------------------------------------------------------------- 1 | # Package 2 | -------------------------------------------------------------------------------- /packages/cli-kit/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/cli-kit/source/index.ts: -------------------------------------------------------------------------------- 1 | import * as color from 'colorette'; 2 | 3 | export { 4 | on, 5 | once, 6 | AbortError, 7 | NestedAbortController, 8 | raceAgainstAbortSignal, 9 | createEventEmitter, 10 | EventEmitter, 11 | addEventHandler, 12 | } from '@quilted/events'; 13 | export {stripIndent} from 'common-tags'; 14 | export {default as parseArguments} from 'arg'; 15 | 16 | export {prompt} from './prompt.ts'; 17 | export { 18 | createTemplate, 19 | createPackageTemplates, 20 | type Template, 21 | type TemplateCopyOptions, 22 | type PackageTemplates, 23 | } from './template.ts'; 24 | export { 25 | getPackageManager, 26 | createPackageManagerRunner, 27 | type PackageManager, 28 | type PackageManagerRunner, 29 | } from './package-manager.ts'; 30 | 31 | export {color}; 32 | -------------------------------------------------------------------------------- /packages/cli-kit/source/prompt.ts: -------------------------------------------------------------------------------- 1 | import {AbortError} from '@quilted/events'; 2 | import prompts, {type PromptObject, type PromptType} from 'prompts'; 3 | 4 | export interface CustomPromptReturnTypes { 5 | confirm: boolean; 6 | toggle: boolean; 7 | number: number; 8 | date: Date; 9 | multiselect: string[]; 10 | autocompleteMultiselect: string[]; 11 | } 12 | 13 | export async function prompt( 14 | prompt: Omit, 'name'> & {type: Prompt}, 15 | ): Promise< 16 | Prompt extends keyof CustomPromptReturnTypes 17 | ? CustomPromptReturnTypes[Prompt] 18 | : string 19 | > { 20 | const result = await prompts<'value'>( 21 | {name: 'value', ...prompt}, 22 | { 23 | onCancel() { 24 | throw new AbortError(); 25 | }, 26 | }, 27 | ); 28 | 29 | return result.value as any; 30 | } 31 | -------------------------------------------------------------------------------- /packages/cli-kit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [{"path": "../events"}] 4 | } 5 | -------------------------------------------------------------------------------- /packages/create/.gitignore: -------------------------------------------------------------------------------- 1 | templates/**/*.graphql.d.ts 2 | templates/app-graphql/graphql/schema.ts 3 | -------------------------------------------------------------------------------- /packages/create/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage({ 4 | bundle: true, 5 | executable: { 6 | 'create-quilt': './source/cli.ts', 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /packages/create/source/index.ts: -------------------------------------------------------------------------------- 1 | export {createApp} from './app.ts'; 2 | export {createProject} from './package.ts'; 3 | export {createModule} from './module.ts'; 4 | export {createServer} from './server.ts'; 5 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/browser.tsx: -------------------------------------------------------------------------------- 1 | import '@quilted/quilt/globals'; 2 | import {hydrate} from '@quilted/quilt/browser'; 3 | import {Router} from '@quilted/quilt/navigation'; 4 | 5 | import type {AppContext} from '~/shared/context.ts'; 6 | import {App} from './App.tsx'; 7 | 8 | const context = { 9 | router: new Router(), 10 | } satisfies AppContext; 11 | 12 | // Makes key parts of the app available in the browser console 13 | Object.defineProperty(globalThis, 'app', { 14 | value: {context}, 15 | enumerable: false, 16 | configurable: true, 17 | }); 18 | 19 | hydrate(); 20 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/features/home.ts: -------------------------------------------------------------------------------- 1 | import {AsyncComponent} from '@quilted/quilt/async'; 2 | 3 | export const Home = AsyncComponent.from(() => import('./home/Home.tsx')); 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/features/home/Home.module.css: -------------------------------------------------------------------------------- 1 | .Home { 2 | font-weight: 900; 3 | } 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/features/home/Home.tsx: -------------------------------------------------------------------------------- 1 | import styles from './Home.module.css'; 2 | 3 | export default function Home() { 4 | return
Hello world!
; 5 | } 6 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/features/home/tests/Home.test.tsx: -------------------------------------------------------------------------------- 1 | import {describe, it, expect} from 'vitest'; 2 | 3 | import {renderApp} from '~/tests/render.ts'; 4 | 5 | import Home from '../Home.tsx'; 6 | 7 | describe('', () => { 8 | it('includes a welcome message', async () => { 9 | const home = await renderApp(); 10 | expect(home).toContainPreactText('Hello world!'); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/foundation/frame.ts: -------------------------------------------------------------------------------- 1 | export {Frame} from './frame/Frame.tsx'; 2 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/foundation/frame/Frame.module.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | } 6 | 7 | html, 8 | body { 9 | margin: 0; 10 | } 11 | 12 | .Frame { 13 | padding: 1rem; 14 | } 15 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/foundation/frame/Frame.tsx: -------------------------------------------------------------------------------- 1 | import type {RenderableProps} from 'preact'; 2 | import {Suspense} from 'preact/compat'; 3 | 4 | import styles from './Frame.module.css'; 5 | 6 | export function Frame({children}: RenderableProps<{}>) { 7 | return ( 8 |
9 | {children} 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/foundation/html.ts: -------------------------------------------------------------------------------- 1 | export {Head} from './html/Head.tsx'; 2 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltApp} from '@quilted/rollup/app'; 2 | 3 | export default quiltApp(); 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/shared/context.ts: -------------------------------------------------------------------------------- 1 | import {createOptionalContext} from '@quilted/quilt/context'; 2 | 3 | export interface AppContext {} 4 | 5 | export const AppContextReact = createOptionalContext(); 6 | export const useAppContext = AppContextReact.use; 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/shared/navigation.ts: -------------------------------------------------------------------------------- 1 | import type {Router} from '@quilted/quilt/navigation'; 2 | import {createContextRouteFunction} from '@quilted/quilt/navigation'; 3 | 4 | import type {AppContext} from '~/shared/context.ts'; 5 | 6 | declare module '~/shared/context.ts' { 7 | interface AppContext { 8 | /** 9 | * The router used to control navigation throughout the application. 10 | */ 11 | readonly router: Router; 12 | } 13 | } 14 | 15 | export const routeWithAppContext = createContextRouteFunction(); 16 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/tests/render.ts: -------------------------------------------------------------------------------- 1 | import '@quilted/quilt/testing'; 2 | 3 | export {TestRouter} from '@quilted/quilt/navigation/testing'; 4 | 5 | export * from './render/types.ts'; 6 | export {renderApp} from './render/render.tsx'; 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact", 5 | "paths": { 6 | "~/shared/*": ["./shared/*"], 7 | "~/tests/*": ["./tests/*"], 8 | "react": ["./node_modules/preact/compat"], 9 | "react-dom": ["./node_modules/preact/compat"] 10 | } 11 | }, 12 | "include": ["**/*"], 13 | "exclude": ["build"], 14 | "references": [] 15 | } 16 | -------------------------------------------------------------------------------- /packages/create/templates/app-basic/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltApp} from '@quilted/vite/app'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltApp()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-empty/App.tsx: -------------------------------------------------------------------------------- 1 | export function App() { 2 | return
Hello world!
; 3 | } 4 | 5 | export default App; 6 | -------------------------------------------------------------------------------- /packages/create/templates/app-empty/browser.tsx: -------------------------------------------------------------------------------- 1 | import {hydrate} from 'preact'; 2 | 3 | import {App} from './App.tsx'; 4 | 5 | const element = document.querySelector('#app')!; 6 | 7 | hydrate(, element); 8 | -------------------------------------------------------------------------------- /packages/create/templates/app-empty/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltApp} from '@quilted/rollup/app'; 2 | 3 | export default quiltApp(); 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-empty/server.tsx: -------------------------------------------------------------------------------- 1 | import '@quilted/quilt/globals'; 2 | 3 | import {RequestRouter} from '@quilted/quilt/request-router'; 4 | import {renderAppToHTMLResponse} from '@quilted/quilt/server'; 5 | import {BrowserAssets} from 'quilt:module/assets'; 6 | 7 | import {App} from './App.tsx'; 8 | 9 | const router = new RequestRouter(); 10 | const assets = new BrowserAssets(); 11 | 12 | // For all GET requests, render our Preact application. 13 | router.get(async (request) => { 14 | const response = await renderAppToHTMLResponse(, { 15 | request, 16 | assets, 17 | }); 18 | 19 | return response; 20 | }); 21 | 22 | export default router; 23 | -------------------------------------------------------------------------------- /packages/create/templates/app-empty/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact", 5 | "paths": { 6 | "react": ["./node_modules/preact/compat"], 7 | "react-dom": ["./node_modules/preact/compat"] 8 | } 9 | }, 10 | "include": ["**/*"], 11 | "exclude": ["build"], 12 | "references": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/create/templates/app-empty/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltApp} from '@quilted/vite/app'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltApp()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/_gitignore: -------------------------------------------------------------------------------- 1 | # Temporary files 2 | *.graphql.d.ts 3 | graphql/schema.ts 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/_prettierignore: -------------------------------------------------------------------------------- 1 | # Temporary files 2 | *.graphql.d.ts 3 | graphql/schema.ts 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/browser.tsx: -------------------------------------------------------------------------------- 1 | import '@quilted/quilt/globals'; 2 | 3 | import {hydrate} from '@quilted/quilt/browser'; 4 | import {Router} from '@quilted/quilt/navigation'; 5 | import {createGraphQLFetch, GraphQLCache} from '@quilted/quilt/graphql'; 6 | 7 | import type {AppContext} from '~/shared/context.ts'; 8 | 9 | import {App} from './App.tsx'; 10 | 11 | const graphQLFetch = createGraphQLFetch({url: '/api/graphql'}); 12 | const graphQLCache = new GraphQLCache({fetch: graphQLFetch}); 13 | 14 | const context = { 15 | router: new Router(), 16 | graphql: { 17 | fetch: graphQLFetch, 18 | cache: graphQLCache, 19 | }, 20 | } satisfies AppContext; 21 | 22 | // Makes key parts of the app available in the browser console 23 | Object.defineProperty(globalThis, 'app', { 24 | value: {context}, 25 | enumerable: false, 26 | configurable: true, 27 | }); 28 | 29 | hydrate(); 30 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/features/home.ts: -------------------------------------------------------------------------------- 1 | import {AsyncComponent} from '@quilted/quilt/async'; 2 | 3 | export {default as homeQuery} from './home/HomeQuery.graphql'; 4 | 5 | export const Home = AsyncComponent.from(() => import('./home/Home.tsx')); 6 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/features/home/Home.module.css: -------------------------------------------------------------------------------- 1 | .Home { 2 | font-weight: 900; 3 | } 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/features/home/Home.tsx: -------------------------------------------------------------------------------- 1 | import {useGraphQLQuery} from '@quilted/quilt/graphql'; 2 | 3 | import styles from './Home.module.css'; 4 | import homeQuery from './HomeQuery.graphql'; 5 | 6 | export default function Home() { 7 | const query = useGraphQLQuery(homeQuery); 8 | 9 | const me = query.result?.data?.me; 10 | const greeting = me ? `Hello ${me.name}!` : 'Hello!'; 11 | 12 | return
{greeting}
; 13 | } 14 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/features/home/HomeQuery.graphql: -------------------------------------------------------------------------------- 1 | query Home { 2 | me { 3 | name 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/features/home/tests/Home.test.tsx: -------------------------------------------------------------------------------- 1 | import {describe, it, expect} from 'vitest'; 2 | 3 | import {renderApp} from '~/tests/render.ts'; 4 | import {fillGraphQL, GraphQLController} from '~/tests/graphql.ts'; 5 | 6 | import Home from '../Home.tsx'; 7 | import homeQuery from '../HomeQuery.graphql'; 8 | 9 | describe('', () => { 10 | it('welcomes the user with their name', async () => { 11 | const name = 'Winston'; 12 | const graphql = new GraphQLController([ 13 | fillGraphQL(homeQuery, {me: {name}}), 14 | ]); 15 | 16 | const home = await renderApp(, {graphql}); 17 | 18 | expect(graphql).toHavePerformedGraphQLQuery(homeQuery); 19 | expect(home).toContainPreactText(`Hello ${name}!`); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/foundation/frame.ts: -------------------------------------------------------------------------------- 1 | export {Frame} from './frame/Frame.tsx'; 2 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/foundation/frame/Frame.module.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | } 6 | 7 | html, 8 | body { 9 | margin: 0; 10 | } 11 | 12 | .Frame { 13 | padding: 1rem; 14 | } 15 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/foundation/frame/Frame.tsx: -------------------------------------------------------------------------------- 1 | import type {RenderableProps} from 'preact'; 2 | import {Suspense} from 'preact/compat'; 3 | 4 | import styles from './Frame.module.css'; 5 | 6 | export function Frame({children}: RenderableProps<{}>) { 7 | return ( 8 |
9 | {children} 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/foundation/html.ts: -------------------------------------------------------------------------------- 1 | export {Head} from './html/Head.tsx'; 2 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/graphql/schema.graphql: -------------------------------------------------------------------------------- 1 | type Person { 2 | name: String! 3 | } 4 | 5 | type Query { 6 | me: Person! 7 | } 8 | 9 | schema { 10 | query: Query 11 | } 12 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltApp} from '@quilted/rollup/app'; 2 | 3 | export default quiltApp(); 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/shared/context.ts: -------------------------------------------------------------------------------- 1 | import {createOptionalContext} from '@quilted/quilt/context'; 2 | 3 | export interface AppContext {} 4 | 5 | export const AppContextReact = createOptionalContext(); 6 | export const useAppContext = AppContextReact.use; 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/shared/graphql.ts: -------------------------------------------------------------------------------- 1 | import type {GraphQLFetch, GraphQLCache} from '@quilted/quilt/graphql'; 2 | 3 | declare module '~/shared/context.ts' { 4 | interface AppContext { 5 | readonly graphql: { 6 | readonly fetch: GraphQLFetch; 7 | readonly cache: GraphQLCache; 8 | }; 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/shared/navigation.ts: -------------------------------------------------------------------------------- 1 | import type {Router} from '@quilted/quilt/navigation'; 2 | import {createContextRouteFunction} from '@quilted/quilt/navigation'; 3 | 4 | import type {AppContext} from '~/shared/context.ts'; 5 | 6 | declare module '~/shared/context.ts' { 7 | interface AppContext { 8 | /** 9 | * The router used to control navigation throughout the application. 10 | */ 11 | readonly router: Router; 12 | } 13 | } 14 | 15 | export const routeWithAppContext = createContextRouteFunction(); 16 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/tests/graphql.ts: -------------------------------------------------------------------------------- 1 | import { 2 | GraphQLTesting, 3 | GraphQLController, 4 | createGraphQLSchema, 5 | createGraphQLFiller, 6 | } from '@quilted/quilt/graphql/testing'; 7 | 8 | import schemaSource from '../graphql/schema.ts'; 9 | 10 | export const schema = createGraphQLSchema(schemaSource); 11 | export const fillGraphQL = createGraphQLFiller(schema); 12 | 13 | export {GraphQLController, GraphQLTesting}; 14 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/tests/render.ts: -------------------------------------------------------------------------------- 1 | import '@quilted/quilt/testing'; 2 | 3 | export {TestRouter} from '@quilted/quilt/navigation/testing'; 4 | 5 | export * from './render/types.ts'; 6 | export {renderApp} from './render/render.tsx'; 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact", 5 | "paths": { 6 | "~/shared/*": ["./shared/*"], 7 | "~/tests/*": ["./tests/*"], 8 | "react": ["./node_modules/preact/compat"], 9 | "react-dom": ["./node_modules/preact/compat"] 10 | } 11 | }, 12 | "include": ["**/*"], 13 | "exclude": ["build"], 14 | "references": [] 15 | } 16 | -------------------------------------------------------------------------------- /packages/create/templates/app-graphql/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltApp} from '@quilted/vite/app'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltApp()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/features/home.ts: -------------------------------------------------------------------------------- 1 | import {AsyncComponent} from '@quilted/quilt/async'; 2 | 3 | export const Home = AsyncComponent.from(() => import('./home/Home.tsx')); 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/features/home/Home.module.css: -------------------------------------------------------------------------------- 1 | .Home { 2 | font-weight: 900; 3 | } 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/features/home/Home.tsx: -------------------------------------------------------------------------------- 1 | import {trpc} from '~/shared/trpc.ts'; 2 | 3 | import styles from './Home.module.css'; 4 | 5 | export default function Home() { 6 | const [data] = trpc.message.useSuspenseQuery('world'); 7 | 8 | return
{data}
; 9 | } 10 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/features/home/tests/Home.test.tsx: -------------------------------------------------------------------------------- 1 | import {describe, it, expect} from 'vitest'; 2 | 3 | import {renderApp} from '~/tests/render.ts'; 4 | 5 | import Home from '../Home.tsx'; 6 | 7 | describe('', () => { 8 | it('includes a welcome message', async () => { 9 | const home = await renderApp(); 10 | expect(home).toContainPreactText('Hello world!'); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/foundation/frame.ts: -------------------------------------------------------------------------------- 1 | export {Frame} from './frame/Frame.tsx'; 2 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/foundation/frame/Frame.module.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | } 6 | 7 | html, 8 | body { 9 | margin: 0; 10 | } 11 | 12 | .Frame { 13 | padding: 1rem; 14 | } 15 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/foundation/frame/Frame.tsx: -------------------------------------------------------------------------------- 1 | import type {RenderableProps} from 'preact'; 2 | import {Suspense} from 'preact/compat'; 3 | 4 | import styles from './Frame.module.css'; 5 | 6 | export function Frame({children}: RenderableProps<{}>) { 7 | return ( 8 |
9 | {children} 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/foundation/html.ts: -------------------------------------------------------------------------------- 1 | export {Head} from './html/Head.tsx'; 2 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltApp} from '@quilted/rollup/app'; 2 | 3 | export default quiltApp(); 4 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/shared/context.ts: -------------------------------------------------------------------------------- 1 | import {createOptionalContext} from '@quilted/quilt/context'; 2 | 3 | export interface AppContext {} 4 | 5 | export const AppContextReact = createOptionalContext(); 6 | export const useAppContext = AppContextReact.use; 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/shared/navigation.ts: -------------------------------------------------------------------------------- 1 | import type {Router} from '@quilted/quilt/navigation'; 2 | import {createContextRouteFunction} from '@quilted/quilt/navigation'; 3 | 4 | import type {AppContext} from '~/shared/context.ts'; 5 | 6 | declare module '~/shared/context.ts' { 7 | interface AppContext { 8 | /** 9 | * The router used to control navigation throughout the application. 10 | */ 11 | readonly router: Router; 12 | } 13 | } 14 | 15 | export const routeWithAppContext = createContextRouteFunction(); 16 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/shared/trpc.ts: -------------------------------------------------------------------------------- 1 | import type {TRPCUntypedClient} from '@trpc/client'; 2 | import {createTRPCReact, type CreateTRPCReact} from '@trpc/react-query'; 3 | import type {QueryClient} from '@tanstack/react-query'; 4 | 5 | // Get access to our app’s router type signature, which will 6 | // provide strong typing on the queries and mutations we can 7 | // perform. 8 | import type {AppRouter} from '../trpc.ts'; 9 | 10 | export const trpc: CreateTRPCReact = 11 | createTRPCReact(); 12 | 13 | declare module '~/shared/context.ts' { 14 | interface AppContext { 15 | trpc: TRPCUntypedClient; 16 | queryClient: QueryClient; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/tests/render.ts: -------------------------------------------------------------------------------- 1 | import '@quilted/quilt/testing'; 2 | 3 | export {TestRouter} from '@quilted/quilt/navigation/testing'; 4 | 5 | export * from './render/types.ts'; 6 | export {renderApp} from './render/render.tsx'; 7 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/trpc.ts: -------------------------------------------------------------------------------- 1 | import {z} from 'zod'; 2 | import {initTRPC} from '@trpc/server'; 3 | 4 | const t = initTRPC.create(); 5 | 6 | export const appRouter = t.router({ 7 | message: t.procedure.input(z.string()).query(({input}) => `Hello ${input}!`), 8 | }); 9 | 10 | // Export type router type signature, not the router itself. 11 | // Our client-side code will use this type to infer the 12 | // procedures that are defined. 13 | export type AppRouter = typeof appRouter; 14 | 15 | export const createCaller = t.createCallerFactory(appRouter); 16 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact", 5 | "paths": { 6 | "~/shared/*": ["./shared/*"], 7 | "~/tests/*": ["./tests/*"], 8 | "react": ["./node_modules/preact/compat"], 9 | "react-dom": ["./node_modules/preact/compat"] 10 | } 11 | }, 12 | "include": ["**/*"], 13 | "exclude": ["build"], 14 | "references": [] 15 | } 16 | -------------------------------------------------------------------------------- /packages/create/templates/app-trpc/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltApp} from '@quilted/vite/app'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltApp()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/create/templates/github/_github/workflows/actions/prepare/action.yml: -------------------------------------------------------------------------------- 1 | name: Prepare repo 2 | runs: 3 | using: 'composite' 4 | steps: 5 | - uses: pnpm/action-setup@v2.2.1 6 | - uses: actions/setup-node@v2 7 | with: 8 | cache: pnpm 9 | registry-url: 'https://registry.npmjs.org' 10 | node-version-file: '.nvmrc' 11 | - name: Install dependencies 12 | run: pnpm install 13 | shell: bash 14 | -------------------------------------------------------------------------------- /packages/create/templates/module/module.ts: -------------------------------------------------------------------------------- 1 | // Replace this module with whatever you want to run in a browser! 2 | 3 | export function run() { 4 | return 'Go build something fun!'; 5 | } 6 | -------------------------------------------------------------------------------- /packages/create/templates/module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "template-module", 3 | "type": "module", 4 | "exports": { 5 | ".": "./module.ts" 6 | }, 7 | "version": "0.0.0", 8 | "private": true, 9 | "scripts": { 10 | "build": "rollup --config ./rollup.config.js" 11 | }, 12 | "dependencies": {}, 13 | "devDependencies": {}, 14 | "browserslist": [ 15 | "defaults and fully supports es6-module" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/create/templates/module/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltModule} from '@quilted/rollup'; 2 | 3 | export default quiltModule(); 4 | -------------------------------------------------------------------------------- /packages/create/templates/module/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "include": ["**/*"], 4 | "exclude": ["build"], 5 | "references": [] 6 | } 7 | -------------------------------------------------------------------------------- /packages/create/templates/package/README.md: -------------------------------------------------------------------------------- 1 | # `{{name}}` 2 | -------------------------------------------------------------------------------- /packages/create/templates/package/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/create/templates/package/source/index.test.ts: -------------------------------------------------------------------------------- 1 | import {describe, it, expect} from 'vitest'; 2 | 3 | import {run} from './index.ts'; 4 | 5 | describe('run()', () => { 6 | it('returns something fun', () => { 7 | expect(run()).toContain('fun'); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/create/templates/package/source/index.ts: -------------------------------------------------------------------------------- 1 | export function run() { 2 | return 'Have fun building!'; 3 | } 4 | -------------------------------------------------------------------------------- /packages/create/templates/package/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/create/templates/package/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/create/templates/server-basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "template-server-basic", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "private": true, 6 | "scripts": { 7 | "build": "rollup --config ./rollup.config.js" 8 | }, 9 | "devDependencies": { 10 | "@quilted/quilt": "^0.6.0" 11 | }, 12 | "browserslist": [ 13 | "current node version" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/create/templates/server-basic/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltServer} from '@quilted/rollup/server'; 2 | 3 | export default quiltServer(); 4 | -------------------------------------------------------------------------------- /packages/create/templates/server-basic/server.ts: -------------------------------------------------------------------------------- 1 | import {RequestRouter} from '@quilted/quilt/request-router'; 2 | 3 | const app = new RequestRouter(); 4 | 5 | app.get('/', () => new Response('Hello, world!')); 6 | 7 | export default app; 8 | -------------------------------------------------------------------------------- /packages/create/templates/server-basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "include": ["**/*"], 4 | "exclude": ["build"], 5 | "references": [] 6 | } 7 | -------------------------------------------------------------------------------- /packages/create/templates/vscode/_vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["esbenp.prettier-vscode", "GraphQL.vscode-graphql"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/create/templates/vscode/_vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "typescript.tsdk": "node_modules/typescript/lib" 5 | } 6 | -------------------------------------------------------------------------------- /packages/create/templates/workspace/_gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | 4 | # Build outputs 5 | build/ 6 | bin/ 7 | 8 | # Special operating system files 9 | .DS_STORE 10 | 11 | # Temporary files 12 | *.log 13 | -------------------------------------------------------------------------------- /packages/create/templates/workspace/_nvmrc: -------------------------------------------------------------------------------- 1 | 22.14.0 2 | -------------------------------------------------------------------------------- /packages/create/templates/workspace/_prettierignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | pnpm-lock.yaml 4 | 5 | # Build outputs 6 | .quilt/ 7 | build/ 8 | bin/ 9 | -------------------------------------------------------------------------------- /packages/create/templates/workspace/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.workspace.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/create/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [ 4 | {"path": "../quilt"}, 5 | {"path": "../cli-kit"}, 6 | {"path": "../events"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /packages/events/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/events/source/abort.ts: -------------------------------------------------------------------------------- 1 | export {AbortError} from './abort/AbortError.ts'; 2 | export {NestedAbortController} from './abort/NestedAbortController.ts'; 3 | export {TimedAbortController} from './abort/TimedAbortController.ts'; 4 | export {raceAgainstAbortSignal} from './abort/race.ts'; 5 | -------------------------------------------------------------------------------- /packages/events/source/abort/AbortError.ts: -------------------------------------------------------------------------------- 1 | // @see https://github.com/nodejs/node/blob/master/lib/internal/errors.js#L822-L834 2 | /** 3 | * An `Error` that indicates that an operation was aborted before 4 | * it finished. 5 | * 6 | * @see https://github.com/nodejs/node/blob/5c65565108c626884c5c722bb512c7c1e5c1c809/lib/internal/errors.js#L843-L855 7 | */ 8 | export class AbortError extends Error { 9 | static test(error: unknown): error is AbortError { 10 | return error != null && (error as any).code === 'ABORT_ERR'; 11 | } 12 | 13 | readonly code = 'ABORT_ERR'; 14 | readonly name = 'AbortError'; 15 | 16 | constructor(message = 'The operation was aborted') { 17 | super(message); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/events/source/index.ts: -------------------------------------------------------------------------------- 1 | export {on} from './on.ts'; 2 | export {once} from './once.ts'; 3 | export { 4 | AbortError, 5 | NestedAbortController, 6 | TimedAbortController, 7 | raceAgainstAbortSignal, 8 | } from './abort.ts'; 9 | export {addEventHandler} from './handler.ts'; 10 | export { 11 | EventEmitter, 12 | createEventEmitter, 13 | type EmitterEmitterInternalEvents, 14 | } from './emitter.ts'; 15 | export {sleep} from './sleep.ts'; 16 | export type { 17 | AbortBehavior, 18 | EventHandler, 19 | EventHandlerMap, 20 | EventTarget, 21 | EventTargetOn, 22 | EventTargetAddEventListener, 23 | EventTargetFunction, 24 | } from './types.ts'; 25 | -------------------------------------------------------------------------------- /packages/events/source/sleep.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns a promise that resolves after a given amount of time. 3 | */ 4 | export function sleep( 5 | time: number, 6 | { 7 | signal, 8 | }: { 9 | /** 10 | * An optional `AbortSignal` that can be used to cancel the sleep. 11 | * This will cause the timeout to be cancelled, if it has not already 12 | * finished. 13 | */ 14 | signal?: AbortSignal; 15 | } = {}, 16 | ) { 17 | let timeout: ReturnType; 18 | let resolvePromise: () => void; 19 | 20 | signal?.addEventListener('abort', () => { 21 | if (resolvePromise == null || timeout == null) return; 22 | clearTimeout(timeout); 23 | resolvePromise(); 24 | }); 25 | 26 | return new Promise((resolve) => { 27 | resolvePromise = resolve; 28 | timeout = setTimeout(() => resolve(), time); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /packages/events/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/events/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/graphql-tools/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage({ 4 | executable: { 5 | 'quilt-graphql-typescript': './source/typescript/cli.ts', 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/index.ts: -------------------------------------------------------------------------------- 1 | export {minifyGraphQLSource} from '@quilted/graphql'; 2 | export { 3 | toGraphQLOperation, 4 | cleanGraphQLDocument, 5 | extractGraphQLImports, 6 | type EnhancedDocumentNode, 7 | } from './transform.ts'; 8 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/project.ts: -------------------------------------------------------------------------------- 1 | export type { 2 | GraphQLConfiguration, 3 | GraphQLProjectConfiguration, 4 | } from './project/types.ts'; 5 | export {loadConfiguration} from './project/load.ts'; 6 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/project/types.ts: -------------------------------------------------------------------------------- 1 | import type {GraphQLSchema} from 'graphql'; 2 | import type {Extensions} from '../configuration.ts'; 3 | 4 | export interface GraphQLConfiguration { 5 | readonly projects: Record; 6 | } 7 | 8 | export interface GraphQLProjectConfiguration { 9 | readonly name: string; 10 | readonly root: string; 11 | readonly schemaPatterns: string[]; 12 | readonly documentPatterns: string[]; 13 | readonly excludePatterns: string[]; 14 | readonly extensions: Partial; 15 | getSchema(): Promise; 16 | } 17 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/typescript.ts: -------------------------------------------------------------------------------- 1 | export {createBuilder, Builder} from './typescript/builder.ts'; 2 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/typescript/print.ts: -------------------------------------------------------------------------------- 1 | export {generateSchemaTypes} from './print/schema.ts'; 2 | export {generateDocumentTypes} from './print/document.ts'; 3 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/typescript/print/generate.ts: -------------------------------------------------------------------------------- 1 | import generate from '@babel/generator'; 2 | 3 | // This package has a legacy setup where it pretends to be an ES module, 4 | // but when imported from an ES module in Node, the default export is 5 | // a named `default` field on the default export instead. This file 6 | // normalizes that value into something we can import normally. 7 | 8 | const normalizedGenerate: typeof generate = 9 | typeof generate === 'function' ? generate : (generate as any).default; 10 | 11 | export default normalizedGenerate; 12 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/typescript/print/utilities.ts: -------------------------------------------------------------------------------- 1 | import * as t from '@babel/types'; 2 | import { 3 | GraphQLString, 4 | GraphQLInt, 5 | GraphQLFloat, 6 | GraphQLBoolean, 7 | GraphQLID, 8 | } from 'graphql'; 9 | 10 | export const scalarTypeMap = { 11 | [GraphQLString.name]: t.tsStringKeyword(), 12 | [GraphQLInt.name]: t.tsNumberKeyword(), 13 | [GraphQLFloat.name]: t.tsNumberKeyword(), 14 | [GraphQLBoolean.name]: t.tsBooleanKeyword(), 15 | [GraphQLID.name]: t.tsStringKeyword(), 16 | }; 17 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/typescript/types.ts: -------------------------------------------------------------------------------- 1 | import type {DocumentNode, GraphQLSchema} from 'graphql'; 2 | 3 | interface Operation { 4 | type: 'fragment' | 'query' | 'mutation'; 5 | name?: string; 6 | } 7 | 8 | export interface DocumentDetails { 9 | path: string; 10 | document: DocumentNode; 11 | provides: Set; 12 | dependencies: Set; 13 | } 14 | 15 | export interface ProjectDetails { 16 | documents: Map; 17 | schema: GraphQLSchema; 18 | } 19 | -------------------------------------------------------------------------------- /packages/graphql-tools/source/utilities/minify.ts: -------------------------------------------------------------------------------- 1 | export function minifyGraphQLSource(source: string) { 2 | return source 3 | .replace(/#.*/g, '') 4 | .replace(/\\n/g, ' ') 5 | .replace(/\s\s+/g, ' ') 6 | .replace(/\s*({|}|\(|\)|\.|:|,)\s*/g, '$1'); 7 | } 8 | -------------------------------------------------------------------------------- /packages/graphql-tools/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [{"path": "../useful-types"}, {"path": "../graphql"}] 4 | } 5 | -------------------------------------------------------------------------------- /packages/graphql/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/graphql/source/gql.ts: -------------------------------------------------------------------------------- 1 | import type {GraphQLSource} from './types.ts'; 2 | 3 | export const graphql: >( 4 | template: {raw: readonly string[] | ArrayLike}, 5 | ...substitutions: any[] 6 | ) => GraphQLSource = String.raw; 7 | 8 | export {graphql as gql}; 9 | -------------------------------------------------------------------------------- /packages/graphql/source/minify.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Minifies a GraphQL source string by removing comments, whitespace, 3 | * and other unnecessary characters. 4 | * 5 | * @example 6 | * minifyGraphQLSource(` 7 | * # Fetches details about me. 8 | * query MyQuery { my { id, name } } 9 | * `); 10 | * // => 'query MyQuery{my{id,name}}' 11 | */ 12 | export function minifyGraphQLSource(source: string) { 13 | return source 14 | .replace(/#.*/g, '') 15 | .replace(/\\n/g, ' ') 16 | .replace(/\s\s+/g, ' ') 17 | .replace(/\s*({|}|\(|\)|\.|:|,)\s*/g, '$1'); 18 | } 19 | -------------------------------------------------------------------------------- /packages/graphql/source/server.ts: -------------------------------------------------------------------------------- 1 | export type { 2 | GraphQLResolver, 3 | GraphQLResolverField, 4 | GraphQLQueryResolver, 5 | GraphQLMutationResolver, 6 | GraphQLReturnResult, 7 | GraphQLDefaultObjectReturnResult, 8 | } from './server/types.ts'; 9 | export {createGraphQLResolverBuilder} from './server/server.ts'; 10 | 11 | export {createGraphQLSchema} from './schema.ts'; 12 | -------------------------------------------------------------------------------- /packages/graphql/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [{"path": "../async"}] 4 | } 5 | -------------------------------------------------------------------------------- /packages/graphql/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/http/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/http/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quilted/http", 3 | "description": "Provides a collection of HTTP-related types and utilities.", 4 | "type": "module", 5 | "version": "0.3.0", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/lemonmade/quilt.git", 10 | "directory": "packages/http" 11 | }, 12 | "publishConfig": { 13 | "access": "public", 14 | "@quilted:registry": "https://registry.npmjs.org" 15 | }, 16 | "exports": { 17 | ".": { 18 | "types": "./build/typescript/index.d.ts", 19 | "quilt:source": "./source/index.ts", 20 | "quilt:esnext": "./build/esnext/index.esnext", 21 | "import": "./build/esm/index.mjs" 22 | } 23 | }, 24 | "types": "./build/typescript/index.d.ts", 25 | "sideEffects": false, 26 | "scripts": { 27 | "build": "rollup --config configuration/rollup.config.js" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/http/source/headers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A `Headers` object that can’t be mutated, typically because it 3 | * represents the headers in a request. 4 | */ 5 | export interface ReadonlyHeaders 6 | extends Omit { 7 | [Symbol.iterator]: Headers[typeof Symbol.iterator]; 8 | } 9 | -------------------------------------------------------------------------------- /packages/http/source/index.ts: -------------------------------------------------------------------------------- 1 | export {CookieString} from './cookies.ts'; 2 | export type { 3 | Cookies, 4 | CookieOptions, 5 | ReadonlyCookies, 6 | WritableCookies, 7 | } from './cookies.ts'; 8 | export type {ReadonlyHeaders} from './headers.ts'; 9 | export {HttpMethod} from './method.ts'; 10 | export {StatusCode} from './status-code.ts'; 11 | export {ResponseType} from './response-type.ts'; 12 | export { 13 | ContentSecurityPolicyDirective, 14 | ContentSecurityPolicySandboxAllow, 15 | ContentSecurityPolicySpecialSource, 16 | } from './content-security-policy.ts'; 17 | export { 18 | PermissionsPolicyDirective, 19 | PermissionsPolicySpecialSource, 20 | } from './permissions-policy.ts'; 21 | export type { 22 | CrossOriginEmbedderPolicyHeaderValue, 23 | CrossOriginOpenerPolicyHeaderValue, 24 | CrossOriginResourcePolicyHeaderValue, 25 | } from './cross-origin-headers.ts'; 26 | -------------------------------------------------------------------------------- /packages/http/source/method.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * HTTP request methods. 3 | * 4 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods 5 | */ 6 | export enum HttpMethod { 7 | Get = 'GET', 8 | Post = 'POST', 9 | Put = 'PUT', 10 | Patch = 'PATCH', 11 | Delete = 'DELETE', 12 | Head = 'HEAD', 13 | Options = 'OPTIONS', 14 | Connect = 'CONNECT', 15 | Trace = 'TRACE', 16 | } 17 | -------------------------------------------------------------------------------- /packages/http/source/response-type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Status code response classes, mapped to their status code range. 3 | * 4 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status 5 | */ 6 | export enum ResponseType { 7 | Informational = '1xx', 8 | Success = '2xx', 9 | Redirection = '3xx', 10 | ClientError = '4xx', 11 | ServerError = '5xx', 12 | Unknown = 'unknown', 13 | } 14 | -------------------------------------------------------------------------------- /packages/http/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/localize/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/localize/source/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | createTranslate, 3 | MissingTranslationError, 4 | MissingTranslationPlaceholderError, 5 | type Translate, 6 | type TranslationDictionary, 7 | } from './translation.ts'; 8 | export {createLocalizedFormatting} from './formatting.ts'; 9 | export type { 10 | LocalizedFormatting, 11 | LocalizedFormattingCache, 12 | LocalizedDateTimeFormatOptions, 13 | LocalizedNumberFormatOptions, 14 | } from './formatting.ts'; 15 | export {parseAcceptLanguageHeader} from './request-header.ts'; 16 | -------------------------------------------------------------------------------- /packages/localize/source/request-header.ts: -------------------------------------------------------------------------------- 1 | // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language 2 | export function parseAcceptLanguageHeader(header: string) { 3 | const parsed = header.split(',')[0]!.split(';')[0]!.trim(); 4 | return parsed === '*' ? undefined : parsed; 5 | } 6 | -------------------------------------------------------------------------------- /packages/localize/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/localize/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/performance/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/performance` 2 | -------------------------------------------------------------------------------- /packages/performance/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/performance/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quilted/performance", 3 | "type": "module", 4 | "version": "0.2.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/lemonmade/quilt.git", 8 | "directory": "packages/performance" 9 | }, 10 | "publishConfig": { 11 | "access": "public", 12 | "@quilted:registry": "https://registry.npmjs.org" 13 | }, 14 | "license": "MIT", 15 | "exports": { 16 | ".": { 17 | "types": "./build/typescript/index.d.ts", 18 | "quilt:source": "./source/index.ts", 19 | "quilt:esnext": "./build/esnext/index.esnext", 20 | "import": "./build/esm/index.mjs" 21 | } 22 | }, 23 | "types": "./build/typescript/index.d.ts", 24 | "sideEffects": false, 25 | "scripts": { 26 | "build": "rollup --config configuration/rollup.config.js" 27 | }, 28 | "dependencies": { 29 | "@quilted/events": "workspace:^2.1.2" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/performance/source/index.ts: -------------------------------------------------------------------------------- 1 | export {createPerformance} from './performance.ts'; 2 | export type { 3 | Performance, 4 | PerformanceNavigation, 5 | PerformanceInflightNavigation, 6 | } from './performance.ts'; 7 | -------------------------------------------------------------------------------- /packages/performance/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [{"path": "../events"}] 4 | } 5 | -------------------------------------------------------------------------------- /packages/preact-async/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-async/source/context.ts: -------------------------------------------------------------------------------- 1 | import type {AsyncActionCache} from '@quilted/async'; 2 | import type {ReadonlySignal} from '@quilted/preact-signals'; 3 | import {createOptionalContext} from '@quilted/preact-context'; 4 | 5 | import type {AsyncComponentProps} from './AsyncComponent.tsx'; 6 | 7 | export const AsyncComponentContext = 8 | createOptionalContext, 'render'>>(); 9 | 10 | export const AsyncHydratedContext = 11 | createOptionalContext>(); 12 | 13 | export const AsyncActionCacheContext = 14 | createOptionalContext(); 15 | 16 | export const useAsyncActionCache = AsyncActionCacheContext.use; 17 | -------------------------------------------------------------------------------- /packages/preact-async/source/hooks/hydration.ts: -------------------------------------------------------------------------------- 1 | import {useContext} from 'preact/hooks'; 2 | 3 | import {AsyncHydratedContext} from '../context.ts'; 4 | 5 | export function useHydrated() { 6 | const hydrated = useContext(AsyncHydratedContext); 7 | return hydrated?.value ?? true; 8 | } 9 | -------------------------------------------------------------------------------- /packages/preact-async/source/hooks/mutation.ts: -------------------------------------------------------------------------------- 1 | import {useMemo, useRef} from 'preact/hooks'; 2 | 3 | import {AsyncAction} from '@quilted/async'; 4 | import type {AsyncActionFunction} from '@quilted/async'; 5 | 6 | export function useAsyncMutation( 7 | asyncFunction: AsyncActionFunction, 8 | ) { 9 | const internalsRef = useRef<{ 10 | function: AsyncActionFunction; 11 | }>(); 12 | internalsRef.current ??= {} as any; 13 | Object.assign(internalsRef.current!, {function: asyncFunction}); 14 | 15 | return useMemo( 16 | () => 17 | new AsyncAction((...args) => 18 | internalsRef.current!.function(...args), 19 | ), 20 | [], 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /packages/preact-async/source/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/async'; 2 | 3 | export { 4 | AsyncComponent, 5 | type AsyncComponentProps, 6 | type AsyncComponentType, 7 | } from './AsyncComponent.tsx'; 8 | export {AsyncContext} from './AsyncContext.tsx'; 9 | 10 | export {useAsyncActionCache} from './context.ts'; 11 | export { 12 | useAsync, 13 | useAsync as useAsyncAction, 14 | type UseAsyncActionOptions, 15 | } from './hooks/async.ts'; 16 | export {useAsyncRetry} from './hooks/async-retry.ts'; 17 | export {useAsyncCacheControl} from './hooks/async-cache-control.ts'; 18 | export {useAsyncMutation} from './hooks/mutation.ts'; 19 | export {useAsyncActionCacheSerialization} from './hooks/cache.ts'; 20 | export { 21 | useAsyncModule, 22 | useAsyncModuleAssets, 23 | useAsyncModulePreload, 24 | } from './hooks/module.ts'; 25 | export {useHydrated} from './hooks/hydration.ts'; 26 | -------------------------------------------------------------------------------- /packages/preact-async/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [ 7 | {"path": "../async"}, 8 | {"path": "../preact-browser"}, 9 | {"path": "../preact-context"}, 10 | {"path": "../preact-signals"} 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/preact-browser/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/preact-browser` 2 | -------------------------------------------------------------------------------- /packages/preact-browser/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-browser/source/components/BodyAttributes.tsx: -------------------------------------------------------------------------------- 1 | import {useBodyAttributes} from '../hooks/body-attributes.ts'; 2 | 3 | type Props = Parameters[0]; 4 | 5 | /** 6 | * Sets the provided attributes on the `` element. 7 | */ 8 | export function BodyAttributes(props: Props) { 9 | useBodyAttributes(props); 10 | return null; 11 | } 12 | -------------------------------------------------------------------------------- /packages/preact-browser/source/components/HTMLAttributes.tsx: -------------------------------------------------------------------------------- 1 | import {useHTMLAttributes} from '../hooks/html-attributes.ts'; 2 | 3 | type Props = Parameters[0]; 4 | 5 | /** 6 | * Sets the provided attributes on the `` element. 7 | */ 8 | export function HTMLAttributes(props: Props) { 9 | useHTMLAttributes(props); 10 | return null; 11 | } 12 | -------------------------------------------------------------------------------- /packages/preact-browser/source/components/Link.tsx: -------------------------------------------------------------------------------- 1 | import type {BrowserLinkAttributes} from '@quilted/browser'; 2 | 3 | import {useLink} from '../hooks/link.ts'; 4 | import {useBrowserEffectsAreActive} from '../context.ts'; 5 | 6 | /** 7 | * Adds a `` tag to the `` of the document with the 8 | * provided attributes. 9 | * 10 | * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link 11 | */ 12 | export function Link(options: BrowserLinkAttributes) { 13 | if (!useBrowserEffectsAreActive()) return ; 14 | 15 | useLink(options); 16 | return null; 17 | } 18 | -------------------------------------------------------------------------------- /packages/preact-browser/source/components/Meta.tsx: -------------------------------------------------------------------------------- 1 | import type {BrowserMetaAttributes} from '@quilted/browser'; 2 | 3 | import {useMeta} from '../hooks/meta.ts'; 4 | import {useBrowserEffectsAreActive} from '../context.ts'; 5 | 6 | /** 7 | * Adds a `` tag to the `` of the document with the 8 | * provided attributes. 9 | * 10 | * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta 11 | */ 12 | export function Meta(options: BrowserMetaAttributes) { 13 | if (!useBrowserEffectsAreActive()) return ; 14 | 15 | useMeta(options); 16 | return null; 17 | } 18 | -------------------------------------------------------------------------------- /packages/preact-browser/source/components/Title.tsx: -------------------------------------------------------------------------------- 1 | import {useBrowserEffectsAreActive} from '../context.ts'; 2 | import {useTitle} from '../hooks/title.ts'; 3 | 4 | /** 5 | * Adds a `` tag to the `<head>` of the document with the 6 | * provided attributes. When more than one `<Title />` (or `useTitle()`) 7 | * exists in your application, the one that runs most deeply in your 8 | * React tree is used. 9 | * 10 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/title 11 | */ 12 | export function Title({children}: {children: Parameters<typeof useTitle>[0]}) { 13 | if (!useBrowserEffectsAreActive()) { 14 | return children ? <title>{children} : null; 15 | } 16 | 17 | useTitle(children); 18 | return null; 19 | } 20 | -------------------------------------------------------------------------------- /packages/preact-browser/source/context.ts: -------------------------------------------------------------------------------- 1 | import {createContext} from 'preact'; 2 | import {useContext} from 'preact/hooks'; 3 | 4 | import {createOptionalContext} from '@quilted/preact-context'; 5 | import type {BrowserDetails} from '@quilted/browser'; 6 | import type {BrowserAssets} from '@quilted/assets'; 7 | 8 | export const BrowserDetailsContext = createOptionalContext(); 9 | export const useBrowserDetails = BrowserDetailsContext.use; 10 | 11 | export const BrowserAssetsManifestContext = 12 | createOptionalContext(); 13 | export const useBrowserAssetsManifest = BrowserAssetsManifestContext.use; 14 | 15 | export const BrowserEffectsAreActiveContext = createContext(true); 16 | export const useBrowserEffectsAreActive = () => 17 | useContext(BrowserEffectsAreActiveContext); 18 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/body-attributes.ts: -------------------------------------------------------------------------------- 1 | import {isSignal, type ReadonlySignal} from '@quilted/signals'; 2 | import type {BrowserBodyAttributes} from '@quilted/browser'; 3 | import {useBrowserEffect} from './browser-effect.ts'; 4 | 5 | /** 6 | * Sets the provided attributes on the `` element. 7 | */ 8 | export function useBodyAttributes( 9 | bodyAttributes: 10 | | false 11 | | null 12 | | undefined 13 | | Partial 14 | | ReadonlySignal, 15 | ) { 16 | useBrowserEffect( 17 | (browser) => { 18 | if (bodyAttributes) return browser.bodyAttributes.add(bodyAttributes); 19 | }, 20 | [ 21 | isSignal(bodyAttributes) || !bodyAttributes 22 | ? bodyAttributes 23 | : JSON.stringify(bodyAttributes), 24 | ], 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/browser-effect.ts: -------------------------------------------------------------------------------- 1 | import {useEffect} from 'preact/hooks'; 2 | import type {BrowserDetails} from '@quilted/browser'; 3 | 4 | import {useBrowserDetails} from '../context.ts'; 5 | 6 | const EMPTY_DEPENDENCIES = Object.freeze([]); 7 | 8 | export function useBrowserEffect( 9 | perform: (browser: BrowserDetails) => void | (() => void), 10 | dependencies: readonly any[] = EMPTY_DEPENDENCIES, 11 | ) { 12 | const browser = useBrowserDetails(); 13 | 14 | if (typeof document === 'undefined') { 15 | perform(browser); 16 | return; 17 | } 18 | 19 | useEffect(() => { 20 | return perform(browser); 21 | }, [browser, ...dependencies]); 22 | } 23 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/browser-request.ts: -------------------------------------------------------------------------------- 1 | import {useBrowserDetails} from '../context.ts'; 2 | 3 | export const useBrowserRequest = () => useBrowserDetails().request; 4 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/favicon.ts: -------------------------------------------------------------------------------- 1 | import {useBrowserEffect} from './browser-effect.ts'; 2 | 3 | export interface FaviconOptions { 4 | /** 5 | * The image MIME type, which will be used as the `type` attribute on the 6 | * underlying `` tag. 7 | */ 8 | type?: string; 9 | } 10 | 11 | /** 12 | * Adds a favicon to your website, using a `` tag. 13 | */ 14 | export function useFavicon(source: string, {type}: FaviconOptions = {}) { 15 | useBrowserEffect( 16 | (browser) => 17 | browser.links.add( 18 | type 19 | ? { 20 | rel: 'icon', 21 | type, 22 | href: source, 23 | } 24 | : {rel: 'icon', href: source}, 25 | ), 26 | [source], 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/html-attributes.ts: -------------------------------------------------------------------------------- 1 | import {isSignal, type ReadonlySignal} from '@quilted/signals'; 2 | import type {BrowserHTMLAttributes} from '@quilted/browser'; 3 | import {useBrowserEffect} from './browser-effect.ts'; 4 | 5 | /** 6 | * Sets the provided attributes on the `` element. 7 | */ 8 | export function useHTMLAttributes( 9 | htmlAttributes: 10 | | false 11 | | null 12 | | undefined 13 | | Partial 14 | | ReadonlySignal, 15 | ) { 16 | useBrowserEffect( 17 | (browser) => { 18 | if (htmlAttributes) return browser.htmlAttributes.add(htmlAttributes); 19 | }, 20 | [ 21 | isSignal(htmlAttributes) || !htmlAttributes 22 | ? htmlAttributes 23 | : JSON.stringify(htmlAttributes), 24 | ], 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/link.ts: -------------------------------------------------------------------------------- 1 | import type {BrowserLinkAttributes} from '@quilted/browser'; 2 | import {isSignal, type ReadonlySignal} from '@quilted/signals'; 3 | 4 | import {useBrowserEffect} from './browser-effect.ts'; 5 | 6 | /** 7 | * Adds a `` tag to the `` of the document with the 8 | * provided attributes. If you want to conditionally disable or 9 | * remove the tag, you can instead pass `false` to this hook. 10 | * 11 | * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link 12 | */ 13 | export function useLink( 14 | link: 15 | | false 16 | | null 17 | | undefined 18 | | BrowserLinkAttributes 19 | | ReadonlySignal, 20 | ) { 21 | useBrowserEffect( 22 | (browser) => { 23 | if (link) return browser.links.add(link); 24 | }, 25 | [isSignal(link) || !link ? link : JSON.stringify(link)], 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/locale.ts: -------------------------------------------------------------------------------- 1 | import {useBrowserEffect} from './browser-effect.ts'; 2 | 3 | export function useLocale(locale: string) { 4 | useBrowserEffect( 5 | (browser) => browser.htmlAttributes.add({lang: locale}), 6 | [locale], 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/meta.ts: -------------------------------------------------------------------------------- 1 | import type {BrowserMetaAttributes} from '@quilted/browser'; 2 | import {isSignal, type ReadonlySignal} from '@quilted/signals'; 3 | 4 | import {useBrowserEffect} from './browser-effect.ts'; 5 | 6 | /** 7 | * Adds a `` tag to the `` of the document with the 8 | * provided attributes. If you want to conditionally disable or 9 | * remove the tag, you can instead pass `false` to this hook. 10 | * 11 | * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta 12 | */ 13 | export function useMeta( 14 | meta: 15 | | false 16 | | null 17 | | undefined 18 | | BrowserMetaAttributes 19 | | ReadonlySignal, 20 | ) { 21 | useBrowserEffect( 22 | (browser) => { 23 | if (meta) return browser.metas.add(meta); 24 | }, 25 | [isSignal(meta) || !meta ? meta : JSON.stringify(meta)], 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/serialized.ts: -------------------------------------------------------------------------------- 1 | import {useBrowserDetails} from '../context.ts'; 2 | 3 | export function useSerialized(id: string): T { 4 | return useBrowserDetails().serializations.get(id); 5 | } 6 | -------------------------------------------------------------------------------- /packages/preact-browser/source/hooks/title.ts: -------------------------------------------------------------------------------- 1 | import {ReadonlySignal} from '@quilted/signals'; 2 | import {useBrowserEffect} from './browser-effect.ts'; 3 | 4 | /** 5 | * Adds a `` tag to the `<head>` of the document with the 6 | * provided attributes. If you want to conditionally disable or 7 | * remove the tag, you can instead pass `false` to this hook. When 8 | * more than one `useTitle()` (or `<Title />`) exists in your 9 | * application, the one that runs most deeply in your React tree 10 | * is used. 11 | * 12 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/title 13 | */ 14 | export function useTitle( 15 | title: false | null | undefined | string | ReadonlySignal<string>, 16 | ) { 17 | useBrowserEffect( 18 | (browser) => { 19 | if (title || title === '') return browser.title.add(title); 20 | }, 21 | [title], 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/CacheControl.tsx: -------------------------------------------------------------------------------- 1 | import {useCacheControl} from '../hooks/cache-control.ts'; 2 | 3 | interface ExplicitProps { 4 | /** 5 | * If you provide the `value` key, that string will be used as the 6 | * Cache-Control directly. 7 | */ 8 | value: string; 9 | } 10 | 11 | type Props = 12 | | ExplicitProps 13 | | Exclude<Parameters<typeof useCacheControl>[0], string>; 14 | 15 | /** 16 | * A component that sets the `Cache-Control` header for this request. 17 | */ 18 | export function CacheControl(options: Props) { 19 | if (typeof document === 'object') return null; 20 | useCacheControl('value' in options ? options.value : options); 21 | return null; 22 | } 23 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/ContentSecurityPolicy.tsx: -------------------------------------------------------------------------------- 1 | import {useContentSecurityPolicy} from '../hooks/content-security-policy.ts'; 2 | 3 | interface ExplicitProps { 4 | /** 5 | * If you provide the `value` key, that string will be used as the 6 | * `Content-Security-Policy` header directly. 7 | */ 8 | value: string; 9 | } 10 | 11 | type Props = 12 | | ExplicitProps 13 | | Exclude<Parameters<typeof useContentSecurityPolicy>[0], string>; 14 | 15 | /** 16 | * A component that sets the `Content-Security-Policy` header for this request. 17 | * 18 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy 19 | */ 20 | export function ContentSecurityPolicy(options: Props) { 21 | if (typeof document === 'object') return null; 22 | useContentSecurityPolicy('value' in options ? options.value : options); 23 | return null; 24 | } 25 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/CrossOriginEmbedderPolicy.tsx: -------------------------------------------------------------------------------- 1 | import {useCrossOriginEmbedderPolicy} from '../hooks/cross-origin-embedder-policy.ts'; 2 | 3 | /** 4 | * Sets the `Cross-Origin-Embedder-Policy` header for this request. 5 | * 6 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy 7 | * @see https://web.dev/security-headers/#coop 8 | */ 9 | export function CrossOriginEmbedderPolicy({ 10 | value, 11 | }: { 12 | value: Parameters<typeof useCrossOriginEmbedderPolicy>[0]; 13 | }) { 14 | if (typeof document === 'object') return null; 15 | useCrossOriginEmbedderPolicy(value); 16 | return null; 17 | } 18 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/CrossOriginOpenerPolicy.tsx: -------------------------------------------------------------------------------- 1 | import {useCrossOriginOpenerPolicy} from '../hooks/cross-origin-opener-policy.ts'; 2 | 3 | /** 4 | * Sets the `Cross-Origin-Opener-Policy` header for this request. 5 | * 6 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy 7 | * @see https://web.dev/security-headers/#coop 8 | */ 9 | export function CrossOriginOpenerPolicy({ 10 | value, 11 | }: { 12 | value: Parameters<typeof useCrossOriginOpenerPolicy>[0]; 13 | }) { 14 | if (typeof document === 'object') return null; 15 | useCrossOriginOpenerPolicy(value); 16 | return null; 17 | } 18 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/CrossOriginResourcePolicy.tsx: -------------------------------------------------------------------------------- 1 | import {useCrossOriginResourcePolicy} from '../hooks/cross-origin-resource-policy.ts'; 2 | 3 | /** 4 | * Sets the `Cross-Origin-Resource-Policy` header for this request. 5 | * 6 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy 7 | * @see https://web.dev/security-headers/#corp 8 | */ 9 | export function CrossOriginResourcePolicy({ 10 | value, 11 | }: { 12 | value: Parameters<typeof useCrossOriginResourcePolicy>[0]; 13 | }) { 14 | if (typeof document === 'object') return null; 15 | useCrossOriginResourcePolicy(value); 16 | return null; 17 | } 18 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/HTMLPlaceholder.tsx: -------------------------------------------------------------------------------- 1 | export function HTMLPlaceholderContent() { 2 | // @ts-expect-error Just used as a placeholder 3 | return <browser-response-placeholder-content />; 4 | } 5 | 6 | export function HTMLPlaceholderEntryAssets() { 7 | // @ts-expect-error Just used as a placeholder 8 | return <browser-response-placeholder-entry-assets />; 9 | } 10 | 11 | export function HTMLPlaceholderSerializations() { 12 | // @ts-expect-error Just used as a placeholder 13 | return <browser-response-placeholder-serializations />; 14 | } 15 | 16 | export function HTMLPlaceholderAsyncAssets() { 17 | // @ts-expect-error Just used as a placeholder 18 | return <browser-response-placeholder-async-assets />; 19 | } 20 | 21 | export function HTMLPlaceholderPreloadAssets() { 22 | // @ts-expect-error Just used as a placeholder 23 | return <browser-response-placeholder-preload-assets />; 24 | } 25 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/HTMLStreamBoundary.tsx: -------------------------------------------------------------------------------- 1 | export function HTMLStreamBoundary() { 2 | // @ts-expect-error Just used as a placeholder 3 | return <browser-response-stream-boundary />; 4 | } 5 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/NotFound.tsx: -------------------------------------------------------------------------------- 1 | import {useResponseStatus} from '../hooks/response-status.ts'; 2 | 3 | /** 4 | * This component sets a 404 status code on the current response. 5 | */ 6 | export function NotFound() { 7 | if (typeof document === 'object') return null; 8 | useResponseStatus(404); 9 | return null; 10 | } 11 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/OpenGraph.tsx: -------------------------------------------------------------------------------- 1 | import {useOpenGraph, type OpenGraphOptions} from '../hooks/open-graph.ts'; 2 | 3 | export interface OpenGraphProps extends OpenGraphOptions {} 4 | 5 | /** 6 | * Sets `og:` meta tags for the current page. 7 | * 8 | * @see https://ogp.me 9 | */ 10 | export function OpenGraph(props: OpenGraphProps) { 11 | if (typeof document === 'object') return null; 12 | useOpenGraph(props); 13 | return null; 14 | } 15 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/PermissionsPolicy.tsx: -------------------------------------------------------------------------------- 1 | import {usePermissionsPolicy} from '../hooks/permissions-policy.ts'; 2 | 3 | interface ExplicitProps { 4 | /** 5 | * If you provide the `value` prop, that string will be used as the 6 | * `Permissions-Policy` header directly. 7 | */ 8 | value: string; 9 | } 10 | 11 | type Props = 12 | | ExplicitProps 13 | | Exclude<Parameters<typeof usePermissionsPolicy>[0], string>; 14 | 15 | /** 16 | * A component that sets the `Permissions-Policy` header for this request. 17 | * 18 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy 19 | */ 20 | export function PermissionsPolicy(options: Props) { 21 | if (typeof document === 'object') return null; 22 | usePermissionsPolicy('value' in options ? options.value : options); 23 | return null; 24 | } 25 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/ResponseHeader.tsx: -------------------------------------------------------------------------------- 1 | import {useResponseHeader} from '../hooks/response-header.ts'; 2 | 3 | interface Props { 4 | /** 5 | * The name of the header to append to. 6 | */ 7 | name: string; 8 | 9 | /** 10 | * The value to append to this header. 11 | */ 12 | value: string; 13 | } 14 | 15 | /** 16 | * Appends a response header to the provided value. Only works during 17 | * server-side rendering. 18 | */ 19 | export function ResponseHeader({name, value}: Props) { 20 | if (typeof document === 'object') return null; 21 | useResponseHeader(name, value); 22 | return null; 23 | } 24 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/ResponseStatus.tsx: -------------------------------------------------------------------------------- 1 | import type {StatusCode} from '@quilted/http'; 2 | import {useResponseStatus} from '../hooks/response-status.ts'; 3 | 4 | export interface Props { 5 | /** 6 | * The response status code for this request. 7 | */ 8 | code: StatusCode; 9 | } 10 | 11 | /** 12 | * Sets the HTTP response status code for this request. If this component 13 | * is rendered multiple times in your React application, the one with 14 | * the highest status code will be used. 15 | * 16 | * This component only works during server-side rendering. 17 | */ 18 | export function ResponseStatus({code}: Props) { 19 | if (typeof document === 'object') return null; 20 | useResponseStatus(code); 21 | return null; 22 | } 23 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/ScriptAssetsPreload.tsx: -------------------------------------------------------------------------------- 1 | import type {JSX} from 'preact'; 2 | import {scriptAssetPreloadAttributes, type Asset} from '@quilted/assets'; 3 | import {useResolvedBaseURL} from './shared/base-url.ts'; 4 | 5 | export function ScriptAssetsPreload({ 6 | scripts, 7 | baseURL: explicitBaseURL, 8 | ...rest 9 | }: { 10 | scripts: readonly Asset[]; 11 | baseURL?: string | URL; 12 | } & JSX.HTMLAttributes<HTMLLinkElement>) { 13 | const baseURL = useResolvedBaseURL(explicitBaseURL); 14 | 15 | return ( 16 | <> 17 | {scripts.map((asset) => ( 18 | <link 19 | key={asset.source} 20 | {...(scriptAssetPreloadAttributes(asset, { 21 | baseURL, 22 | }) as JSX.HTMLAttributes<HTMLLinkElement>)} 23 | {...rest} 24 | /> 25 | ))} 26 | </> 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/SearchRobots.tsx: -------------------------------------------------------------------------------- 1 | import {useSearchRobots} from '../hooks/search-robots.ts'; 2 | 3 | /** 4 | * Adds a `robots` `<meta>` tag to the `<head>` of the document. You can 5 | * customize the behavior of search indexing by passing any subset 6 | * of the available robot options. 7 | * 8 | * @see https://developers.google.com/search/docs/advanced/robots/robots_meta_tag 9 | */ 10 | export function SearchRobots(options: Parameters<typeof useSearchRobots>[0]) { 11 | useSearchRobots(options); 12 | return null; 13 | } 14 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/Serialization.tsx: -------------------------------------------------------------------------------- 1 | import {useBrowserEffectsAreActive} from '../../context.ts'; 2 | import {useResponseSerialization} from '../hooks/serialization.ts'; 3 | 4 | /** 5 | * Sets a serialization for the HTML response. This value can then be read on the client 6 | * using the `useSerialized()` hook. 7 | */ 8 | export function Serialization({ 9 | name, 10 | content, 11 | }: { 12 | name: string; 13 | content: unknown; 14 | }) { 15 | if (!useBrowserEffectsAreActive()) { 16 | return ( 17 | // @ts-expect-error a custom element that I don’t want to define, 18 | <browser-serialization name={name} content={JSON.stringify(content)} /> 19 | ); 20 | } 21 | 22 | if (typeof document === 'object') return null; 23 | 24 | useResponseSerialization(name, content); 25 | return null; 26 | } 27 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/StyleAssetsPreload.tsx: -------------------------------------------------------------------------------- 1 | import type {JSX} from 'preact'; 2 | import {styleAssetPreloadAttributes, type Asset} from '@quilted/assets'; 3 | import {useResolvedBaseURL} from './shared/base-url.ts'; 4 | 5 | export function StyleAssetsPreload({ 6 | styles, 7 | baseURL: explicitBaseURL, 8 | ...rest 9 | }: { 10 | styles: readonly Asset[]; 11 | baseURL?: string | URL; 12 | } & JSX.HTMLAttributes<HTMLLinkElement>) { 13 | const baseURL = useResolvedBaseURL(explicitBaseURL); 14 | 15 | return ( 16 | <> 17 | {styles.map((asset) => ( 18 | <link 19 | key={asset.source} 20 | {...(styleAssetPreloadAttributes(asset, { 21 | baseURL, 22 | }) as JSX.HTMLAttributes<HTMLLinkElement>)} 23 | {...rest} 24 | /> 25 | ))} 26 | </> 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/components/shared/base-url.ts: -------------------------------------------------------------------------------- 1 | import {useBrowserDetails} from '../../../context.ts'; 2 | 3 | export function useResolvedBaseURL(baseURL?: string | URL) { 4 | const urlFromContext = useBrowserDetails({optional: true})?.request.url; 5 | const resolvedURL = baseURL ?? urlFromContext; 6 | return typeof resolvedURL === 'string' ? new URL(resolvedURL) : resolvedURL; 7 | } 8 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/hooks/assets.ts: -------------------------------------------------------------------------------- 1 | import type {AssetLoadTiming} from '@quilted/assets'; 2 | import {useBrowserResponseAction} from './browser-response-action.ts'; 3 | 4 | export function useModuleAssets( 5 | id?: string, 6 | {scripts, styles}: {styles?: AssetLoadTiming; scripts?: AssetLoadTiming} = {}, 7 | ) { 8 | if (typeof document === 'object') return; 9 | 10 | useBrowserResponseAction((response) => { 11 | if (id) response.assets.use(id, {scripts, styles}); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/hooks/browser-response-action.ts: -------------------------------------------------------------------------------- 1 | import {BrowserResponse} from '@quilted/browser/server'; 2 | 3 | import {useBrowserDetails} from '../../context.ts'; 4 | 5 | /** 6 | * During server-side rendering, the function you pass to this hook is 7 | * called with the mutable browser response object, if one is found. 8 | * You typically shouldn’t need to call this hook directly, as all 9 | * of the individual actions you can perform on the HTTP manager are 10 | * exposed as dedicated hooks. 11 | */ 12 | export function useBrowserResponseAction( 13 | perform: (response: BrowserResponse) => void, 14 | ) { 15 | if (typeof document === 'object') return; 16 | const response = useBrowserDetails(); 17 | if (response && response instanceof BrowserResponse) perform(response); 18 | } 19 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/hooks/cross-origin-embedder-policy.ts: -------------------------------------------------------------------------------- 1 | import {type CrossOriginEmbedderPolicyHeaderValue} from '@quilted/http'; 2 | import {useBrowserResponseAction} from './browser-response-action.ts'; 3 | 4 | /** 5 | * Sets the `Cross-Origin-Embedder-Policy` header for this request. 6 | * 7 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy 8 | * @see https://web.dev/security-headers/#coep 9 | */ 10 | export function useCrossOriginEmbedderPolicy( 11 | value: CrossOriginEmbedderPolicyHeaderValue, 12 | ) { 13 | if (typeof document === 'object') return; 14 | 15 | useBrowserResponseAction((response) => { 16 | response.headers.append('Cross-Origin-Embedder-Policy', value); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/hooks/cross-origin-opener-policy.ts: -------------------------------------------------------------------------------- 1 | import {type CrossOriginOpenerPolicyHeaderValue} from '@quilted/http'; 2 | import {useBrowserResponseAction} from './browser-response-action.ts'; 3 | 4 | /** 5 | * Sets the `Cross-Origin-Opener-Policy` header for this request. 6 | * 7 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy 8 | * @see https://web.dev/security-headers/#coop 9 | */ 10 | export function useCrossOriginOpenerPolicy( 11 | value: CrossOriginOpenerPolicyHeaderValue, 12 | ) { 13 | if (typeof document === 'object') return; 14 | 15 | useBrowserResponseAction((response) => { 16 | response.headers.append('Cross-Origin-Opener-Policy', value); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/hooks/cross-origin-resource-policy.ts: -------------------------------------------------------------------------------- 1 | import {type CrossOriginResourcePolicyHeaderValue} from '@quilted/http'; 2 | import {useBrowserResponseAction} from './browser-response-action.ts'; 3 | 4 | /** 5 | * Sets the `Cross-Origin-Resource-Policy` header for this request. 6 | * 7 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy 8 | * @see https://web.dev/security-headers/#corp 9 | */ 10 | export function useCrossOriginResourcePolicy( 11 | value: CrossOriginResourcePolicyHeaderValue, 12 | ) { 13 | if (typeof document === 'object') return; 14 | 15 | useBrowserResponseAction((response) => { 16 | response.headers.append('Cross-Origin-Resource-Policy', value); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/hooks/response-header.ts: -------------------------------------------------------------------------------- 1 | import {useBrowserResponseAction} from './browser-response-action.ts'; 2 | 3 | /** 4 | * Appends a response header to the provided value. Only works during 5 | * server-side rendering. 6 | */ 7 | export function useResponseHeader(header: string, value: string) { 8 | if (typeof document === 'object') return; 9 | 10 | useBrowserResponseAction((response) => { 11 | response.headers.append(header, value); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/hooks/response-status.ts: -------------------------------------------------------------------------------- 1 | import type {StatusCode} from '@quilted/http'; 2 | import {useBrowserResponseAction} from './browser-response-action.ts'; 3 | 4 | /** 5 | * Sets the HTTP response status code for this request. If multiple calls 6 | * are made to this hook, the highest status code will be used. 7 | * 8 | * This hook only works during server-side rendering. 9 | * 10 | * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status 11 | */ 12 | export function useResponseStatus(statusCode: StatusCode) { 13 | if (typeof document === 'object') return; 14 | 15 | useBrowserResponseAction((response) => { 16 | response.status.set(statusCode); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/preact-browser/source/server/hooks/serialization.ts: -------------------------------------------------------------------------------- 1 | import {useBrowserResponseAction} from './browser-response-action.ts'; 2 | 3 | /** 4 | * Sets a serialization for the HTML response. This value can then be read on the client 5 | * using the `useSerialized()` hook. 6 | */ 7 | export function useResponseSerialization(name: string, content: unknown) { 8 | if (typeof document === 'object') return; 9 | 10 | useBrowserResponseAction((response) => { 11 | response.serializations.set(name, content); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /packages/preact-browser/source/testing.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/browser/testing'; 2 | export {BrowserDetailsContext} from './context.ts'; 3 | -------------------------------------------------------------------------------- /packages/preact-browser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [ 7 | {"path": "../assets"}, 8 | {"path": "../browser"}, 9 | {"path": "../http"}, 10 | {"path": "../http"}, 11 | {"path": "../preact-context"}, 12 | {"path": "../request-router"}, 13 | {"path": "../signals"} 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/preact-browser/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/preact-context/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @quilted/preact-context 2 | 3 | ## 0.1.3 4 | 5 | ### Patch Changes 6 | 7 | - [`96016f1`](https://github.com/lemonmade/quilt/commit/96016f1102276bdae3ef4ff0fae7656c9f118d59) Thanks [@lemonmade](https://github.com/lemonmade)! - Update Preact dependencies 8 | 9 | ## 0.1.2 10 | 11 | ### Patch Changes 12 | 13 | - [`e115475`](https://github.com/lemonmade/quilt/commit/e115475e522c0502fa0307d1fc477d4de50a6f41) Thanks [@lemonmade](https://github.com/lemonmade)! - Mark `createOptionalContext()` as side effect-free 14 | 15 | ## 0.1.1 16 | 17 | ### Patch Changes 18 | 19 | - [`285b2f0`](https://github.com/lemonmade/quilt/commit/285b2f083bfc6fe81db35e2950c8b3ae846486d3) Thanks [@lemonmade](https://github.com/lemonmade)! - Fix templates 20 | -------------------------------------------------------------------------------- /packages/preact-context/README.md: -------------------------------------------------------------------------------- 1 | # Package 2 | -------------------------------------------------------------------------------- /packages/preact-context/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-context/source/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | createOptionalContext, 3 | type OptionalContext, 4 | type OptionalContextOptions, 5 | type UseOptionalContextHook, 6 | } from './optional-context.ts'; 7 | -------------------------------------------------------------------------------- /packages/preact-context/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [] 7 | } 8 | -------------------------------------------------------------------------------- /packages/preact-email/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/preact-email` 2 | 3 | React-friendly APIs for rendering emails and their metadata. 4 | -------------------------------------------------------------------------------- /packages/preact-email/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-email/source/context.ts: -------------------------------------------------------------------------------- 1 | import {createOptionalContext} from '@quilted/preact-context'; 2 | import type {EmailManager} from './manager.ts'; 3 | 4 | export const EmailContext = createOptionalContext<EmailManager>(); 5 | -------------------------------------------------------------------------------- /packages/preact-email/source/hooks/email-action.ts: -------------------------------------------------------------------------------- 1 | import {useContext} from 'preact/hooks'; 2 | 3 | import {EmailContext} from '../context.ts'; 4 | import type {EmailManager} from '../manager.ts'; 5 | 6 | export function useEmailAction(perform: (email: EmailManager) => void) { 7 | const email = useContext(EmailContext); 8 | if (email) perform(email); 9 | } 10 | -------------------------------------------------------------------------------- /packages/preact-email/source/hooks/plain-text.ts: -------------------------------------------------------------------------------- 1 | import type {EmailManager} from '../manager.ts'; 2 | import {useEmailAction} from './email-action.ts'; 3 | 4 | export function usePlainTextContent( 5 | text: Parameters<EmailManager['setPlainText']>[0], 6 | ) { 7 | return useEmailAction((email) => email.setPlainText(text)); 8 | } 9 | -------------------------------------------------------------------------------- /packages/preact-email/source/hooks/send-bcc.ts: -------------------------------------------------------------------------------- 1 | import {useEmailAction} from './email-action.ts'; 2 | 3 | export function useSendBCC(emails: string | string[] | undefined) { 4 | return useEmailAction((email) => email.sendBCC(emails)); 5 | } 6 | -------------------------------------------------------------------------------- /packages/preact-email/source/hooks/send-cc.ts: -------------------------------------------------------------------------------- 1 | import {useEmailAction} from './email-action.ts'; 2 | 3 | export function useSendCC(emails: string | string[] | undefined) { 4 | return useEmailAction((email) => email.sendCC(emails)); 5 | } 6 | -------------------------------------------------------------------------------- /packages/preact-email/source/hooks/send-to.ts: -------------------------------------------------------------------------------- 1 | import {useEmailAction} from './email-action.ts'; 2 | 3 | export function useSendTo(emails: string | string[] | undefined) { 4 | return useEmailAction((email) => email.sendTo(emails)); 5 | } 6 | -------------------------------------------------------------------------------- /packages/preact-email/source/hooks/sender.ts: -------------------------------------------------------------------------------- 1 | import type {Sender} from '../types.ts'; 2 | import {useEmailAction} from './email-action.ts'; 3 | 4 | export function useSender(sender: string | Sender | undefined) { 5 | return useEmailAction((email) => email.setSender(sender)); 6 | } 7 | -------------------------------------------------------------------------------- /packages/preact-email/source/hooks/subject.ts: -------------------------------------------------------------------------------- 1 | import {useEmailAction} from './email-action.ts'; 2 | 3 | export function useSubject(subject: string | undefined) { 4 | return useEmailAction((email) => email.setSubject(subject)); 5 | } 6 | -------------------------------------------------------------------------------- /packages/preact-email/source/index.ts: -------------------------------------------------------------------------------- 1 | export {EmailContext} from './context.ts'; 2 | export {EmailManager} from './manager.ts'; 3 | export type {Sender} from './types.ts'; 4 | 5 | export {usePlainTextContent} from './hooks/plain-text.ts'; 6 | export {useSendTo} from './hooks/send-to.ts'; 7 | export {useSendCC} from './hooks/send-cc.ts'; 8 | export {useSendBCC} from './hooks/send-bcc.ts'; 9 | export {useSender} from './hooks/sender.ts'; 10 | export {useSubject} from './hooks/subject.ts'; 11 | -------------------------------------------------------------------------------- /packages/preact-email/source/types.ts: -------------------------------------------------------------------------------- 1 | export interface Sender { 2 | readonly email: string; 3 | readonly name?: string; 4 | } 5 | -------------------------------------------------------------------------------- /packages/preact-email/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [{"path": "../preact-browser"}, {"path": "../preact-context"}] 7 | } 8 | -------------------------------------------------------------------------------- /packages/preact-graphql/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/react-graphql` 2 | -------------------------------------------------------------------------------- /packages/preact-graphql/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-graphql/source/hooks/use-graphql-cache.ts: -------------------------------------------------------------------------------- 1 | import {GraphQLCacheContext} from '../context.tsx'; 2 | 3 | export const useGraphQLCache = GraphQLCacheContext.use; 4 | -------------------------------------------------------------------------------- /packages/preact-graphql/source/hooks/use-graphql-fetch.ts: -------------------------------------------------------------------------------- 1 | import {GraphQLRunContext} from '../context.tsx'; 2 | 3 | export const useGraphQLRun = GraphQLRunContext.use; 4 | 5 | export {useGraphQLRun as useGraphQLFetch}; 6 | -------------------------------------------------------------------------------- /packages/preact-graphql/source/hooks/use-graphql-mutation.ts: -------------------------------------------------------------------------------- 1 | import {useMemo} from 'preact/hooks'; 2 | import { 3 | GraphQLMutation, 4 | type GraphQLFetch, 5 | type GraphQLAnyOperation, 6 | } from '@quilted/graphql'; 7 | 8 | import {useGraphQLFetch} from './use-graphql-fetch.ts'; 9 | 10 | export function useGraphQLMutation<Data, Variables>( 11 | mutation: GraphQLAnyOperation<Data, Variables>, 12 | { 13 | fetch: explicitFetch, 14 | }: { 15 | fetch?: GraphQLFetch<any>; 16 | } = {}, 17 | ) { 18 | const fetchFromContext = useGraphQLFetch({optional: true}); 19 | const fetch = explicitFetch ?? fetchFromContext; 20 | 21 | if (fetch == null) { 22 | throw new Error('No GraphQL fetch function provided.'); 23 | } 24 | 25 | const mutationAction = useMemo( 26 | () => new GraphQLMutation(mutation, {fetch}), 27 | [mutation, fetch], 28 | ); 29 | 30 | return mutationAction; 31 | } 32 | -------------------------------------------------------------------------------- /packages/preact-graphql/source/hooks/use-graphql-query-data.ts: -------------------------------------------------------------------------------- 1 | import type {GraphQLQuery} from '@quilted/graphql'; 2 | 3 | export function useGraphQLQueryData<Data, Variables>( 4 | query: GraphQLQuery<Data, Variables>, 5 | ) { 6 | if (!query.hasFinished) throw query.promise; 7 | 8 | const value = query.value; 9 | 10 | if (value == null) throw query.latest.error; 11 | 12 | const {data, errors} = value; 13 | 14 | if (data == null) { 15 | throw new Error(`GraphQL errors: ${JSON.stringify(errors ?? [])}`); 16 | } 17 | 18 | return data; 19 | } 20 | -------------------------------------------------------------------------------- /packages/preact-graphql/source/hooks/use-graphql-query-refetch.ts: -------------------------------------------------------------------------------- 1 | import {useEffect} from 'preact/hooks'; 2 | import type {GraphQLQuery} from '@quilted/graphql'; 3 | 4 | export function useGraphQLQueryRefetchOnMount<Data, Variables>( 5 | query: GraphQLQuery<Data, Variables>, 6 | dependencies: readonly unknown[] = [], 7 | ) { 8 | return useEffect(() => { 9 | if (!query.isRunning) query.rerun({force: true}); 10 | }, [query, ...dependencies]); 11 | } 12 | -------------------------------------------------------------------------------- /packages/preact-graphql/source/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/graphql'; 2 | 3 | export { 4 | GraphQLContext, 5 | GraphQLCacheContext, 6 | GraphQLRunContext, 7 | } from './context.tsx'; 8 | export {useGraphQLFetch, useGraphQLRun} from './hooks/use-graphql-fetch.ts'; 9 | export {useGraphQLCache} from './hooks/use-graphql-cache.ts'; 10 | export {useGraphQLQuery} from './hooks/use-graphql-query.ts'; 11 | export {useGraphQLQueryData} from './hooks/use-graphql-query-data.ts'; 12 | export {useGraphQLQueryRefetchOnMount} from './hooks/use-graphql-query-refetch.ts'; 13 | export {useGraphQLMutation} from './hooks/use-graphql-mutation.ts'; 14 | -------------------------------------------------------------------------------- /packages/preact-graphql/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [ 7 | {"path": "../graphql"}, 8 | {"path": "../preact-async"}, 9 | {"path": "../preact-context"}, 10 | {"path": "../preact-signals"}, 11 | {"path": "../useful-types"} 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/preact-localize/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-localize/source/context.ts: -------------------------------------------------------------------------------- 1 | import {createOptionalContext} from '@quilted/preact-context'; 2 | import type {LocalizedFormatting} from '@quilted/localize'; 3 | 4 | export const LocalizedFormattingContext = 5 | createOptionalContext<LocalizedFormatting>(); 6 | 7 | export const LocaleContext = createOptionalContext<string>(); 8 | -------------------------------------------------------------------------------- /packages/preact-localize/source/hooks/formatting.ts: -------------------------------------------------------------------------------- 1 | import {LocalizedFormattingContext} from '../context.ts'; 2 | 3 | export const useLocalizedFormatting = LocalizedFormattingContext.use; 4 | -------------------------------------------------------------------------------- /packages/preact-localize/source/hooks/locale.ts: -------------------------------------------------------------------------------- 1 | import {LocaleContext} from '../context.ts'; 2 | 3 | export const useLocale = LocaleContext.use; 4 | -------------------------------------------------------------------------------- /packages/preact-localize/source/routing.ts: -------------------------------------------------------------------------------- 1 | export {LocalizedLink} from './routing/LocalizedLink.tsx'; 2 | export {LocalizedNavigation} from './routing/LocalizedNavigation.tsx'; 3 | export {LocalizedRouter} from './routing/LocalizedRouter.ts'; 4 | export {useRouteLocalization} from './routing/context.ts'; 5 | export {createRouteLocalization} from './routing/localization/by-locale.ts'; 6 | export {createRoutePathLocalization} from './routing/localization/by-path.ts'; 7 | export {createRouteSubdomainLocalization} from './routing/localization/by-subdomain.ts'; 8 | export type { 9 | RouteLocalization, 10 | ResolvedRouteLocalization, 11 | DefaultLocaleDefinition, 12 | } from './routing/types.ts'; 13 | -------------------------------------------------------------------------------- /packages/preact-localize/source/routing/LocalizedLink.tsx: -------------------------------------------------------------------------------- 1 | import type {ComponentProps} from 'preact'; 2 | import {useMemo} from 'preact/hooks'; 3 | import {useCurrentURL, Link, useRouter} from '@quilted/preact-router'; 4 | 5 | import {useRouteLocalization} from './context.ts'; 6 | 7 | type LinkProps = ComponentProps<typeof Link>; 8 | 9 | export function LocalizedLink({ 10 | to, 11 | locale, 12 | ...props 13 | }: Omit<LinkProps, 'to' | 'hrefLang'> & { 14 | locale: string; 15 | to?: LinkProps['to']; 16 | }) { 17 | const router = useRouter(); 18 | const url = useCurrentURL(); 19 | const {redirectURL} = useRouteLocalization(); 20 | 21 | const resolvedURL = useMemo( 22 | () => redirectURL(to ? router.resolve(to).url : url, {to: locale}), 23 | [to, url, locale, redirectURL, router], 24 | ); 25 | 26 | return <Link hrefLang={locale} to={resolvedURL} {...props} />; 27 | } 28 | -------------------------------------------------------------------------------- /packages/preact-localize/source/routing/context.ts: -------------------------------------------------------------------------------- 1 | import {createOptionalContext} from '@quilted/preact-context'; 2 | 3 | import type {ResolvedRouteLocalization} from './types.ts'; 4 | 5 | export const RouteLocalizationContext = 6 | createOptionalContext<ResolvedRouteLocalization>(); 7 | 8 | export const useRouteLocalization = RouteLocalizationContext.use; 9 | -------------------------------------------------------------------------------- /packages/preact-localize/source/routing/types.ts: -------------------------------------------------------------------------------- 1 | export interface RouteLocalization { 2 | readonly locales: string[]; 3 | readonly defaultLocale: string; 4 | matchLocale(locale: string): string | undefined; 5 | redirectURL(from: URL, options: {to: string}): URL; 6 | localeFromURL(url: URL): string | undefined; 7 | } 8 | 9 | export interface ResolvedRouteLocalization extends RouteLocalization { 10 | readonly locale: string; 11 | } 12 | 13 | export interface DefaultLocaleDefinition { 14 | locale: string; 15 | nested?: boolean; 16 | } 17 | -------------------------------------------------------------------------------- /packages/preact-localize/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [ 7 | {"path": "../localize"}, 8 | {"path": "../preact-browser"}, 9 | {"path": "../preact-context"}, 10 | {"path": "../preact-router"}, 11 | {"path": "../request-router"}, 12 | {"path": "../signals"} 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/preact-performance/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @quilted/preact-performance 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - [`96016f1`](https://github.com/lemonmade/quilt/commit/96016f1102276bdae3ef4ff0fae7656c9f118d59) Thanks [@lemonmade](https://github.com/lemonmade)! - Update Preact dependencies 8 | 9 | - Updated dependencies [[`b5846ec`](https://github.com/lemonmade/quilt/commit/b5846ecea4cdf275c3d6837c3bd5c7ce7c6d990c), [`96016f1`](https://github.com/lemonmade/quilt/commit/96016f1102276bdae3ef4ff0fae7656c9f118d59)]: 10 | - @quilted/performance@0.2.1 11 | - @quilted/preact-context@0.1.3 12 | -------------------------------------------------------------------------------- /packages/preact-performance/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/react-performance` 2 | -------------------------------------------------------------------------------- /packages/preact-performance/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-performance/source/PerformanceContext.tsx: -------------------------------------------------------------------------------- 1 | import type {RenderableProps} from 'preact'; 2 | import {useMemo} from 'preact/hooks'; 3 | import {createPerformance, type Performance} from '@quilted/performance'; 4 | 5 | import {PerformanceContextInternal} from './context.ts'; 6 | 7 | export interface Props { 8 | performance?: Performance; 9 | } 10 | 11 | export function PerformanceContext({ 12 | children, 13 | performance: explicitPerformance, 14 | }: RenderableProps<Props>) { 15 | const performance = useMemo( 16 | () => explicitPerformance ?? createPerformance(), 17 | [explicitPerformance], 18 | ); 19 | 20 | return ( 21 | <PerformanceContextInternal.Provider value={performance}> 22 | {children} 23 | </PerformanceContextInternal.Provider> 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /packages/preact-performance/source/context.ts: -------------------------------------------------------------------------------- 1 | import {createOptionalContext} from '@quilted/preact-context'; 2 | import {type Performance} from '@quilted/performance'; 3 | 4 | export const PerformanceContextInternal = createOptionalContext<Performance>(); 5 | -------------------------------------------------------------------------------- /packages/preact-performance/source/hooks/performance.ts: -------------------------------------------------------------------------------- 1 | import {PerformanceContextInternal} from '../context.ts'; 2 | 3 | export const usePerformance = PerformanceContextInternal.use; 4 | -------------------------------------------------------------------------------- /packages/preact-performance/source/index.ts: -------------------------------------------------------------------------------- 1 | export {createPerformance} from '@quilted/performance'; 2 | export type { 3 | Performance, 4 | PerformanceNavigation, 5 | PerformanceInflightNavigation, 6 | } from '@quilted/performance'; 7 | 8 | export {usePerformance} from './hooks/performance.ts'; 9 | export { 10 | usePerformanceNavigation, 11 | type PerformanceNavigationOptions, 12 | type PerformanceNavigationOptionsComplete, 13 | type PerformanceNavigationOptionsLoading, 14 | } from './hooks/navigation.ts'; 15 | export {usePerformanceNavigationEvent} from './hooks/navigation-event.ts'; 16 | 17 | export {PerformanceContext} from './PerformanceContext.tsx'; 18 | -------------------------------------------------------------------------------- /packages/preact-performance/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [{"path": "../performance"}, {"path": "../preact-context"}] 7 | } 8 | -------------------------------------------------------------------------------- /packages/preact-router/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/react-router` 2 | 3 | A universal router for React with first-class support for the [WHATWG `URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) and preloading. 4 | -------------------------------------------------------------------------------- /packages/preact-router/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-router/source/components/Redirect.tsx: -------------------------------------------------------------------------------- 1 | import type {NavigateTo} from '@quilted/routing'; 2 | import {useRouter} from '../hooks/router.ts'; 3 | 4 | export interface RedirectProps { 5 | to: NavigateTo; 6 | } 7 | 8 | export function Redirect({to}: RedirectProps) { 9 | const router = useRouter(); 10 | 11 | throw new Response(null, { 12 | status: 302, 13 | headers: { 14 | Location: router.resolve(to).url.href, 15 | }, 16 | }); 17 | 18 | return null; 19 | } 20 | -------------------------------------------------------------------------------- /packages/preact-router/source/components/Routes.tsx: -------------------------------------------------------------------------------- 1 | import type {RouteDefinition} from '../types.ts'; 2 | import {useRoutes} from '../hooks/routes.tsx'; 3 | 4 | export function Routes<Context = unknown>({ 5 | list, 6 | context, 7 | }: { 8 | list: readonly RouteDefinition<any, any, Context>[]; 9 | context?: Context; 10 | }) { 11 | return useRoutes(list, {context}); 12 | } 13 | -------------------------------------------------------------------------------- /packages/preact-router/source/context.ts: -------------------------------------------------------------------------------- 1 | import {createOptionalContext} from '@quilted/preact-context'; 2 | 3 | import type {Router} from './Router.ts'; 4 | import type {RouteNavigationEntry} from './types.ts'; 5 | 6 | export const RouterContext = createOptionalContext<Router>(); 7 | export const RouteNavigationEntryContext = 8 | createOptionalContext<RouteNavigationEntry<any, any>>(); 9 | -------------------------------------------------------------------------------- /packages/preact-router/source/hooks/current-url.ts: -------------------------------------------------------------------------------- 1 | import {RouterContext} from '../context.ts'; 2 | 3 | export function useCurrentURL() { 4 | return RouterContext.use().currentRequest.url; 5 | } 6 | -------------------------------------------------------------------------------- /packages/preact-router/source/hooks/navigate.ts: -------------------------------------------------------------------------------- 1 | import type {Router} from '../Router.ts'; 2 | import {RouterContext} from '../context.ts'; 3 | 4 | export function useNavigate(): Router['navigate'] { 5 | return RouterContext.use().navigate; 6 | } 7 | -------------------------------------------------------------------------------- /packages/preact-router/source/hooks/route-data.ts: -------------------------------------------------------------------------------- 1 | import {useRouteNavigationEntry} from './route-navigation-entry.ts'; 2 | 3 | export function useRouteData<Data = unknown, Input = unknown>() { 4 | const entry = useRouteNavigationEntry<Data, Input>(); 5 | 6 | if (entry.load == null) { 7 | return undefined as any as Data; 8 | } 9 | 10 | if (!entry.load.hasResolved) { 11 | throw entry.load.promise; 12 | } 13 | 14 | return entry.data; 15 | } 16 | -------------------------------------------------------------------------------- /packages/preact-router/source/hooks/route-navigation-entry.ts: -------------------------------------------------------------------------------- 1 | import {RouteNavigationEntryContext} from '../context.ts'; 2 | import type {RouteNavigationEntry} from '../types.ts'; 3 | 4 | export function useRouteNavigationEntry<Data = unknown, Input = unknown>() { 5 | return RouteNavigationEntryContext.use() as RouteNavigationEntry<Data, Input>; 6 | } 7 | -------------------------------------------------------------------------------- /packages/preact-router/source/hooks/router.ts: -------------------------------------------------------------------------------- 1 | import {RouterContext} from '../context.ts'; 2 | 3 | export const useRouter = RouterContext.use; 4 | -------------------------------------------------------------------------------- /packages/preact-router/source/testing.tsx: -------------------------------------------------------------------------------- 1 | import {Router} from './Router.ts'; 2 | 3 | export {Navigation} from './components/Navigation.tsx'; 4 | 5 | export class TestRouter extends Router { 6 | go() {} 7 | 8 | back() {} 9 | 10 | forward() {} 11 | 12 | navigate = () => { 13 | return this.currentRequest; 14 | }; 15 | 16 | // block() { 17 | // return () => {}; 18 | // } 19 | 20 | // resolve(to: NavigateTo) { 21 | // const url = resolveUrl(to, this.currentUrl); 22 | // return {url, external: this.#isExternal(url, this.currentUrl)}; 23 | // } 24 | } 25 | -------------------------------------------------------------------------------- /packages/preact-router/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [ 7 | {"path": "../async"}, 8 | {"path": "../http"}, 9 | {"path": "../preact-async"}, 10 | {"path": "../preact-context"}, 11 | {"path": "../preact-performance"}, 12 | {"path": "../react-testing"}, 13 | {"path": "../routing"}, 14 | {"path": "../signals"} 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/preact-router/vite.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/vite/package'; 2 | 3 | export default { 4 | esbuild: { 5 | // Without this, vitest preserves `using` statemenets, which aren’t supported in Node. 6 | target: 'es2022', 7 | }, 8 | plugins: [quiltPackage()], 9 | }; 10 | -------------------------------------------------------------------------------- /packages/preact-signals/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @quilted/preact-signals 2 | 3 | ## 0.1.2 4 | 5 | ### Patch Changes 6 | 7 | - [`f098594`](https://github.com/lemonmade/quilt/commit/f0985948408fa592773548d201bf9bc7e2bcdeda) Thanks [@lemonmade](https://github.com/lemonmade)! - Update signal dependencies 8 | 9 | - Updated dependencies [[`f098594`](https://github.com/lemonmade/quilt/commit/f0985948408fa592773548d201bf9bc7e2bcdeda)]: 10 | - @quilted/signals@0.2.3 11 | 12 | ## 0.1.1 13 | 14 | ### Patch Changes 15 | 16 | - [`96016f1`](https://github.com/lemonmade/quilt/commit/96016f1102276bdae3ef4ff0fae7656c9f118d59) Thanks [@lemonmade](https://github.com/lemonmade)! - Update Preact dependencies 17 | -------------------------------------------------------------------------------- /packages/preact-signals/README.md: -------------------------------------------------------------------------------- 1 | # Package 2 | -------------------------------------------------------------------------------- /packages/preact-signals/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-signals/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [{"path": "../signals"}] 7 | } 8 | -------------------------------------------------------------------------------- /packages/preact-testing/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage({ 4 | react: 'preact', 5 | }); 6 | -------------------------------------------------------------------------------- /packages/preact-testing/source/HookRunner.tsx: -------------------------------------------------------------------------------- 1 | import {forwardRef} from 'preact/compat'; 2 | import {useRef, useImperativeHandle} from 'preact/hooks'; 3 | import type {Ref, VNode} from 'preact'; 4 | 5 | interface Props<HookResult = unknown> { 6 | useHook(): HookResult; 7 | } 8 | 9 | export interface ImperativeApi<HookResult = unknown> { 10 | readonly current: HookResult; 11 | } 12 | 13 | export const HookRunner = forwardRef<ImperativeApi, Props>( 14 | ({useHook}: Props, ref) => { 15 | const hookResult = useHook(); 16 | const valueRef = useRef(hookResult); 17 | valueRef.current = hookResult; 18 | 19 | useImperativeHandle(ref, () => ({ 20 | get current() { 21 | return valueRef.current; 22 | }, 23 | })); 24 | 25 | return null; 26 | }, 27 | ) as <HookResult>( 28 | props: Props<HookResult> & {ref?: Ref<ImperativeApi<HookResult>>}, 29 | ) => VNode<any> | null; 30 | -------------------------------------------------------------------------------- /packages/preact-testing/source/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types.ts'; 2 | export * from './environment.tsx'; 3 | -------------------------------------------------------------------------------- /packages/preact-testing/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [] 7 | } 8 | -------------------------------------------------------------------------------- /packages/preact-testing/vite.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/vite/package'; 2 | 3 | export default { 4 | plugins: [quiltPackage()], 5 | }; 6 | -------------------------------------------------------------------------------- /packages/preact-workers/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/preact-workers/source/hooks.ts: -------------------------------------------------------------------------------- 1 | import {useEffect, useRef} from 'preact/hooks'; 2 | 3 | import type { 4 | ThreadOptions, 5 | CustomThreadWorker, 6 | CustomThreadWorkerConstructor, 7 | } from '@quilted/workers'; 8 | 9 | export function useThreadWorker<Worker>( 10 | CustomWorker: CustomThreadWorkerConstructor<any, Worker>, 11 | options?: ThreadOptions<any, Worker>, 12 | ): CustomThreadWorker<unknown, Worker>['thread'] { 13 | const workerRef = useRef<CustomThreadWorker<unknown, Worker>>(null as any); 14 | 15 | if (workerRef.current == null) { 16 | workerRef.current = new CustomWorker(options); 17 | } 18 | 19 | useEffect(() => { 20 | return () => workerRef.current.terminate(); 21 | }, []); 22 | 23 | return workerRef.current.thread; 24 | } 25 | -------------------------------------------------------------------------------- /packages/preact-workers/source/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | createWorker, 3 | createThreadWorker, 4 | retain, 5 | release, 6 | ThreadWebWorker, 7 | } from '@quilted/workers'; 8 | export type { 9 | ThreadOptions, 10 | ThreadImports, 11 | CustomWorker, 12 | CustomWorkerConstructor, 13 | CustomThreadWorker, 14 | CustomThreadWorkerConstructor, 15 | CustomWorkerModuleResolver, 16 | } from '@quilted/workers'; 17 | 18 | export {useThreadWorker} from './hooks.ts'; 19 | -------------------------------------------------------------------------------- /packages/preact-workers/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "lib": ["ESNext", "DOM", "WebWorker"] 5 | }, 6 | "references": [{"path": "../workers"}] 7 | } 8 | -------------------------------------------------------------------------------- /packages/prettier/index.js: -------------------------------------------------------------------------------- 1 | // @see https://prettier.io/docs/en/configuration.html 2 | module.exports = { 3 | arrowParens: 'always', 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /packages/prettier/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quilted/prettier", 3 | "type": "commonjs", 4 | "version": "0.2.11", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/lemonmade/quilt.git", 8 | "directory": "packages/prettier" 9 | }, 10 | "publishConfig": { 11 | "access": "public", 12 | "@quilted:registry": "https://registry.npmjs.org" 13 | }, 14 | "license": "MIT", 15 | "main": "index.js", 16 | "exports": { 17 | ".": { 18 | "require": "./index.js" 19 | } 20 | }, 21 | "sideEffects": false 22 | } 23 | -------------------------------------------------------------------------------- /packages/quilt/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/quilt/source/assets.ts: -------------------------------------------------------------------------------- 1 | import './assets/files.ts'; 2 | import './assets/styles.ts'; 3 | 4 | export * from '@quilted/assets'; 5 | -------------------------------------------------------------------------------- /packages/quilt/source/assets/styles.ts: -------------------------------------------------------------------------------- 1 | declare module '*.module.css' { 2 | const classnames: {[key: string]: string}; 3 | export default classnames; 4 | } 5 | 6 | declare module '*.css' { 7 | const styles: string; 8 | export default styles; 9 | } 10 | -------------------------------------------------------------------------------- /packages/quilt/source/async.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-async'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/browser.ts: -------------------------------------------------------------------------------- 1 | // Browser utilities depend on Signals, import to make sure we get the Preact 2 | // hook for signals installed. 3 | import './signals.ts'; 4 | 5 | export * from '@quilted/preact-browser'; 6 | -------------------------------------------------------------------------------- /packages/quilt/source/browser/testing.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-browser/testing'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/context.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-context'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/env.ts: -------------------------------------------------------------------------------- 1 | export interface EnvironmentVariables { 2 | MODE: string; 3 | } 4 | 5 | const Env: EnvironmentVariables = {} as any; 6 | 7 | export default Env; 8 | -------------------------------------------------------------------------------- /packages/quilt/source/events.ts: -------------------------------------------------------------------------------- 1 | export { 2 | on, 3 | once, 4 | sleep, 5 | addEventHandler, 6 | createEventEmitter, 7 | EventEmitter, 8 | AbortError, 9 | NestedAbortController, 10 | TimedAbortController, 11 | raceAgainstAbortSignal, 12 | } from '@quilted/events'; 13 | export type { 14 | AbortBehavior, 15 | EventHandler, 16 | EventTarget, 17 | EventTargetAddEventListener, 18 | EventTargetFunction, 19 | EventTargetOn, 20 | } from '@quilted/events'; 21 | -------------------------------------------------------------------------------- /packages/quilt/source/globals.ts: -------------------------------------------------------------------------------- 1 | import './modules.ts'; 2 | import './assets/files.ts'; 3 | import './assets/styles.ts'; 4 | 5 | import {AsyncModulesGlobal} from '@quilted/async'; 6 | 7 | export interface QuiltGlobal { 8 | readonly asyncModules: AsyncModulesGlobal; 9 | } 10 | 11 | const property = Symbol.for('quilt'); 12 | const quilt = ((globalThis as any)[property] ?? {}) as QuiltGlobal; 13 | 14 | (quilt as any).asyncModules = new AsyncModulesGlobal({ 15 | cache: quilt.asyncModules, 16 | }); 17 | 18 | Object.defineProperty(globalThis, property, { 19 | value: quilt, 20 | enumerable: false, 21 | configurable: true, 22 | writable: true, 23 | }); 24 | 25 | export default quilt; 26 | export {quilt, quilt as global}; 27 | -------------------------------------------------------------------------------- /packages/quilt/source/graphql.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-graphql'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/graphql/server.ts: -------------------------------------------------------------------------------- 1 | export { 2 | createGraphQLSchema, 3 | createGraphQLResolverBuilder, 4 | } from '@quilted/graphql/server'; 5 | export type { 6 | GraphQLResolver, 7 | GraphQLResolverField, 8 | GraphQLQueryResolver, 9 | GraphQLMutationResolver, 10 | GraphQLReturnResult, 11 | GraphQLDefaultObjectReturnResult, 12 | } from '@quilted/graphql/server'; 13 | -------------------------------------------------------------------------------- /packages/quilt/source/graphql/testing.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'vitest'; 2 | 3 | import {matchers, type CustomMatchers} from './testing/matchers.ts'; 4 | 5 | export * from '@quilted/graphql/testing'; 6 | export {GraphQLTesting} from '@quilted/preact-graphql/testing'; 7 | 8 | declare module 'vitest' { 9 | interface Assertion<T = any> extends CustomMatchers<T> {} 10 | interface AsymmetricMatchersContaining extends CustomMatchers {} 11 | } 12 | 13 | // @ts-expect-error Incompatibilities between `expect()` and vitest 14 | expect.extend(matchers); 15 | -------------------------------------------------------------------------------- /packages/quilt/source/graphql/testing/matchers.ts: -------------------------------------------------------------------------------- 1 | import type {GraphQLAnyOperation} from '@quilted/graphql/testing'; 2 | 3 | import {toHavePerformedGraphQLOperation} from './matchers/operations.ts'; 4 | 5 | export interface CustomMatchers<R = unknown> { 6 | toHavePerformedGraphQLOperation<Variables>( 7 | operation: GraphQLAnyOperation<any, Variables>, 8 | variables?: Variables, 9 | ): R; 10 | toHavePerformedGraphQLQuery<Variables>( 11 | query: GraphQLAnyOperation<any, Variables>, 12 | variables?: Variables, 13 | ): R; 14 | toHavePerformedGraphQLMutation<Variables>( 15 | mutation: GraphQLAnyOperation<any, Variables>, 16 | variables?: Variables, 17 | ): R; 18 | } 19 | 20 | export const matchers = { 21 | toHavePerformedGraphQLOperation, 22 | toHavePerformedGraphQLQuery: toHavePerformedGraphQLOperation, 23 | toHavePerformedGraphQLMutation: toHavePerformedGraphQLOperation, 24 | }; 25 | -------------------------------------------------------------------------------- /packages/quilt/source/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/localize.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-localize'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/modules.ts: -------------------------------------------------------------------------------- 1 | declare module 'quilt:module/env' { 2 | import type {EnvironmentVariables} from '@quilted/quilt/env'; 3 | 4 | export type {EnvironmentVariables}; 5 | 6 | const Env: EnvironmentVariables; 7 | export default Env; 8 | } 9 | 10 | declare module 'quilt:module/app' { 11 | import type {ComponentType} from 'preact'; 12 | 13 | const App: ComponentType<Record<string, unknown>>; 14 | export default App; 15 | } 16 | 17 | declare module 'quilt:module/request-router' { 18 | import type {RequestRouter} from '@quilted/request-router'; 19 | 20 | const router: RequestRouter; 21 | export default router; 22 | } 23 | 24 | declare module 'quilt:module/assets' { 25 | import type {BrowserAssets as BrowserAssetsType} from '@quilted/assets'; 26 | 27 | export const BrowserAssets: { 28 | new (): BrowserAssetsType; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /packages/quilt/source/navigation.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-router'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/navigation/testing.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-router/testing'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/performance.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-performance'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/request-router.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/request-router'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/request-router/node.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/request-router/node'; 2 | -------------------------------------------------------------------------------- /packages/quilt/source/server.browser.ts: -------------------------------------------------------------------------------- 1 | function noopRenderToString() {} 2 | 3 | export { 4 | noopRenderToString as renderToString, 5 | noopRenderToString as renderToStringAsync, 6 | noopRenderToString as renderToStaticMarkup, 7 | }; 8 | export * from '@quilted/preact-browser/server'; 9 | export * from '@quilted/assets'; 10 | 11 | export {parseAcceptLanguageHeader} from '@quilted/preact-localize'; 12 | 13 | function noopCreateRequestRouterLocalization() {} 14 | export {noopCreateRequestRouterLocalization as createRequestRouterLocalization}; 15 | -------------------------------------------------------------------------------- /packages/quilt/source/server.ts: -------------------------------------------------------------------------------- 1 | export { 2 | renderToString, 3 | renderToStringAsync, 4 | renderToStaticMarkup, 5 | } from 'preact-render-to-string'; 6 | export * from '@quilted/preact-browser/server'; 7 | export * from '@quilted/assets'; 8 | 9 | export {parseAcceptLanguageHeader} from '@quilted/preact-localize'; 10 | export {createRequestRouterLocalization} from '@quilted/preact-localize/request-router'; 11 | -------------------------------------------------------------------------------- /packages/quilt/source/signals.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-signals'; 2 | export * from '@quilted/events/signals'; 3 | -------------------------------------------------------------------------------- /packages/quilt/source/testing.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'vitest'; 2 | import {matchers, type CustomMatchers} from '@quilted/preact-testing/matchers'; 3 | 4 | export * from '@quilted/preact-testing'; 5 | 6 | declare module 'vitest' { 7 | interface Assertion<T = any> extends CustomMatchers<T> {} 8 | interface AsymmetricMatchersContaining extends CustomMatchers {} 9 | } 10 | 11 | // @ts-expect-error Incompatibilities between `expect()` and vitest 12 | expect.extend(matchers); 13 | -------------------------------------------------------------------------------- /packages/quilt/source/threads.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/threads'; 2 | export * from '@quilted/threads/signals'; 3 | export * from '@quilted/events'; 4 | export * from '@quilted/preact-workers'; 5 | -------------------------------------------------------------------------------- /packages/quilt/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "jsxImportSource": "preact" 5 | }, 6 | "references": [ 7 | {"path": "../assets"}, 8 | {"path": "../async"}, 9 | {"path": "../events"}, 10 | {"path": "../graphql"}, 11 | {"path": "../preact-async"}, 12 | {"path": "../preact-browser"}, 13 | {"path": "../preact-context"}, 14 | {"path": "../preact-graphql"}, 15 | {"path": "../preact-localize"}, 16 | {"path": "../preact-performance"}, 17 | {"path": "../preact-router"}, 18 | {"path": "../preact-signals"}, 19 | {"path": "../preact-workers"}, 20 | {"path": "../react"}, 21 | {"path": "../react-dom"}, 22 | {"path": "../react-testing"}, 23 | {"path": "../request-router"}, 24 | {"path": "../signals"}, 25 | {"path": "../threads"}, 26 | {"path": "../workers"} 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/react-dom/README.md: -------------------------------------------------------------------------------- 1 | # Package 2 | -------------------------------------------------------------------------------- /packages/react-dom/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage({ 4 | commonjs: true, 5 | }); 6 | -------------------------------------------------------------------------------- /packages/react-dom/source/client.ts: -------------------------------------------------------------------------------- 1 | export * from 'preact/compat/client'; 2 | -------------------------------------------------------------------------------- /packages/react-dom/source/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error No types for this package, but it is typically only used 2 | // as an alias anyways 3 | export * from 'preact/compat'; 4 | export {default} from 'preact/compat'; 5 | -------------------------------------------------------------------------------- /packages/react-dom/source/server.ts: -------------------------------------------------------------------------------- 1 | // Originally, I wanted to just re-export `preact/compat/server`, 2 | // but it lists export conditions in the wrong order. 3 | // @see https://github.com/preactjs/preact/issues/3488 4 | 5 | // I also wanted to export the named exports from this package, but 6 | // unfortunately those are busted in the CommonJS version of the 7 | // library. 8 | // @see https://github.com/preactjs/preact-render-to-string/issues/197 9 | export {renderToString, renderToStaticMarkup} from 'preact-render-to-string'; 10 | -------------------------------------------------------------------------------- /packages/react-dom/source/test-utils.ts: -------------------------------------------------------------------------------- 1 | export * from 'preact/test-utils'; 2 | -------------------------------------------------------------------------------- /packages/react-dom/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/react-testing/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage({ 4 | commonjs: true, 5 | react: 'react', 6 | }); 7 | -------------------------------------------------------------------------------- /packages/react-testing/source/HookRunner.tsx: -------------------------------------------------------------------------------- 1 | import {forwardRef, useRef, useImperativeHandle} from 'react'; 2 | import type {Ref, ReactElement} from 'react'; 3 | 4 | interface Props<HookResult = unknown> { 5 | useHook(): HookResult; 6 | } 7 | 8 | export interface ImperativeApi<HookResult = unknown> { 9 | readonly current: HookResult; 10 | } 11 | 12 | export const HookRunner = forwardRef<ImperativeApi, Props>( 13 | ({useHook}: Props, ref) => { 14 | const hookResult = useHook(); 15 | const valueRef = useRef(hookResult); 16 | valueRef.current = hookResult; 17 | 18 | useImperativeHandle(ref, () => ({ 19 | get current() { 20 | return valueRef.current; 21 | }, 22 | })); 23 | 24 | return null; 25 | }, 26 | ) as <HookResult>( 27 | props: Props<HookResult> & {ref?: Ref<ImperativeApi<HookResult>>}, 28 | ) => ReactElement | null; 29 | -------------------------------------------------------------------------------- /packages/react-testing/source/index.ts: -------------------------------------------------------------------------------- 1 | // @see https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#configuring-your-testing-environment 2 | Reflect.defineProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT', {value: true}); 3 | 4 | export * from './implementations/test-renderer.ts'; 5 | export * from './types.ts'; 6 | export {createEnvironment} from './environment.tsx'; 7 | export type { 8 | CustomRender, 9 | CustomRenderResult, 10 | CustomRenderOptions, 11 | CustomRenderExtendOptions, 12 | HookRunner, 13 | Environment, 14 | EnvironmentOptions, 15 | ContextOption, 16 | RenderOption, 17 | ActionsOption, 18 | } from './environment.tsx'; 19 | -------------------------------------------------------------------------------- /packages/react-testing/source/preact.ts: -------------------------------------------------------------------------------- 1 | export * from '@quilted/preact-testing'; 2 | -------------------------------------------------------------------------------- /packages/react-testing/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [{"path": "../preact-testing"}] 4 | } 5 | -------------------------------------------------------------------------------- /packages/react-testing/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage({react: 'react'})], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/react/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/react` 2 | -------------------------------------------------------------------------------- /packages/react/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage({ 4 | commonjs: true, 5 | }); 6 | -------------------------------------------------------------------------------- /packages/react/source/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error No types for this package, but it is typically only used 2 | // as an alias anyways 3 | export * from 'preact/compat'; 4 | export {default} from 'preact/compat'; 5 | -------------------------------------------------------------------------------- /packages/react/source/jsx-runtime.ts: -------------------------------------------------------------------------------- 1 | export * from 'preact/jsx-runtime'; 2 | -------------------------------------------------------------------------------- /packages/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/request-router/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/request-router` 2 | -------------------------------------------------------------------------------- /packages/request-router/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/request-router/source/errors.ts: -------------------------------------------------------------------------------- 1 | export {ResponseShortCircuitError} from './errors/ResponseShortCircuitError.ts'; 2 | export {ResponseRedirectError} from './errors/ResponseRedirectError.ts'; 3 | -------------------------------------------------------------------------------- /packages/request-router/source/errors/ResponseRedirectError.ts: -------------------------------------------------------------------------------- 1 | import {type NavigateTo} from '@quilted/routing'; 2 | 3 | import {RedirectResponse} from '../response-helpers.ts'; 4 | import {ResponseShortCircuitError} from './ResponseShortCircuitError.ts'; 5 | 6 | export class ResponseRedirectError extends ResponseShortCircuitError { 7 | constructor( 8 | to: NavigateTo, 9 | options?: Omit<ConstructorParameters<typeof RedirectResponse>[1], 'to'>, 10 | ) { 11 | const response = new RedirectResponse(to, options); 12 | super( 13 | response, 14 | `Redirecting to: ${response.headers.get('Location') ?? to}`, 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/request-router/source/errors/ResponseShortCircuitError.ts: -------------------------------------------------------------------------------- 1 | export class ResponseShortCircuitError extends Error { 2 | constructor( 3 | public readonly response: Response, 4 | message = `Short circuiting with status code: ${response.status}`, 5 | ) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/request-router/source/globals.ts: -------------------------------------------------------------------------------- 1 | const GlobalRequest = (typeof Request === 'undefined' 2 | ? class Request { 3 | constructor() { 4 | throw new Error('No Request global was found'); 5 | } 6 | } 7 | : Request) as any as typeof Request; 8 | 9 | const GlobalResponse = (typeof Response === 'undefined' 10 | ? class Response { 11 | constructor() { 12 | throw new Error('No Response global was found'); 13 | } 14 | } 15 | : Response) as any as typeof Response; 16 | 17 | export {GlobalRequest as Request, GlobalResponse as Response}; 18 | 19 | type GlobalBodyInit = BodyInit; 20 | type GlobalResponseInit = ResponseInit; 21 | type GlobalRequestInit = RequestInit; 22 | 23 | export type { 24 | GlobalBodyInit as BodyInit, 25 | GlobalResponseInit as ResponseInit, 26 | GlobalRequestInit as RequestInit, 27 | }; 28 | -------------------------------------------------------------------------------- /packages/request-router/source/index.ts: -------------------------------------------------------------------------------- 1 | export type { 2 | ReadonlyHeaders, 3 | Cookies, 4 | ReadonlyCookies, 5 | WritableCookies, 6 | CookieOptions, 7 | } from '@quilted/http'; 8 | 9 | export * from './router.ts'; 10 | export * from './globals.ts'; 11 | export * from './response.ts'; 12 | export * from './request.ts'; 13 | export * from './response-helpers.ts'; 14 | export * from './errors.ts'; 15 | export {handleRequest} from './handle.ts'; 16 | 17 | export type { 18 | CookieDefinition, 19 | RequestContext, 20 | EnhancedWritableCookies, 21 | } from './types.ts'; 22 | -------------------------------------------------------------------------------- /packages/request-router/source/node/index.ts: -------------------------------------------------------------------------------- 1 | export {serveStatic, type StaticOptions} from './static.ts'; 2 | export { 3 | createHttpServer, 4 | createHttpRequestListener, 5 | createRequest, 6 | sendResponse, 7 | } from './node.ts'; 8 | -------------------------------------------------------------------------------- /packages/request-router/source/node/types.ts: -------------------------------------------------------------------------------- 1 | import type {IncomingMessage, ServerResponse} from 'http'; 2 | 3 | export interface NodeRequestContext { 4 | readonly request: IncomingMessage; 5 | readonly response: ServerResponse; 6 | } 7 | 8 | declare module '../types' { 9 | interface RequestContext extends NodeRequestContext {} 10 | } 11 | -------------------------------------------------------------------------------- /packages/request-router/source/types.ts: -------------------------------------------------------------------------------- 1 | import type {NavigateToLiteral} from '@quilted/routing'; 2 | import type {WritableCookies} from '@quilted/http'; 3 | 4 | export type NavigateTo = NavigateToLiteral | ((url: URL) => URL); 5 | 6 | export interface RequestContext {} 7 | 8 | export interface CookieDefinition { 9 | path?: string; 10 | domain?: string; 11 | maxAge?: number; 12 | expires?: Date; 13 | sameSite?: 'lax' | 'strict' | 'none'; 14 | secure?: boolean; 15 | httpOnly?: boolean; 16 | } 17 | 18 | export interface EnhancedWritableCookies extends WritableCookies { 19 | getAll(): string[] | undefined; 20 | } 21 | 22 | export type ValueOrPromise<T> = T | Promise<T>; 23 | -------------------------------------------------------------------------------- /packages/request-router/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [{"path": "../http"}, {"path": "../routing"}] 4 | } 5 | -------------------------------------------------------------------------------- /packages/rollup/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/rollup` 2 | -------------------------------------------------------------------------------- /packages/rollup/source/constants.ts: -------------------------------------------------------------------------------- 1 | export const MAGIC_MODULE_ENV = 'quilt:module/env'; 2 | export const MAGIC_MODULE_ENTRY = 'quilt:module/entry'; 3 | export const MAGIC_MODULE_APP_COMPONENT = 'quilt:module/app'; 4 | export const MAGIC_MODULE_BROWSER_ASSETS = 'quilt:module/assets'; 5 | export const MAGIC_MODULE_REQUEST_ROUTER = 'quilt:module/request-router'; 6 | -------------------------------------------------------------------------------- /packages/rollup/source/features/react.ts: -------------------------------------------------------------------------------- 1 | import type {Plugin} from 'rollup'; 2 | 3 | export function react() { 4 | return { 5 | name: '@quilted/react', 6 | options(options) { 7 | return { 8 | ...options, 9 | onLog(level, log, handler) { 10 | if ( 11 | log.code === 'MODULE_LEVEL_DIRECTIVE' && 12 | /['"]use client['"]/.test(log.message) 13 | ) { 14 | return; 15 | } 16 | 17 | if (options.onLog) { 18 | options.onLog(level, log, handler); 19 | } else { 20 | handler(level, log); 21 | } 22 | }, 23 | }; 24 | }, 25 | } satisfies Plugin; 26 | } 27 | -------------------------------------------------------------------------------- /packages/rollup/source/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | quiltApp, 3 | quiltAppBrowser, 4 | quiltAppBrowserPlugins, 5 | quiltAppServer, 6 | quiltAppServerPlugins, 7 | type AppOptions, 8 | type AppBaseOptions, 9 | type AppBrowserOptions, 10 | type AppServerOptions, 11 | type AppRuntime, 12 | type AppServerRuntime, 13 | } from './app.ts'; 14 | export {quiltModule, type ModuleOptions, type ModuleRuntime} from './module.ts'; 15 | export { 16 | quiltPackage, 17 | quiltPackageESModules, 18 | quiltPackageESNext, 19 | type PackageOptions, 20 | } from './package.ts'; 21 | export { 22 | quiltServer, 23 | type ServerOptions, 24 | type ServerOutputOptions, 25 | type ServerRuntime, 26 | } from './server.ts'; 27 | export {multiline} from './shared/strings.ts'; 28 | export * from './constants.ts'; 29 | -------------------------------------------------------------------------------- /packages/rollup/source/shared/strings.ts: -------------------------------------------------------------------------------- 1 | export function multiline(strings: TemplateStringsArray, ...values: any[]) { 2 | let result = strings.reduce( 3 | (combined, string, index) => `${combined}${string}${values[index] ?? ''}`, 4 | '', 5 | ); 6 | 7 | // Inspired by https://github.com/zspecza/common-tags/blob/master/src/stripIndentTransformer/stripIndentTransformer.js#L8 8 | const match = result.match(/^[^\S\n]*(?=\S)/gm); 9 | const indent = match && Math.min(...match.map((indent) => indent.length)); 10 | 11 | if (indent) { 12 | const regexp = new RegExp(`^.{${indent}}`, 'gm'); 13 | result = result.replace(regexp, ''); 14 | } 15 | 16 | return result.trim(); 17 | } 18 | -------------------------------------------------------------------------------- /packages/rollup/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [ 4 | {"path": "../assets"}, 5 | {"path": "../babel"}, 6 | {"path": "../graphql"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /packages/routing/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/routing` 2 | -------------------------------------------------------------------------------- /packages/routing/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/routing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quilted/routing", 3 | "type": "module", 4 | "version": "0.4.3", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/lemonmade/quilt.git", 9 | "directory": "packages/routing" 10 | }, 11 | "publishConfig": { 12 | "access": "public", 13 | "@quilted:registry": "https://registry.npmjs.org" 14 | }, 15 | "exports": { 16 | ".": { 17 | "types": "./build/typescript/index.d.ts", 18 | "quilt:source": "./source/index.ts", 19 | "quilt:esnext": "./build/esnext/index.esnext", 20 | "import": "./build/esm/index.mjs" 21 | } 22 | }, 23 | "types": "./build/typescript/index.d.ts", 24 | "sideEffects": false, 25 | "scripts": { 26 | "build": "rollup --config configuration/rollup.config.js" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/routing/source/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utilities.ts'; 2 | export * from './types.ts'; 3 | -------------------------------------------------------------------------------- /packages/routing/source/types.ts: -------------------------------------------------------------------------------- 1 | export interface RouteMatcher { 2 | (url: URL): boolean; 3 | } 4 | 5 | export type RouteMatch = string | boolean | RegExp | RouteMatcher; 6 | 7 | export interface RouteMatchDetails { 8 | matched: string; 9 | consumed?: string; 10 | } 11 | 12 | export type NavigateToSearch = 13 | | string 14 | | Record<string, string | undefined> 15 | | URLSearchParams; 16 | 17 | export type NavigateToLiteral = 18 | | string 19 | | URL 20 | | { 21 | path?: string; 22 | hash?: string; 23 | search?: NavigateToSearch; 24 | }; 25 | 26 | export type NavigateTo = 27 | | NavigateToLiteral 28 | | ((currentURL: URL) => NavigateToLiteral); 29 | -------------------------------------------------------------------------------- /packages/routing/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/routing/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/signals/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/signals` 2 | -------------------------------------------------------------------------------- /packages/signals/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/signals/source/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@preact/signals-core'; 2 | 3 | export { 4 | isSignal, 5 | resolveSignalOrValue, 6 | type SignalOrValue, 7 | } from './signal-or-value.ts'; 8 | export {signalToIterator} from './iterator.ts'; 9 | -------------------------------------------------------------------------------- /packages/signals/source/iterator.ts: -------------------------------------------------------------------------------- 1 | import {type Signal} from '@preact/signals-core'; 2 | import {EventEmitter} from '@quilted/events'; 3 | 4 | export function signalToIterator<T>( 5 | signal: Signal<T>, 6 | {signal: abortSignal}: {signal?: AbortSignal} = {}, 7 | ) { 8 | const emitter = new EventEmitter<{value: T}>(); 9 | 10 | const unsubscribe = signal.subscribe((value) => { 11 | emitter.emit('value', value); 12 | }); 13 | 14 | abortSignal?.addEventListener('abort', () => { 15 | unsubscribe(); 16 | }); 17 | 18 | return run(); 19 | 20 | async function* run() { 21 | yield signal.peek(); 22 | 23 | if (abortSignal?.aborted) return; 24 | 25 | for await (const value of emitter.on('value', {signal: abortSignal})) { 26 | yield value; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/signals/source/signal-or-value.ts: -------------------------------------------------------------------------------- 1 | import {Signal} from '@preact/signals-core'; 2 | 3 | export type SignalOrValue<T> = T | Signal<T>; 4 | 5 | export function isSignal<T = unknown>(value: unknown): value is Signal<T> { 6 | return value != null && value instanceof Signal; 7 | } 8 | 9 | export function resolveSignalOrValue<T>( 10 | value: SignalOrValue<T>, 11 | options?: {peek?: boolean}, 12 | ): T { 13 | return isSignal(value) ? (options?.peek ? value.peek() : value.value) : value; 14 | } 15 | -------------------------------------------------------------------------------- /packages/signals/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [{"path": "../events"}] 4 | } 5 | -------------------------------------------------------------------------------- /packages/threads/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/threads/source/constants.ts: -------------------------------------------------------------------------------- 1 | export const MESSAGE_CALL = 1; 2 | export const MESSAGE_CALL_RESULT = 2; 3 | export const MESSAGE_FUNCTION_CALL = 3; 4 | export const MESSAGE_FUNCTION_RESULT = 4; 5 | export const MESSAGE_FUNCTION_RELEASE = 5; 6 | 7 | export const SERIALIZE_METHOD = Symbol.for('quilt.threads.serialize'); 8 | export const TRANSFERABLE = Symbol.for('quilt.threads.transferable'); 9 | -------------------------------------------------------------------------------- /packages/threads/source/errors.ts: -------------------------------------------------------------------------------- 1 | export class ThreadClosedError extends Error { 2 | constructor() { 3 | super('You attempted to call a function on a closed thread.'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/threads/source/nanoid.ts: -------------------------------------------------------------------------------- 1 | // Copied from https://github.com/ai/nanoid/blob/main/nanoid.js 2 | let a = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; 3 | 4 | export function nanoid(e = 21) { 5 | let t = '', 6 | r = crypto.getRandomValues(new Uint8Array(e)); 7 | for (let n = 0; n < e; n++) t += a[63 & r[n]!]; 8 | return t; 9 | } 10 | -------------------------------------------------------------------------------- /packages/threads/source/serialization/shared.ts: -------------------------------------------------------------------------------- 1 | export function isIterator(value: any) { 2 | return ( 3 | value != null && 4 | (Symbol.asyncIterator in value || Symbol.iterator in value) && 5 | typeof (value as any).next === 'function' 6 | ); 7 | } 8 | 9 | export function isBasicObject(value: unknown) { 10 | if (value == null || typeof value !== 'object') return false; 11 | 12 | const prototype = Object.getPrototypeOf(value); 13 | return prototype == null || prototype === Object.prototype; 14 | } 15 | -------------------------------------------------------------------------------- /packages/threads/source/signals.ts: -------------------------------------------------------------------------------- 1 | export { 2 | threadSignal, 3 | ThreadSignal, 4 | type ThreadSignalOptions, 5 | type ThreadSignalSerialization, 6 | } from './ThreadSignal.ts'; 7 | -------------------------------------------------------------------------------- /packages/threads/source/threads/window/shared.ts: -------------------------------------------------------------------------------- 1 | export const CHECK_MESSAGE = 'quilt.threads.ping'; 2 | export const RESPONSE_MESSAGE = 'quilt.threads.pong'; 3 | -------------------------------------------------------------------------------- /packages/threads/source/transfer.ts: -------------------------------------------------------------------------------- 1 | import {TRANSFERABLE} from './constants.ts'; 2 | 3 | /** 4 | * Marks the value as being transferable between threads. The memory for this object 5 | * will be moved to the target thread once the object is sent. 6 | * 7 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects 8 | */ 9 | export function markAsTransferable<T = unknown>(value: T) { 10 | Object.assign(value as any, {[TRANSFERABLE]: true}); 11 | return value; 12 | } 13 | -------------------------------------------------------------------------------- /packages/threads/source/types.ts: -------------------------------------------------------------------------------- 1 | import type {SERIALIZE_METHOD} from './constants.ts'; 2 | 3 | /** 4 | * An object that provides a custom function to serialize its value. 5 | */ 6 | export interface ThreadSerializable { 7 | [SERIALIZE_METHOD](api: {serialize(value: any): unknown}): any; 8 | } 9 | 10 | export type AnyFunction = Function; 11 | -------------------------------------------------------------------------------- /packages/threads/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "lib": ["DOM", "webWorker", "ESNext"] 5 | }, 6 | "references": [{"path": "../events"}] 7 | } 8 | -------------------------------------------------------------------------------- /packages/threads/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/typescript/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @quilted/typescript 2 | 3 | ## 0.4.2 4 | 5 | ### Patch Changes 6 | 7 | - [`0cdca9a`](https://github.com/lemonmade/quilt/commit/0cdca9a718d29656e4f5ddfd2a501c0a3a2c6bcb) Thanks [@lemonmade](https://github.com/lemonmade)! - Default to excluding `build` directory from TypeScript compilation 8 | 9 | ## 0.4.1 10 | 11 | ### Patch Changes 12 | 13 | - [`b57360e`](https://github.com/lemonmade/quilt/commit/b57360e66a049c31a1a4e48e32a99cf11fd64684) Thanks [@lemonmade](https://github.com/lemonmade)! - Update TypeScript to 5.5 14 | 15 | ## 0.4.0 16 | 17 | ### Minor Changes 18 | 19 | - [`d9cb157`](https://github.com/lemonmade/quilt/commit/d9cb157784982ff32739d3d6284bc547186da250) Thanks [@lemonmade](https://github.com/lemonmade)! - Remove `@quilted/craft` package 20 | -------------------------------------------------------------------------------- /packages/typescript/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/typescript` 2 | -------------------------------------------------------------------------------- /packages/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quilted/typescript", 3 | "description": "Shared configuration for TypeScript projects", 4 | "type": "module", 5 | "license": "MIT", 6 | "publishConfig": { 7 | "access": "public", 8 | "@quilted/registry": "https://registry.npmjs.org" 9 | }, 10 | "version": "0.4.2", 11 | "engines": { 12 | "node": ">=18.0.0" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/lemonmade/quilt.git", 17 | "directory": "packages/typescript" 18 | }, 19 | "exports": { 20 | ".": "./source/tsconfig.json", 21 | "./tsconfig.json": "./source/tsconfig.json", 22 | "./tsconfig.package.json": "./source/tsconfig.package.json", 23 | "./tsconfig.project.json": "./source/tsconfig.project.json", 24 | "./tsconfig.workspace.json": "./source/tsconfig.workspace.json" 25 | }, 26 | "sideEffects": false 27 | } 28 | -------------------------------------------------------------------------------- /packages/typescript/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/typescript/source/tsconfig.package.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "${configDir}source" 5 | }, 6 | "include": ["${configDir}source"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/typescript/source/tsconfig.project.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/typescript/source/tsconfig.workspace.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/typescript/vite.config.js: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import {quiltPackage} from '@quilted/vite/package'; 3 | 4 | export default defineConfig({ 5 | plugins: [quiltPackage()], 6 | }); 7 | -------------------------------------------------------------------------------- /packages/useful-types/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/useful-types` 2 | 3 | A collection of useful TypeScript types. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | # npm 9 | npm install @quilted/useful-types --save-dev 10 | # pnpm 11 | pnpm install @quilted/useful-types --save-dev 12 | # yarn 13 | yarn add @quilted/useful-types --dev 14 | ``` 15 | 16 | ## Usage 17 | 18 | Please refer to the inline documentation for explanations of how to use each helper type provided by this module. 19 | -------------------------------------------------------------------------------- /packages/useful-types/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/useful-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quilted/useful-types", 3 | "description": "A collection of useful TypeScript types", 4 | "type": "module", 5 | "version": "2.0.0", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/lemonmade/quilt.git", 9 | "directory": "packages/useful-types" 10 | }, 11 | "publishConfig": { 12 | "access": "public", 13 | "@quilted:registry": "https://registry.npmjs.org" 14 | }, 15 | "license": "MIT", 16 | "exports": { 17 | ".": { 18 | "types": "./build/typescript/index.d.ts", 19 | "quilt:source": "./source/index.ts", 20 | "quilt:esnext": "./build/esnext/index.esnext", 21 | "import": "./build/esm/index.mjs" 22 | } 23 | }, 24 | "types": "./build/typescript/index.d.ts", 25 | "sideEffects": false, 26 | "scripts": { 27 | "build": "rollup --config configuration/rollup.config.js" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/useful-types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/vite/README.md: -------------------------------------------------------------------------------- 1 | # `@quilted/vite` 2 | -------------------------------------------------------------------------------- /packages/vite/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/vite/source/index.ts: -------------------------------------------------------------------------------- 1 | export {quiltApp, type AppBaseOptions} from './app.ts'; 2 | export {quiltPackage, type PackageBaseOptions} from './package.ts'; 3 | -------------------------------------------------------------------------------- /packages/vite/source/shared/strings.ts: -------------------------------------------------------------------------------- 1 | export function multiline(strings: TemplateStringsArray, ...values: any[]) { 2 | let result = strings.reduce( 3 | (combined, string, index) => `${combined}${string}${values[index] ?? ''}`, 4 | '', 5 | ); 6 | 7 | // Inspired by https://github.com/zspecza/common-tags/blob/master/src/stripIndentTransformer/stripIndentTransformer.js#L8 8 | const match = result.match(/^[^\S\n]*(?=\S)/gm); 9 | const indent = match && Math.min(...match.map((indent) => indent.length)); 10 | 11 | if (indent) { 12 | const regexp = new RegExp(`^.{${indent}}`, 'gm'); 13 | result = result.replace(regexp, ''); 14 | } 15 | 16 | return result.trim(); 17 | } 18 | -------------------------------------------------------------------------------- /packages/vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "references": [{"path": "../request-router"}, {"path": "../rollup"}] 4 | } 5 | -------------------------------------------------------------------------------- /packages/workers/configuration/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltPackage} from '@quilted/rollup/package'; 2 | 3 | export default quiltPackage(); 4 | -------------------------------------------------------------------------------- /packages/workers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quilted/workers", 3 | "type": "module", 4 | "version": "0.5.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/lemonmade/quilt.git", 8 | "directory": "packages/workers" 9 | }, 10 | "publishConfig": { 11 | "access": "public", 12 | "@quilted:registry": "https://registry.npmjs.org" 13 | }, 14 | "license": "MIT", 15 | "exports": { 16 | ".": { 17 | "types": "./build/typescript/index.d.ts", 18 | "quilt:source": "./source/index.ts", 19 | "quilt:esnext": "./build/esnext/index.esnext", 20 | "import": "./build/esm/index.mjs" 21 | } 22 | }, 23 | "types": "./build/typescript/index.d.ts", 24 | "sideEffects": false, 25 | "scripts": { 26 | "build": "rollup --config configuration/rollup.config.js" 27 | }, 28 | "dependencies": { 29 | "@quilted/threads": "workspace:^3.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/workers/source/index.ts: -------------------------------------------------------------------------------- 1 | export {retain, release, ThreadWebWorker} from '@quilted/threads'; 2 | export type {ThreadOptions, ThreadImports} from '@quilted/threads'; 3 | 4 | export { 5 | createWorker, 6 | type CustomWorker, 7 | type CustomWorkerConstructor, 8 | type CustomWorkerModuleResolver, 9 | } from './create/basic.ts'; 10 | export { 11 | createThreadWorker, 12 | type CustomThreadWorker, 13 | type CustomThreadWorkerConstructor, 14 | } from './create/thread.ts'; 15 | -------------------------------------------------------------------------------- /packages/workers/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.package.json", 3 | "compilerOptions": { 4 | "lib": ["ESNext", "DOM", "WebWorker"] 5 | }, 6 | "references": [{"path": "../threads"}] 7 | } 8 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - examples/basic-app 3 | - integrations/* 4 | - packages/* 5 | - tests/e2e 6 | - tests/e2e/fixtures/* 7 | -------------------------------------------------------------------------------- /tests/e2e/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # e2e-tests 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 | - [#645](https://github.com/lemonmade/quilt/pull/645) [`302ed847`](https://github.com/lemonmade/quilt/commit/302ed8479f9c035ef39d48137de958dba50690ca) Thanks [@lemonmade](https://github.com/lemonmade)! - Removed CommonJS support 8 | 9 | The `require` export condition is no longer provided by any package. Quilt only supports ESModules, so if you need to use the CommonJS version, you will need to pre-process Quilt’s output code on your own. 10 | 11 | ## 0.0.1 12 | 13 | ### Patch Changes 14 | 15 | - [`917ea19`](https://github.com/lemonmade/quilt/commit/917ea19edbd8ad210675b11ef7f2ebe0c33e0b3e) Thanks [@lemonmade](https://github.com/lemonmade)! - Fixed dependencies to support stricter pnpm-based project 16 | -------------------------------------------------------------------------------- /tests/e2e/common/images/lemon-tiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/tests/e2e/common/images/lemon-tiny.png -------------------------------------------------------------------------------- /tests/e2e/common/images/lemon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lemonmade/quilt/36fc17355d192095928f9b4f74d24a25c1781883/tests/e2e/common/images/lemon.png -------------------------------------------------------------------------------- /tests/e2e/common/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "compilerOptions": { 4 | "outDir": "build/typescript" 5 | }, 6 | "include": ["**/*"], 7 | "exclude": ["build"] 8 | } 9 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-api/api.ts: -------------------------------------------------------------------------------- 1 | import {RequestRouter, HTMLResponse} from '@quilted/quilt/request-router'; 2 | 3 | const router = new RequestRouter(); 4 | 5 | router.get('/', () => new HTMLResponse('Hello world!')); 6 | 7 | export default router; 8 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "e2e-fixture-basic-api", 3 | "private": true, 4 | "version": "0.0.43", 5 | "type": "module", 6 | "main": "./api.ts", 7 | "scripts": { 8 | "build": "rollup --config ./rollup.config.js" 9 | }, 10 | "dependencies": {}, 11 | "devDependencies": { 12 | "@quilted/quilt": "workspace:*", 13 | "typescript": "^5.7.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-api/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltServer} from '@quilted/rollup/server'; 2 | 3 | export default quiltServer(); 4 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "compilerOptions": { 4 | "outDir": "build/typescript" 5 | }, 6 | "references": [{"path": "../../common"}] 7 | } 8 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-app/App.tsx: -------------------------------------------------------------------------------- 1 | import {Navigation} from '@quilted/quilt/navigation'; 2 | import {Localization} from '@quilted/quilt/localize'; 3 | import {PerformanceContext} from '@quilted/quilt/performance'; 4 | 5 | import {performance} from '../../common/globals.ts'; 6 | 7 | import {HTML} from './foundation/HTML.tsx'; 8 | import {Routes} from './foundation/Routes.tsx'; 9 | 10 | export function App() { 11 | return ( 12 | <PerformanceContext performance={performance}> 13 | <Localization locale="en"> 14 | <HTML> 15 | <Navigation> 16 | <Routes /> 17 | </Navigation> 18 | </HTML> 19 | </Localization> 20 | </PerformanceContext> 21 | ); 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-app/browser.tsx: -------------------------------------------------------------------------------- 1 | import '@quilted/quilt/globals'; 2 | import {hydrate} from '@quilted/quilt/browser'; 3 | 4 | import App from './App.tsx'; 5 | 6 | hydrate(<App />); 7 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-app/foundation/HTML.tsx: -------------------------------------------------------------------------------- 1 | import type {RenderableProps} from 'preact'; 2 | 3 | import {Title} from '@quilted/quilt/browser'; 4 | import {CacheControl} from '@quilted/quilt/server'; 5 | 6 | export function HTML({children}: RenderableProps<{}>) { 7 | return ( 8 | <> 9 | <Headers /> 10 | <Head /> 11 | {children} 12 | </> 13 | ); 14 | } 15 | 16 | function Head() { 17 | return <Title>App; 18 | } 19 | 20 | function Headers() { 21 | return ; 22 | } 23 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-app/foundation/Routes.tsx: -------------------------------------------------------------------------------- 1 | import {useRoutes} from '@quilted/quilt/navigation'; 2 | import {usePerformanceNavigation} from '@quilted/quilt/performance'; 3 | 4 | export function Routes() { 5 | return useRoutes([{match: '/', render: () => }]); 6 | } 7 | 8 | function Home() { 9 | usePerformanceNavigation({state: 'complete'}); 10 | return
Home
; 11 | } 12 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "e2e-fixture-basic-app", 3 | "private": true, 4 | "version": "0.0.43", 5 | "type": "module", 6 | "scripts": { 7 | "build": "rollup --config rollup.config.js" 8 | }, 9 | "dependencies": {}, 10 | "devDependencies": { 11 | "@quilted/quilt": "workspace:*", 12 | "react": "workspace:@quilted/react@*", 13 | "react-dom": "workspace:@quilted/react-dom@*", 14 | "typescript": "^5.7.0" 15 | }, 16 | "browserslist": [ 17 | "defaults and fully supports es6-module-dynamic-import" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-app/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltApp} from '@quilted/rollup/app'; 2 | 3 | export default quiltApp({ 4 | assets: { 5 | // Un-minified assets makes it easier to debug build outputs 6 | minify: false, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-app/server.tsx: -------------------------------------------------------------------------------- 1 | import '@quilted/quilt/globals'; 2 | import {RequestRouter} from '@quilted/quilt/request-router'; 3 | 4 | import {BrowserAssets} from 'quilt:module/assets'; 5 | 6 | const router = new RequestRouter(); 7 | const assets = new BrowserAssets(); 8 | 9 | // For all GET requests, render our Preact application. 10 | router.get(async (request) => { 11 | const [{default: App}, {renderAppToHTMLResponse}] = await Promise.all([ 12 | import('./App.tsx'), 13 | import('@quilted/quilt/server'), 14 | ]); 15 | 16 | assets.entry({id: './inline.css'}).styles; 17 | 18 | const response = await renderAppToHTMLResponse(, { 19 | request, 20 | assets, 21 | }); 22 | 23 | return response; 24 | }); 25 | 26 | export default router; 27 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/basic-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "compilerOptions": { 4 | "outDir": "build/typescript", 5 | "jsxImportSource": "preact" 6 | }, 7 | "include": ["**/*"], 8 | "exclude": ["build"], 9 | "references": [{"path": "../../common"}] 10 | } 11 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/empty-app/App.tsx: -------------------------------------------------------------------------------- 1 | export default function App() { 2 | return <>I am an empty app!; 3 | } 4 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/empty-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "e2e-fixture-empty-app", 3 | "private": true, 4 | "version": "0.0.43", 5 | "type": "module", 6 | "scripts": { 7 | "build": "rollup --config rollup.config.js" 8 | }, 9 | "dependencies": {}, 10 | "devDependencies": { 11 | "@quilted/quilt": "workspace:*", 12 | "react": "workspace:@quilted/react@*", 13 | "react-dom": "workspace:@quilted/react-dom@*", 14 | "typescript": "^5.7.0" 15 | }, 16 | "browserslist": [ 17 | "defaults and fully supports es6-module-dynamic-import" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/empty-app/rollup.config.js: -------------------------------------------------------------------------------- 1 | import {quiltApp} from '@quilted/rollup/app'; 2 | 3 | export default quiltApp({ 4 | assets: { 5 | // Un-minified assets makes it easier to debug build outputs 6 | minify: false, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /tests/e2e/fixtures/empty-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quilted/typescript/tsconfig.project.json", 3 | "compilerOptions": { 4 | "outDir": "build/typescript", 5 | "jsxImportSource": "preact" 6 | }, 7 | "include": ["**/*"], 8 | "exclude": ["build"], 9 | "references": [{"path": "../../common"}] 10 | } 11 | -------------------------------------------------------------------------------- /tests/e2e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "e2e-tests", 3 | "version": "0.0.2", 4 | "private": true, 5 | "devDependencies": { 6 | "@quilted/htmx": "workspace:*", 7 | "@quilted/quilt": "workspace:*", 8 | "@quilted/react-query": "workspace:*", 9 | "@quilted/trpc": "workspace:*", 10 | "@tanstack/react-query": "^5.54.1", 11 | "@trpc/client": "11.0.0-rc.498", 12 | "@trpc/react-query": "11.0.0-rc.498", 13 | "@trpc/server": "11.0.0-rc.498", 14 | "@types/common-tags": "^1.8.4", 15 | "@types/fs-extra": "^11.0.0", 16 | "common-tags": "^1.8.0", 17 | "fs-extra": "^11.3.0", 18 | "get-port": "^7.1.0", 19 | "htmx.org": "^1.9.10", 20 | "nanoid": "^5.1.0", 21 | "playwright": "^1.50.1", 22 | "react": "workspace:@quilted/react@*", 23 | "react-dom": "workspace:@quilted/react-dom@*" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vitest.workspace.js: -------------------------------------------------------------------------------- 1 | export default ['packages/*/vite.config.{js,ts}']; 2 | --------------------------------------------------------------------------------