diff --git a/e2e/adapters-e2e/src/routes/loaders/subpage/index.tsx b/e2e/adapters-e2e/src/routes/loaders/subpage/index.tsx index 41f5c090655..d16bfc3b861 100644 --- a/e2e/adapters-e2e/src/routes/loaders/subpage/index.tsx +++ b/e2e/adapters-e2e/src/routes/loaders/subpage/index.tsx @@ -2,7 +2,8 @@ import { component$ } from '@qwik.dev/core'; import { routeLoader$ } from '@qwik.dev/router'; export const useTest = routeLoader$(async () => { - return 42; + // eslint-disable-next-line @typescript-eslint/await-thenable + return await 42; }); export default component$(() => { diff --git a/e2e/qwik-react-e2e/src/components/counter/index.tsx b/e2e/qwik-react-e2e/src/components/counter/index.tsx index 64fe2694376..51b221c5db2 100644 --- a/e2e/qwik-react-e2e/src/components/counter/index.tsx +++ b/e2e/qwik-react-e2e/src/components/counter/index.tsx @@ -3,8 +3,8 @@ import { useEffect, useState } from 'react'; import { qwikify$ } from '@qwik.dev/react'; interface IProps { - onMount(): void; - onUnmount(): void; + onMount(this: void): void; + onUnmount(this: void): void; } function Counter({ onMount, onUnmount }: IProps) { diff --git a/eslint.config-no-ts.mjs b/eslint.config-no-ts.mjs new file mode 100644 index 00000000000..8c3cd334ebe --- /dev/null +++ b/eslint.config-no-ts.mjs @@ -0,0 +1,160 @@ +import globals from 'globals'; +import js from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import noOnlyTests from 'eslint-plugin-no-only-tests'; +import { globalIgnores } from 'eslint/config'; +// import { qwikEslint9Plugin } from 'eslint-plugin-qwik'; + +const ignores = [ + '**/.history', + '**/.vscode', + '**/dist', + '**/dist-dev', + '**/lib', + '**/node_modules', + '**/tsc-out', + '**/external', + '**/*.', + '**/*.log', + '**/etc', + '**/target', + '**/temp', + '**/tsdoc-metadata.json', + '**/.DS_Store', + '**/*.mp4', + 'scripts', + '**/server/**/*.js', + '**/*.tsbuildinfo', + 'packages/docs/api', + 'packages/docs/public/repl/repl-sw.js*', + 'packages/docs/src/routes/examples/apps', + 'packages/docs/src/routes/playground/app', + 'packages/docs/src/routes/tutorial', + 'packages/qwik/src/optimizer/core/src/fixtures', + 'packages/qwik/bindings', + 'packages/qwik-labs/lib', + 'packages/qwik-labs/lib-types', + 'packages/qwik-labs/vite', + 'packages/insights/drizzle.config.ts', + 'packages/insights/panda.config.ts', + 'packages/qwik/src/napi', + 'starters/apps/base', + 'starters/apps/library', + 'starters/templates', + '**/vite.config.ts', + // packages with eslint.config.mjs + 'packages/qwik-labs', + 'packages/insights', + // eslint.config.* + '**/eslint.config.mjs', + '**/eslint.config.js', + '.changeset', + 'packages/docs/public/builder', +]; + +export default tseslint.config( + globalIgnores(ignores), + js.configs.recommended, + tseslint.configs.recommended, + // qwikEslint9Plugin.configs.recommended, + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + ...globals.es2021, + }, + parserOptions: { + // Needed when using the qwik plugin + // projectService: true, + // tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + plugins: { + 'no-only-tests': noOnlyTests, + }, + rules: { + 'no-only-tests/no-only-tests': 'error', + }, + name: 'no-only-tests', + }, + { + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-empty-interface': 'off', + '@typescript-eslint/no-namespace': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-this-alias': 'off', + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + 'prefer-spread': 'off', + 'no-case-declarations': 'off', + 'no-console': ['error', { allow: ['warn', 'error'] }], + 'no-only-tests/no-only-tests': 'error', + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-var-requires': 'off', + curly: 'error', + 'no-new-func': 'error', + '@typescript-eslint/no-empty-object-type': 'off', + '@typescript-eslint/no-unused-expressions': 'off', + '@typescript-eslint/no-unsafe-function-type': 'off', + '@typescript-eslint/no-require-imports': 'off', + '@typescript-eslint/no-wrapper-object-types': 'off', + }, + }, + { + files: ['packages/docs/**/*.{ts,tsx}'], + rules: { + 'no-console': 'off', + }, + }, + { + files: ['packages/qwik/src/server/**/*.ts'], + ignores: ['packages/qwik/src/server/qwik-copy.ts'], + rules: { + '@typescript-eslint/no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['packages/*'], + message: 'Absolute imports are not allowed.', + }, + { + group: ['../**'], + message: 'Relative imports are not allowed.', + }, + ], + }, + ], + 'no-duplicate-imports': 'error', + }, + }, + { + files: ['packages/qwik/src/server/qwik-types.ts'], + rules: { + '@typescript-eslint/no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['packages/*'], + message: 'Absolute imports are not allowed.', + allowTypeImports: true, + }, + { + group: ['../**'], + message: 'Relative imports are not allowed.', + allowTypeImports: true, + }, + ], + }, + ], + }, + } +); diff --git a/eslint.config.mjs b/eslint.config.mjs index 8c3cd334ebe..abc29e65258 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,160 +1,26 @@ -import globals from 'globals'; -import js from '@eslint/js'; import tseslint from 'typescript-eslint'; -import noOnlyTests from 'eslint-plugin-no-only-tests'; -import { globalIgnores } from 'eslint/config'; -// import { qwikEslint9Plugin } from 'eslint-plugin-qwik'; - -const ignores = [ - '**/.history', - '**/.vscode', - '**/dist', - '**/dist-dev', - '**/lib', - '**/node_modules', - '**/tsc-out', - '**/external', - '**/*.', - '**/*.log', - '**/etc', - '**/target', - '**/temp', - '**/tsdoc-metadata.json', - '**/.DS_Store', - '**/*.mp4', - 'scripts', - '**/server/**/*.js', - '**/*.tsbuildinfo', - 'packages/docs/api', - 'packages/docs/public/repl/repl-sw.js*', - 'packages/docs/src/routes/examples/apps', - 'packages/docs/src/routes/playground/app', - 'packages/docs/src/routes/tutorial', - 'packages/qwik/src/optimizer/core/src/fixtures', - 'packages/qwik/bindings', - 'packages/qwik-labs/lib', - 'packages/qwik-labs/lib-types', - 'packages/qwik-labs/vite', - 'packages/insights/drizzle.config.ts', - 'packages/insights/panda.config.ts', - 'packages/qwik/src/napi', - 'starters/apps/base', - 'starters/apps/library', - 'starters/templates', - '**/vite.config.ts', - // packages with eslint.config.mjs - 'packages/qwik-labs', - 'packages/insights', - // eslint.config.* - '**/eslint.config.mjs', - '**/eslint.config.js', - '.changeset', - 'packages/docs/public/builder', -]; +import baseConfig from './eslint.config-no-ts.mjs'; +// We enable TS processing here, which will run in the IDE. export default tseslint.config( - globalIgnores(ignores), - js.configs.recommended, - tseslint.configs.recommended, - // qwikEslint9Plugin.configs.recommended, + baseConfig, { languageOptions: { - globals: { - ...globals.browser, - ...globals.node, - ...globals.es2021, - }, parserOptions: { - // Needed when using the qwik plugin - // projectService: true, - // tsconfigRootDir: import.meta.dirname, + // Enables TS processing, uses lots of memory and CPU + projectService: true, + tsconfigRootDir: import.meta.dirname, }, }, }, + tseslint.configs.recommendedTypeChecked, { - plugins: { - 'no-only-tests': noOnlyTests, - }, - rules: { - 'no-only-tests/no-only-tests': 'error', - }, - name: 'no-only-tests', - }, - { - rules: { - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-inferrable-types': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-empty-interface': 'off', - '@typescript-eslint/no-namespace': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-this-alias': 'off', - '@typescript-eslint/ban-types': 'off', - '@typescript-eslint/ban-ts-comment': 'off', - 'prefer-spread': 'off', - 'no-case-declarations': 'off', - 'no-console': ['error', { allow: ['warn', 'error'] }], - 'no-only-tests/no-only-tests': 'error', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/no-var-requires': 'off', - curly: 'error', - 'no-new-func': 'error', - '@typescript-eslint/no-empty-object-type': 'off', - '@typescript-eslint/no-unused-expressions': 'off', - '@typescript-eslint/no-unsafe-function-type': 'off', - '@typescript-eslint/no-require-imports': 'off', - '@typescript-eslint/no-wrapper-object-types': 'off', - }, - }, - { - files: ['packages/docs/**/*.{ts,tsx}'], - rules: { - 'no-console': 'off', - }, - }, - { - files: ['packages/qwik/src/server/**/*.ts'], - ignores: ['packages/qwik/src/server/qwik-copy.ts'], - rules: { - '@typescript-eslint/no-restricted-imports': [ - 'error', - { - patterns: [ - { - group: ['packages/*'], - message: 'Absolute imports are not allowed.', - }, - { - group: ['../**'], - message: 'Relative imports are not allowed.', - }, - ], - }, - ], - 'no-duplicate-imports': 'error', - }, - }, - { - files: ['packages/qwik/src/server/qwik-types.ts'], rules: { - '@typescript-eslint/no-restricted-imports': [ - 'error', - { - patterns: [ - { - group: ['packages/*'], - message: 'Absolute imports are not allowed.', - allowTypeImports: true, - }, - { - group: ['../**'], - message: 'Relative imports are not allowed.', - allowTypeImports: true, - }, - ], - }, - ], + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unsafe-return': 'warn', + '@typescript-eslint/no-unsafe-argument': 'warn', + '@typescript-eslint/no-unsafe-member-access': 'warn', + '@typescript-eslint/no-unsafe-assignment': 'off', }, } ); diff --git a/package.json b/package.json index 505bf216d6a..b5bfca33518 100644 --- a/package.json +++ b/package.json @@ -212,8 +212,8 @@ "link.dist.npm": "cd packages/qwik && npm link && cd ../qwik-router && npm link && cd ../eslint-plugin-qwik && npm link && cd ../qwik-react && npm link", "link.dist.yarn": "cd packages/qwik && yarn link && cd ../qwik-router && yarn link && cd ../eslint-plugin-qwik && yarn link && cd ../qwik-react && yarn link", "lint": "pnpm lint.eslint && pnpm lint.prettier && pnpm lint.rust", - "lint.eslint": "eslint --cache \"**/*.ts*\" && pnpm -r --parallel lint", - "lint.fix": "eslint --fix \"**/*.ts*\" && pnpm -r --parallel lint.fix && pnpm prettier.fix", + "lint.eslint": "eslint -c eslint.config-no-ts.mjs && pnpm -r --parallel lint", + "lint.fix": "eslint --fix -c eslint.config-no-ts.mjs && pnpm -r --parallel lint.fix && pnpm prettier.fix", "lint.prettier": "prettier --cache --check .", "lint.rust": "make lint", "lint.syncpack": "syncpack list-mismatches", diff --git a/packages/qwik-react/src/react/qwikify.tsx b/packages/qwik-react/src/react/qwikify.tsx index 1a61506d08f..a650baa9bbe 100644 --- a/packages/qwik-react/src/react/qwikify.tsx +++ b/packages/qwik-react/src/react/qwikify.tsx @@ -22,8 +22,8 @@ import { renderFromServer } from './server-render'; import { getHostProps, main, mainExactProps, useWakeupSignal } from './slot'; import type { Internal, QwikifyOptions, QwikifyProps } from './types'; -export function qwikifyQrl>( - reactCmp$: QRL>, +export function qwikifyQrl>( + reactCmp$: QRL>, opts?: QwikifyOptions ) { return component$((props: QwikifyProps) => { @@ -35,7 +35,7 @@ export function qwikifyQrl>( const internalState = useSignal>>(); const [signal, isClientOnly] = useWakeupSignal(props, opts); const hydrationKeys = useStore({}); - const TagName = opts?.tagName ?? ('qwik-react' as any); + const TagName = opts?.tagName ?? 'qwik-react'; // Task takes cares of updates and partial hydration useTask$(async ({ track }) => { diff --git a/packages/qwik/src/core/reactive-primitives/impl/wrapped-signal-impl.ts b/packages/qwik/src/core/reactive-primitives/impl/wrapped-signal-impl.ts index 4810bc624ab..89253fb4aab 100644 --- a/packages/qwik/src/core/reactive-primitives/impl/wrapped-signal-impl.ts +++ b/packages/qwik/src/core/reactive-primitives/impl/wrapped-signal-impl.ts @@ -15,29 +15,23 @@ import { import { scheduleEffects } from '../utils'; import { SignalImpl } from './signal-impl'; -export class WrappedSignalImpl extends SignalImpl implements BackRef { - $args$: any[]; - $func$: (...args: any[]) => T; - $funcStr$: string | null; - - $flags$: AllSignalFlags; +export class WrappedSignalImpl + extends SignalImpl + implements BackRef +{ $hostElement$: HostElement | null = null; [_EFFECT_BACK_REF]: Map | null = null; constructor( container: Container | null, - fn: (...args: any[]) => T, - args: any[], - fnStr: string | null, + public $func$: (...args: A) => T, + public $args$: A, + public $funcStr$: string | null, // We need a separate flag to know when the computation needs running because // we need the old value to know if effects need running after computation - flags: SignalFlags = SignalFlags.INVALID | WrappedSignalFlags.UNWRAP + public $flags$: AllSignalFlags = SignalFlags.INVALID | WrappedSignalFlags.UNWRAP ) { - super(container, NEEDS_COMPUTATION); - this.$args$ = args; - this.$func$ = fn; - this.$funcStr$ = fnStr; - this.$flags$ = flags; + super(container, NEEDS_COMPUTATION as T); } invalidate() { @@ -46,7 +40,7 @@ export class WrappedSignalImpl extends SignalImpl implements BackRef { // for many signals. If it fails, we schedule a chore to run the computation. try { this.$computeIfNeeded$(); - } catch (_) { + } catch { this.$container$?.$scheduler$( ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS, this.$hostElement$, @@ -107,7 +101,7 @@ export class WrappedSignalImpl extends SignalImpl implements BackRef { } } // Make this signal read-only - set value(_: any) { + set value(_: T) { throw qError(QError.wrappedReadOnly); } // Getters don't get inherited when overriding a setter diff --git a/packages/qwik/src/core/reactive-primitives/internal-api.ts b/packages/qwik/src/core/reactive-primitives/internal-api.ts index 7a9e169d589..0e91dc679ed 100644 --- a/packages/qwik/src/core/reactive-primitives/internal-api.ts +++ b/packages/qwik/src/core/reactive-primitives/internal-api.ts @@ -1,7 +1,7 @@ import { _CONST_PROPS, _IMMUTABLE } from '../shared/utils/constants'; import { assertEqual } from '../shared/error/assert'; import { isObject } from '../shared/utils/types'; -import { isSignal } from './signal.public'; +import { isSignal, type Signal } from './signal.public'; import { getStoreTarget } from './impl/store'; import { isPropsProxy } from '../shared/jsx/jsx-runtime'; import { WrappedSignalFlags } from './types'; @@ -9,12 +9,21 @@ import { WrappedSignalImpl } from './impl/wrapped-signal-impl'; import { AsyncComputedSignalImpl } from './impl/async-computed-signal-impl'; // Keep these properties named like this so they're the same as from wrapSignal -const getValueProp = (p0: any) => p0.value; -const getProp = (p0: any, p1: string) => p0[p1]; +const getValueProp = (p0: { value: T }) => p0.value; +const getProp = (p0: T, p1: P) => p0[p1]; -const getWrapped = (args: any[]) => +const getWrapped = (args: [T, (keyof T | undefined)?]) => new WrappedSignalImpl(null, args.length === 1 ? getValueProp : getProp, args, null); +type PropType = P extends keyof T + ? T[P] + : 'value' extends keyof T + ? T['value'] + : never; +type WrappedProp = T extends Signal + ? WrappedSignalImpl> + : PropType; + /** * This wraps a property access of a possible Signal/Store into a WrappedSignal. The optimizer does * this automatically when a prop is only used as a prop on JSX. @@ -26,7 +35,9 @@ const getWrapped = (args: any[]) => * * @internal */ -export const _wrapProp = , P extends keyof T>(...args: [T, P?]): any => { +export const _wrapProp = ( + ...args: [T, P?] +): WrappedProp => { const obj = args[0]; const prop = args.length < 2 ? 'value' : args[1]!; @@ -37,37 +48,34 @@ export const _wrapProp = , P extends keyof T>(...args if (!(obj instanceof AsyncComputedSignalImpl)) { assertEqual(prop, 'value', 'Left side is a signal, prop must be value'); } - if (obj instanceof WrappedSignalImpl && obj.flags & WrappedSignalFlags.UNWRAP) { - return obj; + if (obj instanceof WrappedSignalImpl && obj.$flags$ & WrappedSignalFlags.UNWRAP) { + return obj as WrappedProp; } - return getWrapped(args); + return getWrapped(args) as WrappedProp; } if (isPropsProxy(obj)) { - const constProps = obj[_CONST_PROPS] as any; + const constProps = obj[_CONST_PROPS]; if (constProps && prop in constProps) { // Const props don't need wrapping - return constProps[prop]; + return constProps[prop as keyof typeof constProps] as WrappedProp; } } else { const target = getStoreTarget(obj); if (target) { - const value = target[prop]; + const value = target[prop as P]; const wrappedValue = isSignal(value) ? // If the value is already a signal, we don't need to wrap it again value : getWrapped(args); - return wrappedValue; + return wrappedValue as WrappedProp; } } // the object is not reactive, so we can just return the value - return obj[prop]; + return obj[prop as P] as WrappedProp; }; /** @internal @deprecated v1 compat */ -export const _wrapSignal = , P extends keyof T>( - obj: T, - prop: P -): any => { +export const _wrapSignal = (obj: T, prop: P) => { const r = _wrapProp(obj, prop); if (r === _IMMUTABLE) { return obj[prop]; diff --git a/packages/qwik/src/core/reactive-primitives/types.ts b/packages/qwik/src/core/reactive-primitives/types.ts index 0642837c31e..ab5215f664a 100644 --- a/packages/qwik/src/core/reactive-primitives/types.ts +++ b/packages/qwik/src/core/reactive-primitives/types.ts @@ -22,7 +22,7 @@ import type { VNode } from '../client/vnode-impl'; * Special value used to mark that a given signal needs to be computed. This is essentially a * "marked as dirty" flag. */ -export const NEEDS_COMPUTATION: any = Symbol('invalid'); +export const NEEDS_COMPUTATION = Symbol('invalid'); /** @internal */ export const _EFFECT_BACK_REF = Symbol('backRef'); diff --git a/packages/qwik/src/core/shared/serdes/serdes.unit.ts b/packages/qwik/src/core/shared/serdes/serdes.unit.ts index 38b1fcb0067..a210f0df805 100644 --- a/packages/qwik/src/core/shared/serdes/serdes.unit.ts +++ b/packages/qwik/src/core/shared/serdes/serdes.unit.ts @@ -1,34 +1,35 @@ +/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */ import { $, componentQrl, noSerialize } from '@qwik.dev/core'; import { describe, expect, it, vi } from 'vitest'; -import { _fnSignal, _serializationWeakRef, _UNINITIALIZED, _wrapProp } from '../../internal'; +import { + _constants, + _createDeserializeContainer, + _typeIdNames, + createSerializationContext, + dumpState, + TypeIds, +} from '.'; +import { _fnSignal, _serializationWeakRef, _wrapProp } from '../../internal'; import { type SignalImpl } from '../../reactive-primitives/impl/signal-impl'; +import { createStore } from '../../reactive-primitives/impl/store'; +import { createAsyncComputedSignal } from '../../reactive-primitives/signal-api'; import { createComputedQrl, createSerializerQrl, createSignal, isSignal, } from '../../reactive-primitives/signal.public'; -import { createStore } from '../../reactive-primitives/impl/store'; +import { SubscriptionData } from '../../reactive-primitives/subscription-data'; +import { StoreFlags } from '../../reactive-primitives/types'; import { createResourceReturn } from '../../use/use-resource'; import { Task } from '../../use/use-task'; +import { QError } from '../error/error'; import { inlinedQrl } from '../qrl/qrl'; import { createQRL, type QRLInternal } from '../qrl/qrl-class'; -import { - TypeIds, - _constants, - _createDeserializeContainer, - _typeIdNames, - createSerializationContext, - dumpState, -} from '.'; -import { EMPTY_ARRAY, EMPTY_OBJ } from '../utils/flyweight'; import { isQrl } from '../qrl/qrl-utils'; -import { NoSerializeSymbol, SerializerSymbol } from '../utils/serialize-utils'; -import { SubscriptionData } from '../../reactive-primitives/subscription-data'; -import { StoreFlags } from '../../reactive-primitives/types'; -import { createAsyncComputedSignal } from '../../reactive-primitives/signal-api'; +import { EMPTY_ARRAY, EMPTY_OBJ } from '../utils/flyweight'; import { retryOnPromise } from '../utils/promises'; -import { QError } from '../error/error'; +import { NoSerializeSymbol, SerializerSymbol } from '../utils/serialize-utils'; const DEBUG = false; @@ -40,7 +41,7 @@ describe('shared-serialization', () => { const shared2 = { shared: 2 }; describe('serialize types', () => { - const dump = async (...value: any) => dumpState(await serialize(...value)); + const dump = async (...value: unknown[]) => dumpState(await serialize(...value)); it(title(TypeIds.Plain), async () => { expect(await dump('hi', 123.456)).toMatchInlineSnapshot(` " @@ -180,7 +181,7 @@ describe('shared-serialization', () => { err.stack = err .stack!.replaceAll(/([A-Z]:){0,1}(\/|\\).*\./g, '/...path/file.') .replaceAll(/:\d+:\d+/g, ':123:456'); - const dumpNoSize = async (obj: any) => + const dumpNoSize = async (obj: unknown) => (await dump(obj)).replaceAll(/\(\d+ chars\)/g, '(x chars)'); expect(await dumpNoSize(err)).toMatchInlineSnapshot(` " @@ -191,7 +192,7 @@ describe('shared-serialization', () => { ] (x chars)" `); - (err as any).extra = 'yey'; + (err as Error & { extra: string }).extra = 'yey'; expect(await dumpNoSize(err)).toMatchInlineSnapshot(` " 0 Error [ @@ -285,7 +286,7 @@ describe('shared-serialization', () => { it(title(TypeIds.Map), async () => { expect( await dump( - new Map([ + new Map([ ['shared', shared1], [shared2, shared1], ]) diff --git a/packages/qwik/src/core/shared/serdes/serialize.ts b/packages/qwik/src/core/shared/serdes/serialize.ts index 49908f47662..5696cdbac85 100644 --- a/packages/qwik/src/core/shared/serdes/serialize.ts +++ b/packages/qwik/src/core/shared/serdes/serialize.ts @@ -43,6 +43,8 @@ import { type SerializationContext, } from './index'; +type SerOutput = number | string | SerOutput[]; + /** * Format: * @@ -87,7 +89,7 @@ export async function serialize(serializationContext: SerializationContext): Pro $writer$.write(']'); }; - const output = (type: number, value: number | string | any[]) => { + const output = (type: number, value: number | string | unknown[]) => { $writer$.write(`${type},`); if (typeof value === 'number') { $writer$.write(value.toString()); @@ -152,7 +154,7 @@ export async function serialize(serializationContext: SerializationContext): Pro }; const writeValue = (value: unknown) => { - if (fastSkipSerialize(value as object | Function)) { + if (fastSkipSerialize(value as object)) { output(TypeIds.Constant, Constants.Undefined); } else if (typeof value === 'bigint') { output(TypeIds.BigInt, value.toString()); diff --git a/packages/qwik/src/optimizer/src/plugins/vite.ts b/packages/qwik/src/optimizer/src/plugins/vite.ts index fc33d4ed2de..bfffe86cdab 100644 --- a/packages/qwik/src/optimizer/src/plugins/vite.ts +++ b/packages/qwik/src/optimizer/src/plugins/vite.ts @@ -357,7 +357,7 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any { qwikPlugin.setSourceMapSupport(true); } // Ensure that the final settings are applied - qwikPlugin.normalizeOptions(qwikViteOpts); + await qwikPlugin.normalizeOptions(qwikViteOpts); }, async buildStart() { diff --git a/packages/qwik/src/server/ssr-container.ts b/packages/qwik/src/server/ssr-container.ts index efd0218ee2a..3bb9c849a38 100644 --- a/packages/qwik/src/server/ssr-container.ts +++ b/packages/qwik/src/server/ssr-container.ts @@ -610,7 +610,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { private _styleNode(styleId: string, content: string) { this.openElement('style', [QStyle, styleId]); this.write(content); - this.closeElement(); + this._closeElement(); } //////////////////////////////////// @@ -792,7 +792,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { } } - this.closeElement(); + this._closeElement(); } private emitStateData(): ValueOrPromise { @@ -801,7 +801,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { } this.openElement('script', ['type', 'qwik/state']); return maybeThen(this.serializationCtx.$serialize$(), () => { - this.closeElement(); + this._closeElement(); }); } @@ -817,7 +817,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { this.write('['); this.writeArray(fns, ','); this.write(']'); - this.closeElement(); + this._closeElement(); } } @@ -839,7 +839,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { } this.openElement('script', scriptAttrs); this.write(JSON.stringify(patches)); - this.closeElement(); + this._closeElement(); } } @@ -857,7 +857,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { const backpatchScript = getQwikBackpatchExecutorScript({ debug: isDev }); this.write(backpatchScript); - this.closeElement(); + this._closeElement(); } emitPreloaderPre() { @@ -886,13 +886,13 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { linkAttrs.push('nonce', nonce); } this.openElement('link', linkAttrs); - this.closeElement(); + this._closeElement(); const scriptAttrs = ['type', 'module', 'async', true, 'src', qwikLoaderBundle]; if (nonce) { scriptAttrs.push('nonce', nonce); } this.openElement('script', scriptAttrs); - this.closeElement(); + this._closeElement(); } } } @@ -916,7 +916,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { } this.openElement('script', scriptAttrs); this.write(qwikLoaderScript); - this.closeElement(); + this._closeElement(); } } @@ -933,7 +933,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { this.write(`(window.qwikevents||(window.qwikevents=[])).push(`); this.writeArray(eventNames, ', '); this.write(')'); - this.closeElement(); + this._closeElement(); } } @@ -994,7 +994,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { throw Error(); // 'should not get here' } } - this.closeElement(); + this._closeElement(); } finally { this.currentComponentNode = previousCurrentComponentNode; } diff --git a/packages/qwik/src/testing/html.ts b/packages/qwik/src/testing/html.ts index 057c9ca4ed6..192814096d5 100644 --- a/packages/qwik/src/testing/html.ts +++ b/packages/qwik/src/testing/html.ts @@ -6,7 +6,7 @@ export function isTemplate(node: Node | null | undefined): node is HTMLTemplateE return tagName.toUpperCase() == 'TEMPLATE'; } -export function prettyHtml(element: HTMLElement, prefix: string = ''): any { +export function prettyHtml(element: HTMLElement, prefix: string = ''): string { const lines = []; lines.push(prefix, '<', element.localName); const attrs = Array.from(element.attributes) @@ -52,10 +52,10 @@ export function prettyHtml(element: HTMLElement, prefix: string = ''): any { return lines.join(''); } -export function isElement(value: any): value is HTMLElement { +export function isElement(value: unknown): value is HTMLElement { return isNode(value) && value.nodeType === 1; } -export function isNode(value: any): value is Node { - return value && typeof value.nodeType === 'number'; +export function isNode(value: unknown): value is Node { + return value ? typeof (value as Node).nodeType === 'number' : false; } diff --git a/packages/qwik/src/web-worker/index.ts b/packages/qwik/src/web-worker/index.ts index 0dc259258c5..9fb5ecc6cff 100644 --- a/packages/qwik/src/web-worker/index.ts +++ b/packages/qwik/src/web-worker/index.ts @@ -1,15 +1,11 @@ -//@ts-ignore import { implicit$FirstArg } from '../core/shared/qrl/implicit_dollar'; import { $, type QRL } from '../core/shared/qrl/qrl.public'; import { _serialize } from '../core/shared/serdes/index'; import { _getContextElement } from '../core/use/use-core'; import workerUrl from './worker.js?worker&url'; -export interface ServerFunction { - (...args: any[]): any; -} export interface WorkerConstructorQRL { - (fnQrl: QRL): QRL; + any>(fnQrl: QRL): QRL; } const qwikWorkers = new Map(); @@ -44,7 +40,7 @@ export const workerQrl: WorkerConstructorQRL = (qrl) => { 'worker$ is experimental and must be enabled with `experimental: ["webWorker"]` in the `qwikVite` plugin.' ); } - return $(async (...args: any[]) => { + return $(async (...args: unknown[]) => { const containerEl = (_getContextElement() as HTMLElement | undefined)?.closest( '[q\\:container]:not([q\\:container=html]):not([q\\:container=text])' diff --git a/packages/qwik/tsconfig.json b/packages/qwik/tsconfig.json index 1cef2dd5506..ebdfbe63ee4 100644 --- a/packages/qwik/tsconfig.json +++ b/packages/qwik/tsconfig.json @@ -18,6 +18,6 @@ "@qwik-client-manifest": ["packages/qwik/src/server/server-modules.d.ts"] } }, - "include": ["src", "global.d.ts"], + "include": ["."], "exclude": ["dist"] } diff --git a/starters/apps/e2e/src/components/qrl/qrl.tsx b/starters/apps/e2e/src/components/qrl/qrl.tsx index ebc90e951c6..370599f1a9e 100644 --- a/starters/apps/e2e/src/components/qrl/qrl.tsx +++ b/starters/apps/e2e/src/components/qrl/qrl.tsx @@ -20,9 +20,7 @@ export const InnerComputedButton = component$((props) => { props.test.value; }); - const handleClick = $(() => { - syncSelection(); - }); + const handleClick = $(() => syncSelection()); return (