Skip to content

Commit

Permalink
Fix regression where extensions used by monitors were not saved
Browse files Browse the repository at this point in the history
Caught by test
  • Loading branch information
GarboMuffin committed Jul 26, 2023
1 parent 126f5a3 commit 24ae386
Showing 1 changed file with 42 additions and 45 deletions.
87 changes: 42 additions & 45 deletions src/serialization/sb3.js
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,45 @@ const serializeMonitors = function (monitors, runtime, extensions) {
.toArray();
};

/**
* @param {any} obj Project or target JSON. Modified in place.
* @param {Set<string>} extensionIds
* @param {Runtime} runtime
* @param {boolean} isSprite
* @returns {void} nothing, operates in-place
*/
const serializeExtensionMetadata = (obj, extensionIds, runtime, isSprite) => {
const serializedExtensions = Array.from(extensionIds);
if (serializedExtensions.length || !isSprite) {
obj.extensions = serializedExtensions;
}

// Save list of URLs to load the current extensions
// Extension manager only exists when runtime is wrapped by VirtualMachine
if (runtime.extensionManager) {
// We'll save the extensions in the format:
// {
// "extensionid": "https://...",
// "otherid": "https://..."
// }
// Which lets the VM know which URLs correspond to which IDs, which is useful when the project
// is being loaded. For example, if the extension is eventually converted to a builtin extension
// or if it is already loaded, then it doesn't need to fetch the script again.
const extensionURLs = runtime.extensionManager.getExtensionURLs();
const urlsToSave = {};
for (const extension of extensionIds) {
const url = extensionURLs[extension];
if (typeof url === 'string') {
urlsToSave[extension] = url;
}
}
// Only save this object if any URLs would actually be saved.
if (Object.keys(urlsToSave).length !== 0) {
obj.extensionURLs = urlsToSave;
}
}
};

/**
* Serializes the specified VM runtime.
* @param {!Runtime} runtime VM runtime instance to be serialized.
Expand Down Expand Up @@ -610,60 +649,18 @@ const serialize = function (runtime, targetId, {allowOptimization = true} = {})

const serializedTargets = flattenedOriginalTargets.map(t => serializeTarget(t, extensions));

const serialiedExtensionList = Array.from(extensions);

// Save list of URLs to load the current extensions
// Extension manager only exists when runtime is wrapped by VirtualMachine
let serializedExtensionURLs = null;
if (runtime.extensionManager) {
// We'll save the extensions in the format:
// {
// "extensionid": "https://...",
// "otherid": "https://..."
// }
// Which lets the VM know which URLs correspond to which IDs, which is useful when the project
// is being loaded. For example, if the extension is eventually converted to a builtin extension
// or if it is already loaded, then it doesn't need to fetch the script again.
const extensionURLs = runtime.extensionManager.getExtensionURLs();
const urlsToSave = {};
for (const extension of extensions) {
const url = extensionURLs[extension];
if (typeof url === 'string') {
urlsToSave[extension] = url;
}
}
// Only save this object if any URLs would actually be saved.
if (Object.keys(urlsToSave).length !== 0) {
serializedExtensionURLs = urlsToSave;
}
}

if (targetId) {
const target = serializedTargets[0];

// Scratch doesn't save extensions for sprites, so don't add if not needed.
if (serialiedExtensionList.length) {
target.extensions = serialiedExtensionList;
}
if (serializedExtensionURLs) {
target.extensionURLs = serializedExtensionURLs;
}

serializeExtensionMetadata(target, extensions, runtime, true);
return serializedTargets[0];
}

// This is part of Scratch
obj.extensions = serialiedExtensionList;

// This is not part of Scratch, so don't add if not needed.
if (serializedExtensionURLs) {
obj.extensionURLs = serializedExtensionURLs;
}

obj.targets = serializedTargets;

obj.monitors = serializeMonitors(runtime.getMonitorState(), runtime, extensions);

serializeExtensionMetadata(obj, extensions, runtime);

// Assemble metadata
const meta = Object.create(null);
meta.semver = '3.0.0';
Expand Down

0 comments on commit 24ae386

Please sign in to comment.