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