lecodes-sdk 1.2.0 → 2.0.1
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 +5 -2
- package/dist/editor.d.ts +12 -0
- package/dist/global.d.ts +4 -8
- package/dist/host.d.ts +2 -3
- package/dist/types/animate/tween/Animation.d.ts +0 -3
- package/dist/types/animate/tween/animateValue.d.ts +4 -2
- package/dist/types/animate/tween/easing.d.ts +8 -0
- package/dist/types/animate/tween/spec.d.ts +15 -7
- package/dist/types/audio/audio.d.ts +2 -1
- package/dist/types/canvas/Canvas.d.ts +40 -108
- package/dist/types/canvas/gen/cssColor.d.ts +17 -0
- package/dist/types/canvas/gen/recorder.d.ts +118 -0
- package/dist/types/canvas/gen/spec.d.ts +144 -0
- package/dist/types/core/color.d.ts +3 -1
- package/dist/types/core/pins.d.ts +18 -0
- package/dist/types/g2/Node2D.d.ts +5 -8
- package/dist/types/g2/Scene2D.d.ts +6 -2
- package/dist/types/gl/Foliage.d.ts +30 -7
- package/dist/types/gl/Light.d.ts +8 -0
- package/dist/types/gl/Lightmap.d.ts +13 -2
- package/dist/types/gl/Material.d.ts +17 -3
- package/dist/types/gl/Model.d.ts +6 -2
- package/dist/types/gl/Node.d.ts +3 -6
- package/dist/types/gl/Scene.d.ts +41 -13
- package/dist/types/gl/Texture.d.ts +1 -1
- package/dist/types/gl/animation/Locomotion.d.ts +8 -1
- package/dist/types/inject.d.ts +11 -11
- package/dist/types/inject.editor.d.ts +1 -0
- package/dist/types/net/core.d.ts +7 -0
- package/dist/types/plugin.d.ts +76 -0
- package/dist/types/plugins/gen/camera/sdk/camera.d.ts +24 -0
- package/dist/types/plugins/gen/camera/sdk/camera.gen.d.ts +25 -0
- package/dist/types/plugins/{geolocation.d.ts → gen/geolocation/sdk/geolocation.d.ts} +2 -20
- package/dist/types/plugins/gen/geolocation/sdk/geolocation.gen.d.ts +31 -0
- package/dist/types/plugins/{map.d.ts → gen/map/sdk/map.d.ts} +9 -50
- package/dist/types/plugins/gen/map/sdk/map.gen.d.ts +53 -0
- package/dist/types/plugins/gen/push/sdk/push.d.ts +23 -0
- package/dist/types/plugins/gen/push/sdk/push.gen.d.ts +35 -0
- package/dist/types/plugins/{qr.d.ts → gen/qr-scanner/sdk/qr-scanner.d.ts} +2 -3
- package/dist/types/plugins/gen/qr-scanner/sdk/qr-scanner.gen.d.ts +15 -0
- package/dist/types/runtime/app.d.ts +9 -2
- package/dist/types/runtime/fetch.d.ts +2 -0
- package/dist/types/runtime/input.d.ts +1 -1
- package/dist/types/runtime/media.d.ts +6 -10
- package/dist/types/runtime/misc.d.ts +4 -1
- package/dist/types/runtime/net.d.ts +3 -2
- package/dist/types/runtime/touch.d.ts +32 -0
- package/dist/types/scene/defineScene.d.ts +43 -2
- package/dist/types/scene/editor.d.ts +52 -0
- package/dist/types/scene/gizmos.d.ts +7 -4
- package/dist/types/ui/NativeView.d.ts +6 -4
- package/dist/types/ui/UI.d.ts +1 -1
- package/dist/types/ui/UIBottomSheet.d.ts +6 -12
- package/dist/types/ui/UIButton.d.ts +12 -14
- package/dist/types/ui/UIContainer.d.ts +0 -6
- package/dist/types/ui/UIImage.d.ts +1 -4
- package/dist/types/ui/UIInput.d.ts +8 -24
- package/dist/types/ui/UIModal.d.ts +0 -2
- package/dist/types/ui/UINode.d.ts +70 -56
- package/dist/types/ui/UIPager.d.ts +28 -27
- package/dist/types/ui/UIPopover.d.ts +0 -2
- package/dist/types/ui/UIScreen.d.ts +12 -17
- package/dist/types/ui/UIScrollable.d.ts +1 -4
- package/dist/types/ui/UIText.d.ts +0 -2
- package/dist/types/ui/UIVideo.d.ts +3 -5
- package/dist/types/ui/UIVirtualizedList.d.ts +14 -16
- package/dist/types/ui/UIWidget.d.ts +10 -9
- package/dist/types/ui/colorKeys.gen.d.ts +9 -0
- package/dist/types/ui/presentable.d.ts +46 -32
- package/dist/types/ui/router.d.ts +18 -7
- package/dist/types/ui/styleColor.d.ts +1 -0
- package/dist/types/ui/transitions.d.ts +18 -0
- package/dist/types/ui/tree.d.ts +75 -0
- package/dist/types/version.d.ts +10 -0
- package/dist/types.json +1 -1
- package/package.json +12 -3
- package/prompts/2d.md +2 -6
- package/prompts/3d.md +1 -5
- package/prompts/README.md +1 -1
- package/prompts/canvas.md +9 -8
- package/prompts/compose.ts +1 -1
- package/prompts/core.md +3 -3
- package/prompts/design.md +1 -1
- package/prompts/dist/2d-game.md +473 -239
- package/prompts/dist/3d-app.md +553 -205
- package/prompts/dist/ar-app.md +435 -202
- package/prompts/dist/design.md +113 -95
- package/prompts/dist/ui-app.md +386 -170
- package/prompts/ui-design.md +2 -3
- package/prompts/ui.md +45 -37
- package/src/animate/tween/Animation.ts +34 -150
- package/src/animate/tween/Timeline.ts +175 -175
- package/src/animate/tween/animateValue.ts +6 -3
- package/src/animate/tween/easing.ts +10 -3
- package/src/animate/tween/spec.ts +41 -15
- package/src/audio/Sound.ts +3 -3
- package/src/audio/audio.ts +2 -1
- package/src/bridges/2d.d.ts +317 -0
- package/src/bridges/app.d.ts +91 -0
- package/src/bridges/audio.d.ts +97 -0
- package/src/bridges/canvas.d.ts +79 -0
- package/src/bridges/device.d.ts +72 -0
- package/src/bridges/fetch.d.ts +80 -0
- package/src/bridges/files.d.ts +70 -0
- package/src/bridges/gl.d.ts +1133 -0
- package/src/bridges/input.d.ts +72 -0
- package/src/bridges/media.d.ts +55 -0
- package/src/bridges/nav.d.ts +71 -0
- package/src/bridges/net.d.ts +52 -0
- package/src/bridges/service.d.ts +52 -0
- package/src/bridges/socket.d.ts +31 -0
- package/src/bridges/storage.d.ts +33 -0
- package/src/bridges/tree.d.ts +301 -0
- package/src/bridges/types.d.ts +49 -0
- package/src/canvas/Canvas.ts +114 -159
- package/src/canvas/gen/cssColor.ts +224 -0
- package/src/canvas/gen/recorder.ts +212 -0
- package/src/canvas/gen/spec.ts +201 -0
- package/src/chisel.ts +193 -0
- package/src/compile/assetMacro.ts +1 -1
- package/src/compile/bundler.ts +11 -2
- package/src/compile/compileProject.ts +43 -4
- package/src/compile/fontMacro.ts +3 -4
- package/src/compile/header.ts +26 -5
- package/src/compile/index.ts +3 -1
- package/src/compile/liteMaterial.ts +1 -1
- package/src/compile/sceneEditor.ts +11 -26
- package/src/core/color.ts +73 -30
- package/src/core/pins.ts +51 -0
- package/src/core/signals.ts +8 -1
- package/src/g2/CharacterController2D.ts +3 -3
- package/src/g2/Node2D.ts +57 -39
- package/src/g2/Physics2D.ts +2 -2
- package/src/g2/Scene2D.ts +35 -23
- package/src/g2/Texture2D.ts +1 -1
- package/src/g2/loop.ts +4 -4
- package/src/gl/CameraPlace.ts +52 -52
- package/src/gl/Foliage.ts +72 -17
- package/src/gl/Geometry.ts +1 -2
- package/src/gl/Light.ts +10 -0
- package/src/gl/Lightmap.ts +45 -29
- package/src/gl/Material.ts +95 -51
- package/src/gl/Mesh.ts +120 -120
- package/src/gl/Model.ts +21 -16
- package/src/gl/Node.ts +91 -24
- package/src/gl/Particles.ts +1 -1
- package/src/gl/Scene.ts +100 -44
- package/src/gl/Texture.ts +8 -7
- package/src/gl/animation/AnimationClip.ts +1 -1
- package/src/gl/animation/DynamicBone.ts +482 -482
- package/src/gl/animation/Locomotion.ts +8 -3
- package/src/gl/nav/NavMesh.ts +3 -4
- package/src/gl/physics/Physics.ts +2 -2
- package/src/gl/physics/physicsEvents.ts +3 -3
- package/src/gl/scenarios.ts +291 -291
- package/src/gl/terrain/Terrain.ts +4 -5
- package/src/gl/touch.ts +14 -15
- package/src/host.d.ts +2 -3
- package/src/inject.editor.ts +7 -0
- package/src/inject.ts +13 -16
- package/src/net/core.ts +6 -5
- package/src/net/index.ts +1 -1
- package/src/net/replication.ts +1 -1
- package/src/plugin.ts +191 -0
- package/src/plugins/gen/camera/contract.d.ts +27 -0
- package/src/plugins/gen/camera/sdk/camera.gen.ts +46 -0
- package/src/plugins/gen/camera/sdk/camera.ts +57 -0
- package/src/plugins/gen/geolocation/contract.d.ts +50 -0
- package/src/plugins/gen/geolocation/sdk/geolocation.gen.ts +54 -0
- package/src/plugins/{geolocation.ts → gen/geolocation/sdk/geolocation.ts} +22 -43
- package/src/plugins/gen/map/contract.d.ts +144 -0
- package/src/plugins/gen/map/sdk/map.gen.ts +88 -0
- package/src/plugins/{map.ts → gen/map/sdk/map.ts} +68 -102
- package/src/plugins/gen/push/contract.d.ts +61 -0
- package/src/plugins/gen/push/sdk/push.gen.ts +60 -0
- package/src/plugins/gen/push/sdk/push.ts +105 -0
- package/src/plugins/gen/qr-scanner/contract.d.ts +16 -0
- package/src/plugins/gen/qr-scanner/sdk/qr-scanner.gen.ts +29 -0
- package/src/plugins/gen/qr-scanner/sdk/qr-scanner.ts +52 -0
- package/src/plugins/permission.ts +5 -4
- package/src/runtime/app.ts +20 -9
- package/src/runtime/appEvents.ts +5 -4
- package/src/runtime/channel.ts +18 -15
- package/src/runtime/clipboard.ts +4 -3
- package/src/runtime/datetime.ts +2 -1
- package/src/runtime/device.ts +17 -15
- package/src/runtime/fetch.ts +30 -20
- package/src/runtime/files.ts +16 -15
- package/src/runtime/input.ts +12 -10
- package/src/runtime/media.ts +50 -46
- package/src/runtime/misc.ts +7 -3
- package/src/runtime/net.ts +8 -7
- package/src/runtime/rpc.ts +1 -3
- package/src/runtime/service.ts +19 -14
- package/src/runtime/share.ts +4 -3
- package/src/runtime/storage.ts +6 -4
- package/src/runtime/touch.ts +32 -0
- package/src/scene/defineScene.ts +61 -365
- package/src/scene/editor.ts +408 -0
- package/src/scene/editorPlugins.ts +3 -3
- package/src/scene/gizmos.ts +15 -9
- package/src/server/db/marci/query.ts +1 -1
- package/src/server/host.ts +1 -1
- package/src/server/runtime.ts +1 -1
- package/src/ui/NativeView.ts +72 -25
- package/src/ui/UI.ts +3 -3
- package/src/ui/UIBottomSheet.ts +16 -17
- package/src/ui/UIButton.ts +54 -16
- package/src/ui/UIContainer.ts +0 -6
- package/src/ui/UIImage.ts +34 -30
- package/src/ui/UIInput.ts +29 -37
- package/src/ui/UIModal.ts +1 -3
- package/src/ui/UINode.ts +347 -297
- package/src/ui/UIPager.ts +93 -78
- package/src/ui/UIPopover.ts +0 -2
- package/src/ui/UIScreen.ts +41 -36
- package/src/ui/UIScrollable.ts +19 -13
- package/src/ui/UISpacer.ts +1 -1
- package/src/ui/UITabs.ts +8 -6
- package/src/ui/UIText.ts +7 -17
- package/src/ui/UIVideo.ts +30 -27
- package/src/ui/UIVirtualizedList.ts +58 -59
- package/src/ui/UIWidget.ts +38 -18
- package/src/ui/colorKeys.gen.ts +37 -0
- package/src/ui/fonts.ts +2 -2
- package/src/ui/presentable.ts +59 -42
- package/src/ui/router.ts +52 -35
- package/src/ui/styleColor.ts +56 -0
- package/src/ui/theme.ts +7 -6
- package/src/ui/transitions.ts +249 -0
- package/src/ui/tree.ts +346 -0
- package/src/version.ts +24 -0
- package/tests/helpers/engineWorld.ts +11 -0
- package/tests/helpers/fakeTree.ts +353 -0
- package/tests/helpers/hostStubs.ts +31 -0
- package/tests/helpers/index.ts +14 -0
- package/tests/helpers/memoryMarci.ts +124 -0
- package/tests/helpers/phases.ts +23 -0
- package/tests/helpers/preload.ts +18 -0
- package/tests/helpers/stubApp.ts +2 -0
- package/tests/helpers/stubDevice.ts +2 -0
- package/tests/helpers/stubFetch.ts +2 -0
- package/tests/helpers/stubInput.ts +2 -0
- package/dist/inject.js +0 -4629
- package/dist/types/core/registry.d.ts +0 -7
- package/dist/types/plugins/camera.d.ts +0 -25
- package/dist/types/plugins/push.d.ts +0 -46
- package/src/bridges.d.ts +0 -1769
- package/src/compile/__tests__/assetIconMacro.test.ts +0 -219
- package/src/compile/__tests__/assetMacro.test.ts +0 -100
- package/src/compile/__tests__/assetName.test.ts +0 -55
- package/src/compile/__tests__/compile.test.ts +0 -310
- package/src/compile/__tests__/detectEntry.test.ts +0 -151
- package/src/compile/__tests__/fontMacro.test.ts +0 -199
- package/src/compile/__tests__/serverSplit.test.ts +0 -27
- package/src/core/__tests__/stateMachine.test.ts +0 -132
- package/src/core/registry.ts +0 -23
- package/src/plugins/camera.ts +0 -81
- package/src/plugins/push.ts +0 -132
- package/src/plugins/qr.ts +0 -73
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-canvas.ts from engines/canvas/recorders/ts/src/recorder.ts @ ae6bc30b952b — do not edit here.
|
|
2
|
+
// Bump the submodule and run `bun run vendor:canvas`; `bun run check:canvas-ops` fails when this copy is stale.
|
|
3
|
+
// The TypeScript recorder: a Canvas2D-shaped API whose calls WRITE the opcode stream of spec/ops.h.
|
|
4
|
+
// Nothing is drawn here — the stream goes to the core interpreter (native, or wasm on the web), which
|
|
5
|
+
// turns it into a draw list a painter replays. An app-facing Canvas class wraps a Recorder and adds
|
|
6
|
+
// what needs a painter (measureText, surfaces, textures).
|
|
7
|
+
//
|
|
8
|
+
// Differences from the browser, on purpose:
|
|
9
|
+
// - colors and fonts are CSS strings resolved by the core (an invalid one keeps the previous style)
|
|
10
|
+
// - a Gradient is serialized when it is ASSIGNED to fillStyle / strokeStyle; stops added later
|
|
11
|
+
// do not affect an assignment already made
|
|
12
|
+
// - drawImage takes a surface id (an ImageRef with its device size for the short forms)
|
|
13
|
+
// - every drawing call returns `this`, so drawing chains
|
|
14
|
+
import { OP, LineJoin, LineCap, TextAlign, TextBaseline, FillRule, Gradient as GradientKind } from "./spec"
|
|
15
|
+
|
|
16
|
+
export type FillRuleName = "nonzero" | "evenodd"
|
|
17
|
+
export type LineJoinName = "miter" | "round" | "bevel"
|
|
18
|
+
export type LineCapName = "butt" | "round" | "square"
|
|
19
|
+
export type TextAlignName = "left" | "center" | "right" | "start" | "end"
|
|
20
|
+
export type TextBaselineName = "alphabetic" | "top" | "middle" | "bottom" | "hanging" | "ideographic"
|
|
21
|
+
|
|
22
|
+
const JOIN: Record<LineJoinName, number> = { miter: LineJoin.MITER, round: LineJoin.ROUND, bevel: LineJoin.BEVEL }
|
|
23
|
+
const CAP: Record<LineCapName, number> = { butt: LineCap.BUTT, round: LineCap.ROUND, square: LineCap.SQUARE }
|
|
24
|
+
const ALIGN: Record<TextAlignName, number> = { left: TextAlign.LEFT, center: TextAlign.CENTER, right: TextAlign.RIGHT, start: TextAlign.START, end: TextAlign.END }
|
|
25
|
+
const BASELINE: Record<TextBaselineName, number> = {
|
|
26
|
+
alphabetic: TextBaseline.ALPHABETIC, top: TextBaseline.TOP, middle: TextBaseline.MIDDLE,
|
|
27
|
+
bottom: TextBaseline.BOTTOM, hanging: TextBaseline.HANGING, ideographic: TextBaseline.IDEOGRAPHIC,
|
|
28
|
+
}
|
|
29
|
+
const RULE: Record<FillRuleName, number> = { nonzero: FillRule.NONZERO, evenodd: FillRule.EVENODD }
|
|
30
|
+
// The shadowed style fields save() / restore() snapshot, as the core's state stack does.
|
|
31
|
+
const SHADOWED = ["_globalAlpha", "_fillStyle", "_strokeStyle", "_lineWidth", "_lineJoin", "_lineCap", "_miterLimit",
|
|
32
|
+
"_lineDash", "_lineDashOffset", "_font", "_textAlign", "_textBaseline", "_letterSpacing"] as const
|
|
33
|
+
|
|
34
|
+
/** A gradient built by createLinearGradient / createRadialGradient; assign it to fillStyle / strokeStyle. */
|
|
35
|
+
export class Gradient {
|
|
36
|
+
readonly stops: { offset: number, color: string }[] = []
|
|
37
|
+
readonly kind: number
|
|
38
|
+
readonly coords: [number, number, number, number, number, number]
|
|
39
|
+
/** @internal */
|
|
40
|
+
constructor(kind: number, coords: [number, number, number, number, number, number]) { this.kind = kind; this.coords = coords }
|
|
41
|
+
addColorStop(offset: number, color: string): this {
|
|
42
|
+
if (!(offset >= 0 && offset <= 1)) throw new RangeError(`gradient stop offset ${offset} is outside 0..1`)
|
|
43
|
+
this.stops.push({ offset, color })
|
|
44
|
+
return this
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** The recorded stream: the f32 words and the string table the core reads. */
|
|
49
|
+
export interface Stream { cmd: Float32Array, refs: string[] }
|
|
50
|
+
|
|
51
|
+
/** A surface with its device size, for the short drawImage forms. */
|
|
52
|
+
export interface ImageRef { surface: number, width: number, height: number }
|
|
53
|
+
|
|
54
|
+
export class Recorder {
|
|
55
|
+
private cmd: number[] = []
|
|
56
|
+
private refs: string[] = []
|
|
57
|
+
private refIndex = new Map<string, number>()
|
|
58
|
+
|
|
59
|
+
// Shadowed state so the getters read back what was set (the stream itself is write-only).
|
|
60
|
+
private _globalAlpha = 1
|
|
61
|
+
private _fillStyle: string | Gradient = "#000000"
|
|
62
|
+
private _strokeStyle: string | Gradient = "#000000"
|
|
63
|
+
private _lineWidth = 1
|
|
64
|
+
private _lineJoin: LineJoinName = "miter"
|
|
65
|
+
private _lineCap: LineCapName = "butt"
|
|
66
|
+
private _miterLimit = 10
|
|
67
|
+
private _lineDash: number[] = []
|
|
68
|
+
private _lineDashOffset = 0
|
|
69
|
+
private _font = "10px sans-serif"
|
|
70
|
+
private _textAlign: TextAlignName = "start"
|
|
71
|
+
private _textBaseline: TextBaselineName = "alphabetic"
|
|
72
|
+
private _letterSpacing = 0
|
|
73
|
+
// One snapshot of the shadowed fields per open save(), so the getters read back what restore()
|
|
74
|
+
// brings back (by reference: setLineDash stores a fresh array, a Gradient is the assigned object).
|
|
75
|
+
private _saved: Record<string, unknown>[] = []
|
|
76
|
+
|
|
77
|
+
// ---- the stream -----------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
/** The words recorded so far (a copy) + the string table. */
|
|
80
|
+
stream(): Stream { return { cmd: new Float32Array(this.cmd), refs: this.refs.slice() } }
|
|
81
|
+
/** Plain arrays, for a JSON file (the golden tests' input). */
|
|
82
|
+
toJSON(): { cmd: number[], refs: string[] } { return { cmd: this.cmd.slice(), refs: this.refs.slice() } }
|
|
83
|
+
/** The number of words recorded. */
|
|
84
|
+
get length(): number { return this.cmd.length }
|
|
85
|
+
/** Discard the recording; the shadowed state is reset too (a fresh replay starts from defaults). */
|
|
86
|
+
reset(): this {
|
|
87
|
+
this.cmd.length = 0
|
|
88
|
+
this.refs.length = 0
|
|
89
|
+
this.refIndex.clear()
|
|
90
|
+
this._globalAlpha = 1; this._fillStyle = "#000000"; this._strokeStyle = "#000000"
|
|
91
|
+
this._lineWidth = 1; this._lineJoin = "miter"; this._lineCap = "butt"; this._miterLimit = 10
|
|
92
|
+
this._lineDash = []; this._lineDashOffset = 0
|
|
93
|
+
this._font = "10px sans-serif"; this._textAlign = "start"; this._textBaseline = "alphabetic"; this._letterSpacing = 0
|
|
94
|
+
this._saved.length = 0
|
|
95
|
+
return this
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private ref(s: string): number {
|
|
99
|
+
let i = this.refIndex.get(s)
|
|
100
|
+
if (i === undefined) { i = this.refs.length; this.refs.push(s); this.refIndex.set(s, i) }
|
|
101
|
+
return i
|
|
102
|
+
}
|
|
103
|
+
private push(...words: number[]): this { for (const w of words) this.cmd.push(w); return this }
|
|
104
|
+
|
|
105
|
+
// ---- state stack + transforms ---------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
save(): this {
|
|
108
|
+
const s: Record<string, unknown> = {}
|
|
109
|
+
for (const k of SHADOWED) s[k] = this[k]
|
|
110
|
+
this._saved.push(s)
|
|
111
|
+
return this.push(OP.SAVE)
|
|
112
|
+
}
|
|
113
|
+
restore(): this {
|
|
114
|
+
const s = this._saved.pop() // an unbalanced restore() keeps the state, like the core
|
|
115
|
+
if (s) Object.assign(this, s)
|
|
116
|
+
return this.push(OP.RESTORE)
|
|
117
|
+
}
|
|
118
|
+
translate(x: number, y: number): this { return this.push(OP.TRANSLATE, x, y) }
|
|
119
|
+
scale(sx: number, sy: number): this { return this.push(OP.SCALE, sx, sy) }
|
|
120
|
+
rotate(rad: number): this { return this.push(OP.ROTATE, rad) }
|
|
121
|
+
transform(a: number, b: number, c: number, d: number, e: number, f: number): this { return this.push(OP.TRANSFORM, a, b, c, d, e, f) }
|
|
122
|
+
setTransform(a: number, b: number, c: number, d: number, e: number, f: number): this { return this.push(OP.SET_TRANSFORM, a, b, c, d, e, f) }
|
|
123
|
+
resetTransform(): this { return this.push(OP.RESET_TRANSFORM) }
|
|
124
|
+
|
|
125
|
+
// ---- styles ---------------------------------------------------------------------------------
|
|
126
|
+
|
|
127
|
+
get globalAlpha(): number { return this._globalAlpha }
|
|
128
|
+
set globalAlpha(a: number) { this._globalAlpha = a; this.push(OP.GLOBAL_ALPHA, a) }
|
|
129
|
+
|
|
130
|
+
get fillStyle(): string | Gradient { return this._fillStyle }
|
|
131
|
+
set fillStyle(v: string | Gradient) { this._fillStyle = v; this.style(OP.FILL_STYLE, OP.FILL_GRADIENT, v) }
|
|
132
|
+
get strokeStyle(): string | Gradient { return this._strokeStyle }
|
|
133
|
+
set strokeStyle(v: string | Gradient) { this._strokeStyle = v; this.style(OP.STROKE_STYLE, OP.STROKE_GRADIENT, v) }
|
|
134
|
+
private style(colorOp: number, gradientOp: number, v: string | Gradient): void {
|
|
135
|
+
if (typeof v === "string") { this.push(colorOp, this.ref(v)); return }
|
|
136
|
+
this.push(gradientOp, v.kind, ...v.coords, v.stops.length)
|
|
137
|
+
for (const s of v.stops) this.push(s.offset, this.ref(s.color))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
createLinearGradient(x0: number, y0: number, x1: number, y1: number): Gradient {
|
|
141
|
+
return new Gradient(GradientKind.LINEAR, [x0, y0, x1, y1, 0, 0])
|
|
142
|
+
}
|
|
143
|
+
createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): Gradient {
|
|
144
|
+
return new Gradient(GradientKind.RADIAL, [x0, y0, x1, y1, r0, r1])
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
get lineWidth(): number { return this._lineWidth }
|
|
148
|
+
set lineWidth(w: number) { this._lineWidth = w; this.push(OP.LINE_WIDTH, w) }
|
|
149
|
+
get lineJoin(): LineJoinName { return this._lineJoin }
|
|
150
|
+
set lineJoin(j: LineJoinName) { this._lineJoin = j; this.push(OP.LINE_JOIN, JOIN[j]) }
|
|
151
|
+
get lineCap(): LineCapName { return this._lineCap }
|
|
152
|
+
set lineCap(c: LineCapName) { this._lineCap = c; this.push(OP.LINE_CAP, CAP[c]) }
|
|
153
|
+
get miterLimit(): number { return this._miterLimit }
|
|
154
|
+
set miterLimit(m: number) { this._miterLimit = m; this.push(OP.MITER_LIMIT, m) }
|
|
155
|
+
setLineDash(segments: number[]): this {
|
|
156
|
+
this._lineDash = segments.slice()
|
|
157
|
+
return this.push(OP.LINE_DASH, segments.length, ...segments)
|
|
158
|
+
}
|
|
159
|
+
getLineDash(): number[] { return this._lineDash.slice() }
|
|
160
|
+
get lineDashOffset(): number { return this._lineDashOffset }
|
|
161
|
+
set lineDashOffset(o: number) { this._lineDashOffset = o; this.push(OP.LINE_DASH_OFFSET, o) }
|
|
162
|
+
|
|
163
|
+
get font(): string { return this._font }
|
|
164
|
+
set font(f: string) { this._font = f; this.push(OP.FONT, this.ref(f)) }
|
|
165
|
+
get textAlign(): TextAlignName { return this._textAlign }
|
|
166
|
+
set textAlign(a: TextAlignName) { this._textAlign = a; this.push(OP.TEXT_ALIGN, ALIGN[a]) }
|
|
167
|
+
get textBaseline(): TextBaselineName { return this._textBaseline }
|
|
168
|
+
set textBaseline(b: TextBaselineName) { this._textBaseline = b; this.push(OP.TEXT_BASELINE, BASELINE[b]) }
|
|
169
|
+
get letterSpacing(): number { return this._letterSpacing }
|
|
170
|
+
set letterSpacing(px: number) { this._letterSpacing = px; this.push(OP.LETTER_SPACING, px) }
|
|
171
|
+
|
|
172
|
+
// ---- paths ----------------------------------------------------------------------------------
|
|
173
|
+
|
|
174
|
+
beginPath(): this { return this.push(OP.PATH_BEGIN) }
|
|
175
|
+
closePath(): this { return this.push(OP.PATH_CLOSE) }
|
|
176
|
+
moveTo(x: number, y: number): this { return this.push(OP.MOVE_TO, x, y) }
|
|
177
|
+
lineTo(x: number, y: number): this { return this.push(OP.LINE_TO, x, y) }
|
|
178
|
+
quadraticCurveTo(cx: number, cy: number, x: number, y: number): this { return this.push(OP.QUADRATIC_TO, cx, cy, x, y) }
|
|
179
|
+
bezierCurveTo(c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number): this {
|
|
180
|
+
return this.push(OP.BEZIER_TO, c1x, c1y, c2x, c2y, x, y)
|
|
181
|
+
}
|
|
182
|
+
arc(x: number, y: number, r: number, a0: number, a1: number, ccw = false): this { return this.push(OP.ARC, x, y, r, a0, a1, ccw ? 1 : 0) }
|
|
183
|
+
arcTo(x1: number, y1: number, x2: number, y2: number, r: number): this { return this.push(OP.ARC_TO, x1, y1, x2, y2, r) }
|
|
184
|
+
ellipse(x: number, y: number, rx: number, ry: number, rotation: number, a0: number, a1: number, ccw = false): this {
|
|
185
|
+
return this.push(OP.ELLIPSE, x, y, rx, ry, rotation, a0, a1, ccw ? 1 : 0)
|
|
186
|
+
}
|
|
187
|
+
rect(x: number, y: number, w: number, h: number): this { return this.push(OP.RECT, x, y, w, h) }
|
|
188
|
+
roundRect(x: number, y: number, w: number, h: number, r: number): this { return this.push(OP.ROUND_RECT, x, y, w, h, r) }
|
|
189
|
+
|
|
190
|
+
fill(rule: FillRuleName = "nonzero"): this { return this.push(OP.FILL, RULE[rule]) }
|
|
191
|
+
stroke(): this { return this.push(OP.STROKE) }
|
|
192
|
+
clip(rule: FillRuleName = "nonzero"): this { return this.push(OP.CLIP, RULE[rule]) }
|
|
193
|
+
|
|
194
|
+
// ---- rectangles, text, images ---------------------------------------------------------------
|
|
195
|
+
|
|
196
|
+
fillRect(x: number, y: number, w: number, h: number): this { return this.push(OP.FILL_RECT, x, y, w, h) }
|
|
197
|
+
strokeRect(x: number, y: number, w: number, h: number): this { return this.push(OP.STROKE_RECT, x, y, w, h) }
|
|
198
|
+
clearRect(x: number, y: number, w: number, h: number): this { return this.push(OP.CLEAR_RECT, x, y, w, h) }
|
|
199
|
+
fillText(text: string, x: number, y: number, maxWidth = 0): this { return this.push(OP.FILL_TEXT, this.ref(text), x, y, maxWidth) }
|
|
200
|
+
strokeText(text: string, x: number, y: number, maxWidth = 0): this { return this.push(OP.STROKE_TEXT, this.ref(text), x, y, maxWidth) }
|
|
201
|
+
|
|
202
|
+
/** Blit a surface. Three browser-style forms; the source rect is in the surface's device px. */
|
|
203
|
+
drawImage(img: ImageRef, dx: number, dy: number): this
|
|
204
|
+
drawImage(img: ImageRef, dx: number, dy: number, dw: number, dh: number): this
|
|
205
|
+
drawImage(img: ImageRef, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): this
|
|
206
|
+
drawImage(img: ImageRef, a: number, b: number, c?: number, d?: number, e?: number, f?: number, g?: number, h?: number): this {
|
|
207
|
+
if (e === undefined) {
|
|
208
|
+
return this.push(OP.DRAW_IMAGE, img.surface, 0, 0, img.width, img.height, a, b, c ?? img.width, d ?? img.height)
|
|
209
|
+
}
|
|
210
|
+
return this.push(OP.DRAW_IMAGE, img.surface, a, b, c!, d!, e, f!, g!, h!)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-canvas.ts from engines/canvas/spec/gen/spec.ts @ ae6bc30b952b — do not edit here.
|
|
2
|
+
// Bump the submodule and run `bun run vendor:canvas`; `bun run check:canvas-ops` fails when this copy is stale.
|
|
3
|
+
// GENERATED by spec/generate.ts from spec/*.h — do not edit.
|
|
4
|
+
|
|
5
|
+
export const SPEC_VERSION = 1
|
|
6
|
+
|
|
7
|
+
export const LineJoin = {
|
|
8
|
+
MITER: 0,
|
|
9
|
+
ROUND: 1,
|
|
10
|
+
BEVEL: 2,
|
|
11
|
+
} as const
|
|
12
|
+
export type LineJoin = (typeof LineJoin)[keyof typeof LineJoin]
|
|
13
|
+
export const LineJoinName: readonly string[] = ["miter", "round", "bevel"]
|
|
14
|
+
|
|
15
|
+
export const LineCap = {
|
|
16
|
+
BUTT: 0,
|
|
17
|
+
ROUND: 1,
|
|
18
|
+
SQUARE: 2,
|
|
19
|
+
} as const
|
|
20
|
+
export type LineCap = (typeof LineCap)[keyof typeof LineCap]
|
|
21
|
+
export const LineCapName: readonly string[] = ["butt", "round", "square"]
|
|
22
|
+
|
|
23
|
+
export const TextAlign = {
|
|
24
|
+
LEFT: 0,
|
|
25
|
+
CENTER: 1,
|
|
26
|
+
RIGHT: 2,
|
|
27
|
+
START: 3,
|
|
28
|
+
END: 4,
|
|
29
|
+
} as const
|
|
30
|
+
export type TextAlign = (typeof TextAlign)[keyof typeof TextAlign]
|
|
31
|
+
export const TextAlignName: readonly string[] = ["left", "center", "right", "start", "end"]
|
|
32
|
+
|
|
33
|
+
export const TextBaseline = {
|
|
34
|
+
ALPHABETIC: 0,
|
|
35
|
+
TOP: 1,
|
|
36
|
+
MIDDLE: 2,
|
|
37
|
+
BOTTOM: 3,
|
|
38
|
+
HANGING: 4,
|
|
39
|
+
IDEOGRAPHIC: 5,
|
|
40
|
+
} as const
|
|
41
|
+
export type TextBaseline = (typeof TextBaseline)[keyof typeof TextBaseline]
|
|
42
|
+
export const TextBaselineName: readonly string[] = ["alphabetic", "top", "middle", "bottom", "hanging", "ideographic"]
|
|
43
|
+
|
|
44
|
+
export const FillRule = {
|
|
45
|
+
NONZERO: 0,
|
|
46
|
+
EVENODD: 1,
|
|
47
|
+
} as const
|
|
48
|
+
export type FillRule = (typeof FillRule)[keyof typeof FillRule]
|
|
49
|
+
export const FillRuleName: readonly string[] = ["nonzero", "evenodd"]
|
|
50
|
+
|
|
51
|
+
export const Spread = {
|
|
52
|
+
PAD: 0,
|
|
53
|
+
REFLECT: 1,
|
|
54
|
+
REPEAT: 2,
|
|
55
|
+
} as const
|
|
56
|
+
export type Spread = (typeof Spread)[keyof typeof Spread]
|
|
57
|
+
export const SpreadName: readonly string[] = ["pad", "reflect", "repeat"]
|
|
58
|
+
|
|
59
|
+
export const Gradient = {
|
|
60
|
+
LINEAR: 0,
|
|
61
|
+
RADIAL: 1,
|
|
62
|
+
} as const
|
|
63
|
+
export type Gradient = (typeof Gradient)[keyof typeof Gradient]
|
|
64
|
+
export const GradientName: readonly string[] = ["linear", "radial"]
|
|
65
|
+
|
|
66
|
+
export const Paint = {
|
|
67
|
+
COLOR: 0,
|
|
68
|
+
LINEAR: 1,
|
|
69
|
+
RADIAL: 2,
|
|
70
|
+
} as const
|
|
71
|
+
export type Paint = (typeof Paint)[keyof typeof Paint]
|
|
72
|
+
export const PaintName: readonly string[] = ["color", "linear", "radial"]
|
|
73
|
+
|
|
74
|
+
export const PathVerb = {
|
|
75
|
+
MOVE: 0,
|
|
76
|
+
LINE: 1,
|
|
77
|
+
QUAD: 2,
|
|
78
|
+
CUBIC: 3,
|
|
79
|
+
CLOSE: 4,
|
|
80
|
+
} as const
|
|
81
|
+
export type PathVerb = (typeof PathVerb)[keyof typeof PathVerb]
|
|
82
|
+
export const PathVerbName: readonly string[] = ["move", "line", "quad", "cubic", "close"]
|
|
83
|
+
|
|
84
|
+
export const ImageFormat = {
|
|
85
|
+
PNG: 0,
|
|
86
|
+
JPEG: 1,
|
|
87
|
+
} as const
|
|
88
|
+
export type ImageFormat = (typeof ImageFormat)[keyof typeof ImageFormat]
|
|
89
|
+
export const ImageFormatName: readonly string[] = ["png", "jpeg"]
|
|
90
|
+
|
|
91
|
+
/** The opcode stream: op id → the word after it. */
|
|
92
|
+
export const OP = {
|
|
93
|
+
SAVE: 0,
|
|
94
|
+
RESTORE: 1,
|
|
95
|
+
TRANSLATE: 2,
|
|
96
|
+
SCALE: 3,
|
|
97
|
+
ROTATE: 4,
|
|
98
|
+
TRANSFORM: 5,
|
|
99
|
+
SET_TRANSFORM: 6,
|
|
100
|
+
RESET_TRANSFORM: 7,
|
|
101
|
+
GLOBAL_ALPHA: 8,
|
|
102
|
+
FILL_STYLE: 9,
|
|
103
|
+
STROKE_STYLE: 10,
|
|
104
|
+
FILL_GRADIENT: 11,
|
|
105
|
+
STROKE_GRADIENT: 12,
|
|
106
|
+
LINE_WIDTH: 13,
|
|
107
|
+
LINE_JOIN: 14,
|
|
108
|
+
LINE_CAP: 15,
|
|
109
|
+
MITER_LIMIT: 16,
|
|
110
|
+
LINE_DASH: 17,
|
|
111
|
+
LINE_DASH_OFFSET: 18,
|
|
112
|
+
FONT: 19,
|
|
113
|
+
TEXT_ALIGN: 20,
|
|
114
|
+
TEXT_BASELINE: 21,
|
|
115
|
+
LETTER_SPACING: 22,
|
|
116
|
+
PATH_BEGIN: 23,
|
|
117
|
+
PATH_CLOSE: 24,
|
|
118
|
+
MOVE_TO: 25,
|
|
119
|
+
LINE_TO: 26,
|
|
120
|
+
QUADRATIC_TO: 27,
|
|
121
|
+
BEZIER_TO: 28,
|
|
122
|
+
ARC: 29,
|
|
123
|
+
ARC_TO: 30,
|
|
124
|
+
ELLIPSE: 31,
|
|
125
|
+
RECT: 32,
|
|
126
|
+
ROUND_RECT: 33,
|
|
127
|
+
FILL: 34,
|
|
128
|
+
STROKE: 35,
|
|
129
|
+
CLIP: 36,
|
|
130
|
+
FILL_RECT: 37,
|
|
131
|
+
STROKE_RECT: 38,
|
|
132
|
+
CLEAR_RECT: 39,
|
|
133
|
+
FILL_TEXT: 40,
|
|
134
|
+
STROKE_TEXT: 41,
|
|
135
|
+
DRAW_IMAGE: 42,
|
|
136
|
+
} as const
|
|
137
|
+
export type OP = (typeof OP)[keyof typeof OP]
|
|
138
|
+
/** Operand layout per op: `args` is one letter per fixed word (f float, i int, r string ref);
|
|
139
|
+
* `repeat` is the group that follows the trailing count. */
|
|
140
|
+
export const OP_ARGS: Record<number, { args: string, repeat: string }> = {
|
|
141
|
+
0: { args: "", repeat: "" },
|
|
142
|
+
1: { args: "", repeat: "" },
|
|
143
|
+
2: { args: "ff", repeat: "" },
|
|
144
|
+
3: { args: "ff", repeat: "" },
|
|
145
|
+
4: { args: "f", repeat: "" },
|
|
146
|
+
5: { args: "ffffff", repeat: "" },
|
|
147
|
+
6: { args: "ffffff", repeat: "" },
|
|
148
|
+
7: { args: "", repeat: "" },
|
|
149
|
+
8: { args: "f", repeat: "" },
|
|
150
|
+
9: { args: "r", repeat: "" },
|
|
151
|
+
10: { args: "r", repeat: "" },
|
|
152
|
+
11: { args: "iffffffi", repeat: "fr" },
|
|
153
|
+
12: { args: "iffffffi", repeat: "fr" },
|
|
154
|
+
13: { args: "f", repeat: "" },
|
|
155
|
+
14: { args: "i", repeat: "" },
|
|
156
|
+
15: { args: "i", repeat: "" },
|
|
157
|
+
16: { args: "f", repeat: "" },
|
|
158
|
+
17: { args: "i", repeat: "f" },
|
|
159
|
+
18: { args: "f", repeat: "" },
|
|
160
|
+
19: { args: "r", repeat: "" },
|
|
161
|
+
20: { args: "i", repeat: "" },
|
|
162
|
+
21: { args: "i", repeat: "" },
|
|
163
|
+
22: { args: "f", repeat: "" },
|
|
164
|
+
23: { args: "", repeat: "" },
|
|
165
|
+
24: { args: "", repeat: "" },
|
|
166
|
+
25: { args: "ff", repeat: "" },
|
|
167
|
+
26: { args: "ff", repeat: "" },
|
|
168
|
+
27: { args: "ffff", repeat: "" },
|
|
169
|
+
28: { args: "ffffff", repeat: "" },
|
|
170
|
+
29: { args: "fffffi", repeat: "" },
|
|
171
|
+
30: { args: "fffff", repeat: "" },
|
|
172
|
+
31: { args: "fffffffi", repeat: "" },
|
|
173
|
+
32: { args: "ffff", repeat: "" },
|
|
174
|
+
33: { args: "fffff", repeat: "" },
|
|
175
|
+
34: { args: "i", repeat: "" },
|
|
176
|
+
35: { args: "", repeat: "" },
|
|
177
|
+
36: { args: "i", repeat: "" },
|
|
178
|
+
37: { args: "ffff", repeat: "" },
|
|
179
|
+
38: { args: "ffff", repeat: "" },
|
|
180
|
+
39: { args: "ffff", repeat: "" },
|
|
181
|
+
40: { args: "rfff", repeat: "" },
|
|
182
|
+
41: { args: "rfff", repeat: "" },
|
|
183
|
+
42: { args: "iffffffff", repeat: "" },
|
|
184
|
+
}
|
|
185
|
+
export const OP_NAME: readonly string[] = ["save", "restore", "translate", "scale", "rotate", "transform", "setTransform", "resetTransform", "globalAlpha", "fillStyle", "strokeStyle", "fillGradient", "strokeGradient", "lineWidth", "lineJoin", "lineCap", "miterLimit", "lineDash", "lineDashOffset", "font", "textAlign", "textBaseline", "letterSpacing", "pathBegin", "pathClose", "moveTo", "lineTo", "quadraticTo", "bezierTo", "arc", "arcTo", "ellipse", "rect", "roundRect", "fill", "stroke", "clip", "fillRect", "strokeRect", "clearRect", "fillText", "strokeText", "drawImage"]
|
|
186
|
+
|
|
187
|
+
/** The draw list: command id → the word after it. */
|
|
188
|
+
export const DRAW = {
|
|
189
|
+
SET_TRANSFORM: 0,
|
|
190
|
+
SAVE: 1,
|
|
191
|
+
RESTORE: 2,
|
|
192
|
+
CLIP: 3,
|
|
193
|
+
FILL_PATH: 4,
|
|
194
|
+
STROKE_PATH: 5,
|
|
195
|
+
FILL_TEXT: 6,
|
|
196
|
+
STROKE_TEXT: 7,
|
|
197
|
+
DRAW_IMAGE: 8,
|
|
198
|
+
CLEAR_RECT: 9,
|
|
199
|
+
} as const
|
|
200
|
+
export type DRAW = (typeof DRAW)[keyof typeof DRAW]
|
|
201
|
+
export const DRAW_NAME: readonly string[] = ["setTransform", "save", "restore", "clip", "fillPath", "strokePath", "fillText", "strokeText", "drawImage", "clearRect"]
|
package/src/chisel.ts
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chisel vocabulary: every SDK name the bundler's passes key on, declared by the SDK itself.
|
|
3
|
+
*
|
|
4
|
+
* chisel (@letary/chisel) holds the ALGORITHMS — method-granular DCE, chain fusion, curve folding,
|
|
5
|
+
* the UI rewrites — and reads the NAMES from here: compile/bundler.ts passes this object as the
|
|
6
|
+
* `vocab` field of every bundle input, and chisel uses only it. A rename in the SDK is an edit
|
|
7
|
+
* here (tests/compile/chisel-vocab.test.ts fails until it is made), never a chisel release; a chisel
|
|
8
|
+
* release is for algorithms only, or when the schema grows.
|
|
9
|
+
*
|
|
10
|
+
* Rules:
|
|
11
|
+
* - Plain data. No imports, no computed values — chisel's own tests read a JSON copy
|
|
12
|
+
* (`<chisel>/fixtures/vocab.json`, held equal by `bun scripts/chisel-parity.ts --fixture`).
|
|
13
|
+
* - `schema` is the contract version. chisel rejects a newer schema than it implements (upgrade
|
|
14
|
+
* @letary/chisel) and falls back to its built-in defaults for a group an older one lacks.
|
|
15
|
+
* - Role maps (`methods`, `stops`, `range`): the key is the role chisel lowers (its algorithm
|
|
16
|
+
* mirrors that method's body), the value is the SDK's name for it.
|
|
17
|
+
* - Global names (factories, classes, helpers) are the names user code sees — inject.ts exports
|
|
18
|
+
* (`asset` is a host global). The date helpers are module-private names of runtime/datetime.ts:
|
|
19
|
+
* chisel finds them beside `date`.
|
|
20
|
+
* - Changing a list changes bundles (adding a chain method makes more calls provably nodes, so
|
|
21
|
+
* more of them skip the runtime dispatch). Keep the lists exact.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export interface ChiselVocab {
|
|
25
|
+
schema: number
|
|
26
|
+
ui: {
|
|
27
|
+
/** Factories going through the variadic `buildUI` dispatch (+ UIPager, which flattens its
|
|
28
|
+
* arguments the same way): literal array arguments are spliced into variadic ones. */
|
|
29
|
+
factories: string[]
|
|
30
|
+
/** factory → its dispatch-free builder (an inject export): a call whose arguments are all
|
|
31
|
+
* provably nodes skips the dispatch. Every key is also in `factories`. */
|
|
32
|
+
raw: Record<string, string>
|
|
33
|
+
/** The other free calls that return a node (argument provability). */
|
|
34
|
+
leaves: string[]
|
|
35
|
+
/** Containers whose function-valued children argument is a reactive children binding. */
|
|
36
|
+
containers: string[]
|
|
37
|
+
/** The text factory: its text argument is a binding position. */
|
|
38
|
+
text: string
|
|
39
|
+
/** Builder methods that keep a chain a node (a conservative whitelist). */
|
|
40
|
+
chain: string[]
|
|
41
|
+
/** The children setter (`x.setContent(() => …)`). */
|
|
42
|
+
setContent: string
|
|
43
|
+
/** Member calls whose object-literal values are bindings (`.style({…})`, `.class({…})`). */
|
|
44
|
+
bindingMethods: string[]
|
|
45
|
+
/** The memoized children-map helper (`__uiMap(list, fn, slot)`). */
|
|
46
|
+
mapHelper: string
|
|
47
|
+
}
|
|
48
|
+
signals: {
|
|
49
|
+
/** Calls that create a signal (the roots of chisel's signal-type inference). */
|
|
50
|
+
factories: string[]
|
|
51
|
+
/** The property a signal is read through. */
|
|
52
|
+
value: string
|
|
53
|
+
}
|
|
54
|
+
fusion: {
|
|
55
|
+
vec3: {
|
|
56
|
+
class: string
|
|
57
|
+
/** The component fields, in order. */
|
|
58
|
+
fields: [ string, string, string ]
|
|
59
|
+
/** Statics that yield a Vec3. */
|
|
60
|
+
statics: string[]
|
|
61
|
+
/** Instance methods that return a Vec3 (local type inference). */
|
|
62
|
+
returning: string[]
|
|
63
|
+
methods: Record<"add" | "sub" | "mul" | "scale" | "negate" | "scaleAndAdd" | "cross" | "normalize" | "dot" | "lengthSq" | "length" | "distanceTo", string>
|
|
64
|
+
}
|
|
65
|
+
date: {
|
|
66
|
+
/** The factory global. */
|
|
67
|
+
factory: string
|
|
68
|
+
/** The value class, and the module-private helpers a fused chain calls (runtime/datetime.ts). */
|
|
69
|
+
class: string
|
|
70
|
+
toMs: string
|
|
71
|
+
formatImpl: string
|
|
72
|
+
timeAgoImpl: string
|
|
73
|
+
/** A value's epoch-ms field. */
|
|
74
|
+
field: string
|
|
75
|
+
/** Methods that return a date (local type inference). */
|
|
76
|
+
returning: string[]
|
|
77
|
+
methods: Record<"add" | "subtract" | "format" | "timeAgo" | "valueOf" | "unix" | "diff" | "isBefore" | "isAfter" | "isSame", string>
|
|
78
|
+
}
|
|
79
|
+
curve: {
|
|
80
|
+
factory: string
|
|
81
|
+
colorFactory: string
|
|
82
|
+
/** The builders' payload getter (a fused chain becomes `{ <data>: new Float32Array([…]) }`). */
|
|
83
|
+
data: string
|
|
84
|
+
/** The bounds of a `Range` object. */
|
|
85
|
+
range: Record<"min" | "max", string>
|
|
86
|
+
/** The stop methods. */
|
|
87
|
+
stops: Record<"from" | "via" | "to" | "fade", string>
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
compWrite: {
|
|
91
|
+
/** `__compWrite(owner, prop, axis, v)` / `__compOp(owner, prop, axis, op, v)` — inject exports. */
|
|
92
|
+
write: string
|
|
93
|
+
op: string
|
|
94
|
+
/** The owner's hook the helpers call, and its static list of routed props (stripped once read). */
|
|
95
|
+
hook: string
|
|
96
|
+
list: string
|
|
97
|
+
/** The component names a routed write may target. */
|
|
98
|
+
axes: string[]
|
|
99
|
+
}
|
|
100
|
+
assets: {
|
|
101
|
+
/** `asset("./x")` → the asset's URL, at compile time. */
|
|
102
|
+
macro: string
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const chiselVocab: ChiselVocab = {
|
|
107
|
+
schema: 1,
|
|
108
|
+
ui: {
|
|
109
|
+
factories: [
|
|
110
|
+
"UIColumn", "UIRow", "UIBox", "UIButton", "UIScrollable", "UIScreen", "UIWidget",
|
|
111
|
+
"UIModal", "UIPopover", "UIBottomSheet", "UIPager",
|
|
112
|
+
],
|
|
113
|
+
raw: {
|
|
114
|
+
UIColumn: "__UIColumn", UIRow: "__UIRow", UIBox: "__UIBox", UIButton: "__UIButton",
|
|
115
|
+
UIScrollable: "__UIScrollable", UIScreen: "__UIScreen", UIWidget: "__UIWidget",
|
|
116
|
+
},
|
|
117
|
+
leaves: [
|
|
118
|
+
"UIText", "UIImage", "UIVideo", "UIInput", "UITextArea", "UISpacer",
|
|
119
|
+
"UITabs", "UIVirtualizedList", "NativeView", "CameraView", "MapView", "QRScanner",
|
|
120
|
+
],
|
|
121
|
+
containers: [ "UIColumn", "UIRow", "UIBox", "UIButton", "UIScrollable", "UIScreen", "UIWidget" ],
|
|
122
|
+
text: "UIText",
|
|
123
|
+
// Exactly the builder methods that return the node (tests/compile/chisel-vocab.test.ts proves it against
|
|
124
|
+
// the interfaces): `animateTo` / `animateFrom` return an Animation, so they are NOT here.
|
|
125
|
+
chain: [
|
|
126
|
+
"style", "class", "named",
|
|
127
|
+
"onClick", "onTouchStart", "onLongPress", "onMouseEnter", "onLayout", "onOpen", "onClose", "onBack",
|
|
128
|
+
"onScroll", "onScrollRelease", "onOverscroll", "onRefresh", "onSubmit",
|
|
129
|
+
"onSelect", "onChange", "onFocus", "onBlur", "onOverlayTap", "onDetent",
|
|
130
|
+
"onEndReached", "onStartReached",
|
|
131
|
+
"append", "insert", "remove", "setContent", "keepAlive",
|
|
132
|
+
"attachTo", "detents", "dismissible", "transition", "setSourceRect",
|
|
133
|
+
"push", "pop", "popToRoot", "replace", "select",
|
|
134
|
+
// UITabs / UIVirtualizedList / the native views (NativeView, CameraView, MapView, QRScanner)
|
|
135
|
+
"badge", "setData", "update", "prepend", "removeByKey",
|
|
136
|
+
"on", "off", "onReady", "onError", "onTap", "onMove", "onScan",
|
|
137
|
+
"flyTo", "jumpTo", "fitPoints", "setPadding", "setUserLocation",
|
|
138
|
+
],
|
|
139
|
+
setContent: "setContent",
|
|
140
|
+
bindingMethods: [ "style", "class" ],
|
|
141
|
+
mapHelper: "__uiMap",
|
|
142
|
+
},
|
|
143
|
+
signals: {
|
|
144
|
+
factories: [ "signal", "computed" ],
|
|
145
|
+
value: "value",
|
|
146
|
+
},
|
|
147
|
+
fusion: {
|
|
148
|
+
vec3: {
|
|
149
|
+
class: "Vec3",
|
|
150
|
+
fields: [ "x", "y", "z" ],
|
|
151
|
+
statics: [ "up", "down", "left", "right", "forward", "back", "zero", "one", "from" ],
|
|
152
|
+
returning: [
|
|
153
|
+
"add", "sub", "mul", "div", "scale", "negate", "scaleAndAdd", "cross", "lerp", "clamp", "min",
|
|
154
|
+
"max", "reflect", "project", "rotateX", "rotateY", "rotateZ", "rotate", "transform", "withX",
|
|
155
|
+
"withY", "withZ", "clone", "normalize", "copy", "set",
|
|
156
|
+
],
|
|
157
|
+
methods: {
|
|
158
|
+
add: "add", sub: "sub", mul: "mul", scale: "scale", negate: "negate", scaleAndAdd: "scaleAndAdd",
|
|
159
|
+
cross: "cross", normalize: "normalize", dot: "dot", lengthSq: "lengthSq", length: "length", distanceTo: "distanceTo",
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
date: {
|
|
163
|
+
factory: "date",
|
|
164
|
+
class: "DateValue",
|
|
165
|
+
toMs: "toMs",
|
|
166
|
+
formatImpl: "formatImpl",
|
|
167
|
+
timeAgoImpl: "timeAgoImpl",
|
|
168
|
+
field: "t",
|
|
169
|
+
returning: [ "add", "subtract", "startOf", "endOf" ],
|
|
170
|
+
methods: {
|
|
171
|
+
add: "add", subtract: "subtract", format: "format", timeAgo: "timeAgo", valueOf: "valueOf",
|
|
172
|
+
unix: "unix", diff: "diff", isBefore: "isBefore", isAfter: "isAfter", isSame: "isSame",
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
curve: {
|
|
176
|
+
factory: "curve",
|
|
177
|
+
colorFactory: "colorCurve",
|
|
178
|
+
data: "_data",
|
|
179
|
+
range: { min: "min", max: "max" },
|
|
180
|
+
stops: { from: "from", via: "via", to: "to", fade: "fade" },
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
compWrite: {
|
|
184
|
+
write: "__compWrite",
|
|
185
|
+
op: "__compOp",
|
|
186
|
+
hook: "_writeComp",
|
|
187
|
+
list: "_comps",
|
|
188
|
+
axes: [ "x", "y", "z", "w" ],
|
|
189
|
+
},
|
|
190
|
+
assets: {
|
|
191
|
+
macro: "asset",
|
|
192
|
+
},
|
|
193
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ported from
|
|
1
|
+
// Ported from tools/cli/src/compile/assetMacro.ts (itself from the backend). The
|
|
2
2
|
// compile-time `asset('./x.png')` macro is desugared into a real import so it goes through the same
|
|
3
3
|
// loader/resolver as a hand-written import.
|
|
4
4
|
|
package/src/compile/bundler.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { collectAssetMacros, desugarAssetMacros, hasAssetMacro, type AssetMacroR
|
|
|
7
7
|
import { scanModulesFallback, type ScanModule } from "./detectEntry"
|
|
8
8
|
import { hasAspectExtends, injectAspectNames } from "./aspectMacro"
|
|
9
9
|
import { hasImportStatement, rewriteLibraryImports } from "./libraryImports"
|
|
10
|
+
import { chiselVocab } from "../chisel"
|
|
10
11
|
|
|
11
12
|
/*
|
|
12
13
|
* The user-project bundler. Project files live in an in-memory map; the whole SDK is delivered via
|
|
@@ -49,7 +50,9 @@ const normalize = (path: string): string => {
|
|
|
49
50
|
// `EDITOR` is a boolean define: `false` (const-folded, `if (EDITOR)` branches DCE'd away) in
|
|
50
51
|
// every shipped bundle, `true` only in scene-editor compiles (CompileOptions.editor). Requires a
|
|
51
52
|
// chisel with boolean-define support — an older binary ignores the entry and leaves `EDITOR` as a
|
|
52
|
-
// free identifier (a runtime ReferenceError
|
|
53
|
+
// free identifier (a runtime ReferenceError in code that uses it). The SDK itself uses it: the
|
|
54
|
+
// edit-mode branches of src/scene/defineScene.ts read `EDITOR && isEditMode()`, so a shipped bundle
|
|
55
|
+
// carries no editor code (sdk/tests/scene/editor-contract.test.ts).
|
|
53
56
|
const CHISEL_DEFINE: Record<string, string> = { RAD2DEG: "57.29577951308232", DEG2RAD: "0.017453292519943295" }
|
|
54
57
|
|
|
55
58
|
// Methods the native host invokes by name have no in-bundle caller, so method-DCE can't see them.
|
|
@@ -62,6 +65,9 @@ const CHISEL_KEEP = [ "_*" ]
|
|
|
62
65
|
* src/server/inject.ts). A bundle gets exactly one of them. */
|
|
63
66
|
export const CLIENT_INJECT = "/__sdk/inject.ts"
|
|
64
67
|
export const SERVER_INJECT = "/__sdk/server/inject.ts"
|
|
68
|
+
/** What an EDITOR bundle gets on top of the client SDK (`editor: true`): the scene editor's
|
|
69
|
+
* contract, `__sceneEditor` (src/inject.editor.ts → src/scene/editor.ts). Never in a shipped bundle. */
|
|
70
|
+
export const EDITOR_INJECT = "/__sdk/inject.editor.ts"
|
|
65
71
|
|
|
66
72
|
/** The SDK source root (parent of `inject.ts`). chisel needs the source tree, not a prebuilt bundle. */
|
|
67
73
|
const resolveSdkSrc = (): string => {
|
|
@@ -248,7 +254,7 @@ const bundleProjectChisel = async (
|
|
|
248
254
|
const input = JSON.stringify({
|
|
249
255
|
files: { ...sdkFiles, ...projFiles },
|
|
250
256
|
entry,
|
|
251
|
-
inject: [ inject ],
|
|
257
|
+
inject: editor ? [ inject, EDITOR_INJECT ] : [ inject ],
|
|
252
258
|
format,
|
|
253
259
|
minify,
|
|
254
260
|
// Chain fusion, ON by default (`LECODES_CHISEL_FUSE=0` opts out): Vec3/date math chains lower to
|
|
@@ -268,6 +274,9 @@ const bundleProjectChisel = async (
|
|
|
268
274
|
// this only drops an array allocation per call site. Safe to always request: the sibling SDK
|
|
269
275
|
// source above has the variadic dispatch, and an older binary ignores the unknown field.
|
|
270
276
|
flatten_ui: process.env.LECODES_CHISEL_FLATTEN_UI !== "0",
|
|
277
|
+
// The SDK names the passes key on (src/chisel.ts). chisel uses only these; a chisel that
|
|
278
|
+
// predates the field ignores it and keeps its built-in lists.
|
|
279
|
+
vocab: chiselVocab,
|
|
271
280
|
})
|
|
272
281
|
|
|
273
282
|
const bin = resolveChiselBin()
|