Skip to content

Commit 1b58840

Browse files
authored
Merge pull request #24 from Nitro-Bolt/required-extensions
"requiredExtensions" extension API
2 parents fe2cc07 + 63a2271 commit 1b58840

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/engine/runtime.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,25 @@ class Runtime extends EventEmitter {
10611061
* @param {ExtensionMetadata} extensionInfo - information about the extension (id, blocks, etc.)
10621062
* @private
10631063
*/
1064-
_registerExtensionPrimitives (extensionInfo) {
1064+
async _registerExtensionPrimitives (extensionInfo) {
1065+
1066+
// If the extension requires other extensions, load them first.
1067+
if (Array.isArray(extensionInfo.requiredExtensions)) {
1068+
for (const extensionId of extensionInfo.requiredExtensions) {
1069+
if (
1070+
this.extensionManager.isCoreExtension(extensionId) ||
1071+
this.extensionManager.isBuiltinExtension(extensionId) ||
1072+
await this.extensionManager.securityManager.canLoadExtensionFromProject(extensionId)
1073+
) {
1074+
this.extensionManager.loadExtensionURL(extensionId);
1075+
} else {
1076+
console.warn(
1077+
`Failed to load required extension: ${extensionId} for extension: ${extensionInfo.id}`
1078+
);
1079+
}
1080+
}
1081+
}
1082+
10651083
const categoryInfo = {
10661084
id: extensionInfo.id,
10671085
name: maybeFormatMessage(extensionInfo.name),

src/extension-support/extension-manager.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ const defaultBuiltinExtensions = {
2929
tw: () => require('../extensions/tw')
3030
};
3131

32+
const coreExtensions = [
33+
'motion',
34+
'looks',
35+
'sound',
36+
'events',
37+
'control',
38+
'sensing',
39+
'operators',
40+
'data',
41+
'json',
42+
'procedures',
43+
'comments'
44+
];
45+
3246
/**
3347
* @typedef {object} ArgumentInfo - Information about an extension block argument
3448
* @property {ArgumentType} type - the type of value this argument can take
@@ -126,6 +140,7 @@ class ExtensionManager {
126140
this.asyncExtensionsLoadedCallbacks = [];
127141

128142
this.builtinExtensions = Object.assign({}, defaultBuiltinExtensions);
143+
this.coreExtensions = coreExtensions;
129144

130145
dispatch.setService('extensions', createExtensionService(this)).catch(e => {
131146
log.error(`ExtensionManager was unable to register extension service: ${JSON.stringify(e)}`);
@@ -153,6 +168,16 @@ class ExtensionManager {
153168
return Object.prototype.hasOwnProperty.call(this.builtinExtensions, extensionId);
154169
}
155170

171+
/**
172+
* Determine whether an extension with a given ID is registered as a core extension in the VM, such as motion.
173+
* Note that custom extensions or extensions that don't load on startup will return false here.
174+
* @param {string} extensionId
175+
* @returns {boolean}
176+
*/
177+
isCoreExtension (extensionId) {
178+
return this.coreExtensions.includes(extensionId);
179+
}
180+
156181
/**
157182
* Synchronously load an internal extension (core or non-core) by ID. This call will
158183
* fail if the provided id is not does not match an internal extension.
@@ -207,8 +232,8 @@ class ExtensionManager {
207232
return;
208233
}
209234

210-
if (this.isExtensionURLLoaded(extensionURL)) {
211-
// Extension is already loaded.
235+
if (this.isExtensionURLLoaded(extensionURL) || this.isCoreExtension(extensionURL)) {
236+
// Extension is already loaded or is a core extension.
212237
return;
213238
}
214239

0 commit comments

Comments
 (0)