{"action":"created","issue":{"url":"https://api.github.com/repos/orbitjs/orbit.js/issues/151","labels_url":"https://api.github.com/repos/orbitjs/orbit.js/issues/151/labels{/name}","comments_url":"https://api.github.com/repos/orbitjs/orbit.js/issues/151/comments","events_url":"https://api.github.com/repos/orbitjs/orbit.js/issues/151/events","html_url":"https://github.com/orbitjs/orbit.js/pull/151","id":80640611,"number":151,"title":"Consolidate operation encoding and identification","user":{"login":"opsb","id":46232,"avatar_url":"https://avatars.githubusercontent.com/u/46232?v=3","gravatar_id":"","url":"https://api.github.com/users/opsb","html_url":"https://github.com/opsb","followers_url":"https://api.github.com/users/opsb/followers","following_url":"https://api.github.com/users/opsb/following{/other_user}","gists_url":"https://api.github.com/users/opsb/gists{/gist_id}","starred_url":"https://api.github.com/users/opsb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opsb/subscriptions","organizations_url":"https://api.github.com/users/opsb/orgs","repos_url":"https://api.github.com/users/opsb/repos","events_url":"https://api.github.com/users/opsb/events{/privacy}","received_events_url":"https://api.github.com/users/opsb/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":23,"created_at":"2015-05-25T19:29:35Z","updated_at":"2015-06-15T20:46:16Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/orbitjs/orbit.js/pulls/151","html_url":"https://github.com/orbitjs/orbit.js/pull/151","diff_url":"https://github.com/orbitjs/orbit.js/pull/151.diff","patch_url":"https://github.com/orbitjs/orbit.js/pull/151.patch"},"body":"This PR pulls together operation encoding and identification into a single class, OperationEncoder. The intention is to ensure that operations are created and identified consistently. I've moved the terminology towards that of the schema but I think it could be made even closer (see below).\r\n\r\n#### Operation identification\r\n\r\nCurrently this is handled by various conditions throughout the code such as operation.path.length === 4. This can cause problems however, e.g. I wanted to set a hasMany with\r\n\r\n    {op: `add`, path: `planet/planet1/__rel/moons`, value: {}}\r\n\r\nbut it was being misidentified as an add hasOne.\r\n\r\nThe operationEncoder introduces an `identify(operation)` method which will respond with one of the following: `addRecord`, `replaceRecord`, `removeRecord`, `addHasMany`, `replaceHasMany`, `removeHasMany`, `addToHasMany`, `removeFromHasMany`, `addHasOne`, `replaceHasOne`, `removeHasOne`, `addAttribute`, `replaceAttribute`, `removeAttribute`.\r\n\r\nIf the operation can't be identified it will throw an OperationNotAllowed error.\r\n\r\n\r\n#### Operation generation\r\n\r\nThe operationEncoder introduces the following methods: `addRecordOp()`, `replaceRecordOp()`, `removeRecordOp()`, `replaceAttributeOp()`, `addLinkOp()`, `removeLinkOp()` and `updateLinkOp()`. The intention is to match the schema semantics as far as possible, the exception being the link operations which I`d perhaps prefer to mirror the identifiers returned by operationEncoder.identify(). This seems like a good place to start though.\r\n    \r\n\r\nI'm going to continue this PR by swapping out conditionals where appropriate to make use of the identification provided by `operationEncoder.identify()` but I'm keen to hear what people think about the general direction."},"comment":{"url":"https://api.github.com/repos/orbitjs/orbit.js/issues/comments/112205878","html_url":"https://github.com/orbitjs/orbit.js/pull/151#issuecomment-112205878","issue_url":"https://api.github.com/repos/orbitjs/orbit.js/issues/151","id":112205878,"user":{"login":"opsb","id":46232,"avatar_url":"https://avatars.githubusercontent.com/u/46232?v=3","gravatar_id":"","url":"https://api.github.com/users/opsb","html_url":"https://github.com/opsb","followers_url":"https://api.github.com/users/opsb/followers","following_url":"https://api.github.com/users/opsb/following{/other_user}","gists_url":"https://api.github.com/users/opsb/gists{/gist_id}","starred_url":"https://api.github.com/users/opsb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opsb/subscriptions","organizations_url":"https://api.github.com/users/opsb/orgs","repos_url":"https://api.github.com/users/opsb/repos","events_url":"https://api.github.com/users/opsb/events{/privacy}","received_events_url":"https://api.github.com/users/opsb/received_events","type":"User","site_admin":false},"created_at":"2015-06-15T20:46:16Z","updated_at":"2015-06-15T20:46:16Z","body":"I think this PR could be merged into master as is (I may need to rebase) as it's independent of the other work and IMHO is a useful step in it's own right."}}