hikkaku 0.3.3 → 0.3.5
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 +2 -1
- package/{composer-bPcsVhIg.mjs → block-helper-DaOyXkRZ.mjs} +164 -90
- package/blocks/index.d.mts +163 -150
- package/blocks/index.mjs +144 -135
- package/{project-CpV5Dm-X.d.mts → index-kUDvI5sE.d.mts} +59 -16
- package/index.d.mts +2 -2
- package/index.mjs +17 -6
- package/package.json +5 -2
- package/types.d.mts +7 -0
- package/vite/index.mjs +22 -17
|
@@ -1,9 +1,27 @@
|
|
|
1
|
+
import { InputType } from "sb3-types/enum";
|
|
1
2
|
import * as sb3 from "sb3-types";
|
|
2
3
|
import { Costume, Sound } from "sb3-types";
|
|
3
4
|
|
|
4
5
|
//#region src/core/types.d.ts
|
|
5
6
|
type PrimitiveAvailableOnScratch = number | boolean | string;
|
|
6
|
-
type
|
|
7
|
+
type HikkakuTypeTag = 'number' | 'bool' | 'string';
|
|
8
|
+
type HikkakuBrand<T extends HikkakuTypeTag> = {
|
|
9
|
+
readonly __hikkakuType: T;
|
|
10
|
+
};
|
|
11
|
+
type HikkakuNumber = HikkakuBrand<'number'>;
|
|
12
|
+
type HikkakuBool = HikkakuBrand<'bool'>;
|
|
13
|
+
type HikkakuString = HikkakuBrand<'string'>;
|
|
14
|
+
type HikkakuType = HikkakuNumber | HikkakuBool | HikkakuString;
|
|
15
|
+
type PrimitiveToHikkakuType<T extends PrimitiveAvailableOnScratch> = T extends number ? HikkakuNumber : T extends boolean ? HikkakuBool : T extends string ? HikkakuString : never;
|
|
16
|
+
type HikkakuTypeToPrimitive<T extends HikkakuType> = T extends HikkakuNumber ? number : T extends HikkakuBool ? boolean : T extends HikkakuString ? string : never;
|
|
17
|
+
interface HikkakuBlock {
|
|
18
|
+
isBlock: true;
|
|
19
|
+
id: string;
|
|
20
|
+
}
|
|
21
|
+
interface HikkakuReporterBlock<T extends HikkakuType = HikkakuType> extends HikkakuBlock {
|
|
22
|
+
readonly __hikkakuType: T['__hikkakuType'];
|
|
23
|
+
}
|
|
24
|
+
type PrimitiveSource<T extends HikkakuType> = HikkakuTypeToPrimitive<T> | HikkakuReporterBlock;
|
|
7
25
|
interface VariableBase {
|
|
8
26
|
id: string;
|
|
9
27
|
name: string;
|
|
@@ -36,8 +54,8 @@ interface VariableReference extends VariableBase {
|
|
|
36
54
|
type: 'variable';
|
|
37
55
|
}
|
|
38
56
|
interface VariableDefinition extends VariableReference {
|
|
39
|
-
get():
|
|
40
|
-
set(value: PrimitiveSource<
|
|
57
|
+
get(): HikkakuReporterBlock<HikkakuNumber | HikkakuString>;
|
|
58
|
+
set(value: PrimitiveSource<HikkakuNumber | HikkakuString>): HikkakuBlock;
|
|
41
59
|
}
|
|
42
60
|
interface ListReference extends VariableBase {
|
|
43
61
|
type: 'list';
|
|
@@ -46,16 +64,12 @@ interface CostumeReference {
|
|
|
46
64
|
name: string;
|
|
47
65
|
type: 'costume';
|
|
48
66
|
}
|
|
49
|
-
type CostumeSource = PrimitiveSource<
|
|
67
|
+
type CostumeSource = PrimitiveSource<HikkakuString> | CostumeReference;
|
|
50
68
|
interface SoundReference {
|
|
51
69
|
name: string;
|
|
52
70
|
type: 'sound';
|
|
53
71
|
}
|
|
54
|
-
type SoundSource = PrimitiveSource<
|
|
55
|
-
interface HikkakuBlock {
|
|
56
|
-
isBlock: true;
|
|
57
|
-
id: string;
|
|
58
|
-
}
|
|
72
|
+
type SoundSource = PrimitiveSource<HikkakuString> | SoundReference;
|
|
59
73
|
type CostumeData = Costume & {
|
|
60
74
|
_data?: Uint8Array;
|
|
61
75
|
};
|
|
@@ -64,17 +78,45 @@ type SoundData = Sound & {
|
|
|
64
78
|
};
|
|
65
79
|
//#endregion
|
|
66
80
|
//#region src/core/block-helper.d.ts
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
declare
|
|
70
|
-
declare
|
|
81
|
+
type MappingToPrimitive<T extends PrimitiveInputType> = T extends InputType.Number ? number : T extends InputType.PositiveNumber ? number : T extends InputType.Integer ? number : T extends InputType.Angle ? number : T extends InputType.PositiveInteger ? number : T extends InputType.String ? string | number : T extends InputType.Broadcast ? string : T extends InputType.Color ? string : never;
|
|
82
|
+
type PrimitiveInputType = sb3.InputPrimitive['0'];
|
|
83
|
+
declare function fromPrimitiveSource<T extends PrimitiveInputType>(inputType: T, source: PrimitiveSource<PrimitiveToHikkakuType<MappingToPrimitive<T>>>, defaultValue?: MappingToPrimitive<T>): sb3.Input;
|
|
84
|
+
declare function fromBooleanSource(source: PrimitiveSource<HikkakuBool>): sb3.Input;
|
|
85
|
+
declare const unwrapCostumeSource: (source: CostumeSource) => PrimitiveSource<HikkakuString>;
|
|
86
|
+
declare const unwrapSoundSource: (source: SoundSource) => PrimitiveSource<HikkakuString>;
|
|
71
87
|
declare const isHikkakuBlock: (block: unknown) => block is HikkakuBlock;
|
|
72
|
-
declare const menuInput: <T extends PrimitiveAvailableOnScratch>(source: PrimitiveSource<T
|
|
88
|
+
declare const menuInput: <T extends PrimitiveAvailableOnScratch>(source: PrimitiveSource<PrimitiveToHikkakuType<T>>, createMenu: (source?: T) => HikkakuReporterBlock<HikkakuString>) => sb3.Input;
|
|
73
89
|
declare const isCostumeReference: (source: unknown) => source is CostumeReference;
|
|
74
90
|
declare const isSoundReference: (source: unknown) => source is SoundReference;
|
|
75
91
|
//#endregion
|
|
76
92
|
//#region src/core/composer.d.ts
|
|
77
93
|
type Handler = () => void;
|
|
94
|
+
type BuildScopeKind = 'run' | 'stack';
|
|
95
|
+
interface BuildScopeFrame {
|
|
96
|
+
id: number;
|
|
97
|
+
kind: BuildScopeKind;
|
|
98
|
+
forbidStop: boolean;
|
|
99
|
+
onExit: Set<() => void>;
|
|
100
|
+
}
|
|
101
|
+
interface RootContext {
|
|
102
|
+
blocks: Record<string, sb3.Block>;
|
|
103
|
+
adder?: (id: string, block: sb3.Block) => void;
|
|
104
|
+
usedAsValueSet: WeakSet<sb3.Block>;
|
|
105
|
+
valueBlockSet: WeakSet<sb3.Block>;
|
|
106
|
+
blockToId: WeakMap<sb3.Block, string>;
|
|
107
|
+
scopeStack: BuildScopeFrame[];
|
|
108
|
+
nextScopeId: number;
|
|
109
|
+
}
|
|
110
|
+
declare const getRootContext: () => RootContext;
|
|
111
|
+
interface BuildScopeFrameSnapshot {
|
|
112
|
+
id: number;
|
|
113
|
+
kind: BuildScopeKind;
|
|
114
|
+
depth: number;
|
|
115
|
+
forbidStop: boolean;
|
|
116
|
+
}
|
|
117
|
+
declare const __unstable_getBuildScopeFrame: () => BuildScopeFrameSnapshot | null;
|
|
118
|
+
declare const __unstable_onBuildScopeExit: (callback: () => void) => void;
|
|
119
|
+
declare const __unstable_forbidStopInCurrentScope: () => void;
|
|
78
120
|
interface BlockInit {
|
|
79
121
|
inputs?: Record<string, sb3.Input>;
|
|
80
122
|
fields?: Record<string, sb3.Fields>;
|
|
@@ -84,7 +126,7 @@ interface BlockInit {
|
|
|
84
126
|
isValue?: boolean;
|
|
85
127
|
}
|
|
86
128
|
declare const block: (opcode: string, init: BlockInit) => HikkakuBlock;
|
|
87
|
-
declare const valueBlock: (opcode: string, init: BlockInit) =>
|
|
129
|
+
declare const valueBlock: <T extends HikkakuType>(opcode: string, init: BlockInit) => HikkakuReporterBlock<T>;
|
|
88
130
|
declare const substack: (handler: Handler) => string | null;
|
|
89
131
|
declare const attachStack: (parentId: string, handler?: Handler) => string | null;
|
|
90
132
|
declare const createBlocks: (handler: Handler) => Record<string, sb3.Block>;
|
|
@@ -131,6 +173,7 @@ interface SpriteOptions {
|
|
|
131
173
|
x?: number;
|
|
132
174
|
y?: number;
|
|
133
175
|
}
|
|
176
|
+
declare const __unstable_getBuildTarget: () => Target | null;
|
|
134
177
|
declare class Target<IsStage extends boolean = boolean> {
|
|
135
178
|
#private;
|
|
136
179
|
readonly isStage: IsStage;
|
|
@@ -157,4 +200,4 @@ declare class Project {
|
|
|
157
200
|
getAdditionalAssets(): Map<string, Uint8Array>;
|
|
158
201
|
}
|
|
159
202
|
//#endregion
|
|
160
|
-
export {
|
|
203
|
+
export { CreateVariableOptions as A, MonitorPosition as B, menuInput as C, CostumeReference as D, CostumeData as E, HikkakuString as F, SoundReference as G, PrimitiveSource as H, HikkakuType as I, VariableDefinition as J, SoundSource as K, HikkakuTypeToPrimitive as L, HikkakuBool as M, HikkakuNumber as N, CostumeSource as O, HikkakuReporterBlock as P, ListMonitorOptions as R, isSoundReference as S, unwrapSoundSource as T, PrimitiveToHikkakuType as U, PrimitiveAvailableOnScratch as V, SoundData as W, VariableMonitorOptions as X, VariableMonitorMode as Y, VariableReference as Z, valueBlock as _, BlockInit as a, isCostumeReference as b, Handler as c, __unstable_onBuildScopeExit as d, attachStack as f, substack as g, getRootContext as h, __unstable_getBuildTarget as i, HikkakuBlock as j, CreateListOptions as k, __unstable_forbidStopInCurrentScope as l, createBlocks as m, SpriteOptions as n, BuildScopeFrameSnapshot as o, block as p, VariableBase as q, Target as r, BuildScopeKind as s, Project as t, __unstable_getBuildScopeFrame as u, fromBooleanSource as v, unwrapCostumeSource as w, isHikkakuBlock as x, fromPrimitiveSource as y, ListReference as z };
|
package/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { BlockInit, CostumeData, CostumeReference, CostumeSource, CreateListOptions, CreateVariableOptions, Handler, HikkakuBlock, ListMonitorOptions, ListReference, MonitorPosition, PrimitiveAvailableOnScratch, PrimitiveSource, Project, SoundData, SoundReference, SoundSource, SpriteOptions, Target, VariableBase, VariableDefinition, VariableMonitorMode, VariableMonitorOptions, VariableReference, attachStack, block, createBlocks, fromPrimitiveSource,
|
|
1
|
+
import { A as CreateVariableOptions, B as MonitorPosition, C as menuInput, D as CostumeReference, E as CostumeData, F as HikkakuString, G as SoundReference, H as PrimitiveSource, I as HikkakuType, J as VariableDefinition, K as SoundSource, L as HikkakuTypeToPrimitive, M as HikkakuBool, N as HikkakuNumber, O as CostumeSource, P as HikkakuReporterBlock, R as ListMonitorOptions, S as isSoundReference, T as unwrapSoundSource, U as PrimitiveToHikkakuType, V as PrimitiveAvailableOnScratch, W as SoundData, X as VariableMonitorOptions, Y as VariableMonitorMode, Z as VariableReference, _ as valueBlock, a as BlockInit, b as isCostumeReference, c as Handler, d as __unstable_onBuildScopeExit, f as attachStack, g as substack, h as getRootContext, i as __unstable_getBuildTarget, j as HikkakuBlock, k as CreateListOptions, l as __unstable_forbidStopInCurrentScope, m as createBlocks, n as SpriteOptions, o as BuildScopeFrameSnapshot, p as block, q as VariableBase, r as Target, s as BuildScopeKind, t as Project, u as __unstable_getBuildScopeFrame, v as fromBooleanSource, w as unwrapCostumeSource, x as isHikkakuBlock, y as fromPrimitiveSource, z as ListReference } from "./index-kUDvI5sE.mjs";
|
|
2
|
+
export { BlockInit, BuildScopeFrameSnapshot, BuildScopeKind, CostumeData, CostumeReference, CostumeSource, CreateListOptions, CreateVariableOptions, Handler, HikkakuBlock, HikkakuBool, HikkakuNumber, HikkakuReporterBlock, HikkakuString, HikkakuType, HikkakuTypeToPrimitive, ListMonitorOptions, ListReference, MonitorPosition, PrimitiveAvailableOnScratch, PrimitiveSource, PrimitiveToHikkakuType, Project, SoundData, SoundReference, SoundSource, SpriteOptions, Target, VariableBase, VariableDefinition, VariableMonitorMode, VariableMonitorOptions, VariableReference, __unstable_forbidStopInCurrentScope, __unstable_getBuildScopeFrame, __unstable_getBuildTarget, __unstable_onBuildScopeExit, attachStack, block, createBlocks, fromBooleanSource, fromPrimitiveSource, getRootContext, isCostumeReference, isHikkakuBlock, isSoundReference, menuInput, substack, unwrapCostumeSource, unwrapSoundSource, valueBlock };
|
package/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as valueBlock, a as isSoundReference, c as unwrapSoundSource, d as __unstable_onBuildScopeExit, f as attachStack, g as substack, h as getRootContext, i as isHikkakuBlock, l as __unstable_forbidStopInCurrentScope, m as createBlocks, n as fromPrimitiveSource, o as menuInput, p as block, r as isCostumeReference, s as unwrapCostumeSource, t as fromBooleanSource, u as __unstable_getBuildScopeFrame } from "./block-helper-DaOyXkRZ.mjs";
|
|
2
|
+
import { InputType } from "sb3-types/enum";
|
|
2
3
|
|
|
3
4
|
//#region src/core/monitors.ts
|
|
4
5
|
const createVariableMonitor = (id, name, defaultValue, spriteName, options) => {
|
|
@@ -76,6 +77,10 @@ const collectExtensions = (targets) => {
|
|
|
76
77
|
}
|
|
77
78
|
return Array.from(extensions).sort();
|
|
78
79
|
};
|
|
80
|
+
const buildTargetStack = [];
|
|
81
|
+
const __unstable_getBuildTarget = () => {
|
|
82
|
+
return buildTargetStack[buildTargetStack.length - 1] ?? null;
|
|
83
|
+
};
|
|
79
84
|
var Target = class {
|
|
80
85
|
isStage;
|
|
81
86
|
name;
|
|
@@ -97,9 +102,15 @@ var Target = class {
|
|
|
97
102
|
this.#y = options?.y;
|
|
98
103
|
}
|
|
99
104
|
run(handler) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
buildTargetStack.push(this);
|
|
106
|
+
let blocks = {};
|
|
107
|
+
try {
|
|
108
|
+
blocks = createBlocks(() => {
|
|
109
|
+
handler(this);
|
|
110
|
+
});
|
|
111
|
+
} finally {
|
|
112
|
+
buildTargetStack.pop();
|
|
113
|
+
}
|
|
103
114
|
this.#blocks = {
|
|
104
115
|
...this.#blocks,
|
|
105
116
|
...blocks
|
|
@@ -120,7 +131,7 @@ var Target = class {
|
|
|
120
131
|
type: "variable",
|
|
121
132
|
get: () => valueBlock("data_variable", { fields: { VARIABLE: [name, id] } }),
|
|
122
133
|
set: (value) => block("data_setvariableto", {
|
|
123
|
-
inputs: { VALUE: fromPrimitiveSource(value) },
|
|
134
|
+
inputs: { VALUE: fromPrimitiveSource(InputType.String, value) },
|
|
124
135
|
fields: { VARIABLE: [name, id] }
|
|
125
136
|
})
|
|
126
137
|
};
|
|
@@ -229,4 +240,4 @@ var Project = class {
|
|
|
229
240
|
};
|
|
230
241
|
|
|
231
242
|
//#endregion
|
|
232
|
-
export { Project, Target, attachStack, block, createBlocks, fromPrimitiveSource,
|
|
243
|
+
export { Project, Target, __unstable_forbidStopInCurrentScope, __unstable_getBuildScopeFrame, __unstable_getBuildTarget, __unstable_onBuildScopeExit, attachStack, block, createBlocks, fromBooleanSource, fromPrimitiveSource, getRootContext, isCostumeReference, isHikkakuBlock, isSoundReference, menuInput, substack, unwrapCostumeSource, unwrapSoundSource, valueBlock };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hikkaku",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"exports": {
|
|
@@ -31,14 +31,17 @@
|
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "bun --bun tsdown",
|
|
34
|
+
"test": "vp test run",
|
|
34
35
|
"typecheck": "tsgo"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@turbowarp/packager": "^3.11.0",
|
|
38
39
|
"@types/bun": "latest",
|
|
39
40
|
"@typescript/native-preview": "^7.0.0-dev.20260127.1",
|
|
41
|
+
"@vitest/coverage-v8": "4.0.18",
|
|
40
42
|
"rolldown": "1.0.0-rc.4",
|
|
41
|
-
"tsdown": "^0.20.0-beta.4"
|
|
43
|
+
"tsdown": "^0.20.0-beta.4",
|
|
44
|
+
"vite-plus": "^0.0.0-3262bda4.20260210-0221"
|
|
42
45
|
},
|
|
43
46
|
"peerDependencies": {
|
|
44
47
|
"typescript": "^5"
|
package/types.d.mts
CHANGED
|
@@ -18,4 +18,11 @@ declare module '*.mp3?scratch' {
|
|
|
18
18
|
import * as sb3 from 'sb3-types';
|
|
19
19
|
const content: sb3.Sound;
|
|
20
20
|
export default content;
|
|
21
|
+
}
|
|
22
|
+
declare module 'vite-plus' {
|
|
23
|
+
export function defineConfig<T>(config: T): T;
|
|
24
|
+
}
|
|
25
|
+
declare module 'vite-plus/test' {
|
|
26
|
+
export { describe, expect, it, test } from 'bun:test';
|
|
27
|
+
export type { TestInterface } from 'bun:test';
|
|
21
28
|
}
|
package/vite/index.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { mkdir,
|
|
1
|
+
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { zip, zipSync } from "fflate/node";
|
|
5
5
|
import { createServerModuleRunner } from "vite";
|
|
6
|
-
import crypto from "node:crypto";
|
|
7
6
|
|
|
8
7
|
//#region src/vite/plugin-scratch-import.ts
|
|
9
8
|
const pluginScratchImport = () => ({
|
|
@@ -22,22 +21,28 @@ const pluginScratchImport = () => ({
|
|
|
22
21
|
const url = new URL(id.slice(9, -8));
|
|
23
22
|
const ext = url.pathname.split(".").pop();
|
|
24
23
|
if (!ext) throw new Error(`Unsupported scratch asset type: ${url.pathname}`);
|
|
25
|
-
const file = await readFile(fileURLToPath(url));
|
|
26
|
-
const hash = crypto.createHash("md5");
|
|
27
|
-
hash.update(file);
|
|
28
|
-
const md5 = hash.digest("hex");
|
|
29
|
-
const data = {
|
|
30
|
-
name: path.basename(url.pathname),
|
|
31
|
-
_data: Buffer.from(file).toString("base64"),
|
|
32
|
-
assetId: md5,
|
|
33
|
-
dataFormat: ext,
|
|
34
|
-
md5ext: `${md5}.${ext}`
|
|
35
|
-
};
|
|
36
24
|
return `
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
import crypto from 'node:crypto';
|
|
26
|
+
import { readFile } from 'node:fs/promises';
|
|
27
|
+
import * as path from 'node:path';
|
|
28
|
+
import { fileURLToPath } from 'node:url';
|
|
29
|
+
|
|
30
|
+
const pathUrl = new URL(${JSON.stringify(url.href)});
|
|
31
|
+
const ext = ${JSON.stringify(ext)};
|
|
32
|
+
const file = await readFile(fileURLToPath(pathUrl));
|
|
40
33
|
|
|
34
|
+
const hash = crypto.createHash('md5');
|
|
35
|
+
hash.update(file);
|
|
36
|
+
const md5 = hash.digest('hex');
|
|
37
|
+
|
|
38
|
+
const data = {
|
|
39
|
+
name: path.basename(pathUrl.pathname),
|
|
40
|
+
_data: Uint8Array.from(file),
|
|
41
|
+
assetId: md5,
|
|
42
|
+
dataFormat: ext,
|
|
43
|
+
md5ext: md5 + "." + ext,
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
export default data
|
|
42
47
|
`;
|
|
43
48
|
}
|