{"id":19467164,"url":"https://github.com/squaresapp/hatjs","last_synced_at":"2025-08-23T04:13:47.691Z","repository":{"id":188159451,"uuid":"607332560","full_name":"squaresapp/hatjs","owner":"squaresapp","description":"Utility Functions For Anonymous Controller Classes","archived":false,"fork":false,"pushed_at":"2024-01-02T22:30:29.000Z","size":35,"stargazers_count":18,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-13T19:38:32.210Z","etag":null,"topics":["javascript","rawjs","vanilla-javascript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/squaresapp.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":"2023-02-27T19:24:52.000Z","updated_at":"2024-04-28T00:10:44.000Z","dependencies_parsed_at":"2023-12-23T17:04:19.815Z","dependency_job_id":"16c6cdae-6328-4273-b057-a929999922b5","html_url":"https://github.com/squaresapp/hatjs","commit_stats":{"total_commits":20,"total_committers":1,"mean_commits":20.0,"dds":0.0,"last_synced_commit":"a861e2dc8af68a85cde6319d367e926a30543642"},"previous_names":["paul-go/hat","squaresapp/hat","squaresapp/hatjs"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/squaresapp/hatjs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaresapp%2Fhatjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaresapp%2Fhatjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaresapp%2Fhatjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaresapp%2Fhatjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/squaresapp","download_url":"https://codeload.github.com/squaresapp/hatjs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaresapp%2Fhatjs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271023620,"owners_count":24686495,"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","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["javascript","rawjs","vanilla-javascript"],"created_at":"2024-11-10T18:33:43.379Z","updated_at":"2025-08-23T04:13:47.675Z","avatar_url":"https://github.com/squaresapp.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# HatJS - Utility Functions For Anonymous Controller Classes\n\nHatJS is a library designed to support the Anonymous Controller Class (ACC) pattern. Technically, you don't need any library to implement this pattern into your code, but using HatJS adds some helpful utility functions that allow you to easily discover and manipulate the anonymous controllers that are associated with a given HTML element.\n\n## Installation\n\nFrom jsDelivr:\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/@squaresapp/hatjs/hat.min.js\"\u003e\u003c/script\u003e\n```\nTypings\n```\nnpm install @squaresapp/hatjs\n```\n\n## What are Anonymous Controller Classes?\n\nAnonymous Controller Classes are a code pattern for organizing vanilla JS apps into a coherent structure. They're classes that wrap the root HTML element of a component, and provide a place for the backing logic that supports its operation. \n\nBelow is an example of an Anonymous Controller Class in action:\n\n```typescript\nclass SomeComponent {\n\treadonly head;\n\t\n\tconstructor() {\n\t\tthis.head = document.createElement(\"div\");\n\t\tthis.head.addEventListener(\"click', () =\u003e this.click());\n\t\t// Probably do some other stuff to this.head\n\t}\n\t\n\tprivate handleClick() {\n\t\talert(\"Clicked!\")\n\t}\n}\n```\n\nACCs are classes that create and wrap a root element, which possibly may container other nested elements, with event listeners connected, styling assigned, etc. They have methods which are typically event handlers or other helper methods. You then instanitate the component, and add the component's .head element to the DOM:\n\n```typescript\nconst component = new SomeComponent();\ndocument.body.append(component.head);\n```\n\nThe class is considered \"anonymous\" because you can discard your instance of the component as soon as its attached to the DOM. The instance of the class will be garbage collected as soon as the element is removed from the DOM and garbage collected. For example:\n\n```typescript\nclass SomeComponent {\n\treadonly head;\n\t\n\tconstructor() {\n\t\tthis.head = document.createElement(\"div\");\n\t\tthis.head.addEventListener(\"click', () =\u003e this.remove());\n\t\t// Probably do some other stuff to this.head\n\t}\n\t\n\tprivate remove() {\n\t\t// Remove the component's .head element from the DOM,\n\t\t// which will by extension garbage collect this instance\n\t\t// of SomeComponent.\n\t\tthis.head.remove();\n\t}\n}\n```\n\nACCs impose no restrictions on you. They can inherit from anything (or nothing). They're just an idea––you can mold them to behave however you like.\n\nThere are many scenarios when you might want to get the ACC associated with a particular element. For example, imagine iterating through the ancestor elements of the this.head element, and getting the ACCs associated with it in order to invoke some public method. **This is where HatJS comes in**.\n\n## HatJS Utility Functions \n\nThe HatJS library is a stateless library of utility functions that allow you to inspect the ACCs associated with an element, and send various signals between them.\n\n`Hat.wear(object)` - Marks an object as a Hat. (Or formally–an \"Anonymous Controller Class\").\n\n`Hat.of(element, HatType)` - Gets a hat, optionally of a specified type, that is associated with the specified element.\n\n`Hat.nearest(element, HatType)` - Returns a reference to the Hat that is nearest in the DOM to the specified element.\n\n`Hat.up(element, HatType)` - Scans upward through through the DOM, starting at the specified element, until it finds a Hat of the specified type. (Can return null)\n\n`Hat.down()` - Finds the first descendent element that has an attached Hat of the specified type, that exists underneath the specified Node (or Hat).\n\n`Hat.over()` -  Scans upward through the DOM, starting at the specified Node, looking for the first element wearing a Hat of the specified type. (Throws an exception)\n\n`Hat.under()` - Finds all descendent elements that have an attached Hat of the specified type, that exist underneath the specified Node or Hat.\n\n`Hat.watch(object, signal, handler)` - Enables a hat to have the ability to respond to signaling functions.\n\n`Hat.signal(SignalingFunction, ...signalingFunctionArguments)` - Invokes the watch handlers on all other hats in the DOM that have subscribed to the specified signaling function, and passes the specified arguments to each call.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquaresapp%2Fhatjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsquaresapp%2Fhatjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquaresapp%2Fhatjs/lists"}