pxt-core 7.4.7 → 7.4.11
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 +90 -53
- package/built/pxtblockly.js +1361 -1450
- package/built/pxtblocks.d.ts +4 -4
- package/built/pxtblocks.js +35 -80
- package/built/pxtlib.d.ts +11 -2
- package/built/pxtlib.js +90 -53
- 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/react-common.css +10 -5
- package/built/web/rtlblockly.css +1 -1
- package/built/web/rtlsemantic.css +2 -2
- package/built/web/semantic.css +2 -2
- package/built/web/skillmap/css/main.96b1b3f1.chunk.css +1 -0
- package/built/web/skillmap/js/2.7dd06a3a.chunk.js +2 -0
- package/built/web/skillmap/js/main.55881627.chunk.js +1 -0
- package/localtypings/blockly.d.ts +12268 -7535
- package/localtypings/pxtarget.d.ts +1 -0
- 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/pxt.less +0 -1
- package/theme/toolbox.less +1 -0
- package/webapp/public/blockly/blockly_compressed.js +1271 -1288
- 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 +2 -2
- package/built/web/skillmap/css/main.70954d9b.chunk.css +0 -1
- package/built/web/skillmap/js/2.c64f6be2.chunk.js +0 -2
- package/built/web/skillmap/js/main.86ef11e3.chunk.js +0 -1
package/built/pxt.js
CHANGED
|
@@ -97871,7 +97871,8 @@ var pxt;
|
|
|
97871
97871
|
highContrast: false,
|
|
97872
97872
|
language: pxt.appTarget.appTheme.defaultLocale,
|
|
97873
97873
|
reader: "",
|
|
97874
|
-
skillmap: { mapProgress: {}, completedTags: {} }
|
|
97874
|
+
skillmap: { mapProgress: {}, completedTags: {} },
|
|
97875
|
+
email: false
|
|
97875
97876
|
});
|
|
97876
97877
|
let _client;
|
|
97877
97878
|
function client() { return _client; }
|
|
@@ -97884,7 +97885,7 @@ var pxt;
|
|
|
97884
97885
|
constructor() {
|
|
97885
97886
|
this.initialUserPreferences_ = undefined;
|
|
97886
97887
|
this.initialAuthCheck_ = undefined;
|
|
97887
|
-
this.
|
|
97888
|
+
this.patchQueue = [];
|
|
97888
97889
|
pxt.Util.assert(!_client);
|
|
97889
97890
|
// Set global instance.
|
|
97890
97891
|
_client = this;
|
|
@@ -98074,62 +98075,86 @@ var pxt;
|
|
|
98074
98075
|
}
|
|
98075
98076
|
return result.success;
|
|
98076
98077
|
}
|
|
98077
|
-
async patchUserPreferencesAsync(
|
|
98078
|
-
|
|
98079
|
-
|
|
98080
|
-
|
|
98081
|
-
|
|
98082
|
-
|
|
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
|
|
98083
98098
|
const curPref = await this.userPreferencesAsync();
|
|
98084
|
-
|
|
98099
|
+
const diff = patchDiff(curPref, patchOps, opts.filter);
|
|
98100
|
+
if (!diff.length) {
|
|
98101
|
+
return await defaultSuccessAsync();
|
|
98102
|
+
}
|
|
98103
|
+
// Apply the new diff to the current state
|
|
98104
|
+
ts.pxtc.jsonPatch.patchInPlace(curPref, diff);
|
|
98085
98105
|
await this.setUserPreferencesAsync(curPref);
|
|
98086
|
-
// If
|
|
98106
|
+
// If the user is not logged in, non-persistent local state is all we'll use (no sync to cloud)
|
|
98087
98107
|
if (!await this.loggedInAsync()) {
|
|
98088
|
-
return;
|
|
98108
|
+
return await defaultSuccessAsync();
|
|
98089
98109
|
}
|
|
98090
|
-
// If the user is logged in,
|
|
98091
|
-
//
|
|
98092
|
-
|
|
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));
|
|
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 });
|
|
98105
98113
|
clearTimeout(debouncePreferencesChangedTimeout);
|
|
98106
|
-
const
|
|
98114
|
+
const syncPrefs = async () => {
|
|
98107
98115
|
debouncePreferencesChangedStarted = 0;
|
|
98108
|
-
|
|
98109
|
-
|
|
98110
|
-
|
|
98111
|
-
|
|
98112
|
-
|
|
98113
|
-
|
|
98114
|
-
|
|
98115
|
-
|
|
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);
|
|
98116
98139
|
}
|
|
98117
98140
|
else {
|
|
98118
|
-
pxt.reportError("identity", "
|
|
98141
|
+
pxt.reportError("identity", "failed to patch preferences", patchResult);
|
|
98119
98142
|
}
|
|
98143
|
+
return { success: patchResult.success, res: patchResult.resp };
|
|
98120
98144
|
};
|
|
98121
|
-
if (immediate) {
|
|
98122
|
-
await
|
|
98145
|
+
if (opts.immediate) {
|
|
98146
|
+
return await syncPrefs();
|
|
98123
98147
|
}
|
|
98124
98148
|
else {
|
|
98125
98149
|
if (!debouncePreferencesChangedStarted) {
|
|
98126
98150
|
debouncePreferencesChangedStarted = pxt.U.now();
|
|
98127
98151
|
}
|
|
98128
98152
|
if (PREFERENCES_DEBOUNCE_MAX_MS < pxt.U.now() - debouncePreferencesChangedStarted) {
|
|
98129
|
-
await
|
|
98153
|
+
return await syncPrefs();
|
|
98130
98154
|
}
|
|
98131
98155
|
else {
|
|
98132
|
-
debouncePreferencesChangedTimeout = setTimeout(
|
|
98156
|
+
debouncePreferencesChangedTimeout = setTimeout(syncPrefs, PREFERENCES_DEBOUNCE_MS);
|
|
98157
|
+
return { success: false, res: undefined }; // This needs to be implemented correctly to return a promise with the debouncer
|
|
98133
98158
|
}
|
|
98134
98159
|
}
|
|
98135
98160
|
}
|
|
@@ -99211,6 +99236,18 @@ var ts;
|
|
|
99211
99236
|
return r;
|
|
99212
99237
|
}
|
|
99213
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;
|
|
99214
99251
|
function toArray(a) {
|
|
99215
99252
|
if (Array.isArray(a)) {
|
|
99216
99253
|
return a;
|
|
@@ -101630,7 +101667,7 @@ var pxt;
|
|
|
101630
101667
|
'pxt_controls_for': {
|
|
101631
101668
|
name: pxt.Util.lf("a loop that repeats the number of times you say"),
|
|
101632
101669
|
tooltip: pxt.Util.lf("Have the variable '{0}' take on the values from 0 to the end number, counting by 1, and do the specified blocks."),
|
|
101633
|
-
url: 'blocks/loops/for',
|
|
101670
|
+
url: '/blocks/loops/for',
|
|
101634
101671
|
category: 'loops',
|
|
101635
101672
|
block: {
|
|
101636
101673
|
message0: pxt.Util.lf("for %1 from 0 to %2"),
|
|
@@ -101641,7 +101678,7 @@ var pxt;
|
|
|
101641
101678
|
'controls_simple_for': {
|
|
101642
101679
|
name: pxt.Util.lf("a loop that repeats the number of times you say"),
|
|
101643
101680
|
tooltip: pxt.Util.lf("Have the variable '{0}' take on the values from 0 to the end number, counting by 1, and do the specified blocks."),
|
|
101644
|
-
url: 'blocks/loops/for',
|
|
101681
|
+
url: '/blocks/loops/for',
|
|
101645
101682
|
category: 'loops',
|
|
101646
101683
|
block: {
|
|
101647
101684
|
message0: pxt.Util.lf("for %1 from 0 to %2"),
|
|
@@ -101652,7 +101689,7 @@ var pxt;
|
|
|
101652
101689
|
'pxt_controls_for_of': {
|
|
101653
101690
|
name: pxt.Util.lf("a loop that repeats for each value in an array"),
|
|
101654
101691
|
tooltip: pxt.Util.lf("Have the variable '{0}' take the value of each item in the array one by one, and do the specified blocks."),
|
|
101655
|
-
url: 'blocks/loops/for-of',
|
|
101692
|
+
url: '/blocks/loops/for-of',
|
|
101656
101693
|
category: 'loops',
|
|
101657
101694
|
block: {
|
|
101658
101695
|
message0: pxt.Util.lf("for element %1 of %2"),
|
|
@@ -101663,7 +101700,7 @@ var pxt;
|
|
|
101663
101700
|
'controls_for_of': {
|
|
101664
101701
|
name: pxt.Util.lf("a loop that repeats for each value in an array"),
|
|
101665
101702
|
tooltip: pxt.Util.lf("Have the variable '{0}' take the value of each item in the array one by one, and do the specified blocks."),
|
|
101666
|
-
url: 'blocks/loops/for-of',
|
|
101703
|
+
url: '/blocks/loops/for-of',
|
|
101667
101704
|
category: 'loops',
|
|
101668
101705
|
block: {
|
|
101669
101706
|
message0: pxt.Util.lf("for element %1 of %2"),
|
|
@@ -101948,7 +101985,7 @@ var pxt;
|
|
|
101948
101985
|
'text': {
|
|
101949
101986
|
name: pxt.Util.lf("a piece of text"),
|
|
101950
101987
|
tooltip: pxt.Util.lf("A letter, word, or line of text."),
|
|
101951
|
-
url: 'types/string',
|
|
101988
|
+
url: '/types/string',
|
|
101952
101989
|
category: 'text',
|
|
101953
101990
|
block: {
|
|
101954
101991
|
search: pxt.Util.lf("a piece of text") // Only used for search; this string is not surfaced in the block's text
|
|
@@ -101957,7 +101994,7 @@ var pxt;
|
|
|
101957
101994
|
'text_length': {
|
|
101958
101995
|
name: pxt.Util.lf("number of characters in the string"),
|
|
101959
101996
|
tooltip: pxt.Util.lf("Returns the number of letters (including spaces) in the provided text."),
|
|
101960
|
-
url: 'reference/text/length',
|
|
101997
|
+
url: '/reference/text/length',
|
|
101961
101998
|
category: 'text',
|
|
101962
101999
|
block: {
|
|
101963
102000
|
TEXT_LENGTH_TITLE: pxt.Util.lf("length of %1")
|
|
@@ -101966,7 +102003,7 @@ var pxt;
|
|
|
101966
102003
|
'text_join': {
|
|
101967
102004
|
name: pxt.Util.lf("join items to create text"),
|
|
101968
102005
|
tooltip: pxt.Util.lf("Create a piece of text by joining together any number of items."),
|
|
101969
|
-
url: 'reference/text/join',
|
|
102006
|
+
url: '/reference/text/join',
|
|
101970
102007
|
category: 'text',
|
|
101971
102008
|
block: {
|
|
101972
102009
|
TEXT_JOIN_TITLE_CREATEWITH: pxt.Util.lf("join")
|
|
@@ -101975,7 +102012,7 @@ var pxt;
|
|
|
101975
102012
|
'procedures_defnoreturn': {
|
|
101976
102013
|
name: pxt.Util.lf("define the function"),
|
|
101977
102014
|
tooltip: pxt.Util.lf("Create a function."),
|
|
101978
|
-
url: 'types/function/define',
|
|
102015
|
+
url: '/types/function/define',
|
|
101979
102016
|
category: 'functions',
|
|
101980
102017
|
block: {
|
|
101981
102018
|
PROCEDURES_DEFNORETURN_TITLE: pxt.Util.lf("function"),
|
|
@@ -101985,7 +102022,7 @@ var pxt;
|
|
|
101985
102022
|
'procedures_callnoreturn': {
|
|
101986
102023
|
name: pxt.Util.lf("call the function"),
|
|
101987
102024
|
tooltip: pxt.Util.lf("Call the user-defined function."),
|
|
101988
|
-
url: 'types/function/call',
|
|
102025
|
+
url: '/types/function/call',
|
|
101989
102026
|
category: 'functions',
|
|
101990
102027
|
block: {
|
|
101991
102028
|
PROCEDURES_CALLNORETURN_TITLE: pxt.Util.lf("call function")
|
|
@@ -101994,7 +102031,7 @@ var pxt;
|
|
|
101994
102031
|
'function_return': {
|
|
101995
102032
|
name: pxt.Util.lf("return a value from within a function"),
|
|
101996
102033
|
tooltip: pxt.Util.lf("Return a value from within a user-defined function."),
|
|
101997
|
-
url: 'types/function/return',
|
|
102034
|
+
url: '/types/function/return',
|
|
101998
102035
|
category: 'functions',
|
|
101999
102036
|
block: {
|
|
102000
102037
|
message_with_value: pxt.Util.lf("return %1"),
|
|
@@ -102004,7 +102041,7 @@ var pxt;
|
|
|
102004
102041
|
'function_definition': {
|
|
102005
102042
|
name: pxt.Util.lf("define the function"),
|
|
102006
102043
|
tooltip: pxt.Util.lf("Create a function."),
|
|
102007
|
-
url: 'types/function/define',
|
|
102044
|
+
url: '/types/function/define',
|
|
102008
102045
|
category: 'functions',
|
|
102009
102046
|
block: {
|
|
102010
102047
|
FUNCTIONS_EDIT_OPTION: pxt.Util.lf("Edit Function")
|
|
@@ -102013,7 +102050,7 @@ var pxt;
|
|
|
102013
102050
|
'function_call': {
|
|
102014
102051
|
name: pxt.Util.lf("call the function"),
|
|
102015
102052
|
tooltip: pxt.Util.lf("Call the user-defined function."),
|
|
102016
|
-
url: 'types/function/call',
|
|
102053
|
+
url: '/types/function/call',
|
|
102017
102054
|
category: 'functions',
|
|
102018
102055
|
block: {
|
|
102019
102056
|
FUNCTIONS_CALL_TITLE: pxt.Util.lf("call"),
|
|
@@ -102023,7 +102060,7 @@ var pxt;
|
|
|
102023
102060
|
'function_call_output': {
|
|
102024
102061
|
name: pxt.Util.lf("call the function with a return value"),
|
|
102025
102062
|
tooltip: pxt.Util.lf("Call the user-defined function with a return value."),
|
|
102026
|
-
url: 'types/function/call',
|
|
102063
|
+
url: '/types/function/call',
|
|
102027
102064
|
category: 'functions',
|
|
102028
102065
|
block: {}
|
|
102029
102066
|
}
|