{"id":13713893,"url":"https://github.com/nofeaturesonlybugs/jsmu","last_synced_at":"2026-05-14T04:36:37.135Z","repository":{"id":57614950,"uuid":"381199068","full_name":"nofeaturesonlybugs/jsmu","owner":"nofeaturesonlybugs","description":"An abstraction for Go's encoding/json that abstracts 2-pass encoding into a single pass similar to encoding/gob.","archived":false,"fork":false,"pushed_at":"2022-06-12T18:21:45.000Z","size":45,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-11T07:49:56.450Z","etag":null,"topics":["go","gob","golang","json","marshaller","marshalling"],"latest_commit_sha":null,"homepage":"","language":"Go","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/nofeaturesonlybugs.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.txt","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-29T00:55:43.000Z","updated_at":"2023-12-05T14:47:48.000Z","dependencies_parsed_at":"2022-09-10T23:31:09.643Z","dependency_job_id":null,"html_url":"https://github.com/nofeaturesonlybugs/jsmu","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nofeaturesonlybugs%2Fjsmu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nofeaturesonlybugs%2Fjsmu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nofeaturesonlybugs%2Fjsmu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nofeaturesonlybugs%2Fjsmu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nofeaturesonlybugs","download_url":"https://codeload.github.com/nofeaturesonlybugs/jsmu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241170222,"owners_count":19921571,"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":["go","gob","golang","json","marshaller","marshalling"],"created_at":"2024-08-02T23:01:47.040Z","updated_at":"2026-05-14T04:36:37.095Z","avatar_url":"https://github.com/nofeaturesonlybugs.png","language":"Go","funding_links":[],"categories":["Repositories"],"sub_categories":[],"readme":"[![Go Reference](https://pkg.go.dev/badge/github.com/nofeaturesonlybugs/jsmu.svg)](https://pkg.go.dev/github.com/nofeaturesonlybugs/jsmu)\n[![Go Report Card](https://goreportcard.com/badge/github.com/nofeaturesonlybugs/jsmu)](https://goreportcard.com/report/github.com/nofeaturesonlybugs/jsmu)\n[![Build Status](https://app.travis-ci.com/nofeaturesonlybugs/jsmu.svg?branch=master)](https://app.travis-ci.com/nofeaturesonlybugs/jsmu)\n[![codecov](https://codecov.io/gh/nofeaturesonlybugs/jsmu/branch/master/graph/badge.svg)](https://codecov.io/gh/nofeaturesonlybugs/jsmu)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n`jsmu` aka `JavaScript Marshal|Unmarshal`. Pronounce as `j◦s◦mew`.\n\n## `jsmu.MU`\n\n`jsmu.MU` abstracts the typical 2-pass JSON marshal|unmarshal into a single pass.\n\nCreate an instance of `jsmu.MU`:\n\n```go\nmu := \u0026jsmu.MU{}\n```\n\nRegister types that will be JSON marshalled or unmarshalled:\n\n```go\nmu.Register( \u0026SomeType{} )\nmu.Register( \u0026OtherType{} )\n```\n\nTo unmarshal:\n\n```go\nvar envelope jsmu.Enveloper\nvar err error\nfor data := range jsonCh { // jsonCh is some stream returning blobs of JSON\n    if envelope, err = mu.Unmarshal([]byte(data)); err != nil {\n        // YOUSHOULD Handle err.\n        continue // break, goto, return, etc.\n    }\n    switch message := envelope.GetMessage().(type) {\n        case *SomeType:\n        case *OtherType:\n    }\n}\n```\n\nTo marshal:\n\n```go\nvar buf []byte\nvar err error\nsome, other := \u0026SomeType{}, \u0026OtherType{}\nif buf, err = mu.Marshal(some); err != nil {\n    // YOUSHOULD Handle err.\n}\n// YOUSHOULD Do something with buf.\nif buf, err = mu.Marshal(other); err != nil {\n    // YOUSHOULD Handle err\n}\n// YOUSHOULD Do something with buf.\n```\n\n### Envelopes\n\n`jsmu` expects JSON encoded data to be wrapped inside an envelope. This envelope must contain some type name information (data type `string`) and the message payload. The default envelope structure is:\n\n```js\n{\n    // string, required : Must uniquely identify the contents of \"message\".\n    \"type\"    : \"\",\n    // string, optional : Provided as a convenience for round trip message flow.\n    \"id\"      : \"\",\n    // The data.\n    \"message\" : any\n}\n```\n\nEnvelopes are created by the `EnveloperFn` member of `jsmu.MU`; if you don't provide a value for `EnveloperFn` then `jsmu.DefaultEnveloperFunc` is used and JSON is expected to conform to the above structure.\n\nIf you want to use a different JSON structure you can implement the `jsmu.Enveloper` interface and provide an appropriate `EnveloperFn` value when instantiating your `jsmu.MU`; see example `MU (CustomEnvelope)`.\n\n### The Dual Nature of `MU.Marshal()`\n\n`MU.Marshal()` _always_ returns JSON representing a message within an envelope.\n\n-   Calling `MU.Marshal(value)` when `value` is already a `jsmu.Enveloper` yields:\n\n    1. `value` is marshalled as-is.\n\n-   Calling `MU.Marshal(value)` when `value` _is not_ a `jsmu.Enveloper` yields:\n    1. A new envelope is created with `MU.EnveloperFn`.\n    2. `value` is placed in the envelope.\n    3. The newly created envelope is marshalled.\n\n## Performance\n\n`jsmu.MU` has not yet been optimized. However the extra overhead is not much slower than handling 2-pass JSON directly in your application (at least for the simple test I put together):\n\n```\ngoos: windows\ngoarch: amd64\npkg: github.com/nofeaturesonlybugs/jsmu\ncpu: Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz\nBenchmarkMU/2-pass_unmarshal_limit_5-8             52425             23602 ns/op            7488 B/op        140 allocs/op\nBenchmarkMU/jsmu_unmarshal_limit_5-8               50223             24460 ns/op            7008 B/op        130 allocs/op\nBenchmarkMU/2-pass_unmarshal_limit_100-8            2731            466576 ns/op          147256 B/op       2800 allocs/op\nBenchmarkMU/jsmu_unmarshal_limit_100-8              2668            476442 ns/op          137656 B/op       2600 allocs/op\nBenchmarkMU/2-pass_unmarshal_limit_250-8             994           1171133 ns/op          367593 B/op       7000 allocs/op\nBenchmarkMU/jsmu_unmarshal_limit_250-8              1014           1194731 ns/op          343593 B/op       6500 allocs/op\nBenchmarkMU/2-pass_unmarshal_limit_500-8             519           2343670 ns/op          734043 B/op      14000 allocs/op\nBenchmarkMU/jsmu_unmarshal_limit_500-8               513           2394790 ns/op          686043 B/op      13000 allocs/op\nBenchmarkMU/2-pass_unmarshal_limit_1000-8            255           4734993 ns/op         1467949 B/op      28000 allocs/op\nBenchmarkMU/jsmu_unmarshal_limit_1000-8              244           4788199 ns/op         1371949 B/op      26000 allocs/op\nPASS\nok      github.com/nofeaturesonlybugs/jsmu      14.532s\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnofeaturesonlybugs%2Fjsmu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnofeaturesonlybugs%2Fjsmu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnofeaturesonlybugs%2Fjsmu/lists"}