Skip to content

Commit

Permalink
Convert serialization-in-atom.md
Browse files Browse the repository at this point in the history
  • Loading branch information
lee-dohm committed Feb 4, 2019
1 parent 1e829ac commit 7fde0f3
Showing 1 changed file with 71 additions and 30 deletions.
101 changes: 71 additions & 30 deletions content/behind-atom/sections/serialization-in-atom.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,33 @@ When a window is refreshed or restored from a previous session, the view and its

Your package's main module can optionally include a `serialize` method, which will be called before your package is deactivated. You should return a JSON-serializable object, which will be handed back to you as an object argument to `activate` next time it is called. In the following example, the package keeps an instance of `MyObject` in the same state across refreshes.

```coffee-script
module.exports =
activate: (state) ->
@myObject =
if state
atom.deserializers.deserialize(state)
else
new MyObject("Hello")

serialize: ->
@myObject.serialize()
```javascript
module.exports = {
activate(state) {
this.myObject = state ? atom.deserializers.deserialize(state) : new MyObject("Hello")
},

serialize() {
return this.myObject.serialize()
}
}
```

#### Serialization Methods

```coffee-script
class MyObject
constructor: (@data) ->
serialize: -> { deserializer: 'MyObject', data: @data }
```javascript
class MyObject {
constructor(data) {
this.data = data
}

serialize() {
return {
deserializer: 'MyObject',
data: this.data
}
}
}
```

##### `serialize()`
Expand All @@ -54,9 +62,12 @@ The preferred way to register deserializers is via your package's `package.json`

Here, the key (`"MyObject"`) is the name of the deserializer—the same string used by the `deserializer` field in the object returned by your `serialize()` method. The value (`"deserializeMyObject"`) is the name of a function in your main module that'll be passed the serialized data and will return a genuine object. For example, your main module might look like this:

```coffee-script
module.exports =
deserializeMyObject: ({data}) -> new MyObject(data)
```javascript
module.exports = {
deserializeMyObject({data}) {
return new MyObject(data)
}
}
```

Now you can call the global `deserialize` method with state returned from `serialize`, and your class's `deserialize` method will be selected automatically.
Expand All @@ -65,26 +76,56 @@ Now you can call the global `deserialize` method with state returned from `seria

An alternative is to use the `atom.deserializers.add` method with your class in order to make it available to the deserialization system. Usually this is used in conjunction with a class-level `deserialize` method:

```coffee-script
class MyObject
atom.deserializers.add(this)
```javascript
class MyObject {
static initClass() {
atom.deserializers.add(this)
}

static deserialize({data}) {
return new MyObject(data)
}

@deserialize: ({data}) -> new MyObject(data)
constructor: (@data) ->
serialize: -> { deserializer: 'MyObject', data: @data }
constructor(data) {
this.data = data;
}

serialize() {
return {
deserializer: 'MyObject',
data: this.data
}
}
}

MyObject.initClass()
```

While this used to be the standard method of registering a deserializer, the `package.json` method is now preferred since it allows Atom to defer loading and executing your code until it's actually needed.

#### Versioning

```coffee-script
class MyObject
atom.deserializers.add(this)
```javascript
class MyObject {
static initClass() {
atom.deserializers.add(this);

this.version = 2;
}

static deserialize(state) {
// ...
}

serialize() {
return {
version: this.constructor.version,
// ...
}
}
}

@version: 2
@deserialize: (state) -> ...
serialize: -> { version: @constructor.version, ... }
MyObject.initClass();
```

Your serializable class can optionally have a class-level `@version` property and include a `version` key in its serialized state. When deserializing, Atom will only attempt to call deserialize if the two versions match, and otherwise return undefined. We plan on implementing a migration system in the future, but this at least protects you from improperly deserializing old state.

0 comments on commit 7fde0f3

Please sign in to comment.