feat: initial utils distribution (#7)

This commit is contained in:
Ayo Ayco 2023-12-08 13:15:00 +01:00 committed by GitHub
parent 1ae5fa7535
commit 703ef9e45d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 42 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "web-component-base", "name": "web-component-base",
"version": "2.0.0-beta.1", "version": "2.0.0-beta.2",
"description": "A zero-dependency, ~600 Bytes (minified & gzipped), JS base class for creating reactive custom elements easily", "description": "A zero-dependency, ~600 Bytes (minified & gzipped), JS base class for creating reactive custom elements easily",
"type": "module", "type": "module",
"exports": { "exports": {
@ -16,6 +16,10 @@
"types": "./attach-effect.d.ts", "types": "./attach-effect.d.ts",
"import": "./attach-effect.js" "import": "./attach-effect.js"
}, },
"./utils": {
"types": "./utils/index.d.ts",
"import": "./utils/index.js"
},
"./WebComponent.min.js": { "./WebComponent.min.js": {
"types": "./WebComponent.d.ts", "types": "./WebComponent.d.ts",
"import": "./WebComponent.min.js" "import": "./WebComponent.min.js"
@ -26,12 +30,11 @@
"start": "npx simple-server .", "start": "npx simple-server .",
"demo": "npx simple-server .", "demo": "npx simple-server .",
"site": "npm start -w site", "site": "npm start -w site",
"build": "npm run clean && npm run generate:types && npm run copy:meta && npm run copy:source && npm run minify", "build": "npm run clean && tsc && npm run copy:meta && npm run copy:source && npm run minify",
"clean": "rm -rf dist", "clean": "rm -rf dist",
"minify": "npx uglifyjs ./dist/WebComponent.js -o ./dist/WebComponent.min.js", "minify": "npx uglifyjs ./dist/WebComponent.js -o ./dist/WebComponent.min.js",
"generate:types": "tsc --allowJs src/* --outDir dist --declaration --emitDeclarationOnly",
"copy:meta": "node prepare.js && cp README.md ./dist && cp LICENSE ./dist", "copy:meta": "node prepare.js && cp README.md ./dist && cp LICENSE ./dist",
"copy:source": "cp ./src/* ./dist", "copy:source": "cp -r ./src/* ./dist",
"pub": "npm run clean && npm run build && cd ./dist && npm publish", "pub": "npm run clean && npm run build && cd ./dist && npm publish",
"pub:beta": "npm run clean && npm run build && cd ./dist && npm publish --tag beta", "pub:beta": "npm run clean && npm run build && cd ./dist && npm publish --tag beta",
"publish:patch": "npm version patch && npm run pub", "publish:patch": "npm version patch && npm run pub",

View file

@ -1,3 +1,7 @@
import { getKebabCase } from "./utils/get-kebab-case";
import { getCamelCase } from "./utils/get-camel-case";
import { serialize, deserialize } from "./utils/parse";
/** /**
* A minimal base class to reduce the complexity of creating reactive custom elements * A minimal base class to reduce the complexity of creating reactive custom elements
* @license MIT <https://opensource.org/licenses/MIT> * @license MIT <https://opensource.org/licenses/MIT>
@ -89,7 +93,7 @@ export class WebComponent extends HTMLElement {
} }
attributeChangedCallback(property, previousValue, currentValue) { attributeChangedCallback(property, previousValue, currentValue) {
const camelCaps = this.#getCamelCaps(property); const camelCaps = getCamelCase(property);
if (previousValue !== currentValue) { if (previousValue !== currentValue) {
this[property] = currentValue === "" || currentValue; this[property] = currentValue === "" || currentValue;
@ -103,26 +107,16 @@ export class WebComponent extends HTMLElement {
} }
#handleUpdateProp(key, stringifiedValue) { #handleUpdateProp(key, stringifiedValue) {
const restored = this.#deserialize(stringifiedValue, this.#typeMap[key]); const restored = deserialize(stringifiedValue, this.#typeMap[key]);
if (restored !== this.props[key]) this.props[key] = restored; if (restored !== this.props[key]) this.props[key] = restored;
} }
#getCamelCaps(kebab) {
return kebab.replace(/-./g, (x) => x[1].toUpperCase());
}
#typeMap = {}; #typeMap = {};
#effectsMap = {}; #effectsMap = {};
#handler(setter, meta) { #handler(setter, meta) {
const effectsMap = meta.#effectsMap; const effectsMap = meta.#effectsMap;
const typeMap = meta.#typeMap; const typeMap = meta.#typeMap;
const getKebab = (str) => {
return str.replace(
/[A-Z]+(?![a-z])|[A-Z]/g,
($, ofs) => (ofs ? "-" : "") + $.toLowerCase()
);
};
return { return {
set(obj, prop, value) { set(obj, prop, value) {
@ -140,9 +134,8 @@ export class WebComponent extends HTMLElement {
} else if (oldValue !== value) { } else if (oldValue !== value) {
obj[prop] = value; obj[prop] = value;
effectsMap[prop]?.forEach((f) => f(value)); effectsMap[prop]?.forEach((f) => f(value));
const kebab = getKebab(prop); const kebab = getKebabCase(prop);
setter(kebab, serialize(value));
setter(kebab, meta.#serialize(value));
} }
return true; return true;
@ -158,29 +151,6 @@ export class WebComponent extends HTMLElement {
}; };
} }
#deserialize(value, type){
switch (type) {
case 'number':
case 'boolean':
case 'object':
case 'undefined':
return JSON.parse(value);
default:
return value;
}
};
#serialize(value) {
switch(typeof value) {
case 'number':
case 'boolean':
case 'object':
case 'undefined':
return JSON.stringify(value);
default: return value;
}
}
#initializeProps() { #initializeProps() {
if (!this.#props) { if (!this.#props) {
this.#props = new Proxy( this.#props = new Proxy(

View file

@ -0,0 +1,3 @@
export function getCamelCase(kebab) {
return kebab.replace(/-./g, (x) => x[1].toUpperCase());
}

View file

@ -0,0 +1,6 @@
export function getKebabCase(str) {
return str.replace(
/[A-Z]+(?![a-z])|[A-Z]/g,
($, ofs) => (ofs ? "-" : "") + $.toLowerCase()
);
}

1
src/utils/index.js Normal file
View file

@ -0,0 +1 @@
export {serialize, deserialize} from './parse.js';

23
src/utils/parse.js Normal file
View file

@ -0,0 +1,23 @@
export function deserialize(value, type) {
switch (type) {
case "number":
case "boolean":
case "object":
case "undefined":
return JSON.parse(value);
default:
return value;
}
}
export function serialize(value) {
switch (typeof value) {
case "number":
case "boolean":
case "object":
case "undefined":
return JSON.stringify(value);
default:
return value;
}
}

15
tsconfig.json Normal file
View file

@ -0,0 +1,15 @@
{
"compilerOptions": {
"allowJs": true,
"outDir": "dist",
"declaration": true,
"emitDeclarationOnly": true
},
"include": [
"src/*",
],
"exclude": [
"src/utils"
]
}