Skip to content

🚚 chore: migrate vm to typescript part 2#236

Open
SimonShiki wants to merge 34 commits into
feat/ts-vmfrom
feat/ts-vm-2
Open

🚚 chore: migrate vm to typescript part 2#236
SimonShiki wants to merge 34 commits into
feat/ts-vmfrom
feat/ts-vm-2

Conversation

@SimonShiki
Copy link
Copy Markdown
Member

@SimonShiki SimonShiki commented May 12, 2026

Requires #235

Description

Migrate the left stuffs to typescript, including some bug fixes that discovered during migration.

Proposed Changes

  1. Migrate almost all vm source files to typescript, except for builtin extensions and serialization stuffs.
  2. Also adjust other related packages to fit this migration. (audio, block, gui, storage, render)
  3. (bugfix) handle block_comment_* and comment_* events properly, and update tests. (engine/blocks.ts, b770245)
  4. Make requestHideMonitor and requestShowMonitor use immutable's Map rather than js's native Map, since other places assume it's a ImmutableMap instance. (engine/runtime.ts, c10865a)
  5. Unsafe getProcedureParamNamesAndIds usage. (engine/runtime.ts, c10865a)
  6. remove useless makeMessageContextForTarget implementation, as it did nothing. (engine/runtime.ts, c10865a)
  7. adjust _convertBlockForScratchBlocks clipcc-blocks json construction to fit modern blockly's definition. (engine/runtime.js, packages/blocks/src/blocks/control.ts, c10865a)
  8. fix broken shareBlocksToTarget logics (virtual-machine.ts, 15a2b22)

Test Coverage

Update ‎packages/vm/test/unit/project_changed_state_blocks.js to fit modern blockly changes.
Any other tests are only updated for removing .js extension.

Additional Context

For AI reviewers

In this migration, the type annotations involved should, to the greatest extent possible, remain zero‑overhead and must not introduce any substantially breaking logic changes. Exceptions are allowed only when:

The original code genuinely has serious defects, and the fix will not potentially affect a large body of other code that depends on this part of the source.

The fix does not alter the original execution logic (for example, it merely performs a type check earlier and bails out (Eg: returns early or throw error), where that bail‑out is a behavior that would have occurred under the original logic anyway).

You need to pay special attention to changes that tangibly affect runtime behavior, and verify whether the change—viewed either as a caller or a callee—has any impact on the other invocations involved.

preserve ALL original comment descriptions except type annotation (Eg: @type {Runtime}, since we've migrated them into typescript native syntax)

Signed-off-by: SimonShiki <sinangentoo@gmail.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 12, 2026

Deploying clipcc-preview with  Cloudflare Pages  Cloudflare Pages

Latest commit: 390a90e
Status: ✅  Deploy successful!
Preview URL: https://00e90e25.clipcc-preview.pages.dev
Branch Preview URL: https://feat-ts-vm-2.clipcc-preview.pages.dev

View logs

SimonShiki added 15 commits May 12, 2026 17:05
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
…s jsdocs

Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
@SimonShiki SimonShiki self-assigned this May 13, 2026
@SimonShiki SimonShiki added bug Something isn't working help wanted Extra attention is needed vm Things related to clipcc-vm. labels May 13, 2026
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
@SimonShiki SimonShiki marked this pull request as ready for review May 13, 2026 15:35
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
@SimonShiki SimonShiki added the feature New feature or request label May 14, 2026
@SimonShiki SimonShiki requested a review from alexcui03 May 14, 2026 03:03
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
@SimonShiki SimonShiki removed the help wanted Extra attention is needed label May 14, 2026
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the VM TypeScript migration (part 2), updating remaining VM sources and aligning adjacent packages (blocks/gui/storage/render/audio) to the new TS-based module layout, while also adjusting tests and a few runtime behaviors discovered during migration (notably comment/block-comment event handling and some Blockly JSON definition updates).

Changes:

  • Migrate many packages/vm modules (engine/io/util/types/extension-support/etc.) to TypeScript and adjust import paths across unit/integration tests.
  • Update extension metadata typings + Blockly JSON definition types to reflect newer Blockly/clipcc-block usage.
  • Update tests/fixtures for modern Blockly comment/block-comment event shapes.

Reviewed changes

Copilot reviewed 130 out of 136 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/vm/test/unit/vm_collectAssets.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/virtual-machine.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/util_variable.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/sprites_rendered-target.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/serialization_sb3.js Update Runtime import path after TS migration.
packages/vm/test/unit/serialization_sb2.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/project_load_changed_state.js Update VM import path after TS migration.
packages/vm/test/unit/project_changed_state.js Update VM import path after TS migration.
packages/vm/test/unit/project_changed_state_blocks.js Update comment/block-comment event test data for modern Blockly events.
packages/vm/test/unit/io_mouse.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/io_keyboard.js Update Runtime import path after TS migration.
packages/vm/test/unit/io_joystick.js Update Runtime import path after TS migration.
packages/vm/test/unit/io_cloud.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/io_clock.js Update Runtime import path after TS migration.
packages/vm/test/unit/extension_conversion.js Adjust expectations for modern block JSON fields.
packages/vm/test/unit/engine_thread.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/engine_target.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/engine_sequencer.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/engine_runtime.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/engine_blocks.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/blocks_sensing.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/blocks_motion.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/blocks_looks.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/blocks_event.js Update imports to extensionless paths after TS migration.
packages/vm/test/unit/blocks_control.js Update imports to extensionless paths after TS migration.
packages/vm/test/integration/sprite3_missing_svg.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sprite3_missing_png.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sprite3_corrupted_svg.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sprite3_corrupted_png.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sprite2_missing_svg.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sprite2_missing_png.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sprite2_corrupted_svg.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sprite2_corrupted_png.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb3-roundtrip.js Update engine/import/runtime imports after TS migration.
packages/vm/test/integration/sb3_missing_svg.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb3_missing_sound.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb3_missing_png.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb3_corrupted_svg.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb3_corrupted_sound.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb3_corrupted_png.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb2_missing_svg.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb2_missing_png.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb2_corrupted_svg.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/sb2_corrupted_png.js Update serialize-assets import path after TS migration.
packages/vm/test/integration/monitor-threads-run-every-frame.js Update Runtime import path after TS migration.
packages/vm/test/integration/load-sb2-originally-sb1-without-backdrop-image.js Update VM import path after TS migration.
packages/vm/test/integration/internal-extension.js Update imports to extensionless paths after TS migration.
packages/vm/test/integration/import_sb2.js Update imports to extensionless paths after TS migration.
packages/vm/test/integration/import_nested_sb2.js Update imports to extensionless paths after TS migration.
packages/vm/test/integration/hat-threads-run-every-frame.js Update Runtime/execute import paths after TS migration.
packages/vm/test/integration/delete-and-restore-sprite.js Update VM import path after TS migration.
packages/vm/test/integration/addSprite.js Update imports to extensionless paths after TS migration.
packages/vm/test/fixtures/events.json Update comment event fixture shape for modern Blockly move events.
packages/vm/src/util/variable-util.ts Export VarReference type and adjust method signature typing.
packages/vm/src/util/timer.ts Remove explicit : void return annotations (TS inference).
packages/vm/src/util/task-queue.ts Remove explicit : void return annotations (TS inference).
packages/vm/src/util/scratch-link-websocket.ts Remove explicit : void return annotations and refine handler typing.
packages/vm/src/util/new-block-ids.ts Remove explicit : void return annotation (TS inference).
packages/vm/src/util/maybe-format-message.ts Broaden accepted “message” inputs + add generic return typing.
packages/vm/src/util/jsonrpc.ts Remove explicit : void return annotations (TS inference).
packages/vm/src/types/modules.d.ts Add module declarations for untyped dependencies.
packages/vm/src/types/json-block-definitions.ts Add a local JsonBlockDefinition type adapted from Blockly.
packages/vm/src/types/global.d.ts Move window ScratchLinkSafariSocket typing to global declaration.
packages/vm/src/types/defined.d.ts Restore compile-time injected clipcc global typing.
packages/vm/src/sprites/sprite.ts Convert to TS imports/types; refine Costume/Sound interfaces.
packages/vm/src/serialization/serialize-assets.ts Add Runtime typing and tighten parameter types.
packages/vm/src/serialization/schema.ts Expand/adjust schema typing (including block comment state and mutations).
packages/vm/src/serialization/sb3.js Update imports and align typedefs with new schema types.
packages/vm/src/serialization/sb2.js Update imports and align JSDoc typing for TS-adjacent usage.
packages/vm/src/serialization/sb2_specmap.ts Convert spec map typing to TS interfaces/unions.
packages/vm/src/playground/benchmark.js Update import paths for benchmark harness.
packages/vm/src/io/video.ts Convert to TS and add provider/runtime typing.
packages/vm/src/io/userData.ts Remove explicit : void return annotation (TS inference).
packages/vm/src/io/mouseWheel.ts Remove explicit : void return annotation (TS inference).
packages/vm/src/io/mouse.ts Convert to TS + add runtime/target typing and null checks.
packages/vm/src/io/keyboard.ts Remove explicit : void return annotation (TS inference).
packages/vm/src/io/joystick.ts Remove explicit : void return annotation (TS inference).
packages/vm/src/io/cloud.ts Convert to TS + add provider/runtime/stage typing.
packages/vm/src/io/clock.ts Remove explicit : void return annotations (TS inference).
packages/vm/src/io/bt.ts Convert to TS + tighten scratch-link socket typing and runtime event usage.
packages/vm/src/io/ble.ts Convert to TS + tighten scratch-link socket typing and runtime event usage.
packages/vm/src/index.ts Update VM entrypoint exports and re-exports for TS consumers.
packages/vm/src/import/load-sound.ts Add TS typing for Sound/Asset/Runtime and error-path modeling.
packages/vm/src/import/load-costume.ts Add TS typing and additional runtime dependency checks.
packages/vm/src/extensions/scratch3_wedo2/index.js Update BLE import path after TS migration.
packages/vm/src/extensions/scratch3_video_sensing/index.js Update Runtime/Video import paths after TS migration.
packages/vm/src/extensions/scratch3_translate/index.js JSDoc return type cleanup.
packages/vm/src/extensions/scratch3_text2speech/index.js JSDoc return type cleanup.
packages/vm/src/extensions/scratch3_speech2text/index.js JSDoc return type cleanup.
packages/vm/src/extensions/scratch3_pen/index.js Update RenderedTarget import path after TS migration.
packages/vm/src/extensions/scratch3_music/index.js JSDoc return type cleanup.
packages/vm/src/extensions/scratch3_microbit/index.js Update BLE import path after TS migration.
packages/vm/src/extensions/scratch3_makeymakey/index.js JSDoc return type cleanup.
packages/vm/src/extensions/scratch3_gdx_for/index.js Update BLE import path after TS migration.
packages/vm/src/extensions/scratch3_ev3/index.js Update BT import path after TS migration.
packages/vm/src/extensions/scratch3_boost/index.js Update BLE import path after TS migration.
packages/vm/src/extension-support/extension-metadata.ts Add/reshape extension metadata types for TS usage.
packages/vm/src/extension-support/extension-manager.ts Convert to TS with stronger typing of built-ins, menus, and dispatch access.
packages/vm/src/engine/variable.ts Adjust constructor signature to accept null id and default isCloud.
packages/vm/src/engine/thread.ts Convert to TS typing for cached args and stack frame state.
packages/vm/src/engine/target.ts Convert to TS with typed events and stronger variable/reference typing.
packages/vm/src/engine/sequencer.ts Update execute import path and tighten step-time typing.
packages/vm/src/engine/profiler.ts Export FrameCallback + minor TS inference changes.
packages/vm/src/engine/monitor-record.ts Export MonitorRecordProps and loosen some props to optional.
packages/vm/src/engine/execute.ts Convert to TS, tighten types for cached args/mutations and execution flow.
packages/vm/src/engine/blocks-runtime-cache.ts Update cached field normalization logic (uppercasing).
packages/vm/src/engine/blocks-execute-cache.ts Export CachedBlockData and add generic typing for cache retrieval.
packages/vm/src/engine/block-utility.ts Tighten typing for startHats match fields and TS inference.
packages/vm/src/engine/adapter.ts Export AdaptableEvents type and remove explicit : void on helpers.
packages/vm/src/dispatch/central-dispatch.ts Make services publicly accessible (used by extension manager).
packages/vm/src/blocks/scratch3_sound.ts Adjust typing for custom state retrieval.
packages/vm/src/blocks/scratch3_motion.ts Add null-guard for keepInFence return.
packages/vm/src/blocks/scratch3_looks.ts Update imports and improve const typing for static getters.
packages/vm/src/blocks/scratch3_core_example.ts Convert to TS typings for ExtensionClass + Runtime.
packages/vm/src/blocks/category_prototype.ts Add Runtime typing and export CategoryPrototypeConstructor.
packages/vm/package.json Update exported types entry to new dist layout.
packages/vm/docs/extensions.md Update reference to extension-manager filename (.ts).
packages/vm/.babelrc Enable optimizeConstEnums for TS preset.
packages/storage/src/ScratchStorage.ts Tighten AssetId usage, allow optional dataFormat in load, and allow null IDs in createAsset signature.
packages/storage/src/Asset.ts Allow assetId to be null in the Asset constructor property.
packages/render/src/Skin.js JSDoc tuple typing for size/center return.
packages/render/src/RenderWebGL.js JSDoc tuple typing and optional rotationCenter param docs.
packages/gui/tsconfig.json Include types/**/*.d.ts for compilation.
packages/gui/src/global.d.ts Add Window.ScratchLinkSafariSocket typing for GUI TS.
packages/gui/.babelrc Enable optimizeConstEnums for TS preset.
packages/block/src/index.ts Export additional Blockly event types + BlockCommentState type.
packages/block/src/events/func_change.ts Adjust visibility of extra-state fields.
packages/block/src/events/block_comment_collapse.ts Adjust visibility of newCollapsed.
packages/block/src/blocks/data.ts Replace legacy lastDummyAlign* with implicitAlign*.
packages/block/src/blocks/control.ts Replace legacy lastDummyAlign* with implicitAlign*.
packages/audio/src/AudioEngine.js Correct JSDoc for sound.data type to ArrayBuffer.
Comments suppressed due to low confidence (2)

packages/vm/src/playground/benchmark.js:49

  • importLoadCostume/importLoadSound objects spread themselves during initialization (...importLoadCostume / ...importLoadSound), which will throw at runtime (TDZ / ReferenceError) and prevents the benchmark from loading. Use the imported module namespace (originalImportLoadCostume / originalImportLoadSound) as the spread base (or rename locals) instead of self-referencing.
    packages/vm/src/io/mouse.ts:101
  • postData uses if (data.x) / if (data.y) to detect coordinate updates. This skips valid 0 coordinates (canvas edges), leaving stale mouse positions and potentially mis-firing click logic. Check for numeric presence (e.g., typeof data.x === 'number') instead of truthiness.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if (field.value?.toUpperCase) {
field.value = field.value.toUpperCase();
}
field.value = field.value?.toUpperCase();
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

field.value, if is not null/undefined, always be string. (as expected runtime behavior). just keep it as is

Comment on lines 125 to 130
const testCategoryInfo = function (t, block) {
t.equal(block.json.category, 'fake test extension');
// t.equal(block.json.category, 'fake test extension');
t.equal(block.json.colour, '#111111');
t.equal(block.json.colourSecondary, '#222222');
t.equal(block.json.colourTertiary, '#333333');
// t.equal(block.json.colourSecondary, '#222222');
// t.equal(block.json.colourTertiary, '#333333');
t.equal(block.json.inputsInline, true);
Comment on lines 120 to 128
export interface ExtensionBlockMetadata {
/** A unique alphanumeric identifier for this block. No special characters allowed. */
opcode: string;
/** The name of the function implementing this block. Can be shared by other blocks/opcodes. */
func?: string;
func?: BlockFunction;
/** The type of block (command, reporter, etc.) being described. */
blockType: BlockType;
blockType: Exclude<BlockType, BlockType.BUTTON>;
/** The text on the block, with [PLACEHOLDERS] for arguments. */
text: string;
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
@SimonShiki SimonShiki changed the title 🚚 chore: migrate vm to typescript, part2 🚚 chore: migrate vm to typescript part 2 May 16, 2026
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Signed-off-by: SimonShiki <sinangentoo@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working feature New feature or request vm Things related to clipcc-vm.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants