@colyseus/schema 3.0.0-alpha.26 → 3.0.0-alpha.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4039,7 +4039,8 @@ __decorate([
4039
4039
  function getDecoderStateCallbacks(decoder) {
4040
4040
  const $root = decoder.root;
4041
4041
  const callbacks = $root.callbacks;
4042
- let isTriggeringOnAdd = false;
4042
+ const onAddCalls = new WeakMap();
4043
+ let currentOnAddCallback;
4043
4044
  decoder.triggerChanges = function (allChanges) {
4044
4045
  const uniqueRefIds = new Set();
4045
4046
  for (let i = 0, l = allChanges.length; i < l; i++) {
@@ -4102,7 +4103,6 @@ function getDecoderStateCallbacks(decoder) {
4102
4103
  }
4103
4104
  }
4104
4105
  // Handle DELETE_AND_ADD operations
4105
- // FIXME: should we set "isTriggeringOnAdd" here?
4106
4106
  if ((change.op & exports.OPERATION.ADD) === exports.OPERATION.ADD) {
4107
4107
  const addCallbacks = $callbacks[exports.OPERATION.ADD];
4108
4108
  for (let i = addCallbacks?.length - 1; i >= 0; i--) {
@@ -4112,12 +4112,10 @@ function getDecoderStateCallbacks(decoder) {
4112
4112
  }
4113
4113
  else if ((change.op & exports.OPERATION.ADD) === exports.OPERATION.ADD && change.previousValue === undefined) {
4114
4114
  // triger onAdd
4115
- isTriggeringOnAdd = true;
4116
4115
  const addCallbacks = $callbacks[exports.OPERATION.ADD];
4117
4116
  for (let i = addCallbacks?.length - 1; i >= 0; i--) {
4118
4117
  addCallbacks[i](change.value, change.dynamicIndex ?? change.field);
4119
4118
  }
4120
- isTriggeringOnAdd = false;
4121
4119
  }
4122
4120
  // trigger onChange
4123
4121
  if (change.value !== change.previousValue) {
@@ -4135,11 +4133,11 @@ function getDecoderStateCallbacks(decoder) {
4135
4133
  let isCollection = ((context.instance && typeof (context.instance['forEach']) === "function") ||
4136
4134
  (metadataOrType && typeof (metadataOrType[Symbol.metadata]) === "undefined"));
4137
4135
  if (metadata && !isCollection) {
4138
- const onAdd = function (ref, prop, callback, immediate) {
4136
+ const onAddListen = function (ref, prop, callback, immediate) {
4139
4137
  // immediate trigger
4140
4138
  if (immediate &&
4141
4139
  context.instance[prop] !== undefined &&
4142
- !isTriggeringOnAdd // FIXME: This is a workaround (https://github.com/colyseus/schema/issues/147)
4140
+ !onAddCalls.has(currentOnAddCallback) // Workaround for https://github.com/colyseus/schema/issues/147
4143
4141
  ) {
4144
4142
  callback(context.instance[prop], undefined);
4145
4143
  }
@@ -4151,13 +4149,13 @@ function getDecoderStateCallbacks(decoder) {
4151
4149
  return new Proxy({
4152
4150
  listen: function listen(prop, callback, immediate = true) {
4153
4151
  if (context.instance) {
4154
- return onAdd(context.instance, prop, callback, immediate);
4152
+ return onAddListen(context.instance, prop, callback, immediate);
4155
4153
  }
4156
4154
  else {
4157
4155
  // collection instance not received yet
4158
4156
  let detachCallback = () => { };
4159
4157
  context.onInstanceAvailable((ref, existing) => {
4160
- detachCallback = onAdd(ref, prop, callback, immediate && existing);
4158
+ detachCallback = onAddListen(ref, prop, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback));
4161
4159
  });
4162
4160
  return () => detachCallback();
4163
4161
  }
@@ -4165,10 +4163,11 @@ function getDecoderStateCallbacks(decoder) {
4165
4163
  onChange: function onChange(callback) {
4166
4164
  return $root.addCallback($root.refIds.get(context.instance), exports.OPERATION.REPLACE, callback);
4167
4165
  },
4166
+ //
4167
+ // TODO: refactor `bindTo()` implementation.
4168
+ // There is room for improvement.
4169
+ //
4168
4170
  bindTo: function bindTo(targetObject, properties) {
4169
- //
4170
- // TODO: refactor this implementation. There is room for improvement here.
4171
- //
4172
4171
  if (!properties) {
4173
4172
  properties = Object.keys(metadata);
4174
4173
  }
@@ -4195,7 +4194,8 @@ function getDecoderStateCallbacks(decoder) {
4195
4194
  }
4196
4195
  });
4197
4196
  return getProxy(metadata[prop].type, {
4198
- instance,
4197
+ // make sure refId is available, otherwise need to wait for the instance to be available.
4198
+ instance: ($root.refIds.get(instance) && instance),
4199
4199
  parentInstance: context.instance,
4200
4200
  onInstanceAvailable,
4201
4201
  });
@@ -4219,7 +4219,13 @@ function getDecoderStateCallbacks(decoder) {
4219
4219
  if (immediate) {
4220
4220
  ref.forEach((v, k) => callback(v, k));
4221
4221
  }
4222
- return $root.addCallback($root.refIds.get(ref), exports.OPERATION.ADD, callback);
4222
+ return $root.addCallback($root.refIds.get(ref), exports.OPERATION.ADD, (value, key) => {
4223
+ onAddCalls.set(callback, true);
4224
+ currentOnAddCallback = callback;
4225
+ callback(value, key);
4226
+ onAddCalls.delete(callback);
4227
+ currentOnAddCallback = undefined;
4228
+ });
4223
4229
  };
4224
4230
  const onRemove = function (ref, callback) {
4225
4231
  return $root.addCallback($root.refIds.get(ref), exports.OPERATION.DELETE, callback);
@@ -4230,19 +4236,17 @@ function getDecoderStateCallbacks(decoder) {
4230
4236
  // https://github.com/colyseus/schema/issues/147
4231
4237
  // If parent instance has "onAdd" registered, avoid triggering immediate callback.
4232
4238
  //
4233
- // FIXME: "isTriggeringOnAdd" is a workaround. We should find a better way to handle this.
4234
- //
4235
- if (context.onInstanceAvailable) {
4239
+ if (context.instance) {
4240
+ return onAdd(context.instance, callback, immediate && !onAddCalls.has(currentOnAddCallback));
4241
+ }
4242
+ else if (context.onInstanceAvailable) {
4236
4243
  // collection instance not received yet
4237
4244
  let detachCallback = () => { };
4238
4245
  context.onInstanceAvailable((ref, existing) => {
4239
- detachCallback = onAdd(ref, callback, immediate && existing && !isTriggeringOnAdd);
4246
+ detachCallback = onAdd(ref, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback));
4240
4247
  });
4241
4248
  return () => detachCallback();
4242
4249
  }
4243
- else if (context.instance) {
4244
- return onAdd(context.instance, callback, immediate && !isTriggeringOnAdd);
4245
- }
4246
4250
  },
4247
4251
  onRemove: function (callback) {
4248
4252
  if (context.onInstanceAvailable) {