Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
a4475d6
:truck: chore(vm): migrate block.js, including logic fixes
SimonShiki May 12, 2026
0aba640
:truck: chore(vm): migrate execute.js
SimonShiki May 12, 2026
6d17837
:truck: chore(vm): migrate serialize-assets.js
SimonShiki May 12, 2026
a64f909
:truck: chore(vm): migrate sb2_specmap.ts
SimonShiki May 12, 2026
08fb82d
:truck: chore(vm): migrate target.js
SimonShiki May 12, 2026
dbeb35c
:truck: chore(vm): migrate rendered-target.js
SimonShiki May 12, 2026
8cffd8c
:wrench: chore(vm): more neat ts usage
SimonShiki May 12, 2026
5adbc65
:truck: chore(vm,render,storage): migrate left io/*.js and load-costu…
SimonShiki May 12, 2026
120b4b4
:wrench: chore(vm): copied json block definitions from blockly
SimonShiki May 12, 2026
156e633
:truck: chore(vm,audio): migrate load-sound.js
SimonShiki May 12, 2026
7d91c21
:wrench: chore(vm): update import
SimonShiki May 12, 2026
d1b2430
:wrench: chore(vm): some cleanup
SimonShiki May 12, 2026
e375f49
:truck: chore(vm,audio): migrate runtime.js
SimonShiki May 13, 2026
69e5e3d
:bug: fix(vm,gui): add missing global declaration for gui & remove us…
SimonShiki May 13, 2026
d5570e4
:bug: fix(vm): tests
SimonShiki May 13, 2026
35256fc
:truck: chore(vm,storage): migrate virtual-machine.js
SimonShiki May 13, 2026
c914562
:bug: fix: build
SimonShiki May 13, 2026
e8fe08a
:wrench: chore(vm): add event map to virtual machine
SimonShiki May 14, 2026
3826e71
:truck: chore(vm,storage): migrate extension-manager.js
SimonShiki May 14, 2026
380ec91
:truck: chore(vm): refine types
SimonShiki May 14, 2026
39f044d
:wrench: chore(vm): add missing runtime events
SimonShiki May 14, 2026
dc77fec
:wrench: chore(vm): cleanup
SimonShiki May 14, 2026
84b79fe
:bug: fix(vm): fix wrong updateBitmapSkin usage
SimonShiki May 14, 2026
606f02e
:wrench: chore: inline const enums as soon as possible
SimonShiki May 14, 2026
53c1ec4
:wrench: chore(vm): make Mouse accept zero for x/y
SimonShiki May 14, 2026
143d397
:truck: chore(vm,storage): migrate deserialize-assets.js
SimonShiki May 15, 2026
7cc6b79
:truck: chore(vm): migrate pen extension
SimonShiki May 16, 2026
6a1d5ed
:wrench: chore(vm): refine types
SimonShiki May 16, 2026
d908f85
:bug: chore(vm): fix test & refine types
SimonShiki May 16, 2026
5052c6f
:wrench: chore(vm): migrate more extensions & refine types
SimonShiki May 17, 2026
df5ad21
:truck: chore: migrate music extension
SimonShiki May 18, 2026
ffaf0ad
:wrench: chore: add node types for audio
SimonShiki May 18, 2026
ad13643
:bug: fix(vm): wrong import
SimonShiki May 18, 2026
3894298
:fire: chore(block): remove unused index.ts
SimonShiki May 18, 2026
5275ab8
:wrench: chore(vm): export necessary types
SimonShiki May 22, 2026
b3fd7a7
:wrench: chore(vm): refine types
SimonShiki May 28, 2026
ae63d9f
:wrench: chore(vm): refine types
SimonShiki May 28, 2026
661fcee
:art: chore(vm): remove unexpected empty line
SimonShiki May 28, 2026
d2bb6f4
:wrench: chore(lint-config): don't require return jsdoc should have t…
SimonShiki May 28, 2026
b15218b
:wrench: chore(vm): migrate extension-worker.js
SimonShiki May 28, 2026
aa0afe9
:wrench: chore(vm): cleanup
SimonShiki Jul 10, 2026
004e8ce
:wrench: chore(vm): refine types
SimonShiki Jul 19, 2026
be7638d
:wrench: chore(vm): refine types
SimonShiki Aug 10, 2026
8994328
:wrench: chore: sync pnpm lockfile after rebase
SimonShiki Aug 14, 2026
78902c3
:wrench: chore(vm): unexpected behavior change
SimonShiki Aug 16, 2026
282ca0e
:construction: merge: update with feat/ts-vm
SimonShiki Aug 17, 2026
9d3468c
:wrench: chore: correct stroage types
SimonShiki Aug 29, 2026
16e8efc
:wrench: chore: use funcction overload for maybeFormatMessage
SimonShiki Aug 29, 2026
8662c48
:wrench: chore(vm): more reasonable types
SimonShiki Aug 29, 2026
5ff79e7
:wrench: chore(vm): correct extension's interface naming
SimonShiki Aug 31, 2026
b2f87e4
:wrench: chore(vm): re-export procedure mutation from blocks
SimonShiki Aug 31, 2026
7f1d21d
:wrench: chore(vm): migrate upstream types
SimonShiki Aug 31, 2026
3e417a5
:wrench: chore(vm): add missing types for sb2 specmap
SimonShiki Aug 31, 2026
e0013ad
:wrench: chore(vm): correct block utility and execute types
SimonShiki Aug 31, 2026
d1478d3
:wrench: chore(vm): continue to correct block utility and execute types
SimonShiki Aug 31, 2026
cc1a58d
:wrench: chore(storage): missing space
SimonShiki Aug 31, 2026
63ec550
:bug: fix(gui): correct default project's translate logics
SimonShiki Aug 31, 2026
b1d9552
:wrench: chore(vm): remove unused extensible props for monitor record…
SimonShiki Aug 31, 2026
d76c217
:wrench: chore(vm): add description for commented-out props
SimonShiki Sep 1, 2026
1bbdbba
:wrench: chore(vm): export execution context in better way
SimonShiki Sep 1, 2026
299888d
:wrench: chore(vm): correct blocks execute cache types
SimonShiki Sep 1, 2026
a213787
:fire: chore(vm): remove xml compatability
SimonShiki Sep 2, 2026
84e0f85
:wrench: chore(vm): remove unused domhandler
SimonShiki Sep 2, 2026
9710bcc
:wrench: chore(vm): add description for commented-out props
SimonShiki Sep 2, 2026
17bf7b2
:wrench: chore(gui): mark translator prop as optional
SimonShiki Sep 2, 2026
3090e1a
:wrench: chore(vm): refine blocks related types
SimonShiki Sep 2, 2026
b38a837
:bug: fix(vm): block event fixtures and adapter tests
SimonShiki Sep 2, 2026
aaa2a53
:bug: fix(gui): default project now migrated to ts
SimonShiki Sep 2, 2026
6451c06
:wrench: chore(vm): correct overload signature
SimonShiki Sep 6, 2026
f7175d8
:wrench: chore(vm): remove unnecessary assertion
SimonShiki Sep 6, 2026
b42ee70
:wrench: chore(vm): correct sb3 target types
SimonShiki Sep 6, 2026
6522692
:wrench: chore(vm): resolve runtime's type problems
SimonShiki Sep 10, 2026
fdba359
:wrench: chore(vm): assume editingTarget presents when call addMonito…
SimonShiki Sep 10, 2026
0163420
:wrench: chore(vm): add missing comments
SimonShiki Sep 12, 2026
f31dd7a
:wrench: chore: narrowing variable type
SimonShiki Oct 5, 2026
b0b7f06
:wrench: chore(vm): correct target types
SimonShiki Oct 5, 2026
ffc313e
:bug: fix(vm): remove rebundant null check in load-costume
SimonShiki Oct 5, 2026
17c90b3
:wrench: chore(vm): make the ble request error noisy
SimonShiki Oct 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/audio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@babel/core": "7.29.0",
"@babel/eslint-parser": "7.28.6",
"@babel/preset-env": "7.29.2",
"@types/node": "^25.5.2",
"babel-eslint": "10.0.3",
"babel-loader": "^10.1.1",
"eslint": "^9.39.2",
Expand Down
6 changes: 3 additions & 3 deletions packages/audio/src/AudioEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class AudioEngine {
* Decode a sound, decompressing it into audio samples.
* @param {object} sound - an object containing audio data and metadata for
* a sound
* @param {Buffer} sound.data - sound data loaded from scratch-storage
* @param {{buffer: ArrayBuffer}} sound.data - sound data loaded from scratch-storage
* @returns {?Promise} - a promise which will resolve to the sound id and
* buffer if decoded
*/
Expand Down Expand Up @@ -217,8 +217,8 @@ class AudioEngine {
*
* @param {object} sound - an object containing audio data and metadata for
* a sound
* @param {Buffer} sound.data - sound data loaded from scratch-storage
* @returns {?Promise} - a promise which will resolve to the buffer
* @param {{buffer: ArrayBuffer}} sound.data - sound data loaded from scratch-storage
* @returns - a promise which will resolve to the buffer
*/
decodeSoundPlayer (sound) {
return this._decodeSound(sound)
Expand Down
2 changes: 1 addition & 1 deletion packages/audio/src/SoundPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class SoundPlayer extends EventEmitter {

/**
* Output audio node.
* @type {AudioNode}
* @type {AudioBufferSourceNode}
*/
this.outputNode = null;

Expand Down
8 changes: 4 additions & 4 deletions packages/block/src/blocks/control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Blockly.Blocks['control_forever'] = {
message0: Blockly.Msg.CONTROL_FOREVER,
message1: '%1', // Statement
message2: '%1', // Icon
lastDummyAlign2: 'RIGHT',
implicitAlign2: 'RIGHT',
args1: [
{
type: 'input_statement',
Expand Down Expand Up @@ -69,7 +69,7 @@ Blockly.Blocks['control_repeat'] = {
message0: Blockly.Msg.CONTROL_REPEAT,
message1: '%1', // Statement
message2: '%1', // Icon
lastDummyAlign2: 'RIGHT',
implicitAlign2: 'RIGHT',
args0: [
{
type: 'input_value',
Expand Down Expand Up @@ -263,7 +263,7 @@ Blockly.Blocks['control_repeat_until'] = {
message0: Blockly.Msg.CONTROL_REPEATUNTIL,
message1: '%1',
message2: '%1',
lastDummyAlign2: 'RIGHT',
implicitAlign2: 'RIGHT',
args0: [
{
type: 'input_value',
Expand Down Expand Up @@ -302,7 +302,7 @@ Blockly.Blocks['control_while'] = {
message0: Blockly.Msg.CONTROL_WHILE,
message1: '%1',
message2: '%1',
lastDummyAlign2: 'RIGHT',
implicitAlign2: 'RIGHT',
args0: [
{
type: 'input_value',
Expand Down
4 changes: 2 additions & 2 deletions packages/block/src/blocks/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Blockly.Blocks['data_variable'] = {
init: function(this: Blockly.Block) {
this.jsonInit({
message0: '%1',
lastDummyAlign0: 'CENTRE',
implicitAlign0: 'CENTRE',
args0: [
{
type: 'field_variable_getter',
Expand Down Expand Up @@ -142,7 +142,7 @@ Blockly.Blocks['data_listcontents'] = {
init: function(this: Blockly.Block) {
this.jsonInit({
message0: '%1',
lastDummyAlign0: 'CENTRE',
implicitAlign0: 'CENTRE',
args0: [
{
type: 'field_variable_getter',
Expand Down
2 changes: 1 addition & 1 deletion packages/block/src/events/block_comment_collapse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class BlockCommentCollapse extends BlockCommentBase {
override type = 'block_comment_collapse';

/** Whether the comment is collpased. */
protected newCollapsed?: boolean;
newCollapsed?: boolean;

/**
* @param icon The comment icon this event corresponds to.
Expand Down
4 changes: 2 additions & 2 deletions packages/block/src/events/func_change.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export class FuncChange extends FuncBase {
override type = FuncChange.TYPE;

/** The previous extra state of the procedure. */
protected oldExtraState?: ProcedureExtraState;
oldExtraState?: ProcedureExtraState;

/** The new extra state of the procedure. */
protected newExtraState?: ProcedureExtraState;
newExtraState?: ProcedureExtraState;

/**
* @param procedure The procedure model.
Expand Down
3 changes: 2 additions & 1 deletion packages/block/src/events/var_create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
*/

import * as Blockly from 'blockly/core';
import type {VariableModel} from '../variable_model';
import type {VariableModel, VariableType} from '../variable_model';
import type {VariableMap} from '../variable_map';

/**
* Class for a variable creation event.
*/
export class VarCreate extends Blockly.Events.VarCreate {
override varType?: VariableType;
isCloud = false;
isLocal = false;

Expand Down
3 changes: 2 additions & 1 deletion packages/block/src/events/var_delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
*/

import * as Blockly from 'blockly/core';
import type {VariableModel} from '../variable_model';
import type {VariableModel, VariableType} from '../variable_model';
import type {VariableMap} from '../variable_map';

/**
* Class for a variable deletion event.
*/
export class VarDelete extends Blockly.Events.VarDelete {
override varType?: VariableType;
isCloud = false;
isLocal = false;

Expand Down
13 changes: 13 additions & 0 deletions packages/block/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,21 @@ export type * as variableModel from './variable_model';
export {reportValue} from './report_value';
export {Colours} from './theme';
export {BlockDragEnd} from './events/block_drag_end';
export {BlockDragOutside} from './events/block_drag_outside';
export {FuncChange} from './events/func_change';
export {FuncCreate} from './events/func_create';
export {FuncDelete} from './events/func_delete';
export {BlockCommentCreate} from './events/block_comment_create';
export {BlockCommentDelete} from './events/block_comment_delete';
export {BlockCommentMove} from './events/block_comment_move';
export {BlockCommentResize} from './events/block_comment_resize';
export {BlockCommentCollapse} from './events/block_comment_collapse';
export {BlockChange} from './events/block_change';
export {VarCreate} from './events/var_create';
export {VarDelete} from './events/var_delete';
export * as Theme from './theme';
export {glowStack} from './glow';
export type {BlockCommentState} from './block_comment_icon';

export {
FieldAngle,
Expand Down
4 changes: 2 additions & 2 deletions packages/block/src/variable_map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import * as Blockly from 'blockly/core';
import type {VariableModel} from './variable_model';
import type {VariableModel, VariableType} from './variable_model';

/**
* Class that provides storage for variables.
Expand All @@ -25,7 +25,7 @@ export class VariableMap extends Blockly.VariableMap {
*/
override createVariable(
name: string,
varType?: string,
varType?: VariableType,
varId?: string,
isLocal?: boolean,
isCloud?: boolean
Expand Down
6 changes: 5 additions & 1 deletion packages/block/src/variable_model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@

import * as Blockly from 'blockly/core';

// It should be consistent with constants.ts definitions.
export type VariableType = '' | 'list' | 'broadcast_msg';

export interface ScratchVariableState extends Blockly.IVariableState {
type?: VariableType;
isLocal: boolean;
isCloud: boolean;
}
Expand All @@ -27,7 +31,7 @@ export class VariableModel
constructor(
workspace: Blockly.Workspace,
name: string,
type?: string,
type?: VariableType,
id?: string,
isLocal = false,
isCloud = false
Expand Down
4 changes: 2 additions & 2 deletions packages/block/src/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import './variable_model';
import './variable_map';
import * as callbackRegistry from './callback_registry';
import * as Constants from './constants';
import {VariableModel} from './variable_model';
import {VariableModel, type VariableType} from './variable_model';
import type {VerticalFlyout} from './toolbox/flyout';
import type {Toolbox} from './toolbox/toolbox';

Expand All @@ -51,7 +51,7 @@ export const CLOUD_PREFIX = '☁ ';
export function createVariable(
workspace: Blockly.WorkspaceSvg,
callback?: (id?: string) => void,
type = Constants.SCALAR_VARIABLE_TYPE
type: VariableType = Constants.SCALAR_VARIABLE_TYPE
) {
// Decide on a modal message based on the type. If type was not
// provided, default to the original message for scalar variables.
Expand Down
2 changes: 1 addition & 1 deletion packages/gui/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"presets": [
["@babel/preset-env", {"targets": {"browsers": ["last 3 versions", "Safari >= 8", "iOS >= 8"]}}],
"@babel/preset-react",
"@babel/preset-typescript"
["@babel/preset-typescript", {"optimizeConstEnums": true}]
]
}
13 changes: 13 additions & 0 deletions packages/gui/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type ScratchLinkWebSocket from '../../vm/src/util/scratch-link-websocket';

type ScratchLinkSafariSocket = (new (type: 'BLE' | 'BT') => ScratchLinkWebSocket) & {
isSafariHelperCompatible: () => boolean;
};

declare global {
interface Window {
Scratch?: {
ScratchLinkSafariSocket?: ScratchLinkSafariSocket;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import projectData from './project-data';
import popWav from '!!arraybuffer-loader!./83a9787d4cb6f3b7632b4ddfebf74367.wav';
// import meowWav from '!arraybuffer-loader!./83c36d806dc92327b9e7049a565c6bff.wav';
import backdrop from './cd21514d0531fdffb22204e0ec5ed84a.svg?raw';
import type {Translator} from '../storage';
// import costume1 from './bcf454acf82e4504149f7ffe07081dbc.svg?raw';
// import costume2 from './0fb9be3e8397c983338cb71dc84d0b25.svg?raw';


const defaultProject = translator => {
const defaultProject = (translator?: Translator) => {
let _TextEncoder;
if (typeof TextEncoder === 'undefined') {
// eslint-disable-next-line global-require
// eslint-disable-next-line global-require, @typescript-eslint/no-require-imports
_TextEncoder = require('fastestsmallesttextencoderdecoder').TextEncoder;
} else {
_TextEncoder = TextEncoder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
import {defineMessages} from 'react-intl';
import sharedMessages from '../shared-messages';
import type {Translator} from '../storage';

let messages = defineMessages({
meow: {
defaultMessage: 'Meow',
description: 'Name for the meow sound',
id: 'gui.defaultProject.meow'
},
variable: {
defaultMessage: 'my variable',
description: 'Name for the default variable',
id: 'gui.defaultProject.variable'
backdrop: {
id: 'gui.defaultProject.backdrop',
defaultMessage: 'Backdrop',
description: 'Name for the default backdrop'
}
});

messages = {...messages, ...sharedMessages};

// use the default message if a translation function is not passed
/** @type {Translator} */
const defaultTranslator = msgObj => msgObj.defaultMessage;
const defaultTranslator: Translator = msgObj => msgObj.defaultMessage ?? msgObj.id;

/**
* @typedef {import('../storage').Translator} Translator
*/

/**
* Generate a localized version of the default project
* @param {Translator} translateFunction a function to use for translating the default names
* @param translateFunction a function to use for translating the default names
* @returns the project data json for the default project
*/
const projectData = translateFunction => {
const projectData = (translateFunction?: Translator) => {
const translator = translateFunction || defaultTranslator;
return ({
targets: [
Expand Down
5 changes: 3 additions & 2 deletions packages/gui/src/lib/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import {
ScratchStorage,
type Asset
} from 'clipcc-storage';
import type {IntlShape} from 'react-intl';

import defaultProject from './default-project';

export type Translator = ((messageId: string, defaultMessage?: string, description?: string) => string) | undefined;
export type Translator = IntlShape['formatMessage'];

type ConfigResponse = string | {
url: string;
Expand All @@ -24,7 +25,7 @@ class Storage extends ScratchStorage {
private assetHost = '';
private cdnHost = '';
private authorizationToken = '';
private translator: Translator;
private translator?: Translator;

constructor () {
super();
Expand Down
2 changes: 1 addition & 1 deletion packages/gui/test/unit/util/default-project.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import defaultProjectGenerator from '../../../src/lib/default-project/index.js';
import defaultProjectGenerator from '../../../src/lib/default-project/index';

describe('defaultProject', () => {
// This test ensures that the assets referenced in the default project JSON
Expand Down
3 changes: 2 additions & 1 deletion packages/gui/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"include": [
"./src/**/*",
"./test/**/*"
"./test/**/*",
"types/**/*.d.ts"
],
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
Expand Down
1 change: 1 addition & 0 deletions packages/lint-config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = [
rules: {
// Most packaages uses JSDoc to generate declaration files, which has lots of undefined types.
'jsdoc/no-undefined-types': 'warn',
'jsdoc/require-returns-type': 'off', /** tsc can infer return types */
'jsdoc/reject-function-type': 'warn',
'jsdoc/check-param-names': 'error',
'jsdoc/check-tag-names': 'error',
Expand Down
7 changes: 5 additions & 2 deletions packages/lint-config/ts.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module.exports = [
// Disable JSDoc type requirements for TypeScript (it has its own types)
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-param-type': 'off',
'jsdoc/require-returns-type': 'off',
'jsdoc/require-property-type': 'off',
'func-style': 'off',

// Disable rules that conflict with TypeScript's type system
Expand All @@ -41,7 +41,10 @@ module.exports = [
'no-useless-constructor': 'off',
// Use TypeScript-aware no-shadow to avoid false positives on enums/types
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error'
'@typescript-eslint/no-shadow': 'error',
// TypeScript overloads and declaration merging are intentional
'no-redeclare': 'off',
'@typescript-eslint/no-redeclare': ['error', {ignoreDeclarationMerge: true}]
}
}
];
Loading