{"id":23219628,"url":"https://github.com/barcek/awb","last_synced_at":"2025-04-05T15:12:07.537Z","repository":{"id":157419468,"uuid":"366819741","full_name":"barcek/awb","owner":"barcek","description":"cultivate HTML | monadic DOM tree transformer | frontend generation | library \u0026 command line tool | Node.js","archived":false,"fork":false,"pushed_at":"2023-07-21T21:01:59.000Z","size":360,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-11T11:53:01.807Z","etag":null,"topics":["automation","backend","command-line-tool","domtree","dx","frontend","functional-programming","html","javascript","library","monad","transformation","traversal","web-development"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/barcek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-12T18:44:39.000Z","updated_at":"2025-01-13T21:29:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"f0918087-5f8f-4c37-9fe1-a130019b4de3","html_url":"https://github.com/barcek/awb","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barcek%2Fawb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barcek%2Fawb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barcek%2Fawb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barcek%2Fawb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/barcek","download_url":"https://codeload.github.com/barcek/awb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247353742,"owners_count":20925329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","backend","command-line-tool","domtree","dx","frontend","functional-programming","html","javascript","library","monad","transformation","traversal","web-development"],"created_at":"2024-12-18T21:36:09.696Z","updated_at":"2025-04-05T15:12:07.514Z","avatar_url":"https://github.com/barcek.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# awb\n\nA library exposing a monad to generate, transform and serialize DOM trees.\n\n## Why?\n\nTo help automate web development. It can be used as part of a model-driven approach with [thru.js](https://github.com/barcek/thru.js), to generate content from HTML thru file methods.\n\nIt could also offer a fresh perspective if you're starting out with functional programming, not least as an example of the monad. The module 'utils.js' also has an implementation of `pipe`.\n\n## How?\n\nEvery instance of the `Awb` class has a `.DOMTree` attribute, set when the instance is created (see [Getting started](#getting-started) below).\n\nEvery instance also has a `.map` method which can be used to modify this `.DOMTree` attribute. The method can be chained, to perform a series of transformations. It takes a handler function which is applied to every element on the DOMTree. For now, you write the handlers.\n\nOther methods - [.ap and .liftAN](#ap--liftAN) - allow multiple DOMTrees to be used together, spliced for example.\n\n## So..?\n\nRather than being typed out in full and manually reworked, web pages can be generated, and later regenerated differently.\n\nFor example, a simple template for a component - a card say - could be passed into an `Awb` instance to be multiplied, modified based on a configuration file and populated from a content source (remembering to validate and/or sanitize), before being combined into a list and inserted into one or more pages.\n\nSmall differences in starting values could create wildly varying designs even with the same handlers and content.\n\n- [Getting started](#getting-started)\n    - [Cloning \u0026 installing](#cloning--installing)\n    - [Importing the library](#importing-the-library)\n    - [Working with DOMTrees](#working-with-domtrees)\n        - [Initialization](#initialization)\n        - [Transformation](#transformation)\n- [Growing further](#growing-further)\n  - [Other methods](#other-methods)\n    - [.join \u0026 .chain](#join--chain)\n    - [.ap \u0026 .liftAN](#ap--liftAN)\n  - [Thicker foresting](#thicker-foresting)\n  - [Use via the CLI](#use-via-the-cli)\n    - [Options](#options)\n      - [Link file](#link-file)\n- [Making changes](#making-changes)\n    - [Test files](#test-files)\n    - [npm audit](#npm-audit)\n- [Development plan](#development-plan)\n- [Repository tree](#repository-tree)\n\n## Getting started\n\nIf you're comfortable cloning repositories, installing dependencies with npm and using ES modules, skip to [Working with DOMTrees](#working-with-domtrees).\n\n### Cloning \u0026 installing\n\nYou'll need Git \u0026 npm installed.\n\nFirst, enter the directory in which you'd like to store the library and run the Git command to clone the repository:\n\n```shell\ngit clone https://github.com/barcek/awb.git\n```\n\nNext, enter the newly created 'awb' directory and run the npm command to install dependencies:\n\n```shell\nnpm install\n```\n\n### Importing the library\n\nImport `Awb` from wherever the library is stored - it's the default export. The following line assumes the library is in the same directory as the importing file.\n\n```js\nimport Awb from './awb/index.js';\n```\n\nIt also assumes the importing file is an ES module, not a CommonJS module, i.e. that the file extension is '.mjs' or the 'package.json' for the file has the following top-level key-value pair:\n\n```json\n\"type\": \"module\"\n```\n\nIf your file is a CommonJS module, it's possible to use the dynamic import statement `import(path)`, which returns a `Promise`. The `Awb` function can be found on the `default` property of the resolved value.\n\n```js\nimport('./awb/index.js')\n  .then(value =\u003e {\n    const Awb = value.default;\n    ...\n  });\n```\n\n### Working with DOMTrees\n\n#### Initialization\n\nSeed a new tree with an HTML string or template object passed into the `.sow` method, or use the `.of` method to work with an existing tree.\n\nWith an HTML string:\n\n```js\nAwb.sow('\u003cp id=\"seed\"\u003ePlanting a seed.\u003c/p\u003e');\n```\n\nWith a template object:\n\n```js\nAwb.sow({ n: 'p', as: { id: 'seed'}, t: 'Planting a seed.', ds: [] });\n```\n\nHere `n` is the element name, `as` any attributes to be set, `t` any text content and `ds` any dependents, nested in the same format. Classes can be added as an array of strings on the attribute object's  `cs` key.\n\nWith an existing DOM tree:\n\n```js\nAwb.of(DOMTree);\n```\n\n#### Transformation\n\nThat done, transform away by chaining the `.map` method, passing in a function to be applied to every element in the tree.\n\n```js\nAwb.of(DOMTree).map(handleElement);\n```\n\nThe element is passed to the function as the first argument.\n\nUse the `.serialize` method to get the final HTML as a string, passing in an integer for that number of spaces of indentation.\n\n```js\nconst HTML = Awb.of(DOMTree).serialize(4);\n```\n\n## Growing further\n\n### Other methods\n\n#### .join \u0026 .chain\n\nThe `.DOMTree` property can be accessed directly or via the `.join` method, which unwraps the value from the Awb instance.\n\nThe `.chain` method is built from `.map` and `.join` and can be used in place of `.map` where the mapping function instantiates an awb around an element in the DOM tree - the use of `.join` unwraps the value of each such instance once the mapping is complete. If that value is an element, not another level of instance, this flattens the whole tree bar the root element, which is wrapped as it was before the mapping.\n\n#### .ap \u0026 .liftAN\n\nThe `.ap` method can be used to work with two or more trees, when the value in the instance is a partially applied function requiring one or more additional trees to complete, for example following a use of `.map` with a curried handler. The value in the Awb instance passed to `.ap` becomes the next argument.\n\n```js\nAwb.of(DOMTree).map(useTrees).ap(instance);\n```\n\nThe `.liftAN` method can combine multiple uses of `.ap` to apply a function to several additional instances. The function is the first argument to the method, followed by each instance to be passed to it.\n\n```js\nAwb.of(DOMTree).liftAN(useTrees, instance1, instance2);\n```\n\n### Thicker foresting\n\nFor generation of multiple pages or larger projects, you could use [thru.js](https://github.com/barcek/thru.js).\n\n### Use via the CLI\n\nThe library can also be used from the command line to transform an HTML string, applying a handler exported from a module as the map function and including an optional number of spaces of indentation.\n\nThe HTML is piped in, with the module path, export name and number of spaces passed as arguments:\n\n```shell\nnode path/to/awb PATH/TO/MODULE EXPORT[ INDENT]\n```\n\nAlternatively, an executable link file can be created (see [Options](#options) below) allowing the library to be run from any directory. This is achieved by placing the link file in a directory listed on the `$PATH` environment variable, e.g. '/bin' or '/usr/bin'. With the default link file name, i.e. 'awb':\n\n```shell\nawb PATH/TO/MODULE EXPORT[ INDENT]\n```\n\nThe base command `node path/to/awb` - or `awb` with a properly placed default link file - can be run to see usage as well as the lists of methods and options.\n\n#### Options\n\nThe following can be passed to `node path/to/awb` in place of the transformation arguments:\n\n- `--show` / `-s`  `METHOD/all`, to show code for METHOD or all methods then exit\n- `--link` / `-l`  `[PATH]`, create link file at path/to/awb/awb or PATH\n- `--version` / `-v`, to show name and version number then exit\n- `--help` / `-h`, to show help text, incl. methods, then exit\n\n##### Link file\n\nThe link file is created by default in the root of the project directory with the name `awb`, the mode `775` and a hashbang referencing `/bin/sh`.\n\n## Making changes\n\nRunning the tests after making changes and adding tests to cover new behaviour is recommended, as is a regular audit of dependencies.\n\n### Test files\n\nThe npm packages `mocha` and `chai` are used for testing and the test files can be run with the following command:\n\n```shell\nmocha\n```\n\nThis command along with the `--recursive` flag is the current content of the 'test' script in the 'package.json' file, which can be run with the following:\n\n```shell\nnpm test\n```\n\nThe command in the 'watch' script is set up to watch for and test on changes:\n\n```shell\nnpm run watch\n```\n\nThe files themselves are in the 'test' folder.\n\n### npm audit\n\nThe `npm audit` command can be used to run a security audit on the dependencies used, with the process returning information on updates where available. The command `npm audit fix` can be used instead or thereafter to install compatible updates. See the npm documentation for [more detail](https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities).\n\n## Development plan\n\nThe following are the expected next steps in the development of the code base. The general medium-term aim is a package for procedural webpage generation with a higher-level interface covering common base patterns. Pull requests are welcome for these and other potential improvements.\n\n- allow for use of the library via the command line\n- implement a map method handler class\n- provide demo handler instances\n- abstract common patterns\n- add fuller testing\n\n## Repository tree\n\n```\n./\n├── lib\n│   ├── awb.js\n│   ├── get.js\n│   ├── index.js\n│   ├── run.js\n│   ├── set.js\n│   ├── use.js\n│   └── utils.js\n├── test\n│   ├── awb.test.js\n│   ├── get.test.js\n│   ├── run.test.js\n│   ├── set.test.js\n│   ├── src.test.js\n│   ├── use.test.js\n│   └── utils.test.js\n├── .gitignore\n├── LICENSE.txt\n├── README.md\n├── index.js\n├── package-lock.json\n└── package.json\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarcek%2Fawb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarcek%2Fawb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarcek%2Fawb/lists"}