{"id":16255299,"url":"https://github.com/qubyte/mixomatic","last_synced_at":"2025-03-19T21:30:39.932Z","repository":{"id":48280206,"uuid":"88523585","full_name":"qubyte/mixomatic","owner":"qubyte","description":"Create mixins which work with instanceof (friendly for unit tests).","archived":false,"fork":false,"pushed_at":"2022-11-24T18:26:17.000Z","size":410,"stargazers_count":23,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-24T13:56:03.825Z","etag":null,"topics":["instanceof","mixin","mixins"],"latest_commit_sha":null,"homepage":null,"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/qubyte.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-17T15:45:58.000Z","updated_at":"2023-09-08T08:19:19.000Z","dependencies_parsed_at":"2022-09-13T18:34:18.407Z","dependency_job_id":null,"html_url":"https://github.com/qubyte/mixomatic","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qubyte%2Fmixomatic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qubyte%2Fmixomatic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qubyte%2Fmixomatic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qubyte%2Fmixomatic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qubyte","download_url":"https://codeload.github.com/qubyte/mixomatic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244507845,"owners_count":20463689,"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":["instanceof","mixin","mixins"],"created_at":"2024-10-10T15:29:22.330Z","updated_at":"2025-03-19T21:30:39.588Z","avatar_url":"https://github.com/qubyte.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mixomatic\n\nCreate mixins which work with `instanceof` (friendly for unit tests). Internally\nreferences are handled by a `WeakSet` instances so there's no need to manually\nkeep records of which objects have been mixed onto and risk memory leaks.\n\n## Install\n\nWith `npm`:\n```\nnpm install --save mixomatic\n```\n\nWith `yarn`:\n```\nyarn add mixomatic\n```\n\nOr alternatively, in a browser or deno you can use it directly in a page via\n[unpkg][0] as a module (not recommended for production use):\n```javascript\nimport mixomatic from 'https://unpkg.com/mixomatic';\n```\n\n## Usage\n\nMake a new mixin which appends [`propertyDescriptors`][1] to an object.\n```javascript\nimport mixomatic from 'mixomatic';\n\nconst myMixin = mixomatic(propertyDescriptors);\n```\n\nMix onto an object.\n```javascript\nconst obj = {};\n\nmyMixin(obj);\n```\n\nCheck if an object has been modified by a given mixin:\n\n```javascript\nobj instanceof myMixin; // true\n```\n\nAlso works with classes!\n\n```javascript\nclass MyClass {}\n\nmyMixin(MyClass.prototype);\n\nconst obj = new MyClass();\n\nobj instanceof MyClass; // true\nobj instanceof myMixin; // true\n```\n\nAnd inheritance!\n\n```javascript\nclass MyChildClass extends MyClass {}\n\nconst obj = new MyChildClass();\n\nobj instanceof MyChildClass; // true\nobj instanceof MyClass;      // true\nobj instanceof myMixin;      // true\n```\n\n## Example\n\nYou're making a game with a little ship which shoots space-bound rocks before\nthey can bash into it. Both the ship and the rocks have position and velocity\nproperties. You _could_ make a class, which provides a `move` method, which they\nwould both inherit from. However, that could be the beginning of a class\nhierarchy and you've heard bad things about those being hard to modify in the\nfuture. JavaScript also has no way to do multiple inheritance with classes, so\nyour options are limited with classes anyway.\n\nInstead you make the wise choice to use `mixomatic`! You use mixomatic to create\na mixin called `movable`, which takes a time difference and uses it to update\nthe position of its host object.\n\n```javascript\nconst movable = mixomatic({\n  move: {\n    value(dt) {\n      this.position.x += dt * this.velocity.x;\n      this.position.y += dt * this.velocity.y;\n    },\n    configurable: true,\n    enumerable: false,\n    writable: true\n  }\n});\n```\n\nSince there'll only be one ship, you define it directly as an object and apply\n`movable` to it to give it the `move` method.\n\n```javascript\nconst ship = {\n  position: { x: 0, y: 0 },\n  velocity: { x: 0, y: 0 }\n};\n\nmovable(ship);\n```\n\nAsteroids are more numerous and can appear in all sorts of places, so you decide\nto go with a class for those.\n\n```javascript\nclass Asteroid {\n  constructor(position, velocity) {\n    this.position = { x: position.x, y: position.y };\n    this.velocity = { x: velocity.x, y: velocity.y };\n  }\n}\n\nmovable(Asteroid.prototype);\n```\n\nNow both `ship` and `Asteroid` instances will have the `move` method, and will\nboth appear to be instances of `movable`, yet are not part of the same class\nhierarchy. All sorts of behaviour can be written as mixins (for example, the\nship can fire missiles, and so can UFOs).\n\nThis is useful because mixins can be tested in isolation, and you can avoid\nduplication of tests for mixed properties by using an `instanceof` check in the\ntest suites of host objects like `ship` and `Asteroid`.\n\n[0]: https://unpkg.com/\n[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqubyte%2Fmixomatic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqubyte%2Fmixomatic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqubyte%2Fmixomatic/lists"}