pxt-core 7.4.9 → 7.4.10
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 +73 -39
- package/built/pxtblockly.js +1359 -1448
- package/built/pxtblocks.d.ts +4 -4
- package/built/pxtblocks.js +35 -80
- package/built/pxtlib.d.ts +6 -2
- package/built/pxtlib.js +73 -39
- package/built/target.js +1 -1
- package/built/web/blockly.css +1 -1
- package/built/web/main.js +1 -1
- package/built/web/pxtapp.js +1 -1
- package/built/web/pxtasseteditor.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtembed.js +1 -1
- package/built/web/pxtlib.js +1 -1
- package/built/web/pxtworker.js +1 -1
- package/built/web/rtlblockly.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/built/web/skillmap/js/main.d5bb4f6b.chunk.js +1 -0
- package/localtypings/blockly.d.ts +12268 -7535
- package/package.json +2 -2
- package/theme/blockly-core.less +22 -13
- package/theme/melodyeditor.less +2 -2
- package/theme/print.less +1 -1
- package/theme/toolbox.less +1 -0
- package/webapp/public/blockly/blockly_compressed.js +1269 -1286
- package/webapp/public/blockly/blocks_compressed.js +47 -65
- package/webapp/public/blockly/msg/js/en.js +8 -17
- package/webapp/public/blockly/msg/json/en.json +6 -15
- package/webapp/public/skillmap.html +1 -1
- package/built/web/skillmap/js/main.ea4b3e23.chunk.js +0 -1
package/built/pxt.js
CHANGED
|
@@ -97885,7 +97885,7 @@ var pxt;
|
|
|
97885
97885
|
constructor() {
|
|
97886
97886
|
this.initialUserPreferences_ = undefined;
|
|
97887
97887
|
this.initialAuthCheck_ = undefined;
|
|
97888
|
-
this.
|
|
97888
|
+
this.patchQueue = [];
|
|
97889
97889
|
pxt.Util.assert(!_client);
|
|
97890
97890
|
// Set global instance.
|
|
97891
97891
|
_client = this;
|
|
@@ -98075,63 +98075,85 @@ var pxt;
|
|
|
98075
98075
|
}
|
|
98076
98076
|
return result.success;
|
|
98077
98077
|
}
|
|
98078
|
-
async patchUserPreferencesAsync(
|
|
98079
|
-
|
|
98080
|
-
|
|
98078
|
+
async patchUserPreferencesAsync(patchOps, opts = {}) {
|
|
98079
|
+
const defaultSuccessAsync = async () => ({ success: true, res: await this.userPreferencesAsync() });
|
|
98080
|
+
patchOps = Array.isArray(patchOps) ? patchOps : [patchOps];
|
|
98081
|
+
patchOps = patchOps.filter(op => !!op);
|
|
98082
|
+
if (!patchOps.length) {
|
|
98083
|
+
return await defaultSuccessAsync();
|
|
98084
|
+
}
|
|
98085
|
+
const patchDiff = (pSrc, ops, filter) => {
|
|
98086
|
+
// Apply patches to pDst and return the diff as a set of new patch ops.
|
|
98087
|
+
const pDst = pxt.U.deepCopy(pSrc);
|
|
98088
|
+
ts.pxtc.jsonPatch.patchInPlace(pDst, ops);
|
|
98089
|
+
let diff = ts.pxtc.jsonPatch.diff(pSrc, pDst);
|
|
98090
|
+
// Run caller-provided filter
|
|
98091
|
+
if (diff.length && filter) {
|
|
98092
|
+
diff = diff.filter(filter);
|
|
98093
|
+
}
|
|
98094
|
+
return diff;
|
|
98095
|
+
};
|
|
98096
|
+
// Process incoming patch operations to produce a more fine-grained set of diffs. Incoming patches may be overly destructive
|
|
98097
|
+
// Apply the patch in isolation and get the diff from original
|
|
98081
98098
|
const curPref = await this.userPreferencesAsync();
|
|
98082
|
-
|
|
98083
|
-
|
|
98099
|
+
const diff = patchDiff(curPref, patchOps, opts.filter);
|
|
98100
|
+
if (!diff.length) {
|
|
98101
|
+
return await defaultSuccessAsync();
|
|
98084
98102
|
}
|
|
98085
|
-
|
|
98103
|
+
// Apply the new diff to the current state
|
|
98104
|
+
ts.pxtc.jsonPatch.patchInPlace(curPref, diff);
|
|
98086
98105
|
await this.setUserPreferencesAsync(curPref);
|
|
98087
|
-
// If
|
|
98106
|
+
// If the user is not logged in, non-persistent local state is all we'll use (no sync to cloud)
|
|
98088
98107
|
if (!await this.loggedInAsync()) {
|
|
98089
|
-
return
|
|
98108
|
+
return await defaultSuccessAsync();
|
|
98090
98109
|
}
|
|
98091
|
-
// If the user is logged in,
|
|
98092
|
-
//
|
|
98093
|
-
|
|
98094
|
-
this.prefPatchOps.some((existing, iExisting) => {
|
|
98095
|
-
if (!ts.pxtc.jsonPatch.opsAreEqual(existing, incoming))
|
|
98096
|
-
return false;
|
|
98097
|
-
// Patches are equivalent, replace in queue
|
|
98098
|
-
this.prefPatchOps[iExisting] = incoming;
|
|
98099
|
-
// Clear from incoming so we don't add it below
|
|
98100
|
-
ops[iIncoming] = null;
|
|
98101
|
-
return true;
|
|
98102
|
-
});
|
|
98103
|
-
});
|
|
98104
|
-
// Add remaining ops to the queue
|
|
98105
|
-
ops.filter(op => !!op).forEach(op => this.prefPatchOps.push(op));
|
|
98110
|
+
// If the user is logged in, sync to cloud, but debounce the api call as this can be called frequently from skillmaps
|
|
98111
|
+
// Queue the patch for sync with backend
|
|
98112
|
+
this.patchQueue.push({ ops: patchOps, filter: opts.filter });
|
|
98106
98113
|
clearTimeout(debouncePreferencesChangedTimeout);
|
|
98107
|
-
const
|
|
98114
|
+
const syncPrefs = async () => {
|
|
98108
98115
|
debouncePreferencesChangedStarted = 0;
|
|
98109
|
-
|
|
98110
|
-
|
|
98111
|
-
|
|
98112
|
-
|
|
98113
|
-
|
|
98114
|
-
|
|
98115
|
-
|
|
98116
|
-
|
|
98116
|
+
if (!this.patchQueue.length) {
|
|
98117
|
+
return await defaultSuccessAsync();
|
|
98118
|
+
}
|
|
98119
|
+
// Fetch latest prefs from remote
|
|
98120
|
+
const getResult = await this.apiAsync('/api/user/preferences');
|
|
98121
|
+
if (!getResult.success) {
|
|
98122
|
+
pxt.reportError("identity", "failed to fetch preferences for patch", getResult);
|
|
98123
|
+
return { success: false, res: undefined };
|
|
98124
|
+
}
|
|
98125
|
+
// Apply queued patches to the remote state in isolation and develop a final diff to send to the backend
|
|
98126
|
+
const remotePrefs = pxt.U.deepCopy(getResult.resp);
|
|
98127
|
+
const patchQueue = this.patchQueue;
|
|
98128
|
+
this.patchQueue = []; // Reset the queue
|
|
98129
|
+
patchQueue.forEach(patch => {
|
|
98130
|
+
const diff = patchDiff(remotePrefs, patch.ops, patch.filter);
|
|
98131
|
+
ts.pxtc.jsonPatch.patchInPlace(remotePrefs, diff);
|
|
98132
|
+
});
|
|
98133
|
+
// Diff the original and patched remote states to get a final set of patch operations
|
|
98134
|
+
const finalOps = pxtc.jsonPatch.diff(getResult.resp, remotePrefs);
|
|
98135
|
+
const patchResult = await this.apiAsync('/api/user/preferences', finalOps, 'PATCH');
|
|
98136
|
+
if (patchResult.success) {
|
|
98137
|
+
// Set user profile from returned value so we stay in sync
|
|
98138
|
+
this.setUserPreferencesAsync(patchResult.resp);
|
|
98117
98139
|
}
|
|
98118
98140
|
else {
|
|
98119
|
-
pxt.reportError("identity", "
|
|
98141
|
+
pxt.reportError("identity", "failed to patch preferences", patchResult);
|
|
98120
98142
|
}
|
|
98121
|
-
return { success:
|
|
98143
|
+
return { success: patchResult.success, res: patchResult.resp };
|
|
98122
98144
|
};
|
|
98123
|
-
if (immediate) {
|
|
98124
|
-
return await
|
|
98145
|
+
if (opts.immediate) {
|
|
98146
|
+
return await syncPrefs();
|
|
98125
98147
|
}
|
|
98126
98148
|
else {
|
|
98127
98149
|
if (!debouncePreferencesChangedStarted) {
|
|
98128
98150
|
debouncePreferencesChangedStarted = pxt.U.now();
|
|
98129
98151
|
}
|
|
98130
98152
|
if (PREFERENCES_DEBOUNCE_MAX_MS < pxt.U.now() - debouncePreferencesChangedStarted) {
|
|
98131
|
-
return await
|
|
98153
|
+
return await syncPrefs();
|
|
98132
98154
|
}
|
|
98133
98155
|
else {
|
|
98134
|
-
debouncePreferencesChangedTimeout = setTimeout(
|
|
98156
|
+
debouncePreferencesChangedTimeout = setTimeout(syncPrefs, PREFERENCES_DEBOUNCE_MS);
|
|
98135
98157
|
return { success: false, res: undefined }; // This needs to be implemented correctly to return a promise with the debouncer
|
|
98136
98158
|
}
|
|
98137
98159
|
}
|
|
@@ -99214,6 +99236,18 @@ var ts;
|
|
|
99214
99236
|
return r;
|
|
99215
99237
|
}
|
|
99216
99238
|
Util.toSet = toSet;
|
|
99239
|
+
function deepCopy(src) {
|
|
99240
|
+
if (typeof src !== "object" || src === null) {
|
|
99241
|
+
return src;
|
|
99242
|
+
}
|
|
99243
|
+
const dst = Array.isArray(src) ? [] : {};
|
|
99244
|
+
for (const key in src) {
|
|
99245
|
+
const value = src[key];
|
|
99246
|
+
dst[key] = deepCopy(value);
|
|
99247
|
+
}
|
|
99248
|
+
return dst;
|
|
99249
|
+
}
|
|
99250
|
+
Util.deepCopy = deepCopy;
|
|
99217
99251
|
function toArray(a) {
|
|
99218
99252
|
if (Array.isArray(a)) {
|
|
99219
99253
|
return a;
|