pxt-core 7.3.13 → 7.3.14

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.
package/built/pxt.js CHANGED
@@ -98076,6 +98076,7 @@ var pxt;
98076
98076
  }
98077
98077
  async patchUserPreferencesAsync(ops, immediate = false) {
98078
98078
  ops = Array.isArray(ops) ? ops : [ops];
98079
+ ops = ops.filter(op => !!op);
98079
98080
  if (!ops.length) {
98080
98081
  return;
98081
98082
  }
@@ -98087,8 +98088,20 @@ var pxt;
98087
98088
  return;
98088
98089
  }
98089
98090
  // If the user is logged in, save to cloud, but debounce the api call as this can be called frequently from skillmaps
98090
- // Accumulate the ops and send to cloud in batch.
98091
- this.prefPatchOps.push(...ops);
98091
+ // Replace matching patches in the queue
98092
+ ops.forEach((incoming, iIncoming) => {
98093
+ this.prefPatchOps.some((existing, iExisting) => {
98094
+ if (!ts.pxtc.jsonPatch.opsAreEqual(existing, incoming))
98095
+ return false;
98096
+ // Patches are equivalent, replace in queue
98097
+ this.prefPatchOps[iExisting] = incoming;
98098
+ // Clear from incoming so we don't add it below
98099
+ ops[iIncoming] = null;
98100
+ return true;
98101
+ });
98102
+ });
98103
+ // Add remaining ops to the queue
98104
+ ops.filter(op => !!op).forEach(op => this.prefPatchOps.push(op));
98092
98105
  clearTimeout(debouncePreferencesChangedTimeout);
98093
98106
  const savePrefs = async () => {
98094
98107
  debouncePreferencesChangedStarted = 0;
@@ -98911,6 +98924,18 @@ var ts;
98911
98924
  return arr;
98912
98925
  }
98913
98926
  Util.reversed = reversed;
98927
+ function arrayEquals(a, b, compare = (c, d) => c === d) {
98928
+ if (a == b)
98929
+ return true;
98930
+ if (!a && b || !b && a || a.length !== b.length)
98931
+ return false;
98932
+ for (let i = 0; i < a.length; i++) {
98933
+ if (!compare(a[i], b[i]))
98934
+ return false;
98935
+ }
98936
+ return true;
98937
+ }
98938
+ Util.arrayEquals = arrayEquals;
98914
98939
  function iterMap(m, f) {
98915
98940
  Object.keys(m).forEach(k => f(k, m[k]));
98916
98941
  }
@@ -100734,6 +100759,10 @@ var ts;
100734
100759
  }
100735
100760
  }
100736
100761
  jsonPatch.patchInPlace = patchInPlace;
100762
+ function opsAreEqual(a, b) {
100763
+ return (a.op === b.op && pxtc.U.arrayEquals(a.path, b.path));
100764
+ }
100765
+ jsonPatch.opsAreEqual = opsAreEqual;
100737
100766
  })(jsonPatch = pxtc.jsonPatch || (pxtc.jsonPatch = {}));
100738
100767
  })(pxtc = ts.pxtc || (ts.pxtc = {}));
100739
100768
  })(ts || (ts = {}));
@@ -116202,8 +116231,8 @@ var pxt;
116202
116231
  if (a == b)
116203
116232
  return true;
116204
116233
  if (a.id !== b.id || a.type !== b.type ||
116205
- !arrayEquals(a.meta.tags, b.meta.tags) ||
116206
- !arrayEquals(a.meta.blockIDs, b.meta.blockIDs) ||
116234
+ !pxt.U.arrayEquals(a.meta.tags, b.meta.tags) ||
116235
+ !pxt.U.arrayEquals(a.meta.blockIDs, b.meta.blockIDs) ||
116207
116236
  a.meta.displayName !== b.meta.displayName)
116208
116237
  return false;
116209
116238
  switch (a.type) {
@@ -116212,7 +116241,7 @@ var pxt;
116212
116241
  return pxt.sprite.bitmapEquals(a.bitmap, b.bitmap);
116213
116242
  case "animation" /* Animation */:
116214
116243
  const bAnimation = b;
116215
- return a.interval === bAnimation.interval && arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
116244
+ return a.interval === bAnimation.interval && pxt.U.arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
116216
116245
  case "tilemap" /* Tilemap */:
116217
116246
  return a.data.equals(b.data);
116218
116247
  }
@@ -116334,17 +116363,6 @@ var pxt;
116334
116363
  }
116335
116364
  return id;
116336
116365
  }
116337
- function arrayEquals(a, b, compare = (c, d) => c === d) {
116338
- if (a == b)
116339
- return true;
116340
- if (!a && b || !b && a || a.length !== b.length)
116341
- return false;
116342
- for (let i = 0; i < a.length; i++) {
116343
- if (!compare(a[i], b[i]))
116344
- return false;
116345
- }
116346
- return true;
116347
- }
116348
116366
  function serializeTilemap(tilemap, id, name) {
116349
116367
  const tm = tilemap.tilemap.data();
116350
116368
  const data = new Uint8ClampedArray(5 + tm.data.length + tilemap.layers.data.length);
package/built/pxtlib.d.ts CHANGED
@@ -270,6 +270,7 @@ declare namespace ts.pxtc.Util {
270
270
  export function listsEqual<T>(a: T[], b: T[]): boolean;
271
271
  export function oops(msg?: string): Error;
272
272
  export function reversed<T>(arr: T[]): T[];
273
+ export function arrayEquals<U>(a: U[], b: U[], compare?: (c: U, d: U) => boolean): boolean;
273
274
  export function iterMap<T>(m: pxt.Map<T>, f: (k: string, v: T) => void): void;
274
275
  export function mapMap<T, S>(m: pxt.Map<T>, f: (k: string, v: T) => S): pxt.Map<S>;
275
276
  export function values<T>(m: pxt.Map<T>): T[];
@@ -465,6 +466,7 @@ declare namespace ts.pxtc.jsonPatch {
465
466
  * Applies a set of JSON Patch operations to the object.
466
467
  */
467
468
  function patchInPlace(obj: any, ops: PatchOperation[]): void;
469
+ function opsAreEqual(a: PatchOperation, b: PatchOperation): boolean;
468
470
  }
469
471
  declare namespace ts.pxtc.jsonPatch.tests {
470
472
  function diffTests(): void;
package/built/pxtlib.js CHANGED
@@ -390,6 +390,7 @@ var pxt;
390
390
  }
391
391
  async patchUserPreferencesAsync(ops, immediate = false) {
392
392
  ops = Array.isArray(ops) ? ops : [ops];
393
+ ops = ops.filter(op => !!op);
393
394
  if (!ops.length) {
394
395
  return;
395
396
  }
@@ -401,8 +402,20 @@ var pxt;
401
402
  return;
402
403
  }
403
404
  // If the user is logged in, save to cloud, but debounce the api call as this can be called frequently from skillmaps
404
- // Accumulate the ops and send to cloud in batch.
405
- this.prefPatchOps.push(...ops);
405
+ // Replace matching patches in the queue
406
+ ops.forEach((incoming, iIncoming) => {
407
+ this.prefPatchOps.some((existing, iExisting) => {
408
+ if (!ts.pxtc.jsonPatch.opsAreEqual(existing, incoming))
409
+ return false;
410
+ // Patches are equivalent, replace in queue
411
+ this.prefPatchOps[iExisting] = incoming;
412
+ // Clear from incoming so we don't add it below
413
+ ops[iIncoming] = null;
414
+ return true;
415
+ });
416
+ });
417
+ // Add remaining ops to the queue
418
+ ops.filter(op => !!op).forEach(op => this.prefPatchOps.push(op));
406
419
  clearTimeout(debouncePreferencesChangedTimeout);
407
420
  const savePrefs = async () => {
408
421
  debouncePreferencesChangedStarted = 0;
@@ -1225,6 +1238,18 @@ var ts;
1225
1238
  return arr;
1226
1239
  }
1227
1240
  Util.reversed = reversed;
1241
+ function arrayEquals(a, b, compare = (c, d) => c === d) {
1242
+ if (a == b)
1243
+ return true;
1244
+ if (!a && b || !b && a || a.length !== b.length)
1245
+ return false;
1246
+ for (let i = 0; i < a.length; i++) {
1247
+ if (!compare(a[i], b[i]))
1248
+ return false;
1249
+ }
1250
+ return true;
1251
+ }
1252
+ Util.arrayEquals = arrayEquals;
1228
1253
  function iterMap(m, f) {
1229
1254
  Object.keys(m).forEach(k => f(k, m[k]));
1230
1255
  }
@@ -3048,6 +3073,10 @@ var ts;
3048
3073
  }
3049
3074
  }
3050
3075
  jsonPatch.patchInPlace = patchInPlace;
3076
+ function opsAreEqual(a, b) {
3077
+ return (a.op === b.op && pxtc.U.arrayEquals(a.path, b.path));
3078
+ }
3079
+ jsonPatch.opsAreEqual = opsAreEqual;
3051
3080
  })(jsonPatch = pxtc.jsonPatch || (pxtc.jsonPatch = {}));
3052
3081
  })(pxtc = ts.pxtc || (ts.pxtc = {}));
3053
3082
  })(ts || (ts = {}));
@@ -18516,8 +18545,8 @@ var pxt;
18516
18545
  if (a == b)
18517
18546
  return true;
18518
18547
  if (a.id !== b.id || a.type !== b.type ||
18519
- !arrayEquals(a.meta.tags, b.meta.tags) ||
18520
- !arrayEquals(a.meta.blockIDs, b.meta.blockIDs) ||
18548
+ !pxt.U.arrayEquals(a.meta.tags, b.meta.tags) ||
18549
+ !pxt.U.arrayEquals(a.meta.blockIDs, b.meta.blockIDs) ||
18521
18550
  a.meta.displayName !== b.meta.displayName)
18522
18551
  return false;
18523
18552
  switch (a.type) {
@@ -18526,7 +18555,7 @@ var pxt;
18526
18555
  return pxt.sprite.bitmapEquals(a.bitmap, b.bitmap);
18527
18556
  case "animation" /* Animation */:
18528
18557
  const bAnimation = b;
18529
- return a.interval === bAnimation.interval && arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
18558
+ return a.interval === bAnimation.interval && pxt.U.arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
18530
18559
  case "tilemap" /* Tilemap */:
18531
18560
  return a.data.equals(b.data);
18532
18561
  }
@@ -18648,17 +18677,6 @@ var pxt;
18648
18677
  }
18649
18678
  return id;
18650
18679
  }
18651
- function arrayEquals(a, b, compare = (c, d) => c === d) {
18652
- if (a == b)
18653
- return true;
18654
- if (!a && b || !b && a || a.length !== b.length)
18655
- return false;
18656
- for (let i = 0; i < a.length; i++) {
18657
- if (!compare(a[i], b[i]))
18658
- return false;
18659
- }
18660
- return true;
18661
- }
18662
18680
  function serializeTilemap(tilemap, id, name) {
18663
18681
  const tm = tilemap.tilemap.data();
18664
18682
  const data = new Uint8ClampedArray(5 + tm.data.length + tilemap.layers.data.length);