Skip to content
sb-util, a library that can query Scratch projects via *.sb3 and project.json files
TypeScript JavaScript
Branch: master
Clone or download
dependabot and gnarf Bump eslint-utils from 1.4.0 to 1.4.2 (#40)
Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.4.0 to 1.4.2.
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](mysticatea/eslint-utils@v1.4.0...v1.4.2)

Signed-off-by: dependabot[bot] <support@github.com>
Latest commit 993d651 Sep 16, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci bump node docker img Aug 7, 2019
examples/datavis
src Reorganize classes to all be in their own JS files (#39) Sep 16, 2019
tests Reorganize classes to all be in their own JS files (#39) Sep 16, 2019
.eslintignore
.eslintrc.json find parent block (#29) Aug 9, 2019
.gitignore Scratch project init (#2) Jul 16, 2019
.prettierignore Reorganize classes to all be in their own JS files (#39) Sep 16, 2019
.prettierrc.json Implement TS Linting and Formatting (#13) Aug 1, 2019
README.md Add count and index to collections (#38) Aug 21, 2019
jest.config.js Reorganize classes to all be in their own JS files (#39) Sep 16, 2019
package-lock.json Bump eslint-utils from 1.4.0 to 1.4.2 (#40) Sep 16, 2019
package.json Reorganize classes to all be in their own JS files (#39) Sep 16, 2019
tsconfig.json Reorganize classes to all be in their own JS files (#39) Sep 16, 2019

README.md

sb-util

Table of Contents


sb-util Proposal (RFC)

We, at Bocoup, propose sb-util, a JavaScript and CLI utility that allows developers to query a Scratch Project for collections of sprites, blocks, assets, and project metadata.

sb-util will accomplish this by consuming .sb3 files generated by Scratch. .sb3 files are used to save and load projects, and within an .sb3 file there is a project.json, which is the JSON representation of the entities within a Scratch project. sb-util will provide an API that allows developers to query the project.json for project information.

The resulting tool should be usable in test suites, scripts, and applications.

Javascript API Proposal

API methods that have been implmented are marked with implemented.

Loading a Scratch Project - implemented

sb-util exposes loading functions to asynchronously instantiate a ScratchProject object. These loading functions handle file I/O and HTTP request handling, decoupling that process from the ScratchProject object itself.


loadSb3(sb3File)

Parameter(s): sb3File. String representing local file location of an _.sb3 file or a URI to an _.sb3 file
Return: Promise. This Promise object will resolve to a ScratchProject

const sp = await loadSb3('foo.sb3');

loadProjectJson(projectJsonFile)

Parameter(s): projectJsonFile. String representing local file location of an project.json file or a URI to an project.json file
Return: Promise. This Promise object will resolve to a ScratchProject

const sp = await loadProjectJson('project.json');

loadCloudId(cloudId)

Parameter(s): cloudId. Number representing a Cloud ID in Scratch
Return: Promise. This Promise object will resolve to a ScratchProject

const sp = await loadCloudId(123456);

ScratchProject

ScratchProject(projectJSON) - implemented
A ScratchProject gets initialized by an object, represented by the project.json. The assetFetcher is an optional constructor argument that represents an object is responsible for retrieving asset buffers for an Asset object.

const { ScratchProject } - require('sb-util');

// Use the above loading methods or directly instantiate:
const sp = new ScratchProject(projectJson);

Methods

assets()
Return: AssetCollection representing all the assets of a project

let assets = sp.assets()

blocks() -- implemented
Return: BlockCollection representing all the blocks in the project. This BlockCollection can be further filtered to get specific blocks

let blocks = sp.blocks();

sprites(...args) - implemented
Return: SpriteCollection representing all sprites in the project. A selector syntax can be passed to this function to get sprites that meet the syntax criteria

let sprites = sp.sprites();

let stage = sp.sprites('[isStage=true]').pop();
let sprite1 = sp.sprites('[name="Cat"]').pop();

stage() - implemented
Return: Sprite a stage

let stage = sp.stage();

variables() Return: a list of Variable objects in the project

let vars = sp.variables();

Collections

There are multiple "Collection" classes that all share some collection methods, the shared methods are listed here.

@__iterator() - implemented Collection objects are meant to be iterated using the for ... of [Symbol.iterator] protocol. Items iterated in this way will be emited using the "Wrapper Class" for the collection (e.g. Block for BlockCollection)

props() - implemented Return: the Iterable of the raw "properties" objects for the items in the collection.

count() - implemented Return: Counts the items in the collection, similar to .length on an array but these collections aren't arrays.

first() - implemented Return: the first item in the collection wrapped, null if no items in collection.

index(n) - implemented Return: Similar to using array[n] on an array, this will get the wrapped item at the specified index in the collection, or null if out-of-bounds.

SpriteCollection

A SpriteCollection represents an iterable collection of objects that represent Sprites.

Methods

query(selector) - implemented
Parameter(s): selector string in the CSS selector syntax style. Return: SpriteCollection

let stage = sp.sprites('[isStage=true]');
let sprite1 = sp.sprites('[name="Cat"]');

Possible selector syntax, in attribute selector style:

Sprite Attribute Selector Syntax
isStage [isStage={true or false}]
layerOrder [layerOrder={a number}]
draggable [draggable={true or false}]
rotationStyle [rotationStyle={"all around" or "left-right" or "don't rotate"}]

Sprite

A Sprite is a singleton of SpriteCollection, with additional methods that are specific to a single Sprite. A Sprite can be a stage or an individual sprite.

Methods

prop(attribute) - implemented
Parameter: attribute string. Return: any value for a given attribute

const currentCostume = sprite.prop('currentCostume');

Attributes available to pass: name, isStage, variables, lists, broadcasts, blocks, comments, currentCostume, costumes, sounds, volume, layerOrder, temp, videoTransparency, videoState, textToSpeechLanguage, visible, x, y, size, direction, draggable, rotationStyle

blocks() - implemented
Return: BlockCollection

const sprite = sp.sprites('[name="Cat"]');
const blocks = sprite.blocks();

assets()
Return: AssetCollection

const assets = sprite.assets();

position() - implemented
Return: the (X, Y) cooredinates of a Sprite in Object notation

const { x, y } = sprite.position();

broadcasts() - implemented
Return: a list of Objects representing a broadcast, which contains an id and a message

const broadcasts = sprite.broadcasts();

// A mapping example
Object.entries(broadcasts).map(([key, value]) => ({ messageId: key, message: value }));

lists() - implemented
Return: a list of Objects representing a list, which contains an id, name, and an Array of values

const lists = sprite.lists();

Object.entries(lists).map(([key, value]) => console.log({key, listName: value[0], values: value[1]}));

BlockCollection

A BlockCollection represents and iterable collection of objects that represent Blocks.

Methods

query(selector) - partially implemented
Parameter(s): selector, a string with the convention similar to CSS selector syntax
Return: BlockCollection

This is a mapping of Block object attributes to selector syntax:

Block Attribute CSS-like Selector Syntax Status
opcode (Full set of opcodes) Type selector. blocks.query('event_whenflagclicked') or blocks.query('control_if_else') implemented
block type (Full set of block types) Class selector. blocks.query('.motion') or blocks.query('.sensing') implemented
block shape (Full set of block shapes) Pseudo class selector. blocks.query(':hat') or blocks.query(':reporter') not implemented

The selector syntax can be combined for more fine-grained filtering.

Get all motion reporter blocks

const motionReporterBlocks = blocks.query('.motion :reporter');

Block

A Block is a singleton of BlockCollection. It has additional methods, specific to the data held by an individual block.

Methods

prop(attribute) - implemented
Parameter: attribute string. Return: any value for a given attribute

Attributes available to pass: opcode, next, parent, inputs, fields, shadow, topLevel

args(selector)
This method is similar to query. args returns the inputs or fields (depending on the query string) of a block using one of the strings defined below. Certain query strings can return an input or a field.

A sample of selector values for the args method is defined in this table:

Inputs Fields Both Input and Field
X, Y, DURATION, MESSAGE, SECS CONDITION, SUBSTACK, OPERAND, TIMES, CHANGE, FROM, VALUE, BROADCAST_INPUT, BACKDROP, VOLUME, NUM1, NUM2 EFFECT, BROADCAST_OPTION, VARIABLE, STOP_OPTION COSTUME, TOUCHINGOBJECTMENU, TO, SOUND_MENU
const condition = block.args('CONDITION');
const variable = block.args('VARIABLE');
const operand = block.args('OPERAND');

substacks()
Returns the substacks for the block as an list of Objects representing a substack. If a block is not capable of having a substack, the list will be empty.


AssetCollection

An AssetCollection represents an interable collection of objects that represent Assets, which are static files included in an *.sb3 file or somwhere the user designates, used for costumes and sounds.

Methods

query(selector)
Parameter(s): A string in the CSS selector style Return: AssetCollection

Possible selector syntax:

Asset Attribute Selector Syntax
name Attribute selector. assets.query('name="83a9787d4cb6f3b7632b4ddfebf74367.wav")
dataFormat Type Selector. assets.query('wav')

Asset

An Asset is a singleton of AssetCollection.

Methods

toBuffer() Return: Promise to the file buffer of this Asset


Variable Collection

A Variable collection represents a collection of local and global variables belonging to a sprite.

Variable


CLI Proposal

Coming soon


Development

sb-util is implemented in TypeScript and will be available as a JavaScript library on npm and as a CLI tool.

Install Dependencies

npm install

Build

npm run build

Run Tests

npm test

Linting Code

This project uses https://prettier.io to format code and https://eslint.org/ for linting (catching errors). To format and lint, run

npm run lint
You can’t perform that action at this time.