lecodes-sdk 1.1.0 → 2.0.0
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 +11 -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/Particles.d.ts +15 -0
- 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 +59 -3
- package/dist/types/gl/terrain/Terrain.d.ts +8 -0
- 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 +8 -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 +142 -142
- 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 +77 -54
- package/prompts/dist/3d-app.md +75 -52
- package/prompts/dist/ar-app.md +74 -51
- package/prompts/dist/design.md +30 -8
- package/prompts/dist/ui-app.md +73 -46
- package/prompts/ui-design.md +2 -3
- package/prompts/ui.md +45 -37
- package/src/animate/tween/Animation.ts +262 -378
- package/src/animate/tween/animateValue.ts +103 -100
- package/src/animate/tween/easing.ts +10 -3
- package/src/animate/tween/spec.ts +505 -479
- package/src/audio/Sound.ts +3 -3
- package/src/audio/audio.ts +162 -161
- 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/Foliage.ts +72 -17
- package/src/gl/Geometry.ts +1 -2
- package/src/gl/Light.ts +13 -0
- package/src/gl/Lightmap.ts +45 -29
- package/src/gl/Material.ts +95 -51
- package/src/gl/Model.ts +172 -167
- package/src/gl/Node.ts +91 -24
- package/src/gl/Particles.ts +20 -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/Locomotion.ts +77 -8
- 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/terrain/Terrain.ts +33 -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 +233 -236
- 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 +21 -8
- 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 +154 -148
- 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 -4730
- 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 -1760
- 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
package/src/ui/tree.ts
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
// The SDK's side of the tree of truth (docs/plans/hosts-unification-plan.md, phase 9): the numbers shared
|
|
2
|
+
// with runtime/native (creator-pkg/tree-events.h — mirrored VERBATIM, `bun run check:tree-consts`),
|
|
3
|
+
// the pin table that keeps the element of every attached node alive and findable by id, the
|
|
4
|
+
// destination registry, and the ONE emitter every event of `_creatorTree` comes through.
|
|
5
|
+
//
|
|
6
|
+
// Ownership (tree.h): an attached node belongs to the runtime's tree and its element is PINNED here
|
|
7
|
+
// (so `children` returns the same objects and listeners survive the app dropping its reference); a
|
|
8
|
+
// detached root belongs to its element — when that is collected, the handle's finalizer frees the
|
|
9
|
+
// node. The runtime tells us when it detaches a root (TREE_EVENT_DETACHED) or frees nodes underneath
|
|
10
|
+
// their handles (TREE_EVENT_FREED); everything else we pin / unpin ourselves.
|
|
11
|
+
|
|
12
|
+
// ---- emit kinds (id = the node, 0 for world-level events) ----------------------------------------
|
|
13
|
+
export const TREE_EVENT_LAYOUT = 1
|
|
14
|
+
export const TREE_EVENT_TOUCH_START = 2
|
|
15
|
+
export const TREE_EVENT_CLICK = 3
|
|
16
|
+
export const TREE_EVENT_LONG_PRESS = 4
|
|
17
|
+
export const TREE_EVENT_TOUCH_MOVE = 5
|
|
18
|
+
export const TREE_EVENT_TOUCH_END = 6
|
|
19
|
+
export const TREE_EVENT_TOUCH_CANCEL = 7
|
|
20
|
+
export const TREE_EVENT_SCROLL = 8
|
|
21
|
+
export const TREE_EVENT_OVERSCROLL = 9
|
|
22
|
+
export const TREE_EVENT_SCROLL_RELEASE = 10
|
|
23
|
+
export const TREE_EVENT_REFRESH = 11
|
|
24
|
+
export const TREE_EVENT_CHANGE = 12
|
|
25
|
+
export const TREE_EVENT_FOCUS = 13
|
|
26
|
+
export const TREE_EVENT_BLUR = 14
|
|
27
|
+
export const TREE_EVENT_SUBMIT = 15
|
|
28
|
+
export const TREE_EVENT_OVERLAY_TAP = 16
|
|
29
|
+
export const TREE_EVENT_DETENT = 17
|
|
30
|
+
export const TREE_EVENT_OPEN = 18
|
|
31
|
+
export const TREE_EVENT_CLOSE = 19
|
|
32
|
+
export const TREE_EVENT_BACK = 20
|
|
33
|
+
export const TREE_EVENT_PAGER_SELECT = 21
|
|
34
|
+
export const TREE_EVENT_PAGER_POP = 22
|
|
35
|
+
export const TREE_EVENT_VLIST_SYNC = 23
|
|
36
|
+
export const TREE_EVENT_VLIST_EDGE = 24
|
|
37
|
+
export const TREE_EVENT_VIEW_EVENT = 25
|
|
38
|
+
export const TREE_EVENT_RESIZE = 26
|
|
39
|
+
export const TREE_EVENT_ROUTER_CHANGE = 27
|
|
40
|
+
export const TREE_EVENT_SCENE_TOUCH_START = 28
|
|
41
|
+
export const TREE_EVENT_SCENE_CLICK = 29
|
|
42
|
+
export const TREE_EVENT_DETACHED = 30
|
|
43
|
+
export const TREE_EVENT_FREED = 31
|
|
44
|
+
export const TREE_EVENT_HOVER_ENTER = 32
|
|
45
|
+
export const TREE_EVENT_HOVER_MOVE = 33
|
|
46
|
+
export const TREE_EVENT_HOVER_END = 34
|
|
47
|
+
export const TREE_EVENT_HOVER_CANCEL = 35
|
|
48
|
+
|
|
49
|
+
// ---- setFlags(id, mask) ---------------------------------------------------------------------------
|
|
50
|
+
export const TREE_FLAG_INTERACTIVE = 1 << 0
|
|
51
|
+
export const TREE_FLAG_CLICK = 1 << 1
|
|
52
|
+
export const TREE_FLAG_LONG_PRESS = 1 << 2
|
|
53
|
+
export const TREE_FLAG_LAYOUT = 1 << 3
|
|
54
|
+
export const TREE_FLAG_SCROLL = 1 << 4
|
|
55
|
+
export const TREE_FLAG_OVERSCROLL = 1 << 5
|
|
56
|
+
export const TREE_FLAG_SCROLL_RELEASE = 1 << 6
|
|
57
|
+
export const TREE_FLAG_REFRESH = 1 << 7
|
|
58
|
+
export const TREE_FLAG_CHANGE = 1 << 8
|
|
59
|
+
export const TREE_FLAG_FOCUS = 1 << 9
|
|
60
|
+
export const TREE_FLAG_BLUR = 1 << 10
|
|
61
|
+
export const TREE_FLAG_SUBMIT = 1 << 11
|
|
62
|
+
export const TREE_FLAG_OVERLAY_TAP = 1 << 12
|
|
63
|
+
export const TREE_FLAG_DETENT = 1 << 13
|
|
64
|
+
export const TREE_FLAG_KEEP_ALIVE = 1 << 14
|
|
65
|
+
export const TREE_FLAG_BACK = 1 << 15
|
|
66
|
+
export const TREE_FLAG_VLIST_END = 1 << 16
|
|
67
|
+
export const TREE_FLAG_VLIST_START = 1 << 17
|
|
68
|
+
export const TREE_FLAG_HOVER = 1 << 18
|
|
69
|
+
|
|
70
|
+
// ---- the touchStart / longPress answer -------------------------------------------------------------
|
|
71
|
+
export const TREE_TRACK_CLAIM_MASK = 0xFF
|
|
72
|
+
export const TREE_TRACK_TRACKED = 1 << 8
|
|
73
|
+
export const TREE_TRACK_MOVE = 1 << 9
|
|
74
|
+
export const TREE_TRACK_HANDLED = 1 << 10
|
|
75
|
+
|
|
76
|
+
// ---- destination kinds -------------------------------------------------------------------------------
|
|
77
|
+
export const TREE_DEST_SCREEN = 0
|
|
78
|
+
export const TREE_DEST_SCENE3D = 1
|
|
79
|
+
export const TREE_DEST_SCENE2D = 2
|
|
80
|
+
export const TREE_DEST_NATIVE = 3
|
|
81
|
+
export const TREE_DEST_VIDEO = 4
|
|
82
|
+
export const TREE_DEST_NONE = 0xFF
|
|
83
|
+
|
|
84
|
+
// Owned-handle kinds (owned.h OwnedKind) — the `_creatorApp.setFreedEmitter` channel names the kind
|
|
85
|
+
// whose resources the runtime freed underneath their wrappers (core/pins.ts).
|
|
86
|
+
export const OWNED_KIND_TREE = 0
|
|
87
|
+
export const OWNED_KIND_FETCH = 1
|
|
88
|
+
export const OWNED_KIND_GL_MATERIAL = 2
|
|
89
|
+
export const OWNED_KIND_GL_TEXTURE = 3
|
|
90
|
+
export const OWNED_KIND_GL_ENTITY = 4
|
|
91
|
+
export const OWNED_KIND_ENTITY_2D = 5
|
|
92
|
+
export const OWNED_KIND_MEDIA = 6
|
|
93
|
+
export const OWNED_KIND_TWEEN = 7
|
|
94
|
+
export const OWNED_KIND_CANVAS = 8
|
|
95
|
+
|
|
96
|
+
// PanDirection (creator-pkg.h) — the low byte of a track answer.
|
|
97
|
+
import { DEAD_HANDLE } from "../core/pins"
|
|
98
|
+
|
|
99
|
+
const PAN: Record<string, number> = { "pan-up": 1, "pan-right": 2, "pan-down": 4, "pan-left": 8, "pan-x": 10, "pan-y": 5 }
|
|
100
|
+
|
|
101
|
+
// ---- the bridge ---------------------------------------------------------------------------------------
|
|
102
|
+
/** @internal The tree bridge. Every host that runs bundles installs it before the bundle evaluates. */
|
|
103
|
+
export const tree = (): typeof _creatorTree => _creatorTree
|
|
104
|
+
|
|
105
|
+
// ---- what an element / presentable must offer the emitter (duck-typed, all `_`-prefixed so chisel keeps them)
|
|
106
|
+
/** @internal */
|
|
107
|
+
export interface TreeElement {
|
|
108
|
+
/** The owned handle (`_h.id` = the node id; DEAD_HANDLE once the node is gone). */
|
|
109
|
+
_h: Handle
|
|
110
|
+
_emitLayout?(box: { left: number, top: number, width: number, height: number }): void
|
|
111
|
+
_emitTouchStart?(pointerId: number, x: number, y: number): TrackLike | null
|
|
112
|
+
_emitClick?(pointerId: number, x: number, y: number): void
|
|
113
|
+
_emitLongPress?(pointerId: number, x: number, y: number): { track: TrackLike | null } | null
|
|
114
|
+
_emitMouseEnter?(x: number, y: number): HoverTrackLike | null
|
|
115
|
+
_emitScroll?(position: number): void
|
|
116
|
+
_emitOverscroll?(delta: number): void
|
|
117
|
+
_emitScrollRelease?(): void
|
|
118
|
+
_emitRefresh?(): unknown
|
|
119
|
+
_emitChange?(value: string): void
|
|
120
|
+
_emitFocus?(): void
|
|
121
|
+
_emitBlur?(): void
|
|
122
|
+
_emitSubmit?(value: string): void
|
|
123
|
+
_emitOverlayTap?(): void
|
|
124
|
+
_emitDetent?(index: number): void
|
|
125
|
+
_hostDidSelect?(index: number): void
|
|
126
|
+
_hostDidPop?(depth: number): void
|
|
127
|
+
_syncWindow?(unmountKeys: string[], mountKeys: string[]): void
|
|
128
|
+
_emitEdge?(end: boolean): void
|
|
129
|
+
_detached?(): void
|
|
130
|
+
_freed?(): void
|
|
131
|
+
/** The element's node got a native owner (it was inserted under a parent) / lost it. */
|
|
132
|
+
_pinned?(): void
|
|
133
|
+
_unpinned?(): void
|
|
134
|
+
_emitBack?(): boolean
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** @internal A track handler (runtime/touch.ts TrackHandler), as the emitter reads it. */
|
|
138
|
+
export interface TrackLike {
|
|
139
|
+
onMove?(pos: { clientX: number, clientY: number, deltaX: number, deltaY: number }): void
|
|
140
|
+
onEnd?(pos: { clientX: number, clientY: number, deltaX: number, deltaY: number }): void
|
|
141
|
+
onCancel?(): void
|
|
142
|
+
claim?: boolean | string
|
|
143
|
+
}
|
|
144
|
+
/** @internal A hover track handler (runtime/touch.ts HoverTrackHandler): TrackLike without a claim. */
|
|
145
|
+
export type HoverTrackLike = Omit<TrackLike, "claim">
|
|
146
|
+
|
|
147
|
+
/** @internal What a destination offers: the presentation lifecycle + the back handler. */
|
|
148
|
+
export interface TreeDest {
|
|
149
|
+
_emitOpen?(): void
|
|
150
|
+
_emitClose?(): void
|
|
151
|
+
_emitBack?(): boolean
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { DEAD_HANDLE }
|
|
155
|
+
|
|
156
|
+
// ---- pins -------------------------------------------------------------------------------------------------
|
|
157
|
+
const pins = new Map<number, TreeElement>()
|
|
158
|
+
|
|
159
|
+
/** @internal Keep `el` alive and findable while its node is attached / presented / shown. */
|
|
160
|
+
export const pin = (el: TreeElement | null | undefined): void => {
|
|
161
|
+
if (!el || el._h.id === 0) return
|
|
162
|
+
pins.set(el._h.id, el)
|
|
163
|
+
el._pinned?.()
|
|
164
|
+
}
|
|
165
|
+
/** @internal */
|
|
166
|
+
export const unpin = (id: number): void => {
|
|
167
|
+
const el = pins.get(id)
|
|
168
|
+
if (!el) return
|
|
169
|
+
pins.delete(id)
|
|
170
|
+
el._unpinned?.()
|
|
171
|
+
}
|
|
172
|
+
/** @internal The pinned element of a node id (an attached node's element), or undefined. */
|
|
173
|
+
export const byId = (id: number): TreeElement | undefined => pins.get(id)
|
|
174
|
+
/** @internal The elements of a list of ids (attached nodes only). */
|
|
175
|
+
export const elementsOf = (ids: number[]): any[] => {
|
|
176
|
+
const out: any[] = []
|
|
177
|
+
for (const id of ids) { const el = pins.get(id); if (el) out.push(el) }
|
|
178
|
+
return out
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ---- destinations ------------------------------------------------------------------------------------------
|
|
182
|
+
// Non-screen presentables (scenes, native views) register here under their engine id; screens and
|
|
183
|
+
// video nodes resolve through the pins (their destination id IS the node id).
|
|
184
|
+
const dests = new Map<string, TreeDest>()
|
|
185
|
+
const destKey = (kind: number, id: number): string => `${kind}:${id}`
|
|
186
|
+
|
|
187
|
+
/** @internal */
|
|
188
|
+
export const registerDest = (kind: number, id: number, p: TreeDest): void => { dests.set(destKey(kind, id), p) }
|
|
189
|
+
/** @internal */
|
|
190
|
+
export const unregisterDest = (kind: number, id: number): void => { dests.delete(destKey(kind, id)) }
|
|
191
|
+
/** @internal The presentable a (kind, id) pair names. */
|
|
192
|
+
export const resolveDest = (kind: number, id: number): (TreeDest & Partial<TreeElement>) | undefined => {
|
|
193
|
+
if (kind === TREE_DEST_SCREEN || kind === TREE_DEST_VIDEO) return pins.get(id) as any
|
|
194
|
+
return dests.get(destKey(kind, id)) as any
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ---- world-level hooks (set by the modules that own them) --------------------------------------------------
|
|
198
|
+
type SceneTouchStart = (pointerId: number, x: number, y: number, entityId: number) => TrackLike | null
|
|
199
|
+
type SceneClick = (pointerId: number, x: number, y: number, entityId: number) => void
|
|
200
|
+
let sceneTouchStart: SceneTouchStart | null = null
|
|
201
|
+
let sceneClick: SceneClick | null = null
|
|
202
|
+
/** @internal gl/touch.ts: the scene-level pointer dispatch. */
|
|
203
|
+
export const setSceneTouchHandlers = (start: SceneTouchStart | null, click: SceneClick | null): void => {
|
|
204
|
+
sceneTouchStart = start
|
|
205
|
+
sceneClick = click
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const resizeListeners: ((width: number, height: number) => void)[] = []
|
|
209
|
+
/** @internal runtime/device.ts */
|
|
210
|
+
export const onTreeResize = (cb: (width: number, height: number) => void): (() => void) => {
|
|
211
|
+
resizeListeners.push(cb)
|
|
212
|
+
return () => { const i = resizeListeners.indexOf(cb); if (i >= 0) resizeListeners.splice(i, 1) }
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
let routerChange: ((kind: number, id: number) => void) | null = null
|
|
216
|
+
/** @internal ui/router.ts */
|
|
217
|
+
export const setRouterChangeHandler = (cb: ((kind: number, id: number) => void) | null): void => { routerChange = cb }
|
|
218
|
+
|
|
219
|
+
let appBack: (() => void) | null = null
|
|
220
|
+
/** @internal runtime/app.ts — the app-level back handler (the end of the runtime's back chain). */
|
|
221
|
+
export const setAppBackHandler = (cb: (() => void) | null): void => { appBack = cb }
|
|
222
|
+
|
|
223
|
+
const nativeViews = new Map<number, { _emitViewEvent(event: string, data?: unknown): void }>()
|
|
224
|
+
/** @internal ui/NativeView.ts: the instance a viewId names (host → view events). */
|
|
225
|
+
export const registerNativeView = (viewId: number, v: { _emitViewEvent(event: string, data?: unknown): void }): void => { nativeViews.set(viewId, v) }
|
|
226
|
+
/** @internal */
|
|
227
|
+
export const unregisterNativeView = (viewId: number): void => { nativeViews.delete(viewId) }
|
|
228
|
+
|
|
229
|
+
// ---- gestures -----------------------------------------------------------------------------------------------
|
|
230
|
+
// The track handler of every pointer a listener claimed (`ev.track(...)`): the runtime feeds the
|
|
231
|
+
// pointer's moves / end / cancel here by pointer id — nothing of it is retained natively.
|
|
232
|
+
const trackers = new Map<number, TrackLike>()
|
|
233
|
+
|
|
234
|
+
// The hover's own slot — the cursor is one, and it is NOT a gesture: a mouse drag keeps its touch
|
|
235
|
+
// tracker under pointer 0 while the hover under the same cursor runs here, independently.
|
|
236
|
+
let hoverTracker: HoverTrackLike | null = null
|
|
237
|
+
|
|
238
|
+
const hoverAnswer = (handler: HoverTrackLike | null | undefined): number => {
|
|
239
|
+
hoverTracker = handler ?? null
|
|
240
|
+
if (!handler) return 0
|
|
241
|
+
return TREE_TRACK_TRACKED | (handler.onMove ? TREE_TRACK_MOVE : 0)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const trackAnswer = (pointerId: number, handler: TrackLike | null | undefined): number => {
|
|
245
|
+
if (!handler) return 0
|
|
246
|
+
trackers.set(pointerId, handler)
|
|
247
|
+
let r = TREE_TRACK_TRACKED
|
|
248
|
+
if (handler.onMove) r |= TREE_TRACK_MOVE
|
|
249
|
+
const claim = handler.claim
|
|
250
|
+
if (claim === true || claim === "all") r |= 15
|
|
251
|
+
else if (typeof claim === "string") r |= PAN[claim] ?? 0
|
|
252
|
+
return r
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ---- the emitter --------------------------------------------------------------------------------------------
|
|
256
|
+
let installed = false
|
|
257
|
+
const emit = (id: number, kind: number, a?: any, b?: any, c?: any, d?: any, e?: any): any => {
|
|
258
|
+
switch (kind) {
|
|
259
|
+
case TREE_EVENT_LAYOUT: pins.get(id)?._emitLayout?.({ left: a, top: b, width: c, height: d }); return
|
|
260
|
+
case TREE_EVENT_TOUCH_START: return trackAnswer(a, pins.get(id)?._emitTouchStart?.(a, b, c))
|
|
261
|
+
case TREE_EVENT_CLICK: pins.get(id)?._emitClick?.(a, b, c); return
|
|
262
|
+
case TREE_EVENT_LONG_PRESS: {
|
|
263
|
+
const r = pins.get(id)?._emitLongPress?.(a, b, c)
|
|
264
|
+
if (!r) return 0
|
|
265
|
+
return TREE_TRACK_HANDLED | trackAnswer(a, r.track)
|
|
266
|
+
}
|
|
267
|
+
case TREE_EVENT_TOUCH_MOVE: trackers.get(a)?.onMove?.({ clientX: b, clientY: c, deltaX: d, deltaY: e }); return
|
|
268
|
+
case TREE_EVENT_TOUCH_END: {
|
|
269
|
+
const t = trackers.get(a)
|
|
270
|
+
trackers.delete(a)
|
|
271
|
+
t?.onEnd?.({ clientX: b, clientY: c, deltaX: d, deltaY: e })
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
case TREE_EVENT_TOUCH_CANCEL: {
|
|
275
|
+
const t = trackers.get(a)
|
|
276
|
+
trackers.delete(a)
|
|
277
|
+
t?.onCancel?.()
|
|
278
|
+
return
|
|
279
|
+
}
|
|
280
|
+
case TREE_EVENT_HOVER_ENTER: return hoverAnswer(pins.get(id)?._emitMouseEnter?.(a, b))
|
|
281
|
+
case TREE_EVENT_HOVER_MOVE: hoverTracker?.onMove?.({ clientX: a, clientY: b, deltaX: c, deltaY: d }); return
|
|
282
|
+
case TREE_EVENT_HOVER_END: {
|
|
283
|
+
const t = hoverTracker
|
|
284
|
+
hoverTracker = null
|
|
285
|
+
t?.onEnd?.({ clientX: a, clientY: b, deltaX: c, deltaY: d })
|
|
286
|
+
return
|
|
287
|
+
}
|
|
288
|
+
case TREE_EVENT_HOVER_CANCEL: {
|
|
289
|
+
const t = hoverTracker
|
|
290
|
+
hoverTracker = null
|
|
291
|
+
t?.onCancel?.()
|
|
292
|
+
return
|
|
293
|
+
}
|
|
294
|
+
case TREE_EVENT_SCROLL: pins.get(id)?._emitScroll?.(a); return
|
|
295
|
+
case TREE_EVENT_OVERSCROLL: pins.get(id)?._emitOverscroll?.(a); return
|
|
296
|
+
case TREE_EVENT_SCROLL_RELEASE: pins.get(id)?._emitScrollRelease?.(); return
|
|
297
|
+
case TREE_EVENT_REFRESH: return pins.get(id)?._emitRefresh?.()
|
|
298
|
+
case TREE_EVENT_CHANGE: pins.get(id)?._emitChange?.(a); return
|
|
299
|
+
case TREE_EVENT_FOCUS: pins.get(id)?._emitFocus?.(); return
|
|
300
|
+
case TREE_EVENT_BLUR: pins.get(id)?._emitBlur?.(); return
|
|
301
|
+
case TREE_EVENT_SUBMIT: pins.get(id)?._emitSubmit?.(a); return
|
|
302
|
+
case TREE_EVENT_OVERLAY_TAP: pins.get(id)?._emitOverlayTap?.(); return
|
|
303
|
+
case TREE_EVENT_DETENT: pins.get(id)?._emitDetent?.(a); return
|
|
304
|
+
case TREE_EVENT_OPEN: resolveDest(a, b)?._emitOpen?.(); return
|
|
305
|
+
case TREE_EVENT_CLOSE: resolveDest(a, b)?._emitClose?.(); return
|
|
306
|
+
case TREE_EVENT_BACK: {
|
|
307
|
+
if (a === TREE_DEST_NONE) {
|
|
308
|
+
if (id !== 0) return pins.get(id)?._emitBack?.() === true // a widget
|
|
309
|
+
if (!appBack) return false
|
|
310
|
+
appBack()
|
|
311
|
+
return true
|
|
312
|
+
}
|
|
313
|
+
return resolveDest(a, b)?._emitBack?.() === true
|
|
314
|
+
}
|
|
315
|
+
case TREE_EVENT_PAGER_SELECT: pins.get(id)?._hostDidSelect?.(a); return
|
|
316
|
+
case TREE_EVENT_PAGER_POP: pins.get(id)?._hostDidPop?.(a); return
|
|
317
|
+
case TREE_EVENT_VLIST_SYNC: pins.get(id)?._syncWindow?.(a, b); return
|
|
318
|
+
case TREE_EVENT_VLIST_EDGE: pins.get(id)?._emitEdge?.(!!a); return
|
|
319
|
+
case TREE_EVENT_VIEW_EVENT: nativeViews.get(a)?._emitViewEvent(b, c); return
|
|
320
|
+
case TREE_EVENT_RESIZE: for (const cb of resizeListeners.slice()) cb(a, b); return
|
|
321
|
+
case TREE_EVENT_ROUTER_CHANGE: routerChange?.(a, b); return
|
|
322
|
+
case TREE_EVENT_SCENE_TOUCH_START: return trackAnswer(a, sceneTouchStart?.(a, b, c, d))
|
|
323
|
+
case TREE_EVENT_SCENE_CLICK: sceneClick?.(a, b, c, d); return
|
|
324
|
+
case TREE_EVENT_DETACHED: {
|
|
325
|
+
const el = pins.get(id)
|
|
326
|
+
pins.delete(id)
|
|
327
|
+
el?._detached?.()
|
|
328
|
+
return
|
|
329
|
+
}
|
|
330
|
+
case TREE_EVENT_FREED: {
|
|
331
|
+
for (const fid of a as number[]) {
|
|
332
|
+
const el = pins.get(fid)
|
|
333
|
+
pins.delete(fid)
|
|
334
|
+
el?._freed?.()
|
|
335
|
+
}
|
|
336
|
+
return
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** @internal Install the emitter once per world (the first element / presentable calls it). */
|
|
342
|
+
export const ensureEmitter = (): void => {
|
|
343
|
+
if (installed) return
|
|
344
|
+
installed = true
|
|
345
|
+
_creatorTree.setEmitter(emit)
|
|
346
|
+
}
|
package/src/version.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// GENERATED by scripts/release/set-version.ts from sdk/package.json — do not edit by hand.
|
|
2
|
+
// The ONE version of the SDK + the runtime (the npm runtime set ships as one version; the C++
|
|
3
|
+
// twin is CREATOR_PKG_SDK_VERSION in creator-pkg/host.gen.h, emitted by gen:bridges from the
|
|
4
|
+
// same manifest). Its MAJOR is the bundle ↔ runtime contract: a bundle's `// sdk:` header line
|
|
5
|
+
// and a host's embedded version must agree on the major for the host to run the bundle; minor
|
|
6
|
+
// and patch never gate anything (features are detected, never versioned).
|
|
7
|
+
export const SDK_VERSION = "2.0.0"
|
|
8
|
+
|
|
9
|
+
/** The major of a semver string, or null when it is not one. */
|
|
10
|
+
export const sdkMajor = (version: string | null | undefined): number | null => {
|
|
11
|
+
const m = version?.match(/^(\d+)\.\d+\.\d+/)
|
|
12
|
+
return m ? Number(m[1]) : null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The `// sdk: <version>` line of a compiled bundle's header (sdk/src/compile/header.ts), read from
|
|
16
|
+
* its first bytes; null for a bundle compiled before the line existed (SDK 0.x / 1.x — the
|
|
17
|
+
* pre-tree contract, which no 2.x host runs). */
|
|
18
|
+
export const bundleSdkVersion = (head: string): string | null =>
|
|
19
|
+
head.slice(0, 2000).match(/^\/\/ sdk: (\d+\.\d+\.\d+\S*)/m)?.[1] ?? null
|
|
20
|
+
|
|
21
|
+
/** Whether a host embedding `hostVersion` can run a bundle whose header carries `bundleVersion`
|
|
22
|
+
* (null = no line = pre-2.0 contract): the majors must match. */
|
|
23
|
+
export const bundleRunsOn = (bundleVersion: string | null, hostVersion: string): boolean =>
|
|
24
|
+
sdkMajor(bundleVersion) !== null && sdkMajor(bundleVersion) === sdkMajor(hostVersion)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// A test file's 3D engine world is its `_creator` stub, and it ends with the file. The runtime frees
|
|
2
|
+
// a torn-down world's nodes and reports them (core/pins.ts); a stub does not, and every stub restarts
|
|
3
|
+
// its entity ids — so a node the SDK still pins (parented / in a scene: gl/Node.ts `nodes`) would
|
|
4
|
+
// answer for a later file's entity with the same id (`parent`, `children`, the rig an IK chain lands
|
|
5
|
+
// on). A file whose nodes get pinned reports its entity ids freed in its afterAll.
|
|
6
|
+
import { nodes } from "../../src/gl/Node"
|
|
7
|
+
|
|
8
|
+
/** Report the entity ids `first`..`last`, plus `extra`, freed — the runtime's world teardown. */
|
|
9
|
+
export const freeEntities = (first: number, last: number, ...extra: number[]): void => {
|
|
10
|
+
nodes.freed([ ...Array.from({ length: Math.max(0, last - first + 1) }, (_, i) => first + i), ...extra ])
|
|
11
|
+
}
|