/ src / deserializer-manager.js
deserializer-manager.js
 1  const { Disposable } = require('event-kit');
 2  
 3  // Extended: Manages the deserializers used for serialized state
 4  //
 5  // An instance of this class is always available as the `atom.deserializers`
 6  // global.
 7  //
 8  // ## Examples
 9  //
10  // ```coffee
11  // class MyPackageView extends View
12  //   atom.deserializers.add(this)
13  //
14  //   @deserialize: (state) ->
15  //     new MyPackageView(state)
16  //
17  //   constructor: (@state) ->
18  //
19  //   serialize: ->
20  //     @state
21  // ```
22  module.exports = class DeserializerManager {
23    constructor(atomEnvironment) {
24      this.atomEnvironment = atomEnvironment;
25      this.deserializers = {};
26    }
27  
28    // Public: Register the given class(es) as deserializers.
29    //
30    // * `deserializers` One or more deserializers to register. A deserializer can
31    //   be any object with a `.name` property and a `.deserialize()` method. A
32    //   common approach is to register a *constructor* as the deserializer for its
33    //   instances by adding a `.deserialize()` class method. When your method is
34    //   called, it will be passed serialized state as the first argument and the
35    //   {AtomEnvironment} object as the second argument, which is useful if you
36    //   wish to avoid referencing the `atom` global.
37    add(...deserializers) {
38      for (let i = 0; i < deserializers.length; i++) {
39        let deserializer = deserializers[i];
40        this.deserializers[deserializer.name] = deserializer;
41      }
42  
43      return new Disposable(() => {
44        for (let j = 0; j < deserializers.length; j++) {
45          let deserializer = deserializers[j];
46          delete this.deserializers[deserializer.name];
47        }
48      });
49    }
50  
51    getDeserializerCount() {
52      return Object.keys(this.deserializers).length;
53    }
54  
55    // Public: Deserialize the state and params.
56    //
57    // * `state` The state {Object} to deserialize.
58    deserialize(state) {
59      if (state == null) {
60        return;
61      }
62  
63      const deserializer = this.get(state);
64      if (deserializer) {
65        let stateVersion =
66          (typeof state.get === 'function' && state.get('version')) ||
67          state.version;
68  
69        if (
70          deserializer.version != null &&
71          deserializer.version !== stateVersion
72        ) {
73          return;
74        }
75        return deserializer.deserialize(state, this.atomEnvironment);
76      } else {
77        return console.warn('No deserializer found for', state);
78      }
79    }
80  
81    // Get the deserializer for the state.
82    //
83    // * `state` The state {Object} being deserialized.
84    get(state) {
85      if (state == null) {
86        return;
87      }
88  
89      let stateDeserializer =
90        (typeof state.get === 'function' && state.get('deserializer')) ||
91        state.deserializer;
92  
93      return this.deserializers[stateDeserializer];
94    }
95  
96    clear() {
97      this.deserializers = {};
98    }
99  };