lecodes-cli 0.19.0 → 0.19.2
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/dist/index.js +730 -235
- package/package.json +14 -13
- package/runtime/scene-harness.json +1 -1
- package/runtime/sdk-types.json +1 -1
- package/src/api.ts +302 -0
- package/src/browserAuth.ts +87 -0
- package/src/cmgenTool.ts +104 -0
- package/src/commands/app.ts +891 -0
- package/src/commands/appAndroid.ts +603 -0
- package/src/commands/appDesktop.ts +326 -0
- package/src/commands/appDesktopMac.ts +470 -0
- package/src/commands/appIcon.ts +187 -0
- package/src/commands/appShared.ts +448 -0
- package/src/commands/appTemplates.ts +883 -0
- package/src/commands/appTemplatesAndroid.ts +599 -0
- package/src/commands/appTemplatesGradlew.ts +9 -0
- package/src/commands/assets.ts +28 -0
- package/src/commands/clone.ts +60 -0
- package/src/commands/compile.ts +253 -0
- package/src/commands/create.ts +59 -0
- package/src/commands/design.ts +863 -0
- package/src/commands/designTemplates.ts +11 -0
- package/src/commands/desktop.ts +122 -0
- package/src/commands/dev.ts +214 -0
- package/src/commands/diff.ts +59 -0
- package/src/commands/init.ts +191 -0
- package/src/commands/install.ts +198 -0
- package/src/commands/lightmap.ts +290 -0
- package/src/commands/link.ts +147 -0
- package/src/commands/login.ts +24 -0
- package/src/commands/navmesh.ts +225 -0
- package/src/commands/pn.ts +305 -0
- package/src/commands/projectTemplates.ts +129 -0
- package/src/commands/pull.ts +109 -0
- package/src/commands/push.ts +173 -0
- package/src/commands/render.ts +414 -0
- package/src/commands/scene.ts +148 -0
- package/src/commands/shaders.ts +157 -0
- package/src/commands/status.ts +29 -0
- package/src/commands/test.ts +370 -0
- package/src/commands/thumbs.ts +178 -0
- package/src/commands/types.ts +87 -0
- package/src/commands/update.ts +190 -0
- package/src/compile/assetIcons.ts +214 -0
- package/src/compile/collect.ts +46 -0
- package/src/compile/collectLocal.ts +37 -0
- package/src/compile/designCompile.ts +104 -0
- package/src/compile/fonts.ts +156 -0
- package/src/compile/headlessBundle.ts +129 -0
- package/src/compile/nativeStack.ts +21 -0
- package/src/compile/projectCompile.ts +109 -0
- package/src/compile/sceneCompile.ts +113 -0
- package/src/compile/screenEntry.ts +127 -0
- package/src/compile/shaders.ts +245 -0
- package/src/config.ts +42 -0
- package/src/designMeta.ts +35 -0
- package/src/desktopRenderer.ts +532 -0
- package/src/desktopScript.ts +276 -0
- package/src/dev/clientTemplates.ts +160 -0
- package/src/dev/devServer.ts +292 -0
- package/src/dev/wsServer.ts +144 -0
- package/src/distRoot.ts +20 -0
- package/src/ignore.ts +163 -0
- package/src/index.ts +491 -0
- package/src/lecodes-3d-editor.d.ts +41 -0
- package/src/lecodes-assets.d.ts +7 -0
- package/src/lecodes-design.d.ts +191 -0
- package/src/lecodes-renderer.d.ts +131 -0
- package/src/localFiles.ts +144 -0
- package/src/manifest.ts +46 -0
- package/src/matcTool.ts +137 -0
- package/src/peers.ts +40 -0
- package/src/project.ts +61 -0
- package/src/projectEnv.ts +94 -0
- package/src/qrcode-terminal.d.ts +9 -0
- package/src/releases.ts +125 -0
- package/src/serverDiff.ts +78 -0
- package/src/textDiff.ts +103 -0
- package/src/types.ts +0 -0
- package/src/util.ts +146 -0
- package/runtime/sdk/animate/animate.ts +0 -238
- package/runtime/sdk/animate/bezier.ts +0 -138
- package/runtime/sdk/animate/easings.ts +0 -126
- package/runtime/sdk/canvas/Canvas.ts +0 -305
- package/runtime/sdk/compile/aspectMacro.ts +0 -86
- package/runtime/sdk/compile/assetIconMacro.ts +0 -384
- package/runtime/sdk/compile/assetMacro.ts +0 -146
- package/runtime/sdk/compile/assetName.ts +0 -50
- package/runtime/sdk/compile/bundler.ts +0 -287
- package/runtime/sdk/compile/compileProject.ts +0 -129
- package/runtime/sdk/compile/detectEntry.ts +0 -128
- package/runtime/sdk/compile/fontMacro.ts +0 -459
- package/runtime/sdk/compile/fontRegistry.ts +0 -78
- package/runtime/sdk/compile/header.ts +0 -67
- package/runtime/sdk/compile/index.ts +0 -100
- package/runtime/sdk/compile/libraryImports.ts +0 -52
- package/runtime/sdk/compile/liteMaterial.ts +0 -247
- package/runtime/sdk/compile/sceneEditor.ts +0 -88
- package/runtime/sdk/compile/serverSplit.ts +0 -233
- package/runtime/sdk/compile/serverTypes.ts +0 -227
- package/runtime/sdk/compile/sfnt.ts +0 -98
- package/runtime/sdk/compile/shaderSchema.ts +0 -202
- package/runtime/sdk/compile/shaderTargets.ts +0 -81
- package/runtime/sdk/compile/sourcemap.ts +0 -25
- package/runtime/sdk/core/Aspect.ts +0 -568
- package/runtime/sdk/core/InspectorUI.ts +0 -212
- package/runtime/sdk/core/StateMachine.ts +0 -308
- package/runtime/sdk/core/color.ts +0 -66
- package/runtime/sdk/core/compWrite.ts +0 -42
- package/runtime/sdk/core/events.ts +0 -38
- package/runtime/sdk/core/fields.ts +0 -120
- package/runtime/sdk/core/registry.ts +0 -23
- package/runtime/sdk/core/signals.ts +0 -277
- package/runtime/sdk/core/time.ts +0 -84
- package/runtime/sdk/g2/Camera2D.ts +0 -40
- package/runtime/sdk/g2/CharacterController2D.ts +0 -276
- package/runtime/sdk/g2/Node2D.ts +0 -267
- package/runtime/sdk/g2/OneWay2D.ts +0 -66
- package/runtime/sdk/g2/Physics2D.ts +0 -346
- package/runtime/sdk/g2/Scene2D.ts +0 -209
- package/runtime/sdk/g2/Shape2D.ts +0 -259
- package/runtime/sdk/g2/Sprite.ts +0 -89
- package/runtime/sdk/g2/SpriteAnimation.ts +0 -171
- package/runtime/sdk/g2/SpriteSheet.ts +0 -166
- package/runtime/sdk/g2/Texture2D.ts +0 -47
- package/runtime/sdk/g2/Tilemap.ts +0 -41
- package/runtime/sdk/g2/Tileset.ts +0 -71
- package/runtime/sdk/g2/Trigger2D.ts +0 -77
- package/runtime/sdk/g2/autotile.ts +0 -433
- package/runtime/sdk/g2/cells.ts +0 -91
- package/runtime/sdk/g2/defineScene2d.ts +0 -381
- package/runtime/sdk/g2/groups2d.ts +0 -106
- package/runtime/sdk/g2/loop.ts +0 -50
- package/runtime/sdk/g2/scenarios2d.ts +0 -69
- package/runtime/sdk/g2/touch.ts +0 -83
- package/runtime/sdk/gl/Camera.ts +0 -160
- package/runtime/sdk/gl/CameraPlace.ts +0 -52
- package/runtime/sdk/gl/CharacterController.ts +0 -238
- package/runtime/sdk/gl/Gearbox.ts +0 -212
- package/runtime/sdk/gl/Geometry.ts +0 -279
- package/runtime/sdk/gl/IK.ts +0 -193
- package/runtime/sdk/gl/InstancedMesh.ts +0 -132
- package/runtime/sdk/gl/Light.ts +0 -107
- package/runtime/sdk/gl/Lightmap.ts +0 -256
- package/runtime/sdk/gl/Material.ts +0 -260
- package/runtime/sdk/gl/Mesh.ts +0 -83
- package/runtime/sdk/gl/Model.ts +0 -124
- package/runtime/sdk/gl/NavAgent.ts +0 -337
- package/runtime/sdk/gl/NavMesh.ts +0 -397
- package/runtime/sdk/gl/Node.ts +0 -350
- package/runtime/sdk/gl/Noise.ts +0 -30
- package/runtime/sdk/gl/Particles.ts +0 -676
- package/runtime/sdk/gl/Physics.ts +0 -222
- package/runtime/sdk/gl/Plane.ts +0 -53
- package/runtime/sdk/gl/Ragdoll.ts +0 -270
- package/runtime/sdk/gl/Ray.ts +0 -16
- package/runtime/sdk/gl/Scene.ts +0 -486
- package/runtime/sdk/gl/Shape.ts +0 -409
- package/runtime/sdk/gl/Terrain.ts +0 -1092
- package/runtime/sdk/gl/Texture.ts +0 -63
- package/runtime/sdk/gl/Trigger.ts +0 -45
- package/runtime/sdk/gl/Vehicle.ts +0 -473
- package/runtime/sdk/gl/Wheel.ts +0 -240
- package/runtime/sdk/gl/animation/AnimationClip.ts +0 -204
- package/runtime/sdk/gl/animation/Animator.ts +0 -120
- package/runtime/sdk/gl/animation/Layer.ts +0 -31
- package/runtime/sdk/gl/animation/Loop.ts +0 -30
- package/runtime/sdk/gl/animation/Playback.ts +0 -44
- package/runtime/sdk/gl/animation/core.ts +0 -336
- package/runtime/sdk/gl/controls.ts +0 -95
- package/runtime/sdk/gl/physicsEvents.ts +0 -20
- package/runtime/sdk/gl/scenarios.ts +0 -291
- package/runtime/sdk/gl/state.ts +0 -6
- package/runtime/sdk/gl/terrainMesh.ts +0 -219
- package/runtime/sdk/gl/touch.ts +0 -68
- package/runtime/sdk/inject.ts +0 -197
- package/runtime/sdk/math/Mathf.ts +0 -118
- package/runtime/sdk/math/mat4.ts +0 -278
- package/runtime/sdk/math/quat.ts +0 -232
- package/runtime/sdk/math/vec.ts +0 -255
- package/runtime/sdk/net/codec.ts +0 -119
- package/runtime/sdk/net/core.ts +0 -384
- package/runtime/sdk/net/index.ts +0 -181
- package/runtime/sdk/net/replication.ts +0 -622
- package/runtime/sdk/plugins/camera.ts +0 -81
- package/runtime/sdk/plugins/geolocation.ts +0 -123
- package/runtime/sdk/plugins/oauth.ts +0 -61
- package/runtime/sdk/plugins/permission.ts +0 -7
- package/runtime/sdk/plugins/push.ts +0 -132
- package/runtime/sdk/plugins/qr.ts +0 -73
- package/runtime/sdk/plugins/service.ts +0 -47
- package/runtime/sdk/runtime/app.ts +0 -101
- package/runtime/sdk/runtime/appEvents.ts +0 -54
- package/runtime/sdk/runtime/channel.ts +0 -61
- package/runtime/sdk/runtime/clipboard.ts +0 -20
- package/runtime/sdk/runtime/datetime.ts +0 -329
- package/runtime/sdk/runtime/device.ts +0 -293
- package/runtime/sdk/runtime/fetch.ts +0 -77
- package/runtime/sdk/runtime/files.ts +0 -23
- package/runtime/sdk/runtime/input.ts +0 -175
- package/runtime/sdk/runtime/media.ts +0 -111
- package/runtime/sdk/runtime/misc.ts +0 -16
- package/runtime/sdk/runtime/net.ts +0 -36
- package/runtime/sdk/runtime/rpc.ts +0 -218
- package/runtime/sdk/runtime/service.ts +0 -83
- package/runtime/sdk/runtime/share.ts +0 -9
- package/runtime/sdk/runtime/storage.ts +0 -13
- package/runtime/sdk/runtime/touch.ts +0 -76
- package/runtime/sdk/scene/defineScene.ts +0 -1353
- package/runtime/sdk/scene/editorPlugins.ts +0 -110
- package/runtime/sdk/scene/gizmos.ts +0 -148
- package/runtime/sdk/scene/grammar.ts +0 -120
- package/runtime/sdk/scene/material.ts +0 -188
- package/runtime/sdk/server/auth/appConfig.ts +0 -12
- package/runtime/sdk/server/auth/global.ts +0 -80
- package/runtime/sdk/server/auth/host.ts +0 -318
- package/runtime/sdk/server/auth/models.ts +0 -83
- package/runtime/sdk/server/auth/types.ts +0 -50
- package/runtime/sdk/server/channel.ts +0 -56
- package/runtime/sdk/server/context.ts +0 -36
- package/runtime/sdk/server/db/defineDb.ts +0 -237
- package/runtime/sdk/server/db/fields.ts +0 -132
- package/runtime/sdk/server/db/httpTransport.ts +0 -93
- package/runtime/sdk/server/db/index.ts +0 -7
- package/runtime/sdk/server/db/marci/query.ts +0 -412
- package/runtime/sdk/server/db/types.ts +0 -202
- package/runtime/sdk/server/errors.ts +0 -12
- package/runtime/sdk/server/host.ts +0 -74
- package/runtime/sdk/server/inject.ts +0 -13
- package/runtime/sdk/server/runtime.ts +0 -133
- package/runtime/sdk/server/validate.ts +0 -87
- package/runtime/sdk/ui/NativeView.ts +0 -142
- package/runtime/sdk/ui/UI.ts +0 -39
- package/runtime/sdk/ui/UIBottomSheet.ts +0 -139
- package/runtime/sdk/ui/UIButton.ts +0 -101
- package/runtime/sdk/ui/UIContainer.ts +0 -60
- package/runtime/sdk/ui/UIImage.ts +0 -83
- package/runtime/sdk/ui/UIInput.ts +0 -185
- package/runtime/sdk/ui/UIModal.ts +0 -139
- package/runtime/sdk/ui/UINode.ts +0 -830
- package/runtime/sdk/ui/UIPager.ts +0 -362
- package/runtime/sdk/ui/UIPopover.ts +0 -100
- package/runtime/sdk/ui/UIScreen.ts +0 -123
- package/runtime/sdk/ui/UIScrollable.ts +0 -87
- package/runtime/sdk/ui/UISpacer.ts +0 -14
- package/runtime/sdk/ui/UITabs.ts +0 -236
- package/runtime/sdk/ui/UIText.ts +0 -51
- package/runtime/sdk/ui/UIVideo.ts +0 -88
- package/runtime/sdk/ui/UIVirtualizedList.ts +0 -241
- package/runtime/sdk/ui/UIWidget.ts +0 -127
- package/runtime/sdk/ui/fonts.ts +0 -13
- package/runtime/sdk/ui/presentable.ts +0 -117
- package/runtime/sdk/ui/router.ts +0 -132
- package/runtime/sdk/ui/theme.ts +0 -84
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { TouchStartEvent } from "../runtime/touch"
|
|
2
|
-
import { _descOf, _navSupported, Presentable } from "./presentable"
|
|
3
|
-
import { ContainerElement, buildUI, type BaseStyle, type Color, type ContainerStyle, type DrawableStyle, type PaddingStyle, type PositionStyle, type UIChildArg, type UIContainerBase, type UINodeChild, type ChildrenFn } from "./UINode"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export type UIWidgetStyle = ContainerStyle & DrawableStyle & PaddingStyle & BaseStyle & PositionStyle & {
|
|
7
|
-
/** A layer behind the widget that intercepts clicks — `"transparent"` still intercepts, `null`
|
|
8
|
-
* removes the layer. A tap on it fires `onOverlayTap`. */
|
|
9
|
-
overlayColor?: Color | null
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
/** A floating overlay — absolutely positioned in device coordinates, mounted above the page as
|
|
14
|
-
* its own layout root (never a child of what's underneath). The base of dialogs, toasts,
|
|
15
|
-
* mini-players and scene HUDs; `UIModal`/`UIPopover`/`UIBottomSheet` build on it. */
|
|
16
|
-
export interface UIWidget extends UIContainerBase<UIWidgetStyle, DrawableStyle & BaseStyle & { overlayColor?: Color | null }> {
|
|
17
|
-
readonly type: "widget",
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Attach this widget to a destination (a `Scene`, a `UIScreen`, …): the widget lives on that
|
|
21
|
-
* page's layer — it shows/hides with the page and rides its transition, and a screen pushed
|
|
22
|
-
* on top covers it (a scene HUD behaves like part of the scene). Sticky until `attachTo(null)`
|
|
23
|
-
* (= back to a global overlay). Set it while the widget is hidden. The widget is always its own
|
|
24
|
-
* overlay root mounted into the owner's page view — it never becomes a child of the owner, so it
|
|
25
|
-
* stays topmost and its updates never trigger the owner's relayout. Works with a `UIScreen` that
|
|
26
|
-
* is a page inside a `UIPager`: the widget mounts into that tab and rides its swipe. (Web shows
|
|
27
|
-
* and hides it with the owner but does not yet ride the transition.)
|
|
28
|
-
*/
|
|
29
|
-
attachTo(owner: Presentable | null): this,
|
|
30
|
-
|
|
31
|
-
/** Show the widget. By default it is a global overlay above every destination — it stays
|
|
32
|
-
* visible across navigation until `hide()` (dialogs, mini-player, global loader). If the
|
|
33
|
-
* widget was attached via `attachTo(owner)`, it mounts on that page's layer instead and is
|
|
34
|
-
* only visible while the owner is presented. */
|
|
35
|
-
show(): void,
|
|
36
|
-
/** Unmount the widget. */
|
|
37
|
-
hide(): void,
|
|
38
|
-
|
|
39
|
-
/** Mounted right now (`show()` ran, `hide()` hasn't). */
|
|
40
|
-
readonly isShow: boolean,
|
|
41
|
-
|
|
42
|
-
/** Touch began on the widget; `ev.track(...)` takes over the rest of the gesture. */
|
|
43
|
-
onTouchStart(callback: (ev: TouchStartEvent<UIWidget>) => void): this,
|
|
44
|
-
/** Tap on the overlay layer (requires an `overlayColor`). */
|
|
45
|
-
onOverlayTap(callback: () => void): this,
|
|
46
|
-
/** Hardware/system back while the widget is shown. */
|
|
47
|
-
onBackPressed(callback: () => void): this
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
export class WidgetElement extends ContainerElement<"widget"> {
|
|
52
|
-
scrollable = false as const
|
|
53
|
-
_owner?: Presentable
|
|
54
|
-
constructor(type: "widget", style: UIWidgetStyle, children: UINodeChild[] | ChildrenFn) {
|
|
55
|
-
// Widgets are absolutely positioned in device coordinates — in the constructor (not the
|
|
56
|
-
// factory) so subclasses like ModalElement inherit it.
|
|
57
|
-
super(type, { position: "absolute", ...style }, children)
|
|
58
|
-
}
|
|
59
|
-
attachTo(owner: Presentable | null): this {
|
|
60
|
-
this._owner = owner ?? undefined
|
|
61
|
-
return this
|
|
62
|
-
}
|
|
63
|
-
show(): void {
|
|
64
|
-
// A widget is always its OWN overlay root (a separate Yoga tree mounted above the owner's
|
|
65
|
-
// content) — never a child of the owner, so it stays topmost, its updates never relayout the
|
|
66
|
-
// owner, and it doesn't pollute the owner's children. `attachTo(owner)` just tells the host
|
|
67
|
-
// which page view to mount that root into; ownerless widgets are global overlays.
|
|
68
|
-
if (this._owner && _navSupported()) {
|
|
69
|
-
_creatorUI.showWidget(this, _descOf(this._owner))
|
|
70
|
-
} else {
|
|
71
|
-
// Unattached (or legacy host): global overlay above navigation.
|
|
72
|
-
_creatorUI.showWidget(this)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
hide(): void {
|
|
76
|
-
_creatorUI.hideWidget(this)
|
|
77
|
-
}
|
|
78
|
-
get isShow(): boolean {
|
|
79
|
-
return this._id !== 0
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
_interactive = false
|
|
83
|
-
readonly touchStartListeners: any[] = []
|
|
84
|
-
onTouchStart (callback: any): this {
|
|
85
|
-
this._interactive = true
|
|
86
|
-
this.touchStartListeners.push(callback)
|
|
87
|
-
return this
|
|
88
|
-
}
|
|
89
|
-
_emitTouchStart(pointerId: number, clientX: number, clientY: number): any {
|
|
90
|
-
const touchEvent = new TouchStartEvent(clientX, clientY, pointerId)
|
|
91
|
-
touchEvent.target = this
|
|
92
|
-
for (let callback of this.touchStartListeners) {
|
|
93
|
-
callback(touchEvent)
|
|
94
|
-
if ((touchEvent as any)._trackHandler) {
|
|
95
|
-
return (touchEvent as any)._trackHandler
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return null
|
|
99
|
-
}
|
|
100
|
-
readonly otl: (() => void)[] = []
|
|
101
|
-
onOverlayTap(callback: () => void): this {
|
|
102
|
-
this.otl.push(callback)
|
|
103
|
-
return this
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
_backButtonCallback?: () => void
|
|
107
|
-
onBackPressed(callback: any): this {
|
|
108
|
-
this._backButtonCallback = callback
|
|
109
|
-
return this
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const makeWidget = (style: any, children: any) => new WidgetElement("widget", style, children)
|
|
115
|
-
|
|
116
|
-
/** @internal Compiler fast path (chisel `flatten_ui` raw lowering) — see UIContainer. */
|
|
117
|
-
export const __UIWidget = (children: UINodeChild[] | ChildrenFn): UIWidget => makeWidget({}, children)
|
|
118
|
-
|
|
119
|
-
/** Create a widget (same argument forms as `UIColumn`). Position it with absolute-style props
|
|
120
|
-
* (`top`/`left`/`bottom`/`right`), then `show()`/`hide()`. */
|
|
121
|
-
export function UIWidget(...children: UIChildArg[]): UIWidget;
|
|
122
|
-
export function UIWidget(children: UINodeChild[] | ChildrenFn): UIWidget;
|
|
123
|
-
/** @deprecated Style as the first argument is legacy — use chained `.style({...})`. */
|
|
124
|
-
export function UIWidget(style: UIWidgetStyle, children?: UINodeChild[] | ChildrenFn): UIWidget;
|
|
125
|
-
export function UIWidget(...args: any[]): UIWidget {
|
|
126
|
-
return buildUI(args, null, makeWidget)
|
|
127
|
-
}
|
package/runtime/sdk/ui/fonts.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
type FontOptions = {
|
|
2
|
-
weight?: number,
|
|
3
|
-
style?: "normal" | "italic"
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
/** Register a font face from a URL at runtime under `fontFamily`; resolves once it's ready to
|
|
7
|
-
* use in styles. For registry/project fonts prefer the compile-time `font()` macro — this is the
|
|
8
|
-
* dynamic escape hatch. */
|
|
9
|
-
export async function registerFont (fontFamily: string, url: string, options: FontOptions = {}): Promise<void> {
|
|
10
|
-
return new Promise<void>((res, rej) => {
|
|
11
|
-
_creatorUI.registerFont(fontFamily, url, options, res, rej)
|
|
12
|
-
})
|
|
13
|
-
}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
// The Presentable contract — the one navigation model (docs/navigation-presentable-plan.md).
|
|
2
|
-
// Anything that can occupy the app's main slot implements it: UIScreen, Scene (+ARScene),
|
|
3
|
-
// Scene2D, NativeView, UIVideo. Exactly one Presentable is visible at a time — a screen no
|
|
4
|
-
// longer overlays a scene, it replaces it (with a transition); UI over a scene goes through
|
|
5
|
-
// `UIWidget.attachTo(scene)`.
|
|
6
|
-
//
|
|
7
|
-
// This module is dependency-free on purpose: gl/ and g2/ import it, so it must not pull any UI
|
|
8
|
-
// element code into engine-only bundles.
|
|
9
|
-
|
|
10
|
-
/** Built-in transition catalog. `push`/`pop` are the stacked-navigation pair (slide + parallax +
|
|
11
|
-
* dim + edge shadow); the rest are simple two-view moves. */
|
|
12
|
-
export type TransitionName =
|
|
13
|
-
| "push" | "pop"
|
|
14
|
-
| "slide-from-left" | "slide-from-right" | "slide-from-top" | "slide-from-bottom"
|
|
15
|
-
| "zoom" | "zoom-in" | "zoom-out" | "fade" | "none"
|
|
16
|
-
|
|
17
|
-
/** Start/end pose of one side of a custom transition. `x`/`y` are logical px, or a percentage of
|
|
18
|
-
* the destination's size (e.g. `"100%"` = one full width to the right). */
|
|
19
|
-
export type TransitionTransform = {
|
|
20
|
-
x?: number | `${number}%`
|
|
21
|
-
y?: number | `${number}%`
|
|
22
|
-
scale?: number
|
|
23
|
-
opacity?: number
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* A custom transition: declarative poses for the incoming/outgoing destination, played natively.
|
|
28
|
-
* Serializes onto each platform's existing transition machinery — there is no per-frame JS.
|
|
29
|
-
* Fields omitted keep the identity pose. Interactive back-swipe stays system-native (push/pop
|
|
30
|
-
* only); a spec applies to non-interactive transitions.
|
|
31
|
-
*/
|
|
32
|
-
export interface TransitionSpec {
|
|
33
|
-
/** Duration in ms (default 300). */
|
|
34
|
-
duration?: number
|
|
35
|
-
/** cubic-bezier control points (default ease-out). */
|
|
36
|
-
easing?: [number, number, number, number]
|
|
37
|
-
/** The entering destination animates FROM this pose to identity. */
|
|
38
|
-
incoming?: { from?: TransitionTransform }
|
|
39
|
-
/** The leaving destination animates from identity TO this pose. */
|
|
40
|
-
outgoing?: { to?: TransitionTransform }
|
|
41
|
-
/** Scrim alpha (0..1) painted over whichever destination is underneath. */
|
|
42
|
-
dim?: number
|
|
43
|
-
/** Which side stacks on top during the animation (default "incoming"). On Android, transitions
|
|
44
|
-
* involving a scene always animate the screen side on top — the scene view itself never moves. */
|
|
45
|
-
onTop?: "incoming" | "outgoing"
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export type Transition = TransitionName | TransitionSpec
|
|
49
|
-
|
|
50
|
-
export type PresentOptions = {
|
|
51
|
-
/** Transition to play while this destination replaces the current one (default "none" for a
|
|
52
|
-
* direct open(); the Router applies its own defaults — push/pop, and the theme's
|
|
53
|
-
* `replaceTransition` for replace). */
|
|
54
|
-
transition?: Transition
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Anything that can be shown as the app's current destination: a `UIScreen`, a `Scene` /
|
|
59
|
-
* `ARScene`, a `Scene2D`, a `NativeView`, or a `UIVideo`. One Presentable is visible at a time;
|
|
60
|
-
* open it directly (`p.open()` — replaces the current destination, suspending an active Router
|
|
61
|
-
* until `Router.restore()`) or navigate with `Router.push/replace/pop`.
|
|
62
|
-
*
|
|
63
|
-
* `onOpen`/`onClose` are the presentation lifecycle (fired when the destination becomes / stops
|
|
64
|
-
* being the visible one — including router pushes covering it and pops revealing it).
|
|
65
|
-
*/
|
|
66
|
-
export interface Presentable {
|
|
67
|
-
// Return type covers the implementers: UIScreen → void, Scene2D → this, ARScene → Promise.
|
|
68
|
-
open(options?: PresentOptions): void | this | Promise<void>
|
|
69
|
-
close(): void
|
|
70
|
-
onOpen(callback: () => void): this
|
|
71
|
-
onClose(callback: () => void): this
|
|
72
|
-
onBackPressed(callback: () => void): this
|
|
73
|
-
/** @internal Async work that must finish BEFORE this destination replaces the current one
|
|
74
|
-
* (camera permission, warm render, session launch — ARScene). The previous destination —
|
|
75
|
-
* typically a loading screen — stays visible while it runs; `open()` and `Router.push/replace`
|
|
76
|
-
* await it and skip the swap entirely if it rejects (permission denied, or superseded by
|
|
77
|
-
* another navigation that happened while preparing). */
|
|
78
|
-
_prepare?(): Promise<void>
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// The destination visible right now. Set optimistically by every successful open()/router
|
|
82
|
-
// navigation, cleared by close(), and corrected by router onChange (hosts hand the wire desc
|
|
83
|
-
// back on every stack change, including back gestures — `_p` resolves it to the SDK instance).
|
|
84
|
-
let current: Presentable | null = null
|
|
85
|
-
/** @internal Call whenever the visible destination changes. */
|
|
86
|
-
export const _setCurrent = (p: Presentable | null): void => { current = p }
|
|
87
|
-
|
|
88
|
-
/** Runtime companion of the `Presentable` interface (declaration merging): the navigation
|
|
89
|
-
* state that isn't tied to the Router. */
|
|
90
|
-
export const Presentable = /*#__PURE__*/ Object.freeze({
|
|
91
|
-
/** The destination visible right now (a `UIScreen`, `Scene`, `Scene2D`, `NativeView` or
|
|
92
|
-
* `UIVideo`), or `null` before the first open. Distinct from `Router.current` — that is the
|
|
93
|
-
* top of the router stack, which stays meaningful while the router is suspended by a direct
|
|
94
|
-
* `open()`; this is what is actually on screen. `UIWidget.show()` attaches to it. */
|
|
95
|
-
get current(): Presentable | null { return current },
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
// Monotonic navigation epoch: every destination change (open/close/router nav) bumps it. Async
|
|
99
|
-
// preparers capture the epoch before their awaits and reject as "superseded" if it moved — so a
|
|
100
|
-
// slow AR prepare can't steal the screen from a navigation the user made in the meantime.
|
|
101
|
-
let navEpoch = 0
|
|
102
|
-
/** @internal */
|
|
103
|
-
export const _navEpoch = (): number => navEpoch
|
|
104
|
-
/** @internal Call on every action that changes the visible destination. */
|
|
105
|
-
export const _bumpNavEpoch = (): void => { navEpoch++ }
|
|
106
|
-
|
|
107
|
-
/** @internal Does this host implement the Presentable navigation surface? The SDK falls back to
|
|
108
|
-
* the legacy openScreen/openScene bridges when it doesn't (screens keep working; scene/native
|
|
109
|
-
* destinations in the Router then throw). */
|
|
110
|
-
export const _navSupported = (): boolean =>
|
|
111
|
-
typeof _creatorUI !== "undefined" && typeof _creatorUI.openView === "function"
|
|
112
|
-
|
|
113
|
-
/** @internal The wire descriptor for a Presentable. Screens (and anything without `_viewDesc`)
|
|
114
|
-
* travel as themselves; scenes/native views/video provide a stable descriptor object carrying
|
|
115
|
-
* `_p` (the SDK instance) so hosts can hand it back through router onChange / lifecycle. */
|
|
116
|
-
export const _descOf = (p: Presentable): object =>
|
|
117
|
-
typeof (p as any)._viewDesc === "function" ? (p as any)._viewDesc() : (p as object)
|
package/runtime/sdk/ui/router.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { _bumpNavEpoch, _descOf, _navSupported, _setCurrent, Presentable, type Transition } from "./presentable"
|
|
2
|
-
import { _navDefaults } from "./theme"
|
|
3
|
-
|
|
4
|
-
type RouterOptions = {
|
|
5
|
-
showDefaultBackButton?: boolean
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
type NavigateOptions = {
|
|
9
|
-
/** Transition to play. Defaults: `"push"` for push, `"pop"` for pop; replace follows the
|
|
10
|
-
* theme's `replaceTransition` (`"none"` out of the box). */
|
|
11
|
-
transition?: Transition
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** Stack navigation over `Presentable` destinations. `init` once with the home page, then
|
|
15
|
-
* `push`/`replace`/`pop`; the back gesture/button pops natively. A direct `page.open()` suspends
|
|
16
|
-
* the router until `restore()`. */
|
|
17
|
-
type Router = {
|
|
18
|
-
/** The top of the router stack (not necessarily what's on screen — see `Presentable.current`). */
|
|
19
|
-
get current(): Presentable
|
|
20
|
-
/** Mount the router with `homePage` as the stack root — the app's navigation entry point. */
|
|
21
|
-
init(homePage: Presentable, opts?: RouterOptions): void
|
|
22
|
-
/** Push a destination onto the stack — a `UIScreen`, a `Scene`, a `Scene2D`, a `NativeView`,
|
|
23
|
-
* or a `UIVideo`. The back gesture/button pops it. Destinations with async preparation
|
|
24
|
-
* (`ARScene`: camera permission + warm render) return a Promise — the current page stays
|
|
25
|
-
* visible until they're ready, and a rejection (permission denied / superseded) leaves the
|
|
26
|
-
* stack untouched. */
|
|
27
|
-
push(page: Presentable, opts?: NavigateOptions): void | Promise<void>
|
|
28
|
-
/** Swap the top of the stack for `page` — no back entry to the replaced one. */
|
|
29
|
-
replace(page: Presentable, opts?: NavigateOptions): void | Promise<void>
|
|
30
|
-
/** Pop the top destination (the programmatic twin of the back gesture); `to` unwinds to a
|
|
31
|
-
* stack index in one step. */
|
|
32
|
-
pop(to?: number, opts?: NavigateOptions): void
|
|
33
|
-
/** Blank the router's page, keeping the stack — `restore()` brings it back. A destination
|
|
34
|
-
* opened directly stays visible. */
|
|
35
|
-
hide(): void
|
|
36
|
-
/** Re-present the stack top after `hide()` or a direct `open()` suspended the router. */
|
|
37
|
-
restore(): void
|
|
38
|
-
|
|
39
|
-
/** `"change"` fires on every stack change — pushes, pops, and native back gestures — with the
|
|
40
|
-
* new top destination. */
|
|
41
|
-
addEventListener(channel: "change", callback: (page: Presentable) => void): void
|
|
42
|
-
removeEventListener(channel: "change", callback: (page: Presentable) => void): void
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
let currentPage: Presentable | null = null
|
|
46
|
-
let onChange = (page: any) => {
|
|
47
|
-
// Hosts hand back the wire object: the screen itself, or a descriptor carrying `_p`.
|
|
48
|
-
currentPage = page && page._p ? page._p : page
|
|
49
|
-
// The router's page is the visible destination (hosts fire this on every stack change,
|
|
50
|
-
// including back gestures) — keep Presentable.current in sync.
|
|
51
|
-
_setCurrent(currentPage)
|
|
52
|
-
for (let callback of (Router as any)._changeListeners) {
|
|
53
|
-
callback(currentPage)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Non-screen destinations have no legacy bridge to fall back to — surface that clearly instead
|
|
58
|
-
// of letting an old host try to build a screen out of a scene descriptor.
|
|
59
|
-
const wireDesc = (page: Presentable): object => {
|
|
60
|
-
const desc = _descOf(page)
|
|
61
|
-
if (desc !== page && !_navSupported()) {
|
|
62
|
-
throw new Error("This host does not support scene/native-view navigation (requires _creatorUI.openView)")
|
|
63
|
-
}
|
|
64
|
-
return desc
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export const Router: Router = /*#__PURE__*/ Object.freeze({
|
|
68
|
-
|
|
69
|
-
init(homePage: Presentable, opts: RouterOptions = {}): void {
|
|
70
|
-
_bumpNavEpoch()
|
|
71
|
-
_creatorUI.routerOpen(wireDesc(homePage), onChange, opts.showDefaultBackButton ?? false)
|
|
72
|
-
currentPage = homePage
|
|
73
|
-
_setCurrent(homePage)
|
|
74
|
-
},
|
|
75
|
-
push(page: Presentable, opts?: NavigateOptions): void | Promise<void> {
|
|
76
|
-
const desc = wireDesc(page) // throws early on unsupported hosts, before any async work
|
|
77
|
-
const go = () => {
|
|
78
|
-
_bumpNavEpoch()
|
|
79
|
-
// Legacy hosts ignore the extra transition argument.
|
|
80
|
-
_creatorUI.routerPush(desc, opts?.transition ?? "push")
|
|
81
|
-
_setCurrent(page) // optimistic — host onChange confirms (async on native hosts)
|
|
82
|
-
}
|
|
83
|
-
// A preparing destination (ARScene) keeps the current page visible until it's ready; a
|
|
84
|
-
// rejection (camera denied / superseded) propagates to the caller and nothing is pushed.
|
|
85
|
-
const prep = page._prepare?.()
|
|
86
|
-
return prep ? prep.then(go) : go()
|
|
87
|
-
},
|
|
88
|
-
replace(page: Presentable, opts?: NavigateOptions): void | Promise<void> {
|
|
89
|
-
const desc = wireDesc(page)
|
|
90
|
-
const go = () => {
|
|
91
|
-
_bumpNavEpoch()
|
|
92
|
-
_creatorUI.routerReplace(desc, opts?.transition ?? _navDefaults.replace)
|
|
93
|
-
_setCurrent(page) // optimistic — host onChange confirms (async on native hosts)
|
|
94
|
-
}
|
|
95
|
-
const prep = page._prepare?.()
|
|
96
|
-
return prep ? prep.then(go) : go()
|
|
97
|
-
},
|
|
98
|
-
pop(to?: number, opts?: NavigateOptions): void {
|
|
99
|
-
_bumpNavEpoch()
|
|
100
|
-
_creatorUI.routerPop(to ?? -1, opts?.transition ?? "pop")
|
|
101
|
-
},
|
|
102
|
-
hide() {
|
|
103
|
-
_bumpNavEpoch()
|
|
104
|
-
_creatorUI.routerHide()
|
|
105
|
-
// hide() only blanks the router's own page — a directly-opened destination stays visible.
|
|
106
|
-
if (Presentable.current === currentPage) _setCurrent(null)
|
|
107
|
-
},
|
|
108
|
-
restore() {
|
|
109
|
-
_bumpNavEpoch()
|
|
110
|
-
_creatorUI.routerRestore()
|
|
111
|
-
_setCurrent(currentPage) // the stack top is visible again
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
get current(): Presentable {
|
|
115
|
-
return currentPage!
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
_changeListeners: [] as any[],
|
|
119
|
-
addEventListener(channel: "change", callback: (page: Presentable) => void): void {
|
|
120
|
-
if (channel === "change") {
|
|
121
|
-
this._changeListeners.push(callback)
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
removeEventListener(channel: "change", callback: (page: Presentable) => void): void {
|
|
125
|
-
if (channel === "change") {
|
|
126
|
-
let index = this._changeListeners.indexOf(callback)
|
|
127
|
-
if (index >= 0) {
|
|
128
|
-
this._changeListeners.splice(index, 1)
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
})
|
package/runtime/sdk/ui/theme.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// theme() — app theme variables (docs/ui-theme-plan.md). One global var table lives in the UI
|
|
2
|
-
// core; `var(--key)` references resolve at style-apply time, so re-calling theme() re-styles the
|
|
3
|
-
// LIVE UI. Bare style tokens (`pt: "comfort-top"`) are keywords that may expand to formulas
|
|
4
|
-
// (max(safe-top, knob)); `var(--comfort-top)` always reads the raw table value.
|
|
5
|
-
|
|
6
|
-
import type { Transition } from "./presentable"
|
|
7
|
-
|
|
8
|
-
export type ThemeValues = Record<string, string | number | null>
|
|
9
|
-
|
|
10
|
-
/** @internal Navigation defaults the theme owns; the router reads them at call time.
|
|
11
|
-
* (SDK-side state, deliberately NOT in the host var table — `var(--replaceTransition)`
|
|
12
|
-
* is not a style value.) */
|
|
13
|
-
export const _navDefaults: { replace: Transition } = { replace: "none" }
|
|
14
|
-
|
|
15
|
-
// (Unconstrained: it also maps inputs whose `replaceTransition` key was carved out.)
|
|
16
|
-
export type ThemeAccessors<T> = {
|
|
17
|
-
readonly [K in keyof T]: K extends string ? `var(--${K})` : never
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const RESERVED = ["safe-top", "safe-bottom", "safe-left", "safe-right", "vw", "vh", "vmin", "vmax"]
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Merge app theme variables into the live table and get typed `var(--key)` accessors back:
|
|
24
|
-
*
|
|
25
|
-
* ```ts
|
|
26
|
-
* export const T = theme({ primaryColor: "#0A84FF", cardBg: "#1C1C1E" })
|
|
27
|
-
* card.style({ bgColor: T.cardBg }) // T.cardBg === "var(--cardBg)"
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* Strings pass through (colors, fonts, expressions like `"max(safe-top, 24px)"`); numbers are
|
|
31
|
-
* lengths (px); `null` removes a key (comfort knobs reset to their defaults). Env names
|
|
32
|
-
* (`safe-*`, `vw`/`vh`/…) are host-owned — skipped with a warning. One special key:
|
|
33
|
-
* `replaceTransition` — the app-wide default transition for `Router.replace` (consumed SDK-side,
|
|
34
|
-
* never sent to the host table).
|
|
35
|
-
*/
|
|
36
|
-
const setTheme = <T extends Record<string, string | number | Transition | null>>(
|
|
37
|
-
// Only `replaceTransition` may carry a Transition — every other key is a style value.
|
|
38
|
-
values: T & { [K in Exclude<keyof T, "replaceTransition">]: string | number | null }
|
|
39
|
-
): ThemeAccessors<Omit<T, "replaceTransition">> => {
|
|
40
|
-
const accessors: Record<string, string> = {}
|
|
41
|
-
let send = values as ThemeValues
|
|
42
|
-
const strip = (key: string) => {
|
|
43
|
-
if (send === values) send = { ...values } as ThemeValues
|
|
44
|
-
delete send[key]
|
|
45
|
-
}
|
|
46
|
-
for (const key of Object.keys(values)) {
|
|
47
|
-
if (key === "replaceTransition") {
|
|
48
|
-
_navDefaults.replace = (values[key] ?? "none") as Transition
|
|
49
|
-
strip(key) // SDK-consumed, no accessor: it isn't a style var
|
|
50
|
-
continue
|
|
51
|
-
}
|
|
52
|
-
if (RESERVED.includes(key)) {
|
|
53
|
-
console.warn(`theme(): "${key}" is an environment value (host-owned) — ignored`)
|
|
54
|
-
strip(key)
|
|
55
|
-
continue
|
|
56
|
-
}
|
|
57
|
-
accessors[key] = `var(--${key})`
|
|
58
|
-
}
|
|
59
|
-
// Optional during rollout: hosts without the method simply don't theme (values still type).
|
|
60
|
-
if (Object.keys(send).length > 0) _creatorUI.setTheme?.(send)
|
|
61
|
-
return accessors as ThemeAccessors<Omit<T, "replaceTransition">>
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** App theme: callable to merge variables (`theme({...})` — re-calling re-styles the live UI, so
|
|
65
|
-
* dark mode is just a second call), with the system vars as static properties
|
|
66
|
-
* (`theme.primaryColor`, `theme["comfort-top"]`, …). */
|
|
67
|
-
export const theme = Object.assign(setTheme, {
|
|
68
|
-
/** The app accent color. Kit components will read it via `var(--primaryColor, <fallback>)`. */
|
|
69
|
-
primaryColor: "var(--primaryColor)",
|
|
70
|
-
/** Secondary / inactive content color for kit components. */
|
|
71
|
-
mutedColor: "var(--mutedColor)",
|
|
72
|
-
/** DEFAULT text color — text without an explicit `color` follows it (hosts source their
|
|
73
|
-
* default from the theme; unset = the host default, white on dark screens). Set it once for
|
|
74
|
-
* a light theme instead of `color: "black"` on every label. */
|
|
75
|
-
color: "var(--color)",
|
|
76
|
-
/** DEFAULT text font — text without an explicit `fontFamily` follows it. */
|
|
77
|
-
fontFamily: "var(--fontFamily)",
|
|
78
|
-
/** Raw comfort knobs (logical px). The bare `comfort-top` style TOKEN applies the safe-area
|
|
79
|
-
* formula — these accessors read the knob value itself, for manual composition. */
|
|
80
|
-
"comfort-top": "var(--comfort-top)",
|
|
81
|
-
"comfort-bottom": "var(--comfort-bottom)",
|
|
82
|
-
"comfort-left": "var(--comfort-left)",
|
|
83
|
-
"comfort-right": "var(--comfort-right)",
|
|
84
|
-
} as const)
|