lecodes-sdk 2.0.7 → 2.0.9

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.
Files changed (68) hide show
  1. package/dist/global.d.ts +6 -0
  2. package/dist/types/g2/Scene2D.d.ts +4 -0
  3. package/dist/types/gl/Light.d.ts +36 -1
  4. package/dist/types/gl/Scene.d.ts +4 -0
  5. package/dist/types/inject.d.ts +2 -1
  6. package/dist/types/runtime/rpc.d.ts +2 -0
  7. package/dist/types/server/context.d.ts +4 -0
  8. package/dist/types/server/db/defineDb.d.ts +1 -1
  9. package/dist/types/server/db/fields.d.ts +25 -1
  10. package/dist/types/server/db/marci/query.d.ts +39 -2
  11. package/dist/types/server/db/types.d.ts +13 -7
  12. package/dist/types/server/files/db.d.ts +39 -0
  13. package/dist/types/server/files/models.d.ts +131 -0
  14. package/dist/types/server/inject.d.ts +1 -0
  15. package/dist/types/ui/NativeView.d.ts +3 -0
  16. package/dist/types/ui/UI.d.ts +1 -0
  17. package/dist/types/ui/UILayer.d.ts +25 -0
  18. package/dist/types/ui/UIModal.d.ts +20 -16
  19. package/dist/types/ui/UIPopover.d.ts +5 -3
  20. package/dist/types/ui/UIVideo.d.ts +3 -0
  21. package/dist/types/ui/UIWidget.d.ts +25 -24
  22. package/dist/types/ui/presentable.d.ts +10 -0
  23. package/dist/types/ui/transitions.d.ts +2 -1
  24. package/dist/types/ui/tree.d.ts +1 -0
  25. package/dist/types/version.d.ts +1 -1
  26. package/dist/types.json +1 -1
  27. package/package.json +3 -2
  28. package/prompts/3d-scene-files.md +3 -3
  29. package/prompts/3d-scene.md +1 -1
  30. package/prompts/dist/3d-app.md +4 -4
  31. package/src/bridges/gl.d.ts +5 -0
  32. package/src/bridges/tree.d.ts +24 -12
  33. package/src/chisel.ts +1 -1
  34. package/src/compile/libraryImports.ts +9 -0
  35. package/src/compile/serverTypes.ts +6 -0
  36. package/src/g2/Scene2D.ts +10 -0
  37. package/src/gl/Light.ts +78 -2
  38. package/src/gl/Material.ts +3 -0
  39. package/src/gl/Scene.ts +11 -1
  40. package/src/inject.ts +2 -0
  41. package/src/runtime/rpc.ts +15 -3
  42. package/src/server/context.ts +4 -0
  43. package/src/server/db/defineDb.ts +62 -9
  44. package/src/server/db/fields.ts +21 -1
  45. package/src/server/db/httpTransport.ts +9 -1
  46. package/src/server/db/marci/query.ts +71 -4
  47. package/src/server/db/types.ts +16 -5
  48. package/src/server/files/db.ts +182 -0
  49. package/src/server/files/host.ts +496 -0
  50. package/src/server/files/models.ts +116 -0
  51. package/src/server/host.ts +17 -4
  52. package/src/server/inject.ts +1 -0
  53. package/src/server/runtime.ts +41 -0
  54. package/src/server/validate.ts +5 -0
  55. package/src/ui/NativeView.ts +11 -0
  56. package/src/ui/UI.ts +1 -0
  57. package/src/ui/UIBottomSheet.ts +8 -7
  58. package/src/ui/UILayer.ts +88 -0
  59. package/src/ui/UIModal.ts +59 -43
  60. package/src/ui/UINode.ts +9 -1
  61. package/src/ui/UIPopover.ts +23 -9
  62. package/src/ui/UIVideo.ts +11 -0
  63. package/src/ui/UIWidget.ts +70 -44
  64. package/src/ui/presentable.ts +11 -1
  65. package/src/ui/transitions.ts +36 -7
  66. package/src/ui/tree.ts +4 -0
  67. package/src/version.ts +1 -1
  68. package/tests/helpers/fakeTree.ts +7 -3
@@ -11,17 +11,20 @@ export type UIModalTransition = DrawableStyle & BaseStyle & {
11
11
  };
12
12
  /**
13
13
  * A dialog: a `UIWidget` with the modal boilerplate built in. Comes with a scrim
14
- * (`overlayColor: "rgba(0, 0, 0, 0.5)"` unless overridden), animates on `show()`/`hide()`
15
- * (a 200 ms fade by default — swap the pose via `transition()`; the exit plays with
16
- * `commit: false`, so the style is intact for the next show), and closes itself on a scrim tap
17
- * or the Android back button (disable via `dismissible(false)`). Everything else is a plain
18
- * widget — same styling, children, touch and `attachTo()` surface; create it **once** at module
19
- * scope and reuse it.
14
+ * (`overlayColor: "rgba(0, 0, 0, 0.5)"` unless overridden), animates on `show()`/`hide()` and on
15
+ * a state block flipping its `display` (a 200 ms fade by default — swap the pose via
16
+ * `transition()`; the runtime plays it as tracks that never touch the style), and closes itself
17
+ * on a scrim tap or the Android back button (disable via `dismissible(false)`). Everything else
18
+ * is a plain widget: declare it where it belongs — among its screen's children, hidden until a
19
+ * tap (`display: "none"`), or shown with `show()` from anywhere, which puts a parentless modal in
20
+ * the app layer. A dialog bound to data (its display from a binding) is declared
21
+ * `dismissible(false)` and routes `onOverlayTap` / `onBack` into the data's dismiss, so the data
22
+ * stays what the screen shows.
20
23
  */
21
24
  export interface UIModal extends UIWidget {
22
- /** Mount as an overlay and play the entrance transition. No-op while already open. */
25
+ /** Show and play the entrance transition. No-op while already open. */
23
26
  show(): void;
24
- /** Play the exit transition, then unmount. No-op while closed or already closing. */
27
+ /** Play the exit transition, then hide. No-op while closed or already closing. */
25
28
  hide(): void;
26
29
  /** True from `show()` until `hide()` starts (already false during the exit animation). */
27
30
  readonly isOpen: boolean;
@@ -36,24 +39,24 @@ export interface UIModal extends UIWidget {
36
39
  * ```
37
40
  */
38
41
  transition(hidden: UIModalTransition): this;
39
- /** Called when `show()` mounts the modal. */
42
+ /** Called when the modal opens — `show()`, or a state block flipping its display. */
40
43
  onOpen(callback: () => void): this;
41
- /** Called when the modal starts closing — scrim tap, back button, or a `hide()` call. */
44
+ /** Called when the modal starts closing — scrim tap, back button, a `hide()` call, or a state
45
+ * block flipping its display. */
42
46
  onClose(callback: () => void): this;
43
47
  /** `dismissible(false)` keeps scrim taps and the back button from closing the modal
44
- * (forced-choice dialogs). Default `true`. */
48
+ * (forced-choice dialogs, a dialog whose display is bound to data). Default `true`. */
45
49
  dismissible(enabled: boolean): this;
46
50
  }
47
51
  export declare class ModalElement extends WidgetElement {
48
- _open: boolean;
49
52
  _dismissible: boolean;
50
53
  _transition: UIModalTransition;
51
- _closeTimer?: ReturnType<typeof setTimeout>;
52
54
  readonly _openListeners: (() => void)[];
53
55
  readonly _closeListeners: (() => void)[];
56
+ private _poseObj?;
57
+ private _poseKey;
54
58
  constructor(style: UIModalStyle, children: UINodeChild[] | ChildrenFn);
55
59
  private _pose;
56
- private get _duration();
57
60
  transition(hidden: UIModalTransition): this;
58
61
  show(): void;
59
62
  hide(): void;
@@ -62,7 +65,8 @@ export declare class ModalElement extends WidgetElement {
62
65
  onClose(callback: () => void): this;
63
66
  dismissible(enabled: boolean): this;
64
67
  }
65
- /** Create a modal dialog (see {@link UIModal}) — create once at module scope, then
66
- * `show()`/`hide()`. Same argument forms as `UIColumn`. */
68
+ /** Create a modal dialog (see {@link UIModal}): declare it among its screen's children with
69
+ * `display: "none"` and `show()` it from a tap, or `show()` a parentless one from anywhere.
70
+ * Same argument forms as `UIColumn`. */
67
71
  export declare function UIModal(...children: UIChildArg[]): UIModal;
68
72
  export declare function UIModal(children: UINodeChild[] | ChildrenFn): UIModal;
@@ -18,9 +18,11 @@ export type UIPopoverAnchor = {
18
18
  * tooltips; create it **once** at module scope and reuse it.
19
19
  */
20
20
  export interface UIPopover extends UIModal {
21
- /** Position next to `anchor` (an element or an `{x, y}` point), attach to
22
- * `Presentable.current` (unless an owner was set via `attachTo`), and play the entrance
23
- * transition. Without an anchor the popover shows wherever its own style puts it. */
21
+ /** Position next to `anchor` (an element or an `{x, y}` point), put the popover where the
22
+ * anchor is — the anchor's screen, page or surface content, found through the tree, so the
23
+ * menu lands where it was opened and goes with it — and play the entrance transition. A
24
+ * popover with no anchor and no parent goes to the app layer; without an anchor it shows
25
+ * wherever its own style puts it. */
24
26
  show(anchor?: UIPopoverAnchor): void;
25
27
  }
26
28
  export declare class PopoverElement extends ModalElement {
@@ -1,4 +1,5 @@
1
1
  import type { VideoPlayer } from "../runtime/media";
2
+ import { type UIWidgetContent } from "./UILayer";
2
3
  import { type DismissOptions, type PresentOptions } from "./presentable";
3
4
  import { type BaseStyle, type DrawableStyle, type ElementStyle, type UIElementBase } from "./UINode";
4
5
  export type UIVideoStyle = ElementStyle & DrawableStyle & {
@@ -21,6 +22,8 @@ export interface UIVideo extends UIElementBase<UIVideoStyle, DrawableStyle & Bas
21
22
  onClose(callback: () => void): this;
22
23
  /** Hardware/system back while current. */
23
24
  onBack(callback: () => void): this;
25
+ /** The UI over the video when presented: widgets over it (`Presentable.setContent`). */
26
+ setContent(content: UIWidgetContent): this;
24
27
  }
25
28
  /** Create a video node showing `player`'s output. */
26
29
  export declare function UIVideo(player: VideoPlayer): UIVideo;
@@ -1,36 +1,39 @@
1
1
  import { TouchStartEvent } from "../runtime/touch";
2
- import { Presentable } from "./presentable";
3
2
  import { ContainerElement, type BaseStyle, type Color, type ContainerStyle, type DrawableStyle, type PaddingStyle, type PositionStyle, type UIChildArg, type UIContainerBase, type UINodeChild, type ChildrenFn } from "./UINode";
4
3
  export type UIWidgetStyle = ContainerStyle & DrawableStyle & PaddingStyle & BaseStyle & PositionStyle & {
4
+ /** Shown (`"flex"`, the default) or not: what `show()` / `hide()` write, what a state block may
5
+ * flip (`$open: { display: "flex" }`). */
6
+ display?: "none" | "flex";
5
7
  /** A layer behind the widget that intercepts clicks — `"transparent"` still intercepts, `null`
6
8
  * removes the layer. A tap on it fires `onOverlayTap`. */
7
9
  overlayColor?: Color | null;
8
10
  };
9
- /** A floating overlay — absolutely positioned in device coordinates, mounted above the page as
10
- * its own layout root (never a child of what's underneath). The base of dialogs, toasts,
11
- * mini-players and scene HUDs; `UIModal`/`UIPopover`/`UIBottomSheet` build on it. */
11
+ /** A floating overlay that belongs to a WINDOW, not to a box (docs/plans/widgets-plan.md): a dialog,
12
+ * a sheet, a HUD, a mini-player. A widget is a CHILD of the place it belongs to — a `UIScreen`
13
+ * (among its children), a surface's content (`scene.setContent([hud])`) or the app layer
14
+ * (`UIOverlay`) — and is laid out and painted in the box of the outermost presented destination
15
+ * that contains it: absolutely positioned in that box, above everything else in it. A widget on a
16
+ * tab page covers the tab bar and rides the shell's push and pop. A widget inside a `UIColumn` or
17
+ * any other box is an error: a floating element of a box is an absolute child, not a widget.
18
+ *
19
+ * It shows with its place unless its style says `display: "none"`; `show()` / `hide()` flip that,
20
+ * and so does a state block (`$class: { display: "flex" }`). `UIModal` / `UIPopover` /
21
+ * `UIBottomSheet` build on it. */
12
22
  export interface UIWidget extends UIContainerBase<UIWidgetStyle, DrawableStyle & BaseStyle & {
13
23
  overlayColor?: Color | null;
14
24
  }> {
15
25
  readonly type: "widget";
16
- /**
17
- * Attach this widget to a destination (a `Scene`, a `UIScreen`, …): the widget lives on that
18
- * page's layer — it shows/hides with the page and rides its transition, and a screen pushed
19
- * on top covers it (a scene HUD behaves like part of the scene). Sticky until `attachTo(null)`
20
- * (= back to a global overlay). Set it while the widget is hidden. The widget is always its own
21
- * overlay root mounted into the owner's page view — it never becomes a child of the owner, so it
22
- * stays topmost and its updates never trigger the owner's relayout. Works with a `UIScreen` that
23
- * is a page inside a `UIPager`: the widget mounts into that tab and rides its swipe.
24
- */
25
- attachTo(owner: Presentable | null): this;
26
- /** Show the widget. By default it is a global overlay above every destination — it stays
27
- * visible across navigation until `hide()` (dialogs, mini-player, global loader). If the
28
- * widget was attached via `attachTo(owner)`, it mounts on that page's layer instead and is
29
- * only visible while the owner is presented. */
26
+ /** Show the widget: `display: "flex"`, on top of its root — it moves to the end of its parent's
27
+ * children, so a dialog opened later covers an earlier one and a HUD declared after it. A widget
28
+ * with no parent is appended to the app layer first (`UIOverlay`) — a global overlay above every
29
+ * destination, up until `hide()`. */
30
30
  show(): void;
31
- /** Unmount the widget. */
31
+ /** Hide the widget: `display: "none"`. It stays where it is (its place, the app layer), ready
32
+ * for the next `show()`. */
32
33
  hide(): void;
33
- /** Mounted right now (`show()` ran, `hide()` hasn't). */
34
+ /** Shown right now by its own display (`show()` ran, `hide()` hasn't, no state block hides
35
+ * it). True for a widget hidden WITH its page or its covered screen: that is its place's
36
+ * visibility, not the widget's. */
34
37
  readonly isShown: boolean;
35
38
  /** Touch began on the widget; `ev.track(...)` takes over the rest of the gesture. */
36
39
  onTouchStart(callback: (ev: TouchStartEvent<UIWidget>) => void): this;
@@ -44,10 +47,7 @@ export interface UIWidget extends UIContainerBase<UIWidgetStyle, DrawableStyle &
44
47
  }
45
48
  export declare class WidgetElement extends ContainerElement<"widget"> {
46
49
  scrollable: false;
47
- _owner?: Presentable;
48
- private _shown;
49
50
  constructor(type: "widget", style: UIWidgetStyle, children: UINodeChild[] | ChildrenFn);
50
- attachTo(owner: Presentable | null): this;
51
51
  show(): void;
52
52
  hide(): void;
53
53
  get isShown(): boolean;
@@ -60,7 +60,8 @@ export declare class WidgetElement extends ContainerElement<"widget"> {
60
60
  /** @deprecated see the interface */
61
61
  onBackPressed(callback: any): this;
62
62
  }
63
- /** Create a widget (same argument forms as `UIColumn`). Position it with absolute-style props
63
+ /** Create a widget (same argument forms as `UIColumn`). Put it where it belongs — among a screen's
64
+ * children, in `scene.setContent([...])`, or `UIOverlay` — position it with absolute-style props
64
65
  * (`top`/`left`/`bottom`/`right`), then `show()`/`hide()`. */
65
66
  export declare function UIWidget(...children: UIChildArg[]): UIWidget;
66
67
  export declare function UIWidget(children: UINodeChild[] | ChildrenFn): UIWidget;
@@ -1,4 +1,5 @@
1
1
  import type { EasingInput } from "../animate/tween/easing";
2
+ import type { UIWidget } from "./UIWidget";
2
3
  /** The built-in transitions (ui/transitions.ts holds what each one is). `push` / `pop` are the
3
4
  * stacked-navigation pair — the incoming screen slides over the other one, which drifts and dims;
4
5
  * the rest are two-screen moves. */
@@ -14,6 +15,9 @@ export type TransitionPose = {
14
15
  opacity?: number | number[];
15
16
  /** Black over this screen, 0..1: how dark the screen UNDER the other one gets. */
16
17
  dim?: number | number[];
18
+ /** A widget's overlay layer (its scrim) in the pose — a widget's enter / exit pose only
19
+ * (`UIModal.transition`): `"transparent"` fades the scrim in with the dialog. */
20
+ overlayColor?: string | string[];
17
21
  /** ms (default 300). */
18
22
  duration?: number;
19
23
  /** ms to wait; the screen holds its first pose through it. */
@@ -70,6 +74,12 @@ export interface Presentable {
70
74
  onOpen(callback: () => void): this;
71
75
  onClose(callback: () => void): this;
72
76
  onBack(callback: () => void): this;
77
+ /** The destination's widgets (docs/plans/widgets-plan.md): a dialog, a HUD, a sheet declared as
78
+ * CONTENT of the place they belong to. A `UIScreen` takes them among its children; a surface — a
79
+ * `Scene`, a `Scene2D`, a `NativeView`, a `UIVideo` — takes widgets alone, laid out over it while
80
+ * it is presented (touches outside a widget's box reach the surface). A widget shows with its
81
+ * destination unless its style says `display: "none"`; `show()` / `hide()` flip that. */
82
+ setContent(content: (UIWidget | null | undefined | false)[] | (() => (UIWidget | null | undefined | false)[])): this;
73
83
  }
74
84
  /** Runtime companion of the `Presentable` interface (declaration merging): the navigation
75
85
  * state that isn't tied to the Router. */
@@ -1,4 +1,4 @@
1
- import type { TransitionSpec } from "./presentable";
1
+ import type { TransitionPose, TransitionSpec } from "./presentable";
2
2
  /** Wire ids: a registered transition is > 0. */
3
3
  export declare const TRANSITION_NONE = 0;
4
4
  /** "The caller names none": the runtime plays what the stack entry remembers (a pop), or keeps
@@ -16,3 +16,4 @@ export declare const TRANSITION_ENTER_ON_TOP = 1;
16
16
  * one that left comes back from its `exit` pose, the same screen stays on top — and the timing and
17
17
  * the curves stay as written. Not a rewind: that would turn an ease-out into a slow start. */
18
18
  export declare const mirrored: (s: TransitionSpec) => TransitionSpec;
19
+ export declare const _widgetPoseId: (pose: TransitionPose | null) => number;
@@ -33,6 +33,7 @@ export declare const TREE_EVENT_HOVER_ENTER = 32;
33
33
  export declare const TREE_EVENT_HOVER_MOVE = 33;
34
34
  export declare const TREE_EVENT_HOVER_END = 34;
35
35
  export declare const TREE_EVENT_HOVER_CANCEL = 35;
36
+ export declare const TREE_EVENT_WIDGET_VISIBLE = 36;
36
37
  export declare const TREE_FLAG_INTERACTIVE: number;
37
38
  export declare const TREE_FLAG_CLICK: number;
38
39
  export declare const TREE_FLAG_LONG_PRESS: number;
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION = "2.0.7";
1
+ export declare const SDK_VERSION = "2.0.9";
2
2
  /** The major of a semver string, or null when it is not one. */
3
3
  export declare const sdkMajor: (version: string | null | undefined) => number | null;
4
4
  /** The `// sdk: <version>` line of a compiled bundle's header (sdk/src/compile/header.ts), read from