From b2fcf6a17462a72aa072bbcfdd08c1e97f6bfd8d Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Thu, 14 Sep 2023 14:36:52 +1000 Subject: [PATCH 01/11] update README.md: fix default banner link Media query links work but the fallback had an extra path segment due to bad copy + paste. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 98ec6b9..f19dff1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ - Project Banner (@nxtlvlsoftware/alpine-typescript) + Project Banner (@nxtlvlsoftware/alpine-typescript)

From 1ba2ec7a3aad7e721de8ff0ebb1cf90717448af9 Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Thu, 14 Sep 2023 14:38:14 +1000 Subject: [PATCH 02/11] update package.json: add module type field, reorganise fields + bump version for next release --- package.json | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 6ebf4ef..f13bbba 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,10 @@ { "name": "@nxtlvlsoftware/alpine-typescript", - "version": "0.0.1", "description": "Typescript definitions for Alpine.js.", + "version": "0.0.3", + "author": "Jack Noordhuis ", + "license": "MIT", + "type": "module", "main": "index.js", "files": [ "README.md", @@ -11,6 +14,12 @@ "index.d.ts", "index.js" ], + "keywords": [ + "alpine", + "alpine.js", + "typescript", + "components" + ], "scripts": { "build": "tsc --inlineSourceMap --removeComments -p ./", "build-ci": "tsc --pretty false --inlineSourceMap --removeComments --listEmittedFiles -p ./", @@ -18,14 +27,6 @@ "docs": "npx typedoc --plugin typedoc-plugin-extras --out docs-build --cacheBust index.ts", "docs-ci": "npx typedoc --plugin typedoc-plugin-extras --gitRemote dist --out docs-build --cacheBust index.ts" }, - "keywords": [ - "alpine", - "alpine.js", - "typescript", - "components" - ], - "author": "Jack Noordhuis ", - "license": "MIT", "dependencies": { "@types/alpinejs": "^3.7.2" }, From 6b1355a274434ffa7e9cbf254c5d5f4a3d9a5acf Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 11:45:13 +1000 Subject: [PATCH 03/11] fix formatting/code style --- index.ts | 4 ++-- src/Global.ts | 4 ++-- src/Plugin.ts | 5 +++-- src/Store.ts | 21 ++++++++++++--------- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/index.ts b/index.ts index cdd4f46..ce814b9 100644 --- a/index.ts +++ b/index.ts @@ -9,14 +9,14 @@ export { type AlpineDataContext, type AlpineData, AlpineComponent -} from './src/Component' +} from './src/Component'; export { type ComponentList, ComponentStore, transformToAlpineData, makeAlpineConstructor -} from './src/Store' +} from './src/Store'; export * as Globals from './src/Global'; diff --git a/src/Global.ts b/src/Global.ts index 4089a33..717cdbe 100644 --- a/src/Global.ts +++ b/src/Global.ts @@ -2,8 +2,8 @@ * Type declarations for Alpine and browser window global. */ import type {Alpine as AlpineType} from 'alpinejs'; -import type {ComponentStore} from "./Store"; -import type {AlpineComponentConstructor} from "./Component"; +import type {ComponentStore} from './Store'; +import type {AlpineComponentConstructor} from './Component'; /** * Define the properties we add to the window.Alpine object. diff --git a/src/Plugin.ts b/src/Plugin.ts index ecc7e21..8f9540b 100644 --- a/src/Plugin.ts +++ b/src/Plugin.ts @@ -1,8 +1,9 @@ -import type * as Globals from './Global' +import Alpine from 'alpinejs'; +import type * as Globals from './Global'; import { type ComponentList, ComponentStore -} from "./Store"; +} from './Store'; export namespace AlpineComponents { diff --git a/src/Store.ts b/src/Store.ts index e639d4d..909a205 100644 --- a/src/Store.ts +++ b/src/Store.ts @@ -1,7 +1,7 @@ -import type * as Impl from "./Component" -import type * as Globals from './Global' +import type * as Impl from './Component'; +import type * as Globals from './Global'; -import {AlpineComponent, type AlpineComponentConstructor} from "./Component"; +import {AlpineComponent, type AlpineComponentConstructor} from './Component'; /** * @see https://www.w3schools.com/js/js_reserved.asp @@ -24,7 +24,10 @@ export type ComponentList = { /** * Internal type for component registration. */ -type ComponentConstructorData = { name: string, constructor: Impl.AlpineComponentConstructor }; +type ComponentConstructorData = { + name: string, + constructor: Impl.AlpineComponentConstructor +}; enum RegisterComponentFailure { GenericMustHaveFunctionAsSecond, @@ -43,11 +46,11 @@ export class ComponentStore { components: ComponentList = {}, private logErrors: boolean = false ) { - Object.entries(components).forEach(([name, component]) => { + Object.entries(components).forEach(([name, component]): void => { this.register(name, component); }); - window.addEventListener('alpine:init', () => { + window.addEventListener('alpine:init', (): void => { this.init(); }); } @@ -187,7 +190,7 @@ export class ComponentStore { console.error(`Cannot register component with provided argument types. Check Typescript definitions for usage.`); break; case RegisterComponentFailure.ReservedName: - console.error(`Cannot register component with name matching a reserved keyword.`) + console.error(`Cannot register component with name matching a reserved keyword.`); break; } } @@ -206,7 +209,7 @@ export function transformToAlpineData(instance: T): o prototype.constructor.name !== 'Object'; prototype = Object.getPrototypeOf(prototype) ) { - Object.getOwnPropertyNames(prototype).forEach((name: string) => { + Object.getOwnPropertyNames(prototype).forEach((name: string): void => { if (methodNames.includes(name)) { return; } @@ -217,7 +220,7 @@ export function transformToAlpineData(instance: T): o return [ ...methodNames, // methods ...Object.getOwnPropertyNames(instance) // properties - ].reduce((obj, name) => { + ].reduce((obj: {}, name: string) => { // @ts-ignore obj[name] = instance[name]; From 503448df4a73158cd004cf6bd32b7dc064348ed0 Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 11:46:42 +1000 Subject: [PATCH 04/11] Plugin.ts: Add option for bootstrapping alpine (defaults to false) * Allows setting window.Alpine inside AlpineComponents.bootstrap() call --- src/Plugin.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Plugin.ts b/src/Plugin.ts index 8f9540b..c4965f4 100644 --- a/src/Plugin.ts +++ b/src/Plugin.ts @@ -9,13 +9,19 @@ export namespace AlpineComponents { export interface Options { components: ComponentList, - startAlpine: boolean + + bootstrapAlpine: boolean; + startAlpine: boolean; + logErrors: boolean; } export const defaultOptions: Options = { components: {}, + + bootstrapAlpine: false, startAlpine: true, + logErrors: false }; @@ -27,6 +33,10 @@ export namespace AlpineComponents { ...defaultOptions, ...options }; + if (opts.bootstrapAlpine) { + window.Alpine = Alpine; + alpine = window.Alpine; + } window.AlpineComponents = new ComponentStore(alpine, opts.components, opts.logErrors); From ea840c6cf7199aeae78197be562f431030edf6bb Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 11:51:42 +1000 Subject: [PATCH 05/11] update example project: Use ESModule features where available + cssnano-preset-advanced * Update configs to use ESModule imports and exports where available * Use cssnano-preset-advanced and strip comments * Use `bootstrapAlpine` option in `AlpineComponents.bootstrap()` call --- examples/project/cssnano.config.cjs | 7 + examples/project/package-lock.json | 169 +++++++++++++----- examples/project/package.json | 23 ++- examples/project/postcss.config.js | 20 ++- .../project/src/components/AlertComponent.ts | 2 +- .../project/src/components/ToggleComponent.ts | 2 +- examples/project/src/index.ts | 9 +- examples/project/tailwind.config.js | 5 +- examples/project/webpack.config.js | 59 ++++-- 9 files changed, 213 insertions(+), 83 deletions(-) create mode 100644 examples/project/cssnano.config.cjs diff --git a/examples/project/cssnano.config.cjs b/examples/project/cssnano.config.cjs new file mode 100644 index 0000000..5f944bf --- /dev/null +++ b/examples/project/cssnano.config.cjs @@ -0,0 +1,7 @@ +const advancedPreset = require('cssnano-preset-advanced'); + +module.exports = advancedPreset({ + discardComments: { + removeAll: true, + } +}); diff --git a/examples/project/package-lock.json b/examples/project/package-lock.json index 1b8bcfd..462c231 100644 --- a/examples/project/package-lock.json +++ b/examples/project/package-lock.json @@ -14,10 +14,10 @@ }, "devDependencies": { "@types/alpinejs": "^3.7.2", - "autoprefixer": "^10.4.15", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", "cssnano": "^6.0.1", + "cssnano-preset-advanced": "^6.0.1", "html-webpack-plugin": "^5.5.3", "mini-css-extract-plugin": "^2.7.6", "postcss": "^8.4.29", @@ -25,22 +25,26 @@ "postcss-loader": "^7.3.3", "postcss-preset-env": "^9.1.2", "tailwindcss": "^3.3.3", - "terser": "^5.19.3", + "terser-webpack-plugin": "^5.3.9", "ts-loader": "^9.4.4", "typescript": "^5.1.6", + "warnings-to-errors-webpack-plugin": "^2.3.0", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" } }, "../..": { - "version": "0.0.1", + "name": "@nxtlvlsoftware/alpine-typescript", + "version": "0.0.3", "license": "MIT", "dependencies": { - "@types/alpinejs": "^3.7.2" + "@types/alpinejs": "^3.7.2", + "alpinejs": "^3.13.0" }, "devDependencies": { "typedoc": "^0.25.1", + "typedoc-plugin-extras": "^3.0.0", "typescript": "^5.1.6" } }, @@ -70,9 +74,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.19.tgz", + "integrity": "sha512-Tinq7ybnEPFFXhlYOYFiSjespWQk0dq2dRNAiMdRTOYQzEGqnnNyrTxPYHP5r6wGjlF1rFgABdDV0g8EwD6Qbg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1018,13 +1022,10 @@ } }, "node_modules/@types/alpinejs": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@types/alpinejs/-/alpinejs-3.7.2.tgz", - "integrity": "sha512-M/PAVysvGxOlhifP/6XmO8bj5HW9w+Ygr03PdryM3tCb1KuQEaAAvVcyeZc5T75PbjH3dCzy/M/w/nJEE0FTSg==", - "dev": true, - "dependencies": { - "@vue/reactivity": "^3.2.26" - } + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@types/alpinejs/-/alpinejs-3.13.0.tgz", + "integrity": "sha512-OZ/hZD3DmrJJOylcLlgsJkLIKOrXhIaWWJF48Zu+V2VkSY2+yQ66uqVRjG0xzQKSAiGGdKTW4/bcqJujO0HKHw==", + "dev": true }, "node_modules/@types/body-parser": { "version": "1.19.2", @@ -1220,19 +1221,17 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", - "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", - "dev": true, + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", + "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", "dependencies": { - "@vue/shared": "3.3.4" + "@vue/shared": "3.1.5" } }, "node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==", - "dev": true + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", + "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", @@ -1523,19 +1522,6 @@ "@vue/reactivity": "~3.1.1" } }, - "node_modules/alpinejs/node_modules/@vue/reactivity": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", - "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", - "dependencies": { - "@vue/shared": "3.1.5" - } - }, - "node_modules/alpinejs/node_modules/@vue/shared": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", - "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==" - }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -1838,9 +1824,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001533", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001533.tgz", - "integrity": "sha512-9aY/b05NKU4Yl2sbcJhn4A7MsGwR1EPfW/nrqsnqVA0Oq50wpmPaGI+R1Z0UKlUl96oxUkGEOILWtOHck0eCWw==", + "version": "1.0.30001534", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz", + "integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==", "dev": true, "funding": [ { @@ -2113,9 +2099,9 @@ "dev": true }, "node_modules/cosmiconfig": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.5.tgz", - "integrity": "sha512-A5Xry3xfS96wy2qbiLkQLAg4JUrR2wvfybxj6yqLmrUfMAvhS3MZxIP2oQn0grgYIvJqzpeTEWu4vK0t+12NNw==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "dependencies": { "import-fresh": "^3.3.0", @@ -2353,6 +2339,26 @@ "postcss": "^8.2.15" } }, + "node_modules/cssnano-preset-advanced": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.0.1.tgz", + "integrity": "sha512-z50X9tDqiZx0Cv+vi3/IRe+5ca1lLLvoG67PjwWdC6gXNqc7JXbU/hWEfYQg+e9/8cq+fVKhyLHO8n3mV7mxDw==", + "dev": true, + "dependencies": { + "autoprefixer": "^10.4.12", + "cssnano-preset-default": "^6.0.1", + "postcss-discard-unused": "^6.0.0", + "postcss-merge-idents": "^6.0.0", + "postcss-reduce-idents": "^6.0.1", + "postcss-zindex": "^6.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, "node_modules/cssnano-preset-default": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.1.tgz", @@ -2628,9 +2634,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.518", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.518.tgz", - "integrity": "sha512-eqbfyW9i/en/qgIPsddW+cuxQvjq3KZmfH+/gc3f/gnynYj0qxee0yRmll69W0SGwiVD+goeU1J9LT6zDHDzlg==", + "version": "1.4.521", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.521.tgz", + "integrity": "sha512-88W7FAsYzc3Vy2mGCFe/YTD6kvoJpqeLRBd5NFMRMdYNqsjHYzkn/mGxaOFJ8yYfLuQqC6vpDYbN6Ps5mtIM3w==", "dev": true }, "node_modules/emoji-regex": { @@ -4832,6 +4838,21 @@ "postcss": "^8.2.15" } }, + "node_modules/postcss-discard-unused": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.0.tgz", + "integrity": "sha512-ZxZWWqCFEc3T6Fzy/Rga7dAiDqDOdoRINM13VGzExMYOpdd5rHoloMEde4Fq+Or6612e9bO6gg5POZm1xgAGAQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, "node_modules/postcss-double-position-gradients": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-5.0.0.tgz", @@ -5113,6 +5134,22 @@ "postcss": "^8.4" } }, + "node_modules/postcss-merge-idents": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.0.tgz", + "integrity": "sha512-MaTP8Ym7SwxtNkHB0e7C/b3jfjgnKo3p07VmJWwbyMTyy3O0SIwzfzQGlJzBfRDDIIBkLYrpLqv1IYBZV1vOBQ==", + "dev": true, + "dependencies": { + "cssnano-utils": "^4.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, "node_modules/postcss-merge-longhand": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.0.tgz", @@ -5651,6 +5688,21 @@ "postcss": "^8.4" } }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.1.tgz", + "integrity": "sha512-KniPTynD5u69rLwcS6++OMBQg2TsH59Z8SX01rqs4LFhcU9A3IqjZ1ax41MiYfqCotseBmo01+hzO+Bqrcd1Og==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, "node_modules/postcss-reduce-initial": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.0.0.tgz", @@ -5780,6 +5832,18 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/postcss-zindex": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.0.tgz", + "integrity": "sha512-lNim6f01ClwALn0J50yyoR+qOu10GXub+xucEB7+x8VwXl+iNJSj/QgXg45XpSoLsWD5HIofVrG/pPrMFcdbig==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -6007,9 +6071,9 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.5.tgz", + "integrity": "sha512-qWhv7PF1V95QPvRoUGHxOtnAlEvlXBylMZcjUR9pAumMmveFtcHJRXGIr+TkjfNJVQypqv2qcDiiars2y1PsSg==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -7158,6 +7222,15 @@ "node": ">= 0.8" } }, + "node_modules/warnings-to-errors-webpack-plugin": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/warnings-to-errors-webpack-plugin/-/warnings-to-errors-webpack-plugin-2.3.0.tgz", + "integrity": "sha512-fzOyw+Ctr2MqJ+4UXKobDiOLzMMSBAdvGMWvZ4NRgTBCofAL2mmdfr6/Of3Bqz9Sq6R6xT5dLs6nnLLCtmppeQ==", + "dev": true, + "peerDependencies": { + "webpack": "^2.2.0-rc || ^3 || ^4 || ^5" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/examples/project/package.json b/examples/project/package.json index 4685377..0f809fa 100644 --- a/examples/project/package.json +++ b/examples/project/package.json @@ -1,13 +1,23 @@ { "name": "alpine-typescript-project-example", - "version": "0.0.1", "description": "Example Alpine.js components project.", - "author": "Jack Noordhuis ", + "version": "0.0.1", "license": "MIT", + "author": { + "name": "Jack Noordhuis", + "email": "me@jacknoordhuis.net", + "url": "https://jacknoordhuis.net" + }, + "repository": "NxtLvlSoftware/alpine-typescript", + "homepage": "https://nxtlvlsoftware.github.io/alpine-typescript/", + "bugs": { + "url": "https://github.com/NxtLvlSoftware/alpine-typescript/issues" + }, + "type": "module", "private": true, "scripts": { - "build": "export NODE_ENV=production && webpack", - "build-ci": "export NODE_ENV=production && webpack --fail-on-warnings --no-color", + "build": "export NODE_ENV=development && webpack --stats-error-details", + "build-ci": "export NODE_ENV=production && webpack --stats-error-details --fail-on-warnings --no-color", "dev": "webpack serve --mode=development --open" }, "dependencies": { @@ -16,10 +26,10 @@ }, "devDependencies": { "@types/alpinejs": "^3.7.2", - "autoprefixer": "^10.4.15", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", "cssnano": "^6.0.1", + "cssnano-preset-advanced": "^6.0.1", "html-webpack-plugin": "^5.5.3", "mini-css-extract-plugin": "^2.7.6", "postcss": "^8.4.29", @@ -27,9 +37,10 @@ "postcss-loader": "^7.3.3", "postcss-preset-env": "^9.1.2", "tailwindcss": "^3.3.3", - "terser": "^5.19.3", + "terser-webpack-plugin": "^5.3.9", "ts-loader": "^9.4.4", "typescript": "^5.1.6", + "warnings-to-errors-webpack-plugin": "^2.3.0", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" diff --git a/examples/project/postcss.config.js b/examples/project/postcss.config.js index d426f2b..0906a95 100644 --- a/examples/project/postcss.config.js +++ b/examples/project/postcss.config.js @@ -1,10 +1,12 @@ -const tailwind = require('tailwindcss'); +import postcssPresetEnv from 'postcss-preset-env'; +import tailwind from 'tailwindcss'; +import cssnano from 'cssnano'; -module.exports = { - plugins: [ - 'postcss-preset-env', - tailwind('tailwind.config.js'), - require('autoprefixer'), - require('cssnano') - ] -}; +import tailwindConfig from './tailwind.config.js'; +import cssnanoConfig from './cssnano.config.cjs'; + +export const plugins = [ + postcssPresetEnv(), + tailwind(tailwindConfig), + cssnano(cssnanoConfig) +]; diff --git a/examples/project/src/components/AlertComponent.ts b/examples/project/src/components/AlertComponent.ts index 2b6ba6f..b081b96 100644 --- a/examples/project/src/components/AlertComponent.ts +++ b/examples/project/src/components/AlertComponent.ts @@ -1,4 +1,4 @@ -import {AlpineComponent} from "@nxtlvlsoftware/alpine-typescript"; +import {AlpineComponent} from '@nxtlvlsoftware/alpine-typescript'; /** * Simple alert component for closing the default alert. diff --git a/examples/project/src/components/ToggleComponent.ts b/examples/project/src/components/ToggleComponent.ts index ceada28..682968b 100644 --- a/examples/project/src/components/ToggleComponent.ts +++ b/examples/project/src/components/ToggleComponent.ts @@ -1,4 +1,4 @@ -import {AlpineComponent} from "@nxtlvlsoftware/alpine-typescript"; +import {AlpineComponent} from '@nxtlvlsoftware/alpine-typescript'; /** * Simple toggle that switches between on/off values. diff --git a/examples/project/src/index.ts b/examples/project/src/index.ts index 4100a85..2e00e68 100644 --- a/examples/project/src/index.ts +++ b/examples/project/src/index.ts @@ -1,15 +1,12 @@ import './style.css'; -import Alpine from 'alpinejs'; - -window.Alpine = Alpine; - import {AlpineComponents} from '@nxtlvlsoftware/alpine-typescript'; -import {AlertComponent} from "./components/AlertComponent"; -import {ToggleComponent} from "./components/ToggleComponent"; +import {AlertComponent} from './components/AlertComponent'; +import {ToggleComponent} from './components/ToggleComponent'; AlpineComponents.bootstrap({ + bootstrapAlpine: true, components: { alert: AlertComponent, toggle: ToggleComponent diff --git a/examples/project/tailwind.config.js b/examples/project/tailwind.config.js index c6cc786..1056e03 100644 --- a/examples/project/tailwind.config.js +++ b/examples/project/tailwind.config.js @@ -1,5 +1,6 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { + +/** @type {Partial} */ +export default { content: [ './src/**/*.{html,ts}', './dist/**/*.{html,ts}' diff --git a/examples/project/webpack.config.js b/examples/project/webpack.config.js index b30bb83..efce731 100644 --- a/examples/project/webpack.config.js +++ b/examples/project/webpack.config.js @@ -1,23 +1,40 @@ -const path = require('path'); +import * as path from 'path'; +import * as fs from 'fs'; +import { fileURLToPath } from 'url'; -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const TerserPlugin = require('terser-webpack-plugin'); +import HtmlWebpackPlugin from 'html-webpack-plugin'; +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import CopyWebpackPlugin from 'copy-webpack-plugin'; +import TerserPlugin from 'terser-webpack-plugin'; +import WarningsToErrorsPlugin from 'warnings-to-errors-webpack-plugin'; const isProduction = process.env.NODE_ENV === 'production'; +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + const rootPath = path.resolve(__dirname); const srcPath = path.resolve(rootPath, 'src'); const outPath = path.resolve(rootPath, 'dist'); -module.exports = { +const Mode = isProduction ? 'production' : 'development'; +const productionPlugins = [ + new WarningsToErrorsPlugin() +]; +const developmentPlugins = [ + // +]; + +/** @type {Partial} */ +let Config = { entry: './src/index.ts', - mode: isProduction ? 'production' : 'development', + mode: Mode, output: { path: outPath, filename: 'index.js', - clean: true + clean: true, + strictModuleErrorHandling: true, + strictModuleExceptionHandling: true }, plugins: [ new HtmlWebpackPlugin({ @@ -38,9 +55,15 @@ module.exports = { module: { rules: [ { - test: /\.tsx?$/, + test: /\.(tsx|ts)$/, use: 'ts-loader', - exclude: /node_modules/, + exclude: /node_modules/ + }, + { + test: /\.m?js$/, + resolve: { + fullySpecified: false + } }, { test: /\.css$/i, @@ -51,6 +74,12 @@ module.exports = { }, resolve: { extensions: ['.tsx', '.ts', '.js'], + fallback: { + '@nxtlvlsoftware/alpine-typescript': path.resolve( + rootPath, + JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'))).dependencies['@nxtlvlsoftware/alpine-typescript'].substring(5) + ) + } }, optimization: { minimize: true, @@ -63,3 +92,13 @@ module.exports = { historyApiFallback: true } }; + +if (isProduction) { + Config.devtool = 'hidden-source-map'; + Config.plugins.push(...productionPlugins); +} else { + Config.devtool = 'inline-source-map'; + Config.plugins.push(...developmentPlugins); +} + +export default Config; From c445e59852da9806f774b0600141aecccaaba074 Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 11:52:44 +1000 Subject: [PATCH 06/11] update example package: organise package.json + add extra fields --- examples/package/package.json | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/examples/package/package.json b/examples/package/package.json index d874563..3956042 100644 --- a/examples/package/package.json +++ b/examples/package/package.json @@ -1,16 +1,31 @@ { "name": "alpine-typescript-package-example", - "type": "module", - "version": "0.0.1", "description": "Example Alpine.js components package.", - "author": "Jack Noordhuis ", + "version": "0.0.1", "license": "MIT", + "author": { + "name": "Jack Noordhuis", + "email": "me@jacknoordhuis.net", + "url": "https://jacknoordhuis.net" + }, + "keywords": [ + "component", + "alpine", + "javascript", + "typescript", + "js", + "ts" + ], + "repository": "NxtLvlSoftware/alpine-typescript", + "homepage": "https://nxtlvlsoftware.github.io/alpine-typescript/", + "bugs": { + "url": "https://github.com/NxtLvlSoftware/alpine-typescript/issues" + }, + "type": "module", "main": "index.js", "files": [ - "index.ts", "index.d.ts", "index.js", - "src/**/*.ts", "src/**/*.d.ts", "src/**/*.js" ], @@ -19,14 +34,6 @@ "build-ci": "tsc --pretty false --inlineSourceMap --removeComments --listEmittedFiles -p ./", "dev": "tsc --watch -p ./" }, - "keywords": [ - "component", - "alpine", - "javascript", - "typescript", - "js", - "ts" - ], "dependencies": { "@nxtlvlsoftware/alpine-typescript": "file:../../", "@types/alpinejs": "^3.7.2" From 50b7f61b66f458396836e8626056acb6e369d28d Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 11:53:41 +1000 Subject: [PATCH 07/11] update package.json: add alpine.js as direct dependency (bootstrap functionality) --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f13bbba..b32730f 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "docs-ci": "npx typedoc --plugin typedoc-plugin-extras --gitRemote dist --out docs-build --cacheBust index.ts" }, "dependencies": { - "@types/alpinejs": "^3.7.2" + "@types/alpinejs": "^3.7.2", + "alpinejs": "^3.13.0" }, "devDependencies": { "typedoc": "^0.25.1", From 7127c379ab693556b54d9386829059b043845814 Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 11:54:07 +1000 Subject: [PATCH 08/11] update package.json: update description + organise/add fields --- package.json | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index b32730f..c45648c 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,27 @@ { "name": "@nxtlvlsoftware/alpine-typescript", - "description": "Typescript definitions for Alpine.js.", + "description": "Write your Alpine.js components in Typescript.", "version": "0.0.3", - "author": "Jack Noordhuis ", "license": "MIT", + "author": { + "name": "Jack Noordhuis", + "email": "me@jacknoordhuis.net", + "url": "https://jacknoordhuis.net" + }, + "keywords": [ + "alpine", + "alpine.js", + "typescript", + "components" + ], + "repository": "NxtLvlSoftware/alpine-typescript", + "homepage": "https://nxtlvlsoftware.github.io/alpine-typescript/", + "bugs": { + "url": "https://github.com/NxtLvlSoftware/alpine-typescript/issues" + }, "type": "module", "main": "index.js", + "types": "index.d.ts", "files": [ "README.md", "LICENSE", @@ -14,12 +30,6 @@ "index.d.ts", "index.js" ], - "keywords": [ - "alpine", - "alpine.js", - "typescript", - "components" - ], "scripts": { "build": "tsc --inlineSourceMap --removeComments -p ./", "build-ci": "tsc --pretty false --inlineSourceMap --removeComments --listEmittedFiles -p ./", From 37a0e8662a87283c6b5c03b6a94deab039960c45 Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 12:30:01 +1000 Subject: [PATCH 09/11] update README.md: update examples --- README.md | 54 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index f19dff1..9e7ff94 100644 --- a/README.md +++ b/README.md @@ -59,29 +59,34 @@ $ npm install --save @nxtlvlsoftware/alpine-typescript ``` The package requires manual initialization in the browser as we don't assume a specific use-case: -Using `Alpine.plugin()`: +Using `Alpine.plugin()` (ESModule syntax): ```typescript import Alpine from 'alpinejs'; window.Alpine = Alpine; +// {default as componentPlugin} also works import {componentPlugin} from '@nxtlvlsoftware/alpine-typescript'; window.addEventListener('alpine-components:init', () => { - // window.Alpine.Components.register(); + window.Alpine.Components.registerAll({ + // + }); }); window.Alpine.plugin(componentPlugin); window.Alpine.start(); ``` -Using the default export: +Using the default export (CommonJS syntax): ```typescript import Alpine from 'alpinejs'; window.Alpine = Alpine; window.addEventListener('alpine-components:init', () => { - // window.Alpine.Components.register(); + window.Alpine.Components.registerAll({ + // + }); }); window.Alpine.plugin(require('@nxtlvlsoftware/alpine-typescript')); @@ -90,36 +95,39 @@ window.Alpine.start(); This is the easiest way to get started in existing projects but doesn't offer a way to modify the default options provided the package. -Using `AlpineComponents.bootstrap()`: +Using `AlpineComponents.bootstrap()` (all examples in ESModule syntax): ```typescript -import Alpine from 'alpinejs'; - -window.Alpine = Alpine; - import {AlpineComponents} from '@nxtlvlsoftware/alpine-typescript'; AlpineComponents.bootstrap({ + bootstrapAlpine: true, components: { // - }}); + } +}); ``` -The default options are best suited to new projects and automatically starts Alpine for you. -To integrate into existing projects seamlessly, just pass in an options object: +The default options are best suited to new projects as `Alpine.start()` will be called for you. +To integrate into existing projects seamlessly, just set `startAlpine` to `false` on the options +object: ```typescript +import Alpine from 'alpinejs'; + +window.Alpine = Alpine; + import {AlpineComponents} from '@nxtlvlsoftware/alpine-typescript'; AlpineComponents.bootstrap({ + startAlpine: false, + logErrors: true, // should only enable this in dev enviroments for debugging components: { // - }, - startAlpine: false, - logErrors: true // should only enable this in dev enviroments for debugging -}); // pass the Alpine object explicity if you aren't following the default convention + } +}); window.Alpine.start(); ``` -If you aren't following the default convention of defining `window.Alpine` after importing Alpine -just pass it after your options object: +If you aren't following the default convention of defining `window.Alpine` after importing Alpine, +just pass it as the second argument to the `AlpineComponents.bootstrap()` call: ```typescript import Alpine from 'alpinejs'; @@ -129,10 +137,10 @@ import {AlpineComponents} from '@nxtlvlsoftware/alpine-typescript'; const isProduction = () => false; // equivelent would be injected/definied server-side by your framework AlpineComponents.bootstrap({ - components: { - // - }, - logErrors: !isProduction() + components: { + // + }, + logErrors: !isProduction() }, myAlpine); // might break alpine or other packages by defining after init but we support it ¯\_(ツ)_/¯ @@ -469,7 +477,7 @@ The main drawback of using this library is the added compilation step needed to Alpine is an elegant library that provides a thin layer on-top of vanilla JavaScript. Using Alpine the way it was intended is the way to go until your list of components grows and you need a way to organise them. If you're not already using a bundler in your project (webpack, -Vite, Rollup, etc) then this probably isn't for you. +Vite, Rollup, etc.) then this probably isn't for you. ## Contributing From c868b1fa911dc0c6fff8c3e03a2fb51e3f9c88df Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 12:30:28 +1000 Subject: [PATCH 10/11] update README.md: add pull requests section --- .github/workflows/pages-publish.yml | 2 +- README.md | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pages-publish.yml b/.github/workflows/pages-publish.yml index 81bd96f..ac70200 100644 --- a/.github/workflows/pages-publish.yml +++ b/.github/workflows/pages-publish.yml @@ -32,7 +32,7 @@ jobs: - name: Remove README.md index lines run: | - sed -i '28,45d' README.md + sed -i '28,46d' README.md - name: Use Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@v3 diff --git a/README.md b/README.md index 9e7ff94..0e6e176 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ * [Using Components](#using-components) * [Contributing](#contributing) * [Issues](#issues) + * [Pull Requests](#pull-requests) * [License](#license-information)


@@ -480,12 +481,20 @@ need a way to organise them. If you're not already using a bundler in your proje Vite, Rollup, etc.) then this probably isn't for you. ## Contributing - #### Issues - Found a problem with this project? Make sure to open an issue on the [issue tracker](https://github.com/NxtLvLSoftware/alpine-typescript/issues) and we'll do our best to get it sorted! +#### Pull Requests +Pull requests will be reviewed by maintainers when they are available. + +Depending on the changes, maintainers might ask you to make changes to the PR to fix problems +or to improve the code. Do not delete your fork while your pull request remains open, otherwise +you won't be able to make any requested changes and the PR will end up being declined. + +By proposing a pull request, you agree to your code being distributed under [this projects license](https://github.com/NxtLvlSoftware/alpine-typescript/blob/dev/LICENSE). + + ## License Information [`nxtlvlsoftware/alpine-typescript`](https://github.com/NxtLvlSoftware/alpine-typescript) is open-sourced software, From 4c6dbfa5f9ee0f001c9b683c743fe710db5b91bf Mon Sep 17 00:00:00 2001 From: JackNoordhuis Date: Fri, 15 Sep 2023 02:31:53 +0000 Subject: [PATCH 11/11] [create-pull-request] update tsc build dist files --- index.d.ts | 6 ++ index.js | 7 ++ src/Component.d.ts | 19 ++++++ src/Component.js | 7 ++ src/Global.d.ts | 15 +++++ src/Global.js | 2 + src/Plugin.d.ts | 13 ++++ src/Plugin.js | 42 ++++++++++++ src/Store.d.ts | 24 +++++++ src/Store.js | 159 +++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 294 insertions(+) create mode 100644 index.d.ts create mode 100644 index.js create mode 100644 src/Component.d.ts create mode 100644 src/Component.js create mode 100644 src/Global.d.ts create mode 100644 src/Global.js create mode 100644 src/Plugin.d.ts create mode 100644 src/Plugin.js create mode 100644 src/Store.d.ts create mode 100644 src/Store.js diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..0c7c6a7 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,6 @@ +export { type KnownClassConstructor, type KnownConstructor, type AlpineComponentConstructor, type AlpineDataContext, type AlpineData, AlpineComponent } from './src/Component'; +export { type ComponentList, ComponentStore, transformToAlpineData, makeAlpineConstructor } from './src/Store'; +export * as Globals from './src/Global'; +export { AlpineComponents, componentsPlugin } from './src/Plugin'; +import { componentsPlugin } from './src/Plugin'; +export default componentsPlugin; diff --git a/index.js b/index.js new file mode 100644 index 0000000..6cc16b2 --- /dev/null +++ b/index.js @@ -0,0 +1,7 @@ +export { AlpineComponent } from './src/Component'; +export { ComponentStore, transformToAlpineData, makeAlpineConstructor } from './src/Store'; +export * as Globals from './src/Global'; +export { AlpineComponents, componentsPlugin } from './src/Plugin'; +import { componentsPlugin } from './src/Plugin'; +export default componentsPlugin; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBTU4sZUFBZSxFQUNmLE1BQU0saUJBQWlCLENBQUM7QUFFekIsT0FBTyxFQUVOLGNBQWMsRUFDZCxxQkFBcUIsRUFDckIscUJBQXFCLEVBQ3JCLE1BQU0sYUFBYSxDQUFDO0FBRXJCLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE9BQU8sRUFDTixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLE1BQU0sY0FBYyxDQUFDO0FBTXRCLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUM5QyxlQUFlLGdCQUFnQixDQUFDIn0= \ No newline at end of file diff --git a/src/Component.d.ts b/src/Component.d.ts new file mode 100644 index 0000000..9804e51 --- /dev/null +++ b/src/Component.d.ts @@ -0,0 +1,19 @@ +export type KnownClassConstructor = new (...args: any[]) => T; +export type KnownGenericConstructor = (...args: any[]) => T; +export type KnownConstructor = KnownGenericConstructor | KnownClassConstructor; +export type AlpineComponentConstructor = (...args: any[]) => any; +export declare interface AlpineDataContext { + init?(): void; + [stateKey: string]: any; +} +export declare type AlpineData = AlpineDataContext | string | number | boolean; +export declare abstract class AlpineComponent implements AlpineDataContext { + $data: this; + $el: HTMLElement; + $refs: Record; + $store: AlpineData; + $dispatch: (event: string, data?: any) => void; + $id: (name: string, key?: number | string) => string; + $nextTick: (callback?: () => void) => Promise; + $watch: (property: K, callback: (newValue: V, oldValue: V) => void) => void; +} diff --git a/src/Component.js b/src/Component.js new file mode 100644 index 0000000..f685936 --- /dev/null +++ b/src/Component.js @@ -0,0 +1,7 @@ +var AlpineComponent = (function () { + function AlpineComponent() { + } + return AlpineComponent; +}()); +export { AlpineComponent }; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiQ29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTRDQTtJQUFBO0lBd0RBLENBQUM7SUFBRCxzQkFBQztBQUFELENBQUMsQUF4REQsSUF3REMifQ== \ No newline at end of file diff --git a/src/Global.d.ts b/src/Global.d.ts new file mode 100644 index 0000000..b46a042 --- /dev/null +++ b/src/Global.d.ts @@ -0,0 +1,15 @@ +import type { Alpine as AlpineType } from 'alpinejs'; +import type { ComponentStore } from './Store'; +import type { AlpineComponentConstructor } from './Component'; +export declare interface AlpineComponentMixins { + Components: ComponentStore; + component: (name: string) => AlpineComponentConstructor; +} +export declare type AlpineWithComponents = AlpineType & AlpineComponentMixins; +export declare type Alpine = AlpineType | AlpineWithComponents; +declare global { + interface Window { + Alpine: Alpine; + AlpineComponents: ComponentStore; + } +} diff --git a/src/Global.js b/src/Global.js new file mode 100644 index 0000000..9c3a2b4 --- /dev/null +++ b/src/Global.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiR2xvYmFsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiR2xvYmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ== \ No newline at end of file diff --git a/src/Plugin.d.ts b/src/Plugin.d.ts new file mode 100644 index 0000000..84cbdf6 --- /dev/null +++ b/src/Plugin.d.ts @@ -0,0 +1,13 @@ +import type * as Globals from './Global'; +import { type ComponentList } from './Store'; +export declare namespace AlpineComponents { + interface Options { + components: ComponentList; + bootstrapAlpine: boolean; + startAlpine: boolean; + logErrors: boolean; + } + const defaultOptions: Options; + function bootstrap(options?: Partial, alpine?: Globals.Alpine): void; +} +export declare function componentsPlugin(alpine: Globals.Alpine): void; diff --git a/src/Plugin.js b/src/Plugin.js new file mode 100644 index 0000000..1b2ca06 --- /dev/null +++ b/src/Plugin.js @@ -0,0 +1,42 @@ +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +import Alpine from 'alpinejs'; +import { ComponentStore } from './Store'; +export var AlpineComponents; +(function (AlpineComponents) { + AlpineComponents.defaultOptions = { + components: {}, + bootstrapAlpine: false, + startAlpine: true, + logErrors: false + }; + function bootstrap(options, alpine) { + if (options === void 0) { options = AlpineComponents.defaultOptions; } + if (alpine === void 0) { alpine = window.Alpine; } + var opts = __assign(__assign({}, AlpineComponents.defaultOptions), options); + if (opts.bootstrapAlpine) { + window.Alpine = Alpine; + alpine = window.Alpine; + } + window.AlpineComponents = new ComponentStore(alpine, opts.components, opts.logErrors); + if (opts.startAlpine) { + alpine.start(); + } + } + AlpineComponents.bootstrap = bootstrap; +})(AlpineComponents || (AlpineComponents = {})); +export function componentsPlugin(alpine) { + AlpineComponents.bootstrap({ + startAlpine: false + }, alpine); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiUGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBRTlCLE9BQU8sRUFFTixjQUFjLEVBQ2QsTUFBTSxTQUFTLENBQUM7QUFFakIsTUFBTSxLQUFXLGdCQUFnQixDQXdDaEM7QUF4Q0QsV0FBaUIsZ0JBQWdCO0lBV25CLCtCQUFjLEdBQVk7UUFDdEMsVUFBVSxFQUFFLEVBQUU7UUFFZCxlQUFlLEVBQUUsS0FBSztRQUN0QixXQUFXLEVBQUUsSUFBSTtRQUVqQixTQUFTLEVBQUUsS0FBSztLQUNoQixDQUFDO0lBRUYsU0FBZ0IsU0FBUyxDQUN4QixPQUEwQyxFQUMxQyxNQUFzQztRQUR0Qyx3QkFBQSxFQUFBLFVBQTRCLCtCQUFjO1FBQzFDLHVCQUFBLEVBQUEsU0FBeUIsTUFBTSxDQUFDLE1BQU07UUFFdEMsSUFBTSxJQUFJLHlCQUNOLGlCQUFBLGNBQWMsR0FDZCxPQUFPLENBQ1YsQ0FBQztRQUNGLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN6QixNQUFNLENBQUMsTUFBTSxHQUFpQyxNQUFNLENBQUM7WUFDckQsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7U0FDdkI7UUFFRCxNQUFNLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXRGLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNyQixNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDZjtJQUNGLENBQUM7SUFsQmUsMEJBQVMsWUFrQnhCLENBQUE7QUFFRixDQUFDLEVBeENnQixnQkFBZ0IsS0FBaEIsZ0JBQWdCLFFBd0NoQztBQU9ELE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxNQUFzQjtJQUN0RCxnQkFBZ0IsQ0FBQyxTQUFTLENBQUM7UUFDMUIsV0FBVyxFQUFFLEtBQUs7S0FDbEIsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUNaLENBQUMifQ== \ No newline at end of file diff --git a/src/Store.d.ts b/src/Store.d.ts new file mode 100644 index 0000000..b85da2f --- /dev/null +++ b/src/Store.d.ts @@ -0,0 +1,24 @@ +import type * as Impl from './Component'; +import type * as Globals from './Global'; +import { AlpineComponent } from './Component'; +export type ComponentList = { + [name: string]: Impl.KnownConstructor; +}; +export declare class ComponentStore { + private alpine; + private logErrors; + private initialized; + private components; + constructor(alpine: Globals.Alpine, components?: ComponentList, logErrors?: boolean); + private init; + component(name: string): Impl.AlpineComponentConstructor; + registerAll(components: ComponentList): void; + register(name: string, component: Impl.KnownConstructor): void; + register(component: Impl.KnownClassConstructor, name?: string): void; + private registerConstructorAsAlpineData; + private static getObjectData; + private static getClassData; + private logRegisterFailure; +} +export declare function transformToAlpineData(instance: T): object; +export declare function makeAlpineConstructor(component: Impl.KnownClassConstructor): Impl.AlpineComponentConstructor; diff --git a/src/Store.js b/src/Store.js new file mode 100644 index 0000000..ee99238 --- /dev/null +++ b/src/Store.js @@ -0,0 +1,159 @@ +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +import { AlpineComponent } from './Component'; +var ReservedNames = ['abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', + 'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', + 'enum', 'eval', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', + 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new', + 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', + 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', + 'with', 'yield']; +var RegisterComponentFailure; +(function (RegisterComponentFailure) { + RegisterComponentFailure[RegisterComponentFailure["GenericMustHaveFunctionAsSecond"] = 0] = "GenericMustHaveFunctionAsSecond"; + RegisterComponentFailure[RegisterComponentFailure["NameMustBeProvidedForComponentWithNoDefault"] = 1] = "NameMustBeProvidedForComponentWithNoDefault"; + RegisterComponentFailure[RegisterComponentFailure["UnknownArgumentTypes"] = 2] = "UnknownArgumentTypes"; + RegisterComponentFailure[RegisterComponentFailure["ReservedName"] = 3] = "ReservedName"; +})(RegisterComponentFailure || (RegisterComponentFailure = {})); +var ComponentStore = (function () { + function ComponentStore(alpine, components, logErrors) { + var _this = this; + if (components === void 0) { components = {}; } + if (logErrors === void 0) { logErrors = false; } + this.alpine = alpine; + this.logErrors = logErrors; + this.initialized = false; + this.components = {}; + Object.entries(components).forEach(function (_a) { + var name = _a[0], component = _a[1]; + _this.register(name, component); + }); + window.addEventListener('alpine:init', function () { + _this.init(); + }); + } + ComponentStore.prototype.init = function () { + var _this = this; + if (this.initialized) { + return; + } + this.alpine.Components = this; + this.alpine.component = this.component; + document.dispatchEvent(new CustomEvent('alpine-components:init')); + Object.entries(this.components) + .forEach(function (_a) { + var name = _a[0]; + return _this.registerConstructorAsAlpineData(name); + }); + this.initialized = true; + }; + ComponentStore.prototype.component = function (name) { + return this.components[name]; + }; + ComponentStore.prototype.registerAll = function (components) { + var _this = this; + Object.entries(components) + .forEach(function (_a) { + var name = _a[0], component = _a[1]; + return _this.register(name, component); + }); + }; + ComponentStore.prototype.register = function (nameOrComponentClass, constructorOrComponentName) { + if (constructorOrComponentName === void 0) { constructorOrComponentName = ''; } + var component; + if (typeof nameOrComponentClass === 'string') { + if (typeof constructorOrComponentName === 'string') { + this.logRegisterFailure(RegisterComponentFailure.GenericMustHaveFunctionAsSecond); + return; + } + component = ComponentStore.getObjectData(nameOrComponentClass, constructorOrComponentName); + } + else if (typeof nameOrComponentClass === 'function') { + component = ComponentStore.getClassData(nameOrComponentClass, constructorOrComponentName); + if (component.name === "") { + this.logRegisterFailure(RegisterComponentFailure.NameMustBeProvidedForComponentWithNoDefault); + } + } + else { + this.logRegisterFailure(RegisterComponentFailure.UnknownArgumentTypes); + return; + } + if (ReservedNames.includes(component.name)) { + this.logRegisterFailure(RegisterComponentFailure.ReservedName); + } + this.components[component.name] = component.constructor; + if (this.initialized) { + this.registerConstructorAsAlpineData(component.name); + } + }; + ComponentStore.prototype.registerConstructorAsAlpineData = function (name) { + this.alpine.data(name, this.component(name)); + }; + ComponentStore.getObjectData = function (name, component) { + return { + name: name, + constructor: ((component.prototype instanceof AlpineComponent) ? + makeAlpineConstructor(component) : component) + }; + }; + ComponentStore.getClassData = function (component, name) { + var resolvedName = (name !== undefined ? name : component.prototype.name); + return { + name: resolvedName, + constructor: makeAlpineConstructor(component) + }; + }; + ComponentStore.prototype.logRegisterFailure = function (reason) { + if (!this.logErrors) { + return; + } + switch (reason) { + case RegisterComponentFailure.GenericMustHaveFunctionAsSecond: + console.error("Second argument must be a constructor function for component."); + break; + case RegisterComponentFailure.NameMustBeProvidedForComponentWithNoDefault: + console.error("Component name must be provided when class doesn't specify a default."); + break; + case RegisterComponentFailure.UnknownArgumentTypes: + console.error("Cannot register component with provided argument types. Check Typescript definitions for usage."); + break; + case RegisterComponentFailure.ReservedName: + console.error("Cannot register component with name matching a reserved keyword."); + break; + } + }; + return ComponentStore; +}()); +export { ComponentStore }; +export function transformToAlpineData(instance) { + var methodNames = []; + for (var prototype = Object.getPrototypeOf(instance); prototype.constructor.name !== 'Object'; prototype = Object.getPrototypeOf(prototype)) { + Object.getOwnPropertyNames(prototype).forEach(function (name) { + if (methodNames.includes(name)) { + return; + } + methodNames.push(name); + }); + } + return __spreadArray(__spreadArray([], methodNames, true), Object.getOwnPropertyNames(instance), true).reduce(function (obj, name) { + obj[name] = instance[name]; + return obj; + }, {}); +} +export function makeAlpineConstructor(component) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return transformToAlpineData(new (component.bind.apply(component, __spreadArray([void 0], args, false)))()); + }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJTdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFHQSxPQUFPLEVBQUMsZUFBZSxFQUFrQyxNQUFNLGFBQWEsQ0FBQztBQUs3RSxJQUFNLGFBQWEsR0FBRyxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU07SUFDMUYsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU07SUFDdEcsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU07SUFDcEcsSUFBSSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEtBQUs7SUFDcEcsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUcsV0FBVyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUTtJQUNwRyxNQUFNLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTztJQUNuRyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFpQmxCLElBQUssd0JBS0o7QUFMRCxXQUFLLHdCQUF3QjtJQUM1Qiw2SEFBK0IsQ0FBQTtJQUMvQixxSkFBMkMsQ0FBQTtJQUMzQyx1R0FBb0IsQ0FBQTtJQUNwQix1RkFBWSxDQUFBO0FBQ2IsQ0FBQyxFQUxJLHdCQUF3QixLQUF4Qix3QkFBd0IsUUFLNUI7QUFFRDtJQUtDLHdCQUNTLE1BQXNCLEVBQzlCLFVBQThCLEVBQ3RCLFNBQTBCO1FBSG5DLGlCQVlDO1FBVkEsMkJBQUEsRUFBQSxlQUE4QjtRQUN0QiwwQkFBQSxFQUFBLGlCQUEwQjtRQUYxQixXQUFNLEdBQU4sTUFBTSxDQUFnQjtRQUV0QixjQUFTLEdBQVQsU0FBUyxDQUFpQjtRQVAzQixnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUU3QixlQUFVLEdBQStDLEVBQUUsQ0FBQztRQU9uRSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLEVBQWlCO2dCQUFoQixJQUFJLFFBQUEsRUFBRSxTQUFTLFFBQUE7WUFDbkQsS0FBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFO1lBQ3RDLEtBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNiLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVPLDZCQUFJLEdBQVo7UUFBQSxpQkFpQkM7UUFoQkEsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3JCLE9BQU87U0FDUDtRQUdELElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUU5QixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBRXZDLFFBQVEsQ0FBQyxhQUFhLENBQUMsSUFBSSxXQUFXLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDO1FBRWxFLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQzthQUM3QixPQUFPLENBQUMsVUFBQyxFQUFNO2dCQUFMLElBQUksUUFBQTtZQUNkLE9BQUEsS0FBSSxDQUFDLCtCQUErQixDQUFDLElBQUksQ0FBQztRQUExQyxDQUEwQyxDQUFDLENBQUM7UUFFOUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQVlELGtDQUFTLEdBQVQsVUFBVSxJQUFZO1FBRXJCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQsb0NBQVcsR0FBWCxVQUFZLFVBQXlCO1FBQXJDLGlCQUlDO1FBSEEsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7YUFDeEIsT0FBTyxDQUFDLFVBQUMsRUFBaUI7Z0JBQWhCLElBQUksUUFBQSxFQUFFLFNBQVMsUUFBQTtZQUN6QixPQUFBLEtBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQztRQUE5QixDQUE4QixDQUFDLENBQUM7SUFDbkMsQ0FBQztJQWtCRCxpQ0FBUSxHQUFSLFVBRUMsb0JBQW1GLEVBQ25GLDBCQUFnRTtRQUFoRSwyQ0FBQSxFQUFBLCtCQUFnRTtRQUVoRSxJQUFJLFNBQW1DLENBQUM7UUFFeEMsSUFBSSxPQUFPLG9CQUFvQixLQUFLLFFBQVEsRUFBRTtZQUM3QyxJQUFJLE9BQU8sMEJBQTBCLEtBQUssUUFBUSxFQUFFO2dCQUNuRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsd0JBQXdCLENBQUMsK0JBQStCLENBQUMsQ0FBQztnQkFDbEYsT0FBTzthQUNQO1lBQ0QsU0FBUyxHQUFHLGNBQWMsQ0FBQyxhQUFhLENBQUksb0JBQW9CLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztTQUM5RjthQUFNLElBQUksT0FBTyxvQkFBb0IsS0FBSyxVQUFVLEVBQUU7WUFDdEQsU0FBUyxHQUFHLGNBQWMsQ0FBQyxZQUFZLENBQW1ELG9CQUFvQixFQUFVLDBCQUEwQixDQUFDLENBQUM7WUFDcEosSUFBSSxTQUFTLENBQUMsSUFBSSxLQUFLLEVBQUUsRUFBRTtnQkFDMUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLHdCQUF3QixDQUFDLDJDQUEyQyxDQUFDLENBQUM7YUFDOUY7U0FDRDthQUFNO1lBQ04sSUFBSSxDQUFDLGtCQUFrQixDQUFDLHdCQUF3QixDQUFDLG9CQUFvQixDQUFDLENBQUM7WUFDdkUsT0FBTztTQUNQO1FBRUQsSUFBSSxhQUFhLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUMzQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsd0JBQXdCLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDL0Q7UUFFRCxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDO1FBRXhELElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNyQixJQUFJLENBQUMsK0JBQStCLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3JEO0lBQ0YsQ0FBQztJQUVPLHdEQUErQixHQUF2QyxVQUF3QyxJQUFZO1FBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVjLDRCQUFhLEdBQTVCLFVBQ0MsSUFBWSxFQUNaLFNBQW1DO1FBRW5DLE9BQU87WUFDTixJQUFJLEVBQUUsSUFBSTtZQUNWLFdBQVcsRUFBOEIsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLFlBQVksZUFBZSxDQUFDLENBQUMsQ0FBQztnQkFFM0YscUJBQXFCLENBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztTQUNqRCxDQUFDO0lBQ0gsQ0FBQztJQUVjLDJCQUFZLEdBQTNCLFVBQ0MsU0FBd0MsRUFDeEMsSUFBYTtRQUViLElBQU0sWUFBWSxHQUFXLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXBGLE9BQU87WUFDTixJQUFJLEVBQUUsWUFBWTtZQUNsQixXQUFXLEVBQUUscUJBQXFCLENBQUksU0FBUyxDQUFDO1NBQ2hELENBQUM7SUFDSCxDQUFDO0lBRU8sMkNBQWtCLEdBQTFCLFVBQTJCLE1BQWdDO1FBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ3BCLE9BQU87U0FDUDtRQUVELFFBQVEsTUFBTSxFQUFFO1lBQ2YsS0FBSyx3QkFBd0IsQ0FBQywrQkFBK0I7Z0JBQzVELE9BQU8sQ0FBQyxLQUFLLENBQUMsK0RBQStELENBQUMsQ0FBQztnQkFDL0UsTUFBTTtZQUNQLEtBQUssd0JBQXdCLENBQUMsMkNBQTJDO2dCQUV4RSxPQUFPLENBQUMsS0FBSyxDQUFDLHVFQUF1RSxDQUFDLENBQUM7Z0JBQ3ZGLE1BQU07WUFDUCxLQUFLLHdCQUF3QixDQUFDLG9CQUFvQjtnQkFDakQsT0FBTyxDQUFDLEtBQUssQ0FBQyxpR0FBaUcsQ0FBQyxDQUFDO2dCQUNqSCxNQUFNO1lBQ1AsS0FBSyx3QkFBd0IsQ0FBQyxZQUFZO2dCQUN6QyxPQUFPLENBQUMsS0FBSyxDQUFDLGtFQUFrRSxDQUFDLENBQUM7Z0JBQ2xGLE1BQU07U0FDUDtJQUNGLENBQUM7SUFFRixxQkFBQztBQUFELENBQUMsQUEvSkQsSUErSkM7O0FBT0QsTUFBTSxVQUFVLHFCQUFxQixDQUE0QixRQUFXO0lBQzNFLElBQUksV0FBVyxHQUFhLEVBQUUsQ0FBQztJQUMvQixLQUNDLElBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQy9DLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFDdkMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEVBQzNDO1FBQ0QsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQVk7WUFDMUQsSUFBSSxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMvQixPQUFPO2FBQ1A7WUFDRCxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO0tBQ0g7SUFFRCxPQUFPLGdDQUNILFdBQVcsU0FDWCxNQUFNLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLFFBQ3RDLE1BQU0sQ0FBQyxVQUFDLEdBQU8sRUFBRSxJQUFZO1FBRTlCLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFM0IsT0FBTyxHQUFHLENBQUM7SUFDWixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDUixDQUFDO0FBT0QsTUFBTSxVQUFVLHFCQUFxQixDQUE0QixTQUF3QztJQUN4RyxPQUFPO1FBQUMsY0FBYzthQUFkLFVBQWMsRUFBZCxxQkFBYyxFQUFkLElBQWM7WUFBZCx5QkFBYzs7UUFBSyxPQUFBLHFCQUFxQixNQUFLLFNBQVMsWUFBVCxTQUFTLDBCQUFJLElBQUksYUFBRTtJQUE3QyxDQUE2QyxDQUFDO0FBQzFFLENBQUMifQ== \ No newline at end of file