Package lifecycle tension: serialization vs. lazy package activation


#1

Suppose I have a package that’s only activated in response to the my-package:start command, and in response to that command, it adds an instance of MyPackageView as a new item in the current Pane.

What if I want that view to be serialized when the editor closes?

Naively, it seems like I’d just register deserialization like this:

class MyPackageView
  atom.deserializers.add(this)

  constructor: (@data) -> #property assigned
  serialize: -> { deserializer: 'MyPackageView', data: @data } 
  @deserialize: ({data}) -> new MyPackageView(data)

(from serialization docs, see also DeserializeManager)

But now say I close Atom and open it back up again. It’ll try to deserialize whatever pane items were open, but since my package hasn’t been activated yet, MyPackageView class won’t be found.

Am I missing something here? If not, then maybe this suggests that either you should be able to register your package when adding a deserializer (or maybe that DeserializerManager.add could infer the package and store it as metadata).

I’ll create an issue for this, but just wanted to give someone the chance to tell me why I’m just being stupid here. Heh.


#2

If you only require your view class during the activation then yes, there’s an issue as at the activation moment it doesn’t know that it have to use a specific serializer.
You may want to either require your view sooner than the activation or extract the serializer from your view class:

# Serializer is registered here
MyPackageView = require 'my-package-view'

module.exports = 
  activate: -> #...

Or

MyPackageView = null

deserializer = deserialize: ({data}) -> 
  MyPackageView ||= require 'my-package-view'
  new MyPackageView(data)

atom.deserializers.add deserializer

module.exports = 
  activate: -> #...

#3

I don’t think this works, because even package’s script seems to be getting loaded lazily. I.e., the log statement below won’t fire till the activation event is triggered. (Incidentally, this makes me question the suggestion in How To Speed Up Your Packages about moving require's into activate().)

console.log 'Requiring MyPackageView!'
MyPackageView = require './my-package-view'
 
module.exports =
...

Here’s a full (minimal) package in a gist demonstrating this.


How To Speed Up Your Packages
#4

You’re right, seems like a recent change, that mean that serialization is only available for auto-activated packages, unless I’m missing something.


#5

Issue here: https://github.com/atom/atom/issues/3695