{"id":18941949,"url":"https://github.com/bahrus/obj-ml","last_synced_at":"2026-02-27T11:31:23.294Z","repository":{"id":54864401,"uuid":"370317299","full_name":"bahrus/obj-ml","owner":"bahrus","description":"obj-ml is a web component that enables a declarative, HTML-based markup language to instantiate, and update, a JavaScript object.","archived":false,"fork":false,"pushed_at":"2023-03-12T13:38:48.000Z","size":203,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"baseline","last_synced_at":"2025-11-01T11:14:40.053Z","etag":null,"topics":["custom-element","custom-elements","customelement","customelements","web-component","web-components","webcomponent","webcomponents"],"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/bahrus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-24T10:44:22.000Z","updated_at":"2024-06-05T05:34:44.000Z","dependencies_parsed_at":"2024-11-08T12:32:06.522Z","dependency_job_id":"adfb381b-c028-4ad9-8bc2-475c0b1d87c8","html_url":"https://github.com/bahrus/obj-ml","commit_stats":{"total_commits":71,"total_committers":1,"mean_commits":71.0,"dds":0.0,"last_synced_commit":"f19df50d524693304b00746ab349efd2d516adc6"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bahrus/obj-ml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahrus%2Fobj-ml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahrus%2Fobj-ml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahrus%2Fobj-ml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahrus%2Fobj-ml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bahrus","download_url":"https://codeload.github.com/bahrus/obj-ml/tar.gz/refs/heads/baseline","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahrus%2Fobj-ml/sbom","scorecard":{"id":223691,"data":{"date":"2025-08-11","repo":{"name":"github.com/bahrus/obj-ml","commit":"f19df50d524693304b00746ab349efd2d516adc6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.1,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'baseline'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":3,"reason":"7 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T03:10:43.154Z","repository_id":54864401,"created_at":"2025-08-17T03:10:43.154Z","updated_at":"2025-08-17T03:10:43.154Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29892106,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T09:48:51.284Z","status":"ssl_error","status_checked_at":"2026-02-27T09:48:43.992Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["custom-element","custom-elements","customelement","customelements","web-component","web-components","webcomponent","webcomponents"],"created_at":"2024-11-08T12:30:09.708Z","updated_at":"2026-02-27T11:31:23.271Z","avatar_url":"https://github.com/bahrus.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# obj-ml (WIP)\n\nobj-ml (or o-m for short) is a web component that enables a declarative, HTML-based markup language to instantiate, and update, a lazy-loaded JavaScript object.\n\n\u003ca href=\"https://nodei.co/npm/obj-ml/\"\u003e\u003cimg src=\"https://nodei.co/npm/obj-ml.png\"\u003e\u003c/a\u003e\n\n\u003cimg src=\"https://badgen.net/bundlephobia/minzip/obj-ml\"\u003e\n\nUse cases:  \n\n1.  Provide a way to represent structured data that needs to be submitted with a post request, within a form element (or specifying a form target element.)\n2.  Provides a place to pass data from, say, a form, which can then broadcast to other elements on the page via event subscription.\n3.  Provides considerably more data types than JSON.\n3.  Data can stream in as the HTML streams in.\n4.  Querying the data with css/xpath now possible for free.\n5.  XSLT can be used to generate the view off it.\n6.  Can you use XSLT to \"reverse engineer\" server rendered HTML to obj-ml, essentially extracting the data out of the HTML sent to the browser.\n\n## Syntax\n\n```html\n\u003cobj-ml prop1='string property' prop2-bool prop3-int=5 prop4-float=2.7 prop5-date=\"May 24, 2021\" prop6-obj='{\"mySubSubObj\":\"hello\"}' prop7-num=1,234,567\u003e\u003c/obj-ml\u003e\n```\n\nResults in creating a JavaScript object:\n\n```JSON\n{\n    \"prop1\": \"string property\",\n    \"prop2\": true,\n    \"prop3\": 5,\n    ... \n}\n```\n\n\n... and setting property \"value\" to that JavaScript object.  Event \"value-changed\" is fired as the value changes.  The value is passed in the detail, as well as some indication of what part of the object changed, when applicable.\n\nAn extending component, o-m, does the same thing as obj-ml, but the syntax will involve less typing, but is more likely to conflict with other web component names.\n\nAlso, for both obj-ml and o-m, the part of the attribute that specifies the type of the data can be abbreviated by the first letter, e.g. prop3-i, prop4-d, etc.\n\nProperty names are derived by \"camelCasing\" the attribute name before the type postfix.  -obj or -o postfix means use JSON.parse on the attribute (and arrays are objects).\n\nIf the property name is not a compound name, or if it ends with a non-recognized postfix, it is assumed to be a string property, and the entire name is camelCased to turn it into a property.\n\nIf you need a property to end with one of the reserved types, use it twice:\n\n```html\n\u003cobj-ml root-beer-float-float=1.99\u003e\u003c/obj-ml\u003e\n```\n\n## Attribute Changes\n\nobj-ml watches for all attribute changes, and if one changes, it updates the \"value\", and an event is emitted, containing the name of the property that changed (e.detail.propLastChanged).\n\n## Nested obj-ml's\n\n```html\n\u003cobj-ml\u003e\n    \u003cobj-ml itemprop='subObj' prop1='string property'\u003e\u003c/obj-ml\u003e\n    \u003cinput itemprop='myEditableProp'\u003e\n\u003c/obj-ml\u003e\n```\n\nresults in outer obj-ml having value:\n\n```JSON\n{\n    \"subObj\": {\n        \"prop1\": \"string property\"\n    }\n}\n```\n\n## Arrays\n\n```html\n\u003cobj-ml my-list-arr\u003e\n    \u003cli-ml itemprop=myList prop1='string property'\u003e\u003c/li-ml\u003e\n    \u003cli-ml itemprop=myList prop2-num=42\u003e\u003c/li-ml\u003e\n\u003c/obj-ml\u003e\n```\n\n\nThe advantage of nesting like this, as opposed to using the flat attribute/JSON parse, is changes to the object can be more thoroughly described in the event that is passed.  \n\nIn addition, css / xpath queries can be done to filter the list.\n\nThe disadvantage may be that more memory is used (and more event listening).\n\n\n## Form participation\n\nobj-ml/o-l can partake in forms, becoming part of oForm.elements, formdata, etc.\n\nIt might make most sense to include outside the form, but integrate with the form via the form attribute:\n\n```html\n    \u003co-m form='form1' name='om' prop1='string property' prop2-b=true prop3-i=5 prop4-f=2.7 prop5-d=\"May 24, 2021\" prop6-o='{\"mySubSubObj\":\"hello\"}'\u003e\n        \u003co-m itemprop='subObj' prop1='string property'\u003e\u003c/o-m\u003e\n        \u003cinput itemprop='myEditableProp'\u003e\n    \u003c/o-m\u003e\n\n    \u003cform id='form1'\u003e\n\n    \u003c/form\u003e\n```\n\n## Priors\n\nA very likely non-exhaustive list:\n\n1.  datalist\n2.  Silverlight [XmlDataProvider](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-bind-to-xml-data-using-an-xmldataprovider-and-xpath-queries?view=netframeworkdesktop-4.8)\n\n\n\n[TODO]  Use itemref to reference another om element to incorporate repeating data.\n\n## Viewing Your Element Locally\n\n1.  Install node.\n2.  Clone or for fork this git repo.\n3.  In a command prompt from the folder of this git repo:\n\n```\n$ npm run serve\n```\n\n4.  Open browser to http://localhost/demo.\n\nhttps://www.measurethat.net/Benchmarks/Show/14562/0/number-vs-parseint\n\nhttps://stackoverflow.com/questions/55364947/is-there-any-javascript-standard-api-to-parse-to-number-according-to-locale\n\nmaybe return proxy for subobjects?","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahrus%2Fobj-ml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbahrus%2Fobj-ml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahrus%2Fobj-ml/lists"}