Skip to content

Commit

Permalink
refactor(optimizer): allow documenting experimental features
Browse files Browse the repository at this point in the history
by using a string enum we can refer to the items directly and they end up in the API docs. Plus the code is cleaner.
  • Loading branch information
wmertens committed Oct 6, 2024
1 parent dda3962 commit 60df208
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 30 deletions.
57 changes: 54 additions & 3 deletions packages/docs/src/routes/api/qwik-optimizer/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@
"id": "experimentalfeatures"
}
],
"kind": "TypeAlias",
"content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nUse `__EXPERIMENTAL__.x` to check if feature `x` is enabled. It will be replaced with `true` or `false` via an exact string replacement.\n\n\n```typescript\nexport type ExperimentalFeatures = (typeof experimental)[number];\n```",
"kind": "Enum",
"content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nUse `__EXPERIMENTAL__.x` to check if feature `x` is enabled. It will be replaced with `true` or `false` via an exact string replacement.\n\nAdd experimental features to this enum definition.\n\n\n```typescript\nexport declare enum ExperimentalFeatures \n```\n\n\n<table><thead><tr><th>\n\nMember\n\n\n</th><th>\n\nValue\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\nnoSPA\n\n\n</td><td>\n\n`\"noSPA\"`\n\n\n</td><td>\n\n**_(ALPHA)_** Disable SPA navigation handler in Qwik City\n\n\n</td></tr>\n<tr><td>\n\npreventNavigate\n\n\n</td><td>\n\n`\"preventNavigate\"`\n\n\n</td><td>\n\n**_(ALPHA)_** Enable the usePreventNavigate hook\n\n\n</td></tr>\n<tr><td>\n\nvalibot\n\n\n</td><td>\n\n`\"valibot\"`\n\n\n</td><td>\n\n**_(ALPHA)_** Enable the Valibot form validation\n\n\n</td></tr>\n</tbody></table>",
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/plugins/plugin.ts",
"mdFile": "qwik.experimentalfeatures.md"
},
Expand Down Expand Up @@ -261,6 +261,23 @@
"content": "```typescript\nnormalize(path: string): string;\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\npath\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nstring",
"mdFile": "qwik.path.normalize.md"
},
{
"name": "noSPA",
"id": "experimentalfeatures-nospa",
"hierarchy": [
{
"name": "ExperimentalFeatures",
"id": "experimentalfeatures-nospa"
},
{
"name": "noSPA",
"id": "experimentalfeatures-nospa"
}
],
"kind": "EnumMember",
"content": "",
"mdFile": "qwik.experimentalfeatures.nospa.md"
},
{
"name": "Optimizer",
"id": "optimizer",
Expand Down Expand Up @@ -334,6 +351,23 @@
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/types.ts",
"mdFile": "qwik.path.md"
},
{
"name": "preventNavigate",
"id": "experimentalfeatures-preventnavigate",
"hierarchy": [
{
"name": "ExperimentalFeatures",
"id": "experimentalfeatures-preventnavigate"
},
{
"name": "preventNavigate",
"id": "experimentalfeatures-preventnavigate"
}
],
"kind": "EnumMember",
"content": "",
"mdFile": "qwik.experimentalfeatures.preventnavigate.md"
},
{
"name": "QwikBuildMode",
"id": "qwikbuildmode",
Expand Down Expand Up @@ -414,7 +448,7 @@
}
],
"kind": "Interface",
"content": "```typescript\nexport interface QwikRollupPluginOptions \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[buildMode?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[QwikBuildMode](#qwikbuildmode)\n\n\n</td><td>\n\n_(Optional)_ Build `production` or `development`<!-- -->.\n\nDefault `development`\n\n\n</td></tr>\n<tr><td>\n\n[csr?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[debug?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\n_(Optional)_ Prints verbose Qwik plugin debug logs.\n\nDefault `false`\n\n\n</td></tr>\n<tr><td>\n\n[entryStrategy?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[EntryStrategy](#entrystrategy)\n\n\n</td><td>\n\n_(Optional)_ The Qwik entry strategy to use while building for production. During development the type is always `segment`<!-- -->.\n\nDefault `{ type: \"smart\" }`<!-- -->)\n\n\n</td></tr>\n<tr><td>\n\n[experimental?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[ExperimentalFeatures](#experimentalfeatures)<!-- -->\\[\\]\n\n\n</td><td>\n\n_(Optional)_ Experimental features. These can come and go in patch releases, and their API is not guaranteed to be stable between releases.\n\n\n</td></tr>\n<tr><td>\n\n[lint?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\n_(Optional)_ Run eslint on the source files for the ssr build or dev server. This can slow down startup on large projects. Defaults to `true`\n\n\n</td></tr>\n<tr><td>\n\n[manifestInput?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[QwikManifest](#qwikmanifest)\n\n\n</td><td>\n\n_(Optional)_ The SSR build requires the manifest generated during the client build. The `manifestInput` option can be used to manually provide a manifest.\n\nDefault `undefined`\n\n\n</td></tr>\n<tr><td>\n\n[manifestOutput?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(manifest: [QwikManifest](#qwikmanifest)<!-- -->) =&gt; Promise&lt;void&gt; \\| void\n\n\n</td><td>\n\n_(Optional)_ The client build will create a manifest and this hook is called with the generated build data.\n\nDefault `undefined`\n\n\n</td></tr>\n<tr><td>\n\n[optimizerOptions?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[OptimizerOptions](#optimizeroptions)\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[rootDir?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The root of the application, which is commonly the same directory as `package.json` and `rollup.config.js`<!-- -->.\n\nDefault `process.cwd()`\n\n\n</td></tr>\n<tr><td>\n\n[srcDir?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The source directory to find all the Qwik components. Since Qwik does not have a single input, the `srcDir` is used to recursively find Qwik files.\n\nDefault `src`\n\n\n</td></tr>\n<tr><td>\n\n[srcInputs?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[TransformModuleInput](#transformmoduleinput)<!-- -->\\[\\] \\| null\n\n\n</td><td>\n\n_(Optional)_ Alternative to `srcDir`<!-- -->, where `srcInputs` is able to provide the files manually. This option is useful for an environment without a file system, such as a webworker.\n\nDefault: `null`\n\n\n</td></tr>\n<tr><td>\n\n[target?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[QwikBuildTarget](#qwikbuildtarget)\n\n\n</td><td>\n\n_(Optional)_ Target `client` or `ssr`<!-- -->.\n\nDefault `client`\n\n\n</td></tr>\n<tr><td>\n\n[transformedModuleOutput?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n((transformedModules: [TransformModule](#transformmodule)<!-- -->\\[\\]) =&gt; Promise&lt;void&gt; \\| void) \\| null\n\n\n</td><td>\n\n_(Optional)_ Hook that's called after the build and provides all of the transformed modules that were used before bundling.\n\n\n</td></tr>\n</tbody></table>",
"content": "```typescript\nexport interface QwikRollupPluginOptions \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[buildMode?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[QwikBuildMode](#qwikbuildmode)\n\n\n</td><td>\n\n_(Optional)_ Build `production` or `development`<!-- -->.\n\nDefault `development`\n\n\n</td></tr>\n<tr><td>\n\n[csr?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[debug?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\n_(Optional)_ Prints verbose Qwik plugin debug logs.\n\nDefault `false`\n\n\n</td></tr>\n<tr><td>\n\n[entryStrategy?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[EntryStrategy](#entrystrategy)\n\n\n</td><td>\n\n_(Optional)_ The Qwik entry strategy to use while building for production. During development the type is always `segment`<!-- -->.\n\nDefault `{ type: \"smart\" }`<!-- -->)\n\n\n</td></tr>\n<tr><td>\n\n[experimental?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(keyof typeof [ExperimentalFeatures](#experimentalfeatures)<!-- -->)\\[\\]\n\n\n</td><td>\n\n_(Optional)_ Experimental features. These can come and go in patch releases, and their API is not guaranteed to be stable between releases.\n\n\n</td></tr>\n<tr><td>\n\n[lint?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\n_(Optional)_ Run eslint on the source files for the ssr build or dev server. This can slow down startup on large projects. Defaults to `true`\n\n\n</td></tr>\n<tr><td>\n\n[manifestInput?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[QwikManifest](#qwikmanifest)\n\n\n</td><td>\n\n_(Optional)_ The SSR build requires the manifest generated during the client build. The `manifestInput` option can be used to manually provide a manifest.\n\nDefault `undefined`\n\n\n</td></tr>\n<tr><td>\n\n[manifestOutput?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(manifest: [QwikManifest](#qwikmanifest)<!-- -->) =&gt; Promise&lt;void&gt; \\| void\n\n\n</td><td>\n\n_(Optional)_ The client build will create a manifest and this hook is called with the generated build data.\n\nDefault `undefined`\n\n\n</td></tr>\n<tr><td>\n\n[optimizerOptions?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[OptimizerOptions](#optimizeroptions)\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[rootDir?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The root of the application, which is commonly the same directory as `package.json` and `rollup.config.js`<!-- -->.\n\nDefault `process.cwd()`\n\n\n</td></tr>\n<tr><td>\n\n[srcDir?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The source directory to find all the Qwik components. Since Qwik does not have a single input, the `srcDir` is used to recursively find Qwik files.\n\nDefault `src`\n\n\n</td></tr>\n<tr><td>\n\n[srcInputs?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[TransformModuleInput](#transformmoduleinput)<!-- -->\\[\\] \\| null\n\n\n</td><td>\n\n_(Optional)_ Alternative to `srcDir`<!-- -->, where `srcInputs` is able to provide the files manually. This option is useful for an environment without a file system, such as a webworker.\n\nDefault: `null`\n\n\n</td></tr>\n<tr><td>\n\n[target?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[QwikBuildTarget](#qwikbuildtarget)\n\n\n</td><td>\n\n_(Optional)_ Target `client` or `ssr`<!-- -->.\n\nDefault `client`\n\n\n</td></tr>\n<tr><td>\n\n[transformedModuleOutput?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n((transformedModules: [TransformModule](#transformmodule)<!-- -->\\[\\]) =&gt; Promise&lt;void&gt; \\| void) \\| null\n\n\n</td><td>\n\n_(Optional)_ Hook that's called after the build and provides all of the transformed modules that were used before bundling.\n\n\n</td></tr>\n</tbody></table>",
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/plugins/rollup.ts",
"mdFile": "qwik.qwikrolluppluginoptions.md"
},
Expand Down Expand Up @@ -856,6 +890,23 @@
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/types.ts",
"mdFile": "qwik.transpileoption.md"
},
{
"name": "valibot",
"id": "experimentalfeatures-valibot",
"hierarchy": [
{
"name": "ExperimentalFeatures",
"id": "experimentalfeatures-valibot"
},
{
"name": "valibot",
"id": "experimentalfeatures-valibot"
}
],
"kind": "EnumMember",
"content": "",
"mdFile": "qwik.experimentalfeatures.valibot.md"
},
{
"name": "versions",
"id": "versions",
Expand Down
66 changes: 64 additions & 2 deletions packages/docs/src/routes/api/qwik-optimizer/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,10 +330,66 @@ export type EntryStrategy =

Use `__EXPERIMENTAL__.x` to check if feature `x` is enabled. It will be replaced with `true` or `false` via an exact string replacement.

Add experimental features to this enum definition.

```typescript
export type ExperimentalFeatures = (typeof experimental)[number];
export declare enum ExperimentalFeatures
```

<table><thead><tr><th>

Member

</th><th>

Value

</th><th>

Description

</th></tr></thead>
<tbody><tr><td>

noSPA

</td><td>

`"noSPA"`

</td><td>

**_(ALPHA)_** Disable SPA navigation handler in Qwik City

</td></tr>
<tr><td>

preventNavigate

</td><td>

`"preventNavigate"`

</td><td>

**_(ALPHA)_** Enable the usePreventNavigate hook

</td></tr>
<tr><td>

valibot

</td><td>

`"valibot"`

</td><td>

**_(ALPHA)_** Enable the Valibot form validation

</td></tr>
</tbody></table>

[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/plugins/plugin.ts)

## extname
Expand Down Expand Up @@ -699,6 +755,8 @@ string

string

## noSPA

## Optimizer

```typescript
Expand Down Expand Up @@ -1204,6 +1262,8 @@ Description

[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/types.ts)

## preventNavigate

## QwikBuildMode

```typescript
Expand Down Expand Up @@ -1620,7 +1680,7 @@ Default `{ type: "smart" }`)

</td><td>

[ExperimentalFeatures](#experimentalfeatures)[]
(keyof typeof [ExperimentalFeatures](#experimentalfeatures))[]

</td><td>

Expand Down Expand Up @@ -3572,6 +3632,8 @@ export type TranspileOption = boolean | undefined | null;

[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/types.ts)

## valibot

## versions

```typescript
Expand Down
10 changes: 6 additions & 4 deletions packages/qwik/src/optimizer/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ export type DiagnosticCategory = 'error' | 'warning' | 'sourceError';
// @public (undocumented)
export type EntryStrategy = InlineEntryStrategy | HoistEntryStrategy | SingleEntryStrategy | HookEntryStrategy_2 | SegmentEntryStrategy | ComponentEntryStrategy | SmartEntryStrategy;

// Warning: (ae-forgotten-export) The symbol "experimental" needs to be exported by the entry point index.d.ts
//
// @alpha
export type ExperimentalFeatures = (typeof experimental)[number];
export enum ExperimentalFeatures {
noSPA = "noSPA",
preventNavigate = "preventNavigate",
valibot = "valibot"
}

// @public (undocumented)
export interface GlobalInjections {
Expand Down Expand Up @@ -225,7 +227,7 @@ export interface QwikRollupPluginOptions {
debug?: boolean;
entryStrategy?: EntryStrategy;
// Warning: (ae-incompatible-release-tags) The symbol "experimental" is marked as @public, but its signature references "ExperimentalFeatures" which is marked as @alpha
experimental?: ExperimentalFeatures[];
experimental?: (keyof typeof ExperimentalFeatures)[];
lint?: boolean;
manifestInput?: QwikManifest;
manifestOutput?: (manifest: QwikManifest) => Promise<void> | void;
Expand Down
30 changes: 15 additions & 15 deletions packages/qwik/src/optimizer/src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,22 @@ const CLIENT_STRIP_CTX_NAME = [
'event$',
];

/** List experimental features here */
export const experimental = [
/** Enable the usePreventNavigate hook */
'preventNavigate',
/** Enable the Valibot form validation */
'valibot',
/** Disable SPA navigation handler in Qwik City */
'noSPA',
] as const;
/**
* Use `__EXPERIMENTAL__.x` to check if feature `x` is enabled. It will be replaced with `true` or
* `false` via an exact string replacement.
*
* Add experimental features to this enum definition.
*
* @alpha
*/
export type ExperimentalFeatures = (typeof experimental)[number];
export enum ExperimentalFeatures {
/** Enable the usePreventNavigate hook */
preventNavigate = 'preventNavigate',
/** Enable the Valibot form validation */
valibot = 'valibot',
/** Disable SPA navigation handler in Qwik City */
noSPA = 'noSPA',
}

export interface QwikPackages {
id: string;
Expand Down Expand Up @@ -334,10 +334,10 @@ export function createPlugin(optimizerOptions: OptimizerOptions = {}) {

opts.experimental = undefined;
for (const feature of updatedOpts.experimental ?? []) {
if (!experimental.includes(feature as ExperimentalFeatures)) {
if (!ExperimentalFeatures[feature as ExperimentalFeatures]) {
console.error(`Qwik plugin: Unknown experimental feature: ${feature}`);
} else {
(opts.experimental ||= {} as any)[feature as ExperimentalFeatures] = true;
(opts.experimental ||= {} as any)[feature] = true;
}
}

Expand Down Expand Up @@ -1051,15 +1051,15 @@ export interface QwikPluginOptions {
lint?: boolean;
/**
* Experimental features. These can come and go in patch releases, and their API is not guaranteed
* to be stable between releases
* to be stable between releases.
*/
experimental?: ExperimentalFeatures[];
experimental?: (keyof typeof ExperimentalFeatures)[];
}

export interface NormalizedQwikPluginOptions
extends Omit<Required<QwikPluginOptions>, 'vendorRoots' | 'experimental'> {
input: string[] | { [entry: string]: string };
experimental?: Record<ExperimentalFeatures, boolean>;
experimental?: Record<keyof typeof ExperimentalFeatures, boolean>;
}

/** @public */
Expand Down
4 changes: 2 additions & 2 deletions packages/qwik/src/optimizer/src/plugins/plugin.unit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path, { resolve } from 'node:path';
import { assert, test } from 'vitest';
import type { QwikManifest } from '../types';
import { createPlugin, experimental } from './plugin';
import { ExperimentalFeatures, createPlugin } from './plugin';
import { normalizePath } from '../../../testing/util';
import { qwikVite } from './vite';

Expand Down Expand Up @@ -209,7 +209,7 @@ test('resolveQwikBuild false', async () => {

test('experimental[]', async () => {
const plugin = await mockPlugin();
const flag = experimental[0];
const flag = Object.values(ExperimentalFeatures)[0];
if (!flag) {
// we can't test this without a flag
return;
Expand Down
4 changes: 2 additions & 2 deletions packages/qwik/src/optimizer/src/plugins/rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ export interface QwikRollupPluginOptions {
* Experimental features. These can come and go in patch releases, and their API is not guaranteed
* to be stable between releases.
*/
experimental?: ExperimentalFeatures[];
experimental?: (keyof typeof ExperimentalFeatures)[];
}
export type { ExperimentalFeatures } from './plugin';
export { ExperimentalFeatures } from './plugin';
type P<T> = Rollup.Plugin<T> & { api: T };
export interface QwikRollupPlugin extends P<QwikRollupPluginApi> {}
4 changes: 2 additions & 2 deletions packages/qwik/src/optimizer/src/plugins/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ interface QwikVitePluginCommonOptions {
* Experimental features. These can come and go in patch releases, and their API is not guaranteed
* to be stable between releases
*/
experimental?: ExperimentalFeatures[];
experimental?: (keyof typeof ExperimentalFeatures)[];
}

interface QwikVitePluginCSROptions extends QwikVitePluginCommonOptions {
Expand Down Expand Up @@ -1080,7 +1080,7 @@ interface QwikVitePluginCSROptions extends QwikVitePluginCommonOptions {

/** @public */
export type QwikVitePluginOptions = QwikVitePluginCSROptions | QwikVitePluginSSROptions;
export type { ExperimentalFeatures } from './plugin';
export { ExperimentalFeatures } from './plugin';

/** @public */
export interface QwikVitePluginApi {
Expand Down

0 comments on commit 60df208

Please sign in to comment.