From 0864d68f305208f9fa46537efd49a0245a8e9e4b Mon Sep 17 00:00:00 2001 From: Ross Bulat Date: Sat, 2 Nov 2024 14:27:26 +0700 Subject: [PATCH] feat: init `factories` package with `withProviders` (#137) --- README.md | 6 ++- builder/package.json | 1 + builder/src/builders/factories/index.ts | 54 +++++++++++++++++++++++ builder/src/index.ts | 5 +++ library/factories/gulpfile.js | 43 ++++++++++++++++++ library/factories/package.json | 23 ++++++++++ library/factories/packageInfo.yml | 8 ++++ library/factories/src/index.tsx | 4 ++ library/factories/src/withProviders.tsx | 22 +++++++++ library/factories/tsconfig.json | 18 ++++++++ library/hooks/src/{index.ts => index.tsx} | 0 library/hooks/src/useOnResize.tsx | 3 ++ library/hooks/src/useOutsideAlerter.tsx | 4 +- library/hooks/src/useSize.tsx | 4 +- package.json | 3 +- release-please-config.json | 1 + yarn.lock | 17 +++++++ 17 files changed, 209 insertions(+), 7 deletions(-) create mode 100644 builder/src/builders/factories/index.ts create mode 100644 library/factories/gulpfile.js create mode 100644 library/factories/package.json create mode 100644 library/factories/packageInfo.yml create mode 100644 library/factories/src/index.tsx create mode 100644 library/factories/src/withProviders.tsx create mode 100644 library/factories/tsconfig.json rename library/hooks/src/{index.ts => index.tsx} (100%) diff --git a/README.md b/README.md index 5c90341..4409445 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ -![W3uxOG](https://github.com/user-attachments/assets/f35f990a-6e9c-4870-b2cb-8122231cefcf) - # w3ux Library #### `@w3ux/extension-assets`  [[npm](https://www.npmjs.com/package/@w3ux/extension-assets) |  [source](https://github.com/w3ux/w3ux-library/tree/main/library/extension-assets)] A list of popular Web3 wallet extensions with metadata and icons. +#### `@w3ux/factories`  [[npm](https://www.npmjs.com/package/@w3ux/factories) |  [source](https://github.com/w3ux/w3ux-library/tree/main/library/factories)] + +A collection of general purpose TypeScript factories. + #### `@w3ux/hooks`  [[npm](https://www.npmjs.com/package/@w3ux/hooks) |  [source](https://github.com/w3ux/w3ux-library/tree/main/library/hooks)] A collection of generic React hooks. diff --git a/builder/package.json b/builder/package.json index a3480cd..680ce4d 100644 --- a/builder/package.json +++ b/builder/package.json @@ -12,6 +12,7 @@ "build:react-polkicon": "node dist/index.js -t build:react-polkicon", "build:react-connect-kit": "node dist/index.js -t build:react-connect-kit", "build:hooks": "node dist/index.js -t build:hooks", + "build:factories": "node dist/index.js -t build:factories", "build:types": "node dist/index.js -t build:types", "build:utils": "node dist/index.js -t build:utils", "clear": "rm -rf node_modules dist tsconfig.tsbuildinfo" diff --git a/builder/src/builders/factories/index.ts b/builder/src/builders/factories/index.ts new file mode 100644 index 0000000..a110981 --- /dev/null +++ b/builder/src/builders/factories/index.ts @@ -0,0 +1,54 @@ +/* @license Copyright 2024 w3ux authors & contributors +SPDX-License-Identifier: GPL-3.0-only */ + +import { PACKAGE_OUTPUT } from "config"; +import { prebuild } from "builders/common/prebuild"; +import { + gePackageDirectory, + generatePackageJson, + removePackageOutput, +} from "builders/util"; +import { promisify } from "util"; +import { exec } from "child_process"; + +const execPromisify = promisify(exec); + +export const build = async () => { + const folder = "factories"; + const libDirectory = gePackageDirectory(folder); + + try { + // Prebuild integrity checks. + if (!(await prebuild(folder))) { + throw `Prebuild failed.`; + } + + // Call gump command to build dist folder. + try { + await execPromisify(`cd ../library/${folder} && yarn build`); + } catch (e) { + throw `Failed to generate dist. ${e}`; + } + + // Generate package.json. + if ( + !(await generatePackageJson( + libDirectory, + `${libDirectory}/${PACKAGE_OUTPUT}`, + "gulp" + )) + ) { + throw `Failed to generate package.json file.`; + } + + console.log(`✅ Package successfully built.`); + } catch (err) { + // Handle on error. + console.error(`❌ Error occurred while building the package.`, err); + + // Remove package output directory if it exists. + if (!(await removePackageOutput(libDirectory, false))) { + console.error(`❌ Failed to remove package output directory.`); + } + } +}; diff --git a/builder/src/index.ts b/builder/src/index.ts index 811c7d8..b838390 100644 --- a/builder/src/index.ts +++ b/builder/src/index.ts @@ -10,6 +10,7 @@ import * as directory from "./builders/directory"; import * as reactOdometer from "./builders/react-odometer"; import * as reactPolkicon from "./builders/react-polkicon"; import * as hooks from "./builders/hooks"; +import * as factories from "./builders/factories"; import * as reactConnectKit from "./builders/react-connect-kit"; const args = minimist(process.argv.slice(2)); @@ -41,6 +42,10 @@ switch (task) { hooks.build(); break; + case "build:factories": + factories.build(); + break; + case "build:react-connect-kit": reactConnectKit.build(); break; diff --git a/library/factories/gulpfile.js b/library/factories/gulpfile.js new file mode 100644 index 0000000..5faeeb6 --- /dev/null +++ b/library/factories/gulpfile.js @@ -0,0 +1,43 @@ +/* @license Copyright 2024 w3ux authors & contributors +SPDX-License-Identifier: GPL-3.0-only */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +import gulp from "gulp"; +import ts from "gulp-typescript"; +import sourcemaps from "gulp-sourcemaps"; +import merge from "merge-stream"; + +const { dest, series } = gulp; + +// Buld CommonJS module. +const buildCommonJs = () => + doBuild( + ts.createProject("tsconfig.json", { + module: "commonjs", + target: "es2015", + removeComments: true, + }), + "cjs" + ); + +// Build ES module. +const buildEsm = () => + doBuild( + ts.createProject("tsconfig.json", { + module: "esnext", + target: "esnext", + removeComments: true, + }), + "mjs" + ); + +// Build package with provided Typescript project. +const doBuild = (tsProject, outDir) => { + var tsResult = tsProject.src().pipe(sourcemaps.init()).pipe(tsProject()); + + return merge(tsResult, tsResult.js) + .pipe(sourcemaps.write(".")) + .pipe(dest(`dist/${outDir}`)); +}; + +export default series(buildCommonJs, buildEsm); diff --git a/library/factories/package.json b/library/factories/package.json new file mode 100644 index 0000000..fe9ae88 --- /dev/null +++ b/library/factories/package.json @@ -0,0 +1,23 @@ +{ + "name": "@w3ux/factories-source", + "license": "GPL-3.0-only", + "version": "1.0.0-beta.0", + "type": "module", + "scripts": { + "clear": "rm -rf node_modules dist tsconfig.tsbuildinfo", + "build": "gulp --silent" + }, + "peerDependencies": { + "react": "^18" + }, + "devDependencies": { + "@types/react": "^18", + "@w3ux/types": "^0.2.0", + "gulp": "^5.0.0", + "gulp-sourcemaps": "^3.0.0", + "gulp-strip-comments": "^2.6.0", + "gulp-typescript": "^6.0.0-alpha.1", + "react": "^18", + "typescript": "^5.4.5" + } +} diff --git a/library/factories/packageInfo.yml b/library/factories/packageInfo.yml new file mode 100644 index 0000000..054978f --- /dev/null +++ b/library/factories/packageInfo.yml @@ -0,0 +1,8 @@ +directory: + - name: Factories + description: A collection of general purpose TypeScript factories. + +npm: + title: Hooks + contents: + - item: A collection of general purpose TypeScript factories. diff --git a/library/factories/src/index.tsx b/library/factories/src/index.tsx new file mode 100644 index 0000000..bbeb761 --- /dev/null +++ b/library/factories/src/index.tsx @@ -0,0 +1,4 @@ +/* @license Copyright 2024 w3ux authors & contributors +SPDX-License-Identifier: GPL-3.0-only */ + +export * from "./withProviders"; diff --git a/library/factories/src/withProviders.tsx b/library/factories/src/withProviders.tsx new file mode 100644 index 0000000..b7da263 --- /dev/null +++ b/library/factories/src/withProviders.tsx @@ -0,0 +1,22 @@ +/* @license Copyright 2024 w3ux authors & contributors +SPDX-License-Identifier: GPL-3.0-only */ + +import type { FC } from "react"; + +// `providers` accepts standalone functional components or an array of a functional component and its props. +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type Provider = FC | [FC, any]; + +// A pure function that applies an arbitrary amount of context providers to a wrapped component. +export const withProviders = (providers: Provider[], Wrapped: FC) => + providers.reduceRight( + (acc, prov) => { + if (Array.isArray(prov)) { + const Provider = prov[0]; + return {acc}; + } + const Provider = prov; + return {acc}; + }, + + ); diff --git a/library/factories/tsconfig.json b/library/factories/tsconfig.json new file mode 100644 index 0000000..3020424 --- /dev/null +++ b/library/factories/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": "./src", + "rootDir": "./src", + "outDir": "./dist", + "module": "ESNext", + "moduleResolution": "Node", + "target": "es5", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "sourceMap": false, + "jsx": "react-jsx", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "esModuleInterop": true, + }, + "include": ["src/**/*"], +} diff --git a/library/hooks/src/index.ts b/library/hooks/src/index.tsx similarity index 100% rename from library/hooks/src/index.ts rename to library/hooks/src/index.tsx diff --git a/library/hooks/src/useOnResize.tsx b/library/hooks/src/useOnResize.tsx index f0a8fd1..58cbf28 100644 --- a/library/hooks/src/useOnResize.tsx +++ b/library/hooks/src/useOnResize.tsx @@ -1,3 +1,6 @@ +/* @license Copyright 2024 w3ux authors & contributors +SPDX-License-Identifier: GPL-3.0-only */ + import { MutableRefObject, useEffect, useRef } from "react"; interface UseOnResizeOptions { diff --git a/library/hooks/src/useOutsideAlerter.tsx b/library/hooks/src/useOutsideAlerter.tsx index 695a5a4..94d580b 100644 --- a/library/hooks/src/useOutsideAlerter.tsx +++ b/library/hooks/src/useOutsideAlerter.tsx @@ -1,5 +1,5 @@ -// Copyright 2024 @polkadot-cloud/polkadot-staking-dashboard authors & contributors -// SPDX-License-Identifier: GPL-3.0-only +/* @license Copyright 2024 w3ux authors & contributors +SPDX-License-Identifier: GPL-3.0-only */ import { useEffect, type RefObject } from "react"; import type { AnyFunction, AnyJson } from "@w3ux/types"; diff --git a/library/hooks/src/useSize.tsx b/library/hooks/src/useSize.tsx index e7a719b..3051725 100644 --- a/library/hooks/src/useSize.tsx +++ b/library/hooks/src/useSize.tsx @@ -1,5 +1,5 @@ -// Copyright 2024 @polkadot-cloud/polkadot-staking-dashboard authors & contributors -// SPDX-License-Identifier: GPL-3.0-only +/* @license Copyright 2024 w3ux authors & contributors +SPDX-License-Identifier: GPL-3.0-only */ import type { MutableRefObject } from "react"; import { useEffect, useRef, useState } from "react"; diff --git a/package.json b/package.json index 379df70..83eac88 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "license": "GPL-3.0-only", "description": "w3ux library source code", "scripts": { - "build:directory": "node builder/run.mjs -t directory:build", + "build:directory": "node builder/dist/index.js -t build:directory", "clear": "npm run --workspaces clear && rm -rf node_modules coverage", "build": "npm run build --workspaces --if-present", "lint": "eslint './**' --fix && npx prettier --write .", @@ -37,6 +37,7 @@ "builder", "library/utils", "library/types", + "library/factories", "library/hooks", "library/extension-assets", "library/validator-assets", diff --git a/release-please-config.json b/release-please-config.json index d4381e9..e95490f 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -3,6 +3,7 @@ "include-component-in-tag": true, "packages": { "library/extension-assets": {}, + "library/factories": {}, "library/hooks": {}, "library/react-connect-kit": {}, "library/react-odometer": {}, diff --git a/yarn.lock b/yarn.lock index 7515cf9..cc25c52 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1679,6 +1679,23 @@ __metadata: languageName: node linkType: hard +"@w3ux/factories-source@workspace:library/factories": + version: 0.0.0-use.local + resolution: "@w3ux/factories-source@workspace:library/factories" + dependencies: + "@types/react": "npm:^18" + "@w3ux/types": "npm:^0.2.0" + gulp: "npm:^5.0.0" + gulp-sourcemaps: "npm:^3.0.0" + gulp-strip-comments: "npm:^2.6.0" + gulp-typescript: "npm:^6.0.0-alpha.1" + react: "npm:^18" + typescript: "npm:^5.4.5" + peerDependencies: + react: ^18 + languageName: unknown + linkType: soft + "@w3ux/hooks-source@workspace:library/hooks": version: 0.0.0-use.local resolution: "@w3ux/hooks-source@workspace:library/hooks"