@turbowarp/types 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  Scratch doesn't provide type definitions for their libraries, so we wrote our own.
4
4
 
5
- This project is still at an early stage.
6
-
7
- Despite being in the TurboWarp organization, this project is currently focused only on the vanilla (LLK) Scratch runtime and editor. Additional types for TurboWarp may be added later.
5
+ This repository only contains types for the vanilla (LLK) Scratch runtime and editor. For the additional types in the TurboWarp runtimes, see [@turbowarp/types-tw](https://github.com/TurboWarp/types-tw).
8
6
 
9
7
  |Module|Status|
10
8
  |:-:|:-:|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@turbowarp/types",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Type definitions for the Scratch VM and editor",
5
5
  "keywords": [
6
6
  "scratch"
@@ -0,0 +1,16 @@
1
+ declare const stream: JSZip.StreamHelper<'uint8array'>;
2
+
3
+ stream.on('data', data => {
4
+ data as Uint8Array
5
+ });
6
+ stream.on('data', (data, metadata) => {
7
+ metadata.percent as number
8
+ });
9
+
10
+ stream.pause();
11
+ stream.resume();
12
+
13
+ // @ts-expect-error
14
+ stream.on('whatever', () => {
15
+
16
+ });
@@ -15,3 +15,11 @@ audioEngine.decodeSoundPlayer({
15
15
  });
16
16
  return player.finished();
17
17
  });
18
+
19
+ declare const pitchEffect: AudioEngine.PitchEffect;
20
+ pitchEffect.ratio as number
21
+ pitchEffect.updatePlayers([]);
22
+
23
+ declare const soundPlayer: AudioEngine.SoundPlayer;
24
+
25
+ new audioEngine.effects[0](audioEngine, soundPlayer, pitchEffect);
@@ -0,0 +1,105 @@
1
+ (function(Scratch) {
2
+ 'use strict';
3
+
4
+ class Fetch {
5
+ /** @returns {Scratch.Info} */
6
+ getInfo () {
7
+ return {
8
+ id: 'fetch',
9
+ name: 'Fetch',
10
+ blocks: [
11
+ {
12
+ opcode: 'get',
13
+ blockType: Scratch.BlockType.REPORTER,
14
+ text: 'GET [URL]',
15
+ arguments: {
16
+ URL: {
17
+ type: Scratch.ArgumentType.STRING,
18
+ defaultValue: 'https://extensions.turbowarp.org/hello.txt'
19
+ }
20
+ }
21
+ },
22
+ {
23
+ opcode: 'test',
24
+ text: 'test [STRING] [IMAGE] [BOOLEAN] [NUMBER] [MATRIX] [NOTE] [ANGLE] [COLOR]',
25
+ blockType: Scratch.BlockType.COMMAND,
26
+ hideFromPalette: false,
27
+ isTerminal: true,
28
+ arguments: {
29
+ STRING: {
30
+ type: Scratch.ArgumentType.STRING,
31
+ defaultValue: 'test',
32
+ menu: 'test1'
33
+ },
34
+ IMAGE: {
35
+ type: Scratch.ArgumentType.IMAGE,
36
+ dataURI: 'https://extensions.turbowarp.org/dango.png'
37
+ },
38
+ BOOLEAN: {
39
+ type: Scratch.ArgumentType.BOOLEAN
40
+ },
41
+ NUMBER: {
42
+ type: Scratch.ArgumentType.NUMBER,
43
+ defaultValue: 5,
44
+ },
45
+ MATRIX: {
46
+ type: Scratch.ArgumentType.MATRIX,
47
+ defaultValue: '0101001010000001000101110'
48
+ },
49
+ NOTE: {
50
+ type: Scratch.ArgumentType.NOTE,
51
+ defaultValue: '30'
52
+ },
53
+ ANGLE: {
54
+ type: Scratch.ArgumentType.ANGLE,
55
+ defaultValue: 30
56
+ },
57
+ COLOR: {
58
+ type: Scratch.ArgumentType.COLOR,
59
+ defaultValue: '#123456'
60
+ }
61
+ }
62
+ },
63
+ {
64
+ opcode: 'button',
65
+ blockType: Scratch.BlockType.BUTTON,
66
+ func: 'MAKE_A_VARIABLE',
67
+ text: 'button text'
68
+ }
69
+ ],
70
+ menus: {
71
+ test1: ['1', '2', '3'],
72
+ test2: {
73
+ acceptReporters: false,
74
+ items: [
75
+ { text: 'text', value: 'value' },
76
+ 'another value'
77
+ ]
78
+ }
79
+ }
80
+ };
81
+ }
82
+
83
+ /**
84
+ * @param {{URL: string;}} args
85
+ */
86
+ get (args) {
87
+ return fetch(args.URL)
88
+ .then(r => r.text())
89
+ .catch(() => '');
90
+ }
91
+
92
+ /**
93
+ * @param {unknown} args
94
+ */
95
+ test (args) {
96
+ console.log(args);
97
+ }
98
+ }
99
+
100
+ if (Scratch.extensions.unsandboxed) {
101
+ // ...
102
+ }
103
+
104
+ Scratch.extensions.register(new Fetch());
105
+ })(Scratch);
@@ -53,3 +53,15 @@ if (target) {
53
53
  const audioEngine = new AudioEngine();
54
54
  vm.attachAudioEngine(audioEngine);
55
55
  audioEngine.audioContext.suspend();
56
+
57
+ vm.setTurboMode(true);
58
+ vm.runtime.turboMode as boolean
59
+ vm.setCompatibilityMode(true);
60
+ vm.runtime.compatibilityMode as boolean
61
+
62
+ const costume = vm.runtime.getTargetForStage()?.getCostumes()?.[0];
63
+ costume?.skinId as number;
64
+
65
+ declare const util: VM.BlockUtility;
66
+ util.startHats('hats', {BROADCAST_OPTION: 'test'}) as VM.Thread[];
67
+ util.ioQuery('mouse', 'getIsDown', []);
@@ -0,0 +1,29 @@
1
+ (function () {
2
+ const ext = {};
3
+
4
+ ext._getStatus = () => ({
5
+ status: 2,
6
+ msg: 'Ready'
7
+ });
8
+
9
+ ext.testReporter = () => Math.random();
10
+
11
+ /**
12
+ * @param {number} delay
13
+ * @param {function} callback
14
+ */
15
+ ext.testReporterWait = (delay, callback) => {
16
+ setTimeout(() => {
17
+ callback(Math.random())
18
+ }, delay * 1000);
19
+ };
20
+
21
+ var descriptor = {
22
+ blocks: [
23
+ ['r', 'test reporter', 'testReporter'],
24
+ ['R', 'test reporter 2 %n', 'testReporterWait', '1'],
25
+ ],
26
+ };
27
+
28
+ ScratchExtensions.register('ScratchX Test', descriptor, ext);
29
+ }());
package/types/jszip.d.ts CHANGED
@@ -3,6 +3,30 @@
3
3
 
4
4
  declare namespace JSZip {
5
5
  // TODO
6
+
7
+ interface OutputTypes {
8
+ base64: string;
9
+ binarystring: string;
10
+ array: number[];
11
+ uint8array: Uint8Array;
12
+ arraybuffer: ArrayBuffer;
13
+ blob: Blob;
14
+ nodebuffer: Uint8Array; // actually a Node.js Buffer
15
+ }
16
+
17
+ interface ProgressMetadata {
18
+ percent: number;
19
+ currentFile: string;
20
+ }
21
+
22
+ interface StreamHelper<T extends keyof OutputTypes> {
23
+ resume(): void;
24
+ pause(): void;
25
+ on(event: 'data', callback: (data: OutputTypes[T], metadata: ProgressMetadata) => void): void;
26
+ on(event: 'end', callback: () => void): void;
27
+ on(event: 'error', callback: (error: Error) => void): void;
28
+ accumulate(updateCallback?: (metadata: ProgressMetadata) => void): Promise<OutputTypes[T]>;
29
+ }
6
30
  }
7
31
 
8
32
  declare class JSZip {
@@ -19,10 +19,10 @@ declare namespace AudioEngine {
19
19
  getLoudness(): number;
20
20
  }
21
21
 
22
- interface Effect {
22
+ interface AbstractEffect {
23
23
  audioEngine: AudioEngine;
24
24
  audioPlayer: SoundPlayer;
25
- lastEffect: Effect;
25
+ lastEffect: AbstractEffect;
26
26
  value: number;
27
27
  initialized: boolean;
28
28
  initialize(): void;
@@ -41,11 +41,36 @@ declare namespace AudioEngine {
41
41
  dispose(): void;
42
42
  }
43
43
 
44
+ interface PitchEffect extends AbstractEffect {
45
+ get name(): 'pitch';
46
+ ratio: number;
47
+ getRatio(val: number): number;
48
+ updatePlayer(soundPlayer: SoundPlayer): void;
49
+ updatePlayers(soundPlayers: Record<string, SoundPlayer> | SoundPlayer[]): void;
50
+ }
51
+
52
+ interface PanEffect extends AbstractEffect {
53
+ get name(): 'pan';
54
+ leftGain: GainNode;
55
+ rightGain: GainNode;
56
+ channelMerger: ChannelMergerNode;
57
+ }
58
+
59
+ interface VolumeEffect extends AbstractEffect {
60
+ get name(): 'volume';
61
+ }
62
+
63
+ type Effect = PitchEffect | PanEffect | VolumeEffect;
64
+
65
+ interface EffectConstructor {
66
+ new(audioEngine: AudioEngine, soundPlayer: SoundPlayer, lastEffect: Effect | null): Effect;
67
+ }
68
+
44
69
  interface EffectChain {
45
70
  audioEngine: AudioEngine;
46
71
  inputNode: GainNode;
47
72
  getInputNode(): GainNode;
48
- effects: Effect[];
73
+ effects: EffectConstructor[];
49
74
  _effects: Effect[];
50
75
  firstEffect: Effect;
51
76
  lastEffect: Effect;
@@ -86,14 +111,32 @@ declare namespace AudioEngine {
86
111
  stopImmediately(): void;
87
112
  finished(): Promise<void>;
88
113
  setPlaybackRate(playbackRate: number): void;
114
+ take(): SoundPlayer;
89
115
  }
90
116
 
91
117
  interface SoundBank {
92
118
  audioEngine: AudioEngine;
119
+
120
+ /**
121
+ * Maps sound ID to its sound player.
122
+ */
93
123
  soundPlayers: Record<string, SoundPlayer>;
94
- playerTargets: Record<string, Target>;
95
- soundEffects: Record<string, EffectChain>;
124
+
125
+ /**
126
+ * Maps sound IDs to the target they were most recently been started by.
127
+ */
128
+ playerTargets: Map<string, Target>;
129
+
130
+ /**
131
+ * Maps sound IDs to their effect chain.
132
+ */
133
+ soundEffects: Map<string, EffectChain>;
134
+
135
+ /**
136
+ * Original effect chain cloned for each sound.
137
+ */
96
138
  effectChainPrime: EffectChain;
139
+
97
140
  addSoundPlayer(soundPlayer: SoundPlayer): void;
98
141
  getSoundPlayer(soundId: string): SoundPlayer | undefined;
99
142
  getSoundEffects(soundId: string): EffectChain;
@@ -128,7 +171,8 @@ declare class AudioEngine {
128
171
  */
129
172
  getLoudness(): number;
130
173
 
131
- effects: AudioEngine.Effect[];
174
+ effects: AudioEngine.EffectConstructor[];
175
+
132
176
  get EFFECT_NAMES(): Record<string, string>;
133
177
  get DECAY_DURATION(): number;
134
178
  get DECAY_WAIT(): number;
@@ -0,0 +1,251 @@
1
+ declare namespace Scratch {
2
+ // Note that the 'B' in the BOOLEAN enums are capitalized in Scratch. It is not a typo in this file.
3
+
4
+ namespace ArgumentType {
5
+ const ANGLE: 'angle';
6
+ const BOOLEAN: 'Boolean';
7
+ const COLOR: 'color';
8
+ const IMAGE: 'image';
9
+ const MATRIX: 'matrix';
10
+ const NOTE: 'note';
11
+ const NUMBER: 'number';
12
+ const STRING: 'string';
13
+ }
14
+
15
+ namespace BlockType {
16
+ const BOOLEAN: 'Boolean';
17
+ /** @deprecated very incomplete and not useful yet */
18
+ const BUTTON: 'button';
19
+ const COMMAND: 'command';
20
+ /** @deprecated does not work in compiler */
21
+ const CONDITIONAL: 'conditional';
22
+ /** @deprecated use HAT instead */
23
+ const EVENT: 'event';
24
+ const HAT: 'hat';
25
+ /** @deprecated does not work in compiler */
26
+ const LOOP: 'loop';
27
+ const REPORTER: 'reporter';
28
+ }
29
+
30
+ namespace TargetType {
31
+ const SPRITE: 'sprite';
32
+ const STAGE: 'stage';
33
+ }
34
+
35
+ interface AngleArgument {
36
+ type: 'angle';
37
+ /**
38
+ * Defaults to 0.
39
+ */
40
+ defaultValue?: string | number;
41
+ }
42
+ interface BooleanArgument {
43
+ type: 'Boolean';
44
+ }
45
+ interface ColorArgument {
46
+ type: 'color';
47
+ /**
48
+ * Should be a hex color code. No alpha channel supported. Defaults to random color.
49
+ */
50
+ defaultValue?: string | number;
51
+ }
52
+ interface NumberArgument {
53
+ type: 'number';
54
+ /**
55
+ * Defaults to 0.
56
+ */
57
+ defaultValue?: string | number;
58
+ menu?: string;
59
+ }
60
+ interface StringArgument {
61
+ type: 'string';
62
+ /**
63
+ * Defaults to empty string.
64
+ */
65
+ defaultValue?: string | number;
66
+ menu?: string;
67
+ }
68
+ interface MatrixArgument {
69
+ type: 'matrix';
70
+ /**
71
+ * Should be a 25 character long string of 1s and 0s.
72
+ * Numbers are technically accepted, but be aware that due to floating point precision, some detail may be lost.
73
+ * Technically optional, but behaves strangely with no default value.
74
+ */
75
+ defaultValue?: string | number;
76
+ }
77
+ interface NoteArgument {
78
+ type: 'note';
79
+ /**
80
+ * Defaults to 0 ("C (0)")
81
+ */
82
+ defaultValue?: string | number;
83
+ }
84
+ interface ImageArgument {
85
+ type: 'image';
86
+ dataURI: string;
87
+ /**
88
+ * Defaults to false.
89
+ */
90
+ flipRTL?: boolean;
91
+ }
92
+ type Argument = (
93
+ AngleArgument |
94
+ BooleanArgument |
95
+ ColorArgument |
96
+ NumberArgument |
97
+ StringArgument |
98
+ MatrixArgument |
99
+ NoteArgument |
100
+ ImageArgument
101
+ );
102
+
103
+ interface AbstractBlock {
104
+ opcode: string;
105
+ func?: string;
106
+ text: string | string[];
107
+ arguments?: Record<string, Argument>;
108
+ hideFromPalette?: boolean;
109
+ filter?: Array<'target' | 'sprite'>;
110
+ blockIconURI?: string;
111
+ }
112
+ interface BooleanBlock extends AbstractBlock {
113
+ blockType: 'Boolean';
114
+ }
115
+ interface ButtonBlock extends AbstractBlock {
116
+ blockType: 'button';
117
+ func: 'MAKE_A_LIST' | 'MAKE_A_PROCEDURE' | 'MAKE_A_VARIABLE';
118
+ }
119
+ interface CommandBlock extends AbstractBlock {
120
+ blockType: 'command';
121
+ /**
122
+ * Defaults to false.
123
+ */
124
+ isTerminal?: boolean;
125
+ }
126
+ interface ConditionalBlock extends AbstractBlock {
127
+ blockType: 'conditional';
128
+ /**
129
+ * Defaults to false.
130
+ */
131
+ isTerminal?: boolean;
132
+ /**
133
+ * Defaults to 1.
134
+ */
135
+ branchCount?: number;
136
+ }
137
+ interface EventBlock extends AbstractBlock {
138
+ blockType: 'event';
139
+ /**
140
+ * This must be explicitly set to false, otherwise the block will not work.
141
+ * Event blocks cannot be edge activated. Use hat instead.
142
+ */
143
+ isEdgeActivated: false;
144
+ /**
145
+ * Defaults to false.
146
+ */
147
+ shouldRestartExistingThreads?: boolean;
148
+ }
149
+ interface HatBlock extends AbstractBlock {
150
+ blockType: 'hat';
151
+ /**
152
+ * Defaults to true.
153
+ */
154
+ isEdgeActivated?: boolean;
155
+ /**
156
+ * Defaults to false.
157
+ */
158
+ shouldRestartExistingThreads?: boolean;
159
+ }
160
+ interface ReporterBlock extends AbstractBlock {
161
+ blockType: 'reporter';
162
+ /**
163
+ * Defaults to false.
164
+ */
165
+ disableMonitor?: boolean;
166
+ }
167
+ interface LoopBlock extends AbstractBlock {
168
+ blockType: 'loop';
169
+ /**
170
+ * Defaults to false.
171
+ */
172
+ isTerminal?: boolean;
173
+ /**
174
+ * Defaults to 1.
175
+ */
176
+ branchCount?: number;
177
+ }
178
+ type Block = (
179
+ BooleanBlock |
180
+ ButtonBlock |
181
+ CommandBlock |
182
+ ConditionalBlock |
183
+ EventBlock |
184
+ HatBlock |
185
+ ReporterBlock |
186
+ LoopBlock
187
+ );
188
+
189
+ interface Menu {
190
+ acceptReporters?: boolean;
191
+ /**
192
+ * A list of static items in the menu, or the name of the dynamic menu function.
193
+ */
194
+ items: Array<string | {
195
+ text: string;
196
+ value: string;
197
+ }> | string;
198
+ }
199
+
200
+ interface Info {
201
+ id: string;
202
+
203
+ /**
204
+ * Defaults to extension ID if not specified.
205
+ */
206
+ name?: string;
207
+
208
+ /**
209
+ * Should be a hex color code.
210
+ */
211
+ color1?: string;
212
+
213
+ /**
214
+ * Should be a hex color code.
215
+ */
216
+ color2?: string;
217
+
218
+ /**
219
+ * Should be a hex color code.
220
+ */
221
+ color3?: string;
222
+
223
+ /**
224
+ * Should be a data: URI
225
+ */
226
+ menuIconURI?: string;
227
+
228
+ /**
229
+ * Should be a data: URI
230
+ */
231
+ blockIconURI?: string;
232
+
233
+ docsURI?: string;
234
+
235
+ blocks: (Block | string)[];
236
+ menus?: Record<string, Menu | string[]>;
237
+ }
238
+
239
+ interface Extension {
240
+ getInfo(): Info;
241
+ }
242
+
243
+ namespace extensions {
244
+ function register(extensionObject: Extension): void;
245
+
246
+ /**
247
+ * True if the extension is running unsandboxed, otherwise undefined.
248
+ */
249
+ const unsandboxed: undefined | boolean;
250
+ }
251
+ }
@@ -60,6 +60,7 @@ declare namespace VM {
60
60
  rotationCenterX: number;
61
61
  rotationCenterY: number;
62
62
  size: [number, number];
63
+ skinId: number;
63
64
  }
64
65
 
65
66
  interface Sound extends BaseAsset {
@@ -613,7 +614,72 @@ declare namespace VM {
613
614
  }
614
615
 
615
616
  interface StackFrame {
616
- // TODO
617
+ isLoop: boolean;
618
+ warpMode: boolean;
619
+ justReported: unknown;
620
+ reporting: string;
621
+ reported: unknown;
622
+ /** @deprecated unused */
623
+ waitingReporter: unknown;
624
+ params: unknown;
625
+ executionContext: unknown;
626
+ reset(): void;
627
+ }
628
+
629
+ interface BlockUtility {
630
+ sequencer: Sequencer;
631
+ thread: Thread;
632
+ _nowObj: {
633
+ now(): number;
634
+ };
635
+ nowObj: BlockUtility['_nowObj'],
636
+ target: Target;
637
+ runtime: Runtime;
638
+ stackFrame: StackFrame;
639
+ stackTimerFinished(): boolean;
640
+ stackTimerNeedsInit(): boolean;
641
+ startStackTimer(milliseconds: number): void;
642
+ yield(): void;
643
+ yieldTick(): void;
644
+ startBranch(branchNumber: number, isLoop: boolean): void;
645
+ /**
646
+ * @see {Runtime.stopAll}
647
+ */
648
+ stopAll(): void;
649
+ /**
650
+ * @see {Runtime.stopForTarget}
651
+ */
652
+ stopOtherTargetThreads(): void;
653
+ /**
654
+ * @see {Thread.stopThisScript}
655
+ */
656
+ stopThisScript(): void;
657
+ /**
658
+ * @see {Blocks.getProcedureParamNamesAndIds}
659
+ */
660
+ getProcedureParamNamesAndIds(): [string[], string[]];
661
+ /**
662
+ * @see {Blocks.getProcedureParamNamesIdsAndDefaults}
663
+ */
664
+ getProcedureParamNamesIdsAndDefaults(): [string[], string[], string[]];
665
+ /**
666
+ * @see {Thread.initParams}
667
+ */
668
+ initParams(): void;
669
+ /**
670
+ * @see {Thread.pushParam}
671
+ */
672
+ pushParam(name: string, value: ScratchCompatibleValue): void;
673
+ /**
674
+ * @see {Thread.getParam}
675
+ */
676
+ getParam(name: string): ScratchCompatibleValue;
677
+ /**
678
+ * Use instead of runtime.startHats inside blocks.
679
+ * @see {Runtime.startHats}
680
+ */
681
+ startHats: Runtime['startHats'];
682
+ ioQuery<Device extends keyof IODevices>(device: Device, func: keyof IODevices[Device], args: unknown[]): unknown;
617
683
  }
618
684
 
619
685
  const enum ThreadStatus {
@@ -636,16 +702,19 @@ declare namespace VM {
636
702
  blockGlowInFrame: string | null;
637
703
  warpTimer: Timer | null;
638
704
  justReported: unknown;
705
+ reuseStackForNextBlock(blockId: string): void;
639
706
  pushStack(blockId: string): void;
640
707
  popStack(): string;
641
708
  peekStack(): string;
642
709
  peekStackFrame(): StackFrame | null;
643
710
  peekParentStackFrame(): StackFrame | null;
711
+ pushReportedValue(value: ScratchCompatibleValue): void;
644
712
  initParams(): void;
645
713
  pushParam(name: string, value: ScratchCompatibleValue): void;
646
714
  getParam(name: string): ScratchCompatibleValue | null;
647
715
  atStackTop(): boolean;
648
716
  goToNextBlock(): void;
717
+ stopThisScript(): void;
649
718
  isRecursiveCall(procedureCode: string): boolean;
650
719
  stackClick: boolean;
651
720
  updateMonitor: boolean;
@@ -817,6 +886,8 @@ declare namespace VM {
817
886
  _isDown: boolean;
818
887
  getIsDown(): boolean;
819
888
  postData(data: MouseData): void;
889
+ _activateClickHats(target: Target): void;
890
+ _pickTarget(x: number, y: number): Target;
820
891
  }
821
892
 
822
893
  interface MouseWheelData {
@@ -1014,6 +1085,13 @@ declare namespace VM {
1014
1085
  */
1015
1086
  _step(): void;
1016
1087
 
1088
+ turboMode: boolean;
1089
+
1090
+ /**
1091
+ * If true, the runtime is running at 60 FPS. If false, the runtime is running at 30 FPS.
1092
+ */
1093
+ compatibilityMode: boolean;
1094
+
1017
1095
  renderer: IfRenderer<RenderWebGL, undefined>;
1018
1096
 
1019
1097
  attachRenderer(renderer: RenderWebGL): void;
@@ -1107,7 +1185,7 @@ declare namespace VM {
1107
1185
 
1108
1186
  _getMonitorThreadCount(threads: Thread[]): number;
1109
1187
 
1110
- startHats(opcode: string, matchFields?: Record<string, unknown>, target?: Target): void;
1188
+ startHats(opcode: string, matchFields?: Record<string, unknown>, target?: Target): Thread[];
1111
1189
 
1112
1190
  toggleScript(topBlockId: string, options?: {
1113
1191
  target?: string;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @deprecated ScratchX is deprecated. Do not use in new extensions.
3
+ */
4
+ declare namespace ScratchExtensions {
5
+ /**
6
+ * @deprecated ScratchX is deprecated. Do not use in new extensions.
7
+ */
8
+ function register(name: string, descriptor: unknown, extension: unknown): void;
9
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes