diff --git a/.gitignore b/.gitignore index ee47302..4231334 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ coverage # In case contributors use yarn (just prevent it from being committed). Standardizing on npm for broad compatibility. yarn.lock + +# Ignore autogenerated .d.ts (and associated .map) files since this are automatically generated prior to publish to NPM. +*.d.ts* diff --git a/README.md b/README.md index 0d193c3..db4ddf9 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ Changes since forking from [`svelte-tag`](https://github.com/crisward/svelte-tag - Add step-by-step instructions and provided a simple MVP example (https://github.com/patricknelson/svelte-retag/pull/24) - Automatically forward all attributes to component (i.e. `attributes: true`) (https://github.com/patricknelson/svelte-retag/issues/34) +- Add better TypeScript support (https://github.com/patricknelson/svelte-retag/pull/33) ### v2 diff --git a/index.js b/index.js index e2d73df..ac541b7 100644 --- a/index.js +++ b/index.js @@ -66,24 +66,29 @@ function renderElements(timestamp) { } +/** + * @typedef {new(...args: any[]) => any} Newable Type alias for a really generic class constructor + * @typedef {Newable} CmpConstructor Svelte component class constructor (basically a "newable" object) + */ + /** * Please see README.md for usage information. * * @param {object} opts Custom element options * - * @param {any} opts.component Svelte component instance to incorporate into your custom element. - * @param {string} opts.tagname Name of the custom element tag you'd like to define. - * @param {string[]|boolean|undefined} opts.attributes Optional array of attributes that should be reactively forwarded to the component when modified. Set to true to automatically watch all attributes. - * @param {boolean?} opts.shadow Indicates if we should build the component in the shadow root instead of in the regular ("light") DOM. - * @param {string?} opts.href URL to the CSS stylesheet to incorporate into the shadow DOM (if enabled). + * @param {CmpConstructor} opts.component The Svelte component *class* constructor to incorporate into your custom element (this is the imported component class, *not* an instance) + * @param {string} opts.tagname Name of the custom element tag you'd like to define. + * @param {string[]|boolean} [opts.attributes=[]] Optional array of attributes that should be reactively forwarded to the component when modified. Set to true to automatically watch all attributes. + * @param {boolean} [opts.shadow=false] Indicates if we should build the component in the shadow root instead of in the regular ("light") DOM. + * @param {string} [opts.href=""] URL to the CSS stylesheet to incorporate into the shadow DOM (if enabled). * * Experimental: - * @param {boolean?} opts.hydratable Light DOM slot hydration (specific to svelte-retag): Enables pre-rendering of the - * web component (e.g. SSR) by adding extra markers (attributes & wrappers) during - * rendering to enable svelte-retag to find and restore light DOM slots when - * restoring interactivity. + * @param {boolean} [opts.hydratable=false] EXPERIMENTAL.Light DOM slot hydration (specific to svelte-retag): Enables + * pre-rendering of the web component (e.g. SSR) by adding extra markers + * (attributes & wrappers) during rendering to enable svelte-retag to find and + * restore light DOM slots when restoring interactivity. See README.md for more. * - * @param {boolean|string?} opts.debugMode Hidden option to enable debugging for package development purposes. + * @param {boolean|string} [opts.debugMode=false] Hidden option to enable debugging for package development purposes. */ export default function svelteRetag(opts) { /** diff --git a/package-lock.json b/package-lock.json index 0e5fcdf..28557db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "svelte-retag", - "version": "1.3.8", + "version": "1.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "svelte-retag", - "version": "1.3.8", + "version": "1.4.0", "license": "MIT", "devDependencies": { "@sveltejs/adapter-auto": "^2.1.1", @@ -15,6 +15,7 @@ "eslint-plugin-svelte": "^2.35.1", "jsdom": "^22.1.0", "svelte": "^4.2.8", + "typescript": "^5.3.3", "vite": "^4.5.1", "vitest": "^0.25.8" }, @@ -2732,6 +2733,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undici": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", @@ -4901,6 +4915,12 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true + }, "undici": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", diff --git a/package.json b/package.json index 525f0d3..beba24b 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,13 @@ "version": "1.4.0", "description": "Light DOM custom element wrapper for Svelte 3 and 4 with slots, context and Vite HMR support", "main": "index.js", + "types": "./types/index.d.ts", "scripts": { "test": "npm run eslint && vitest run", "vitest": "vitest run", "eslint": "eslint index.js tests/*", - "pub": "npm run test && npm run eslint && npm publish" + "build": "tsc --emitDeclarationOnly", + "pub": "npm run test && npm run eslint && npm run build && npm publish" }, "repository": { "type": "git", @@ -23,6 +25,7 @@ "eslint-plugin-svelte": "^2.35.1", "jsdom": "^22.1.0", "svelte": "^4.2.8", + "typescript": "^5.3.3", "vite": "^4.5.1", "vitest": "^0.25.8" }, diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a238c93 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + // Only needed for JS files in the project root (exclude vite config). + "include": ["*.js"], + "exclude": ["vite.config.js"], + + // See: https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html + "compilerOptions": { + // Tells TypeScript to read JS files, as + // normally they are ignored as source files + "allowJs": true, + // Generate d.ts files + "declaration": true, + // This compiler run should + // only output d.ts files + "emitDeclarationOnly": true, + // Types should go into this directory. + // Removing this would place the .d.ts files + // next to the .js files + "outDir": "types", + // go to js file when using IDE functions like + // "Go to Definition" in VSCode + "declarationMap": true + } +}