{"id":16542533,"url":"https://github.com/tada5hi/smob","last_synced_at":"2026-05-14T14:02:37.481Z","repository":{"id":59454006,"uuid":"537369571","full_name":"tada5hi/smob","owner":"tada5hi","description":"A zero dependency library to safe merge objects and arrays with customizable behavior.","archived":false,"fork":false,"pushed_at":"2026-05-08T23:47:02.000Z","size":2589,"stargazers_count":64,"open_issues_count":21,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-05-10T22:36:48.192Z","etag":null,"topics":["array-merge","deep-merge","merge","merge-deep","nodejs","object","object-merge","safe","typescript"],"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/tada5hi.png","metadata":{"files":{"readme":"README.MD","changelog":"CHANGELOG.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-09-16T08:24:05.000Z","updated_at":"2026-02-11T14:18:08.000Z","dependencies_parsed_at":"2024-05-06T10:28:58.630Z","dependency_job_id":"07cb9b89-ae92-45d4-93a9-d7adefffabe4","html_url":"https://github.com/tada5hi/smob","commit_stats":{"total_commits":149,"total_committers":3,"mean_commits":"49.666666666666664","dds":"0.21476510067114096","last_synced_commit":"38b4331f5b7941d2dbb757cd0b9747d849b575b2"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/tada5hi/smob","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fsmob","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fsmob/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fsmob/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fsmob/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tada5hi","download_url":"https://codeload.github.com/tada5hi/smob/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fsmob/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33028203,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"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":["array-merge","deep-merge","merge","merge-deep","nodejs","object","object-merge","safe","typescript"],"created_at":"2024-10-11T18:57:50.400Z","updated_at":"2026-05-14T14:02:37.008Z","avatar_url":"https://github.com/tada5hi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SMOB 🧪\n\n[![npm version](https://badge.fury.io/js/smob.svg)](https://badge.fury.io/js/smob)\n[![main](https://github.com/tada5hi/smob/actions/workflows/main.yml/badge.svg)](https://github.com/tada5hi/smob/actions/workflows/main.yml)\n[![codecov](https://codecov.io/gh/tada5hi/smob/branch/master/graph/badge.svg?token=0VL41WO0CG)](https://codecov.io/gh/tada5hi/smob)\n[![Known Vulnerabilities](https://snyk.io/test/github/Tada5hi/smob/badge.svg?targetFile=package.json)](https://snyk.io/test/github/Tada5hi/smob?targetFile=package.json)\n[![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)\n\nA zero dependency library to **s**afe **m**erge **ob**jects and arrays with customizable behavior.\n\n**Table of Contents**\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Merger](#merger)\n  - [Utils](#utils)\n- [License](#license)\n\n## Installation\n\n```bash\nnpm install smob --save\n```\n\n## Usage\n\n```typescript\nimport { merge } from \"smob\";\n\nconst output = merge(...sources);\n```\n\nThe following merge options are set by default:\n- **array**: `true` Merge object array properties.\n- **arrayDistinct**: `false` Remove duplicates, when merging array elements.\n- **arrayPriority**: `left` (options.priority) The source aka leftmost array has by **default** the highest priority.\n- **clone**: `false` Deep clone input sources.\n- **inPlace**: `false` Merge sources in place.\n- **priority**: `left` The source aka leftmost object has by **default** the highest priority.\n\nThe merge behaviour can be changed by creating a custom [merger](#merger).\n\n**Arguments**\n- sources `(any[] | Record\u003cstring, any\u003e)[]`: The source arrays/objects.\n\n```typescript\nimport { merge } from 'smob';\n\nmerge({ a: 1 }, { b: 2 }, { c: 3 });\n// { a: 1, b: 2, c: 3 }\n\nmerge(['foo'], ['bar']);\n// ['foo', 'bar']\n\n```\n\n### Merger\n\nA custom merger can simply be created by using the `createMerger` method.\n\n**Array**\n```typescript\nimport { createMerger } from 'smob';\n\nconst merge = createMerger({ array: false });\n\nmerge({ a: [1,2,3] }, { a: [4,5,6] });\n// { a: [1,2,3] }\n```\n\n**ArrayDistinct**\n```typescript\nimport { createMerger } from 'smob';\n\nconst merge = createMerger({ arrayDistinct: true });\n\nmerge({ a: [1,2,3] }, { a: [3,4,5] });\n// { a: [1,2,3,4,5] }\n```\n\n**Priority**\n```typescript\nimport { createMerger } from 'smob';\n\nconst merge = createMerger({ priority: 'right' });\n\nmerge({ a: 1 }, { a: 2 }, { a: 3 })\n// { a: 3 }\n```\n\n**Strategy**\n```typescript\nimport { createMerger } from 'smob';\n\nconst merge = createMerger({\n    strategy: (target, key, value) =\u003e {\n        if (\n            typeof target[key] === 'number' \u0026\u0026\n            typeof value === 'number'\n        ) {\n            target[key] += value;\n            return target;\n        }\n    }\n});\n\nmerge({ a: 1 }, { a: 2 }, { a: 3 });\n// { a: 6 }\n```\n\nA returned value indicates that the strategy has been applied.\n\n## Utils\n\n### distinctArray\n\n```typescript\nimport { distinctArray } from 'smob';\n\ndistnctArray(['foo', 'bar', 'foo']);\n// ['foo', 'bar']\n```\n\nThe function also removes non-primitive\nelements that are identical by value or reference.\n\n**Objects**\n```typescript\nimport { distinctArray } from 'smob';\n\ndistinctArray([{ foo: 'bar' }, { foo: 'bar' }]);\n// [{ foo: 'bar' }]\n```\n\n**Arrays**\n```typescript\nimport { distinctArray } from 'smob';\n\ndistinctArray([['foo', 'bar'], ['foo', 'bar']]);\n// [['foo', 'bar']]\n```\n\n### isEqual\n\nChecks if two (non-primitive) elements\nare identical by value or reference.\n\n````typescript\nimport { isEqual } from 'smob';\n\nisEqual({foo: 'bar'}, {foo: 'bar'});\n// true\n\nisEqual(['foo', 'bar'], ['foo', 'bar']);\n// true\n````\n\n## License\n\nMade with 💚\n\nPublished under [MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftada5hi%2Fsmob","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftada5hi%2Fsmob","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftada5hi%2Fsmob/lists"}