code: function notify(gobj, source) {
  	const state = gobj.__gawk__;
  
  	if (source === undefined) {
  		source = gobj;
  	}
  
  	// if we're paused, add this object to the list of objects that may have changed
  	if (state.queue) {
  		state.queue.add(gobj);
  		return;
  	}
  
  	// notify all of this object's listeners
  	if (state.listeners) {
  		for (const [ listener, filter ] of state.listeners) {
  			if (filter) {
  				const { found, obj } = filterObject(gobj, filter);
  
  				// compute the hash of the stringified value
  				const hash = hashValue(obj);
  
  				// check if the value changed
  				if ((found && !state.previous) || (state.previous && hash !== state.previous.get(listener))) {
  					listener(obj, source);
  				}
  
  				if (!state.previous) {
  					state.previous = new WeakMap();
  				}
  
  				state.previous.set(listener, hash);
  			} else {
  				listener(gobj, source);
  			}
  		}
  	}
  
  	// notify all of this object's parents
  	if (state.parents) {
  		for (const parent of state.parents) {
  			notify(parent, source);
  		}
  	}
  }
docs: Dispatches change notifications to the listeners.
  
  @param {Object} gobj - The gawked object.
  @param {Object|Array} [source] - The gawk object that was modified.