lecodes-sdk 2.2.11 → 2.2.14
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/global.d.ts +13 -0
- package/dist/host.d.ts +8 -2
- package/dist/types/core/Aspect.d.ts +5 -0
- package/dist/types/g2/Physics2D.d.ts +3 -2
- package/dist/types/g2/Scene2D.d.ts +6 -0
- package/dist/types/gl/Scene.d.ts +6 -0
- package/dist/types/gl/Texture.d.ts +2 -7
- package/dist/types/gl/animation/DynamicBone.d.ts +3 -0
- package/dist/types/gl/animation/Locomotion.d.ts +3 -0
- package/dist/types/gl/physics/Physics.d.ts +2 -1
- package/dist/types/gl/physics/Ragdoll.d.ts +4 -0
- package/dist/types/gl/vehicle/Vehicle.d.ts +4 -0
- package/dist/types/inject.d.ts +4 -3
- package/dist/types/plugin.d.ts +3 -0
- package/dist/types/plugins/gen/push/sdk/push.d.ts +10 -3
- package/dist/types/plugins/gen/push/sdk/push.gen.d.ts +11 -3
- package/dist/types/runtime/app.d.ts +4 -2
- package/dist/types/runtime/fetch.d.ts +3 -0
- package/dist/types/runtime/pushSeam.d.ts +23 -0
- package/dist/types/runtime/rpc.d.ts +15 -1
- package/dist/types/runtime/storage.d.ts +6 -1
- package/dist/types/server/auth/models.d.ts +13 -1
- package/dist/types/server/auth/types.d.ts +2 -0
- package/dist/types/server/db/marci/query.d.ts +8 -2
- package/dist/types/server/inject.d.ts +1 -0
- package/dist/types/server/pushChannel.d.ts +79 -0
- package/dist/types/ui/UIButton.d.ts +2 -2
- package/dist/types/ui/UIContainer.d.ts +4 -2
- package/dist/types/ui/UINode.d.ts +2 -2
- package/dist/types/ui/UIScreen.d.ts +2 -2
- package/dist/types/ui/UIVideo.d.ts +3 -2
- package/dist/types/ui/router.d.ts +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types.json +1 -1
- package/package.json +2 -5
- package/src/compile/assetIconMacro.ts +2 -1
- package/src/compile/assetMacro.ts +2 -1
- package/src/compile/compileProject.ts +28 -4
- package/src/compile/header.ts +17 -0
- package/src/compile/index.ts +2 -0
- package/src/compile/serverSplit.ts +29 -19
- package/src/compile/serverTypes.ts +1 -1
- package/src/core/Aspect.ts +2 -1
- package/src/g2/Physics2D.ts +6 -3
- package/src/g2/Scene2D.ts +9 -1
- package/src/gl/Scene.ts +9 -1
- package/src/gl/Texture.ts +2 -1
- package/src/gl/animation/DynamicBone.ts +6 -2
- package/src/gl/animation/Locomotion.ts +11 -1
- package/src/gl/physics/Physics.ts +3 -2
- package/src/gl/physics/Ragdoll.ts +8 -3
- package/src/gl/vehicle/Vehicle.ts +7 -2
- package/src/host.d.ts +8 -2
- package/src/inject.ts +4 -3
- package/src/plugin.ts +3 -0
- package/src/plugins/gen/push/contract.d.ts +24 -2
- package/src/plugins/gen/push/sdk/push.gen.ts +17 -5
- package/src/plugins/gen/push/sdk/push.ts +159 -55
- package/src/runtime/app.ts +4 -2
- package/src/runtime/fetch.ts +6 -0
- package/src/runtime/pushSeam.ts +22 -0
- package/src/runtime/rpc.ts +35 -1
- package/src/runtime/storage.ts +14 -4
- package/src/server/auth/host.ts +40 -9
- package/src/server/auth/models.ts +5 -1
- package/src/server/auth/types.ts +2 -0
- package/src/server/db/marci/query.ts +8 -2
- package/src/server/host.ts +6 -0
- package/src/server/inject.ts +3 -2
- package/src/server/push/host.ts +143 -0
- package/src/server/pushChannel.ts +121 -0
- package/src/server/runtime.ts +20 -8
- package/src/ui/UIButton.ts +2 -2
- package/src/ui/UIContainer.ts +4 -2
- package/src/ui/UIInput.ts +2 -2
- package/src/ui/UINode.ts +2 -2
- package/src/ui/UIScreen.ts +2 -2
- package/src/ui/UIVideo.ts +3 -2
- package/src/ui/router.ts +4 -3
- package/src/version.ts +1 -1
- package/prompts/2d.md +0 -391
- package/prompts/3d-scene-files.md +0 -113
- package/prompts/3d-scene.md +0 -122
- package/prompts/3d.md +0 -299
- package/prompts/README.md +0 -142
- package/prompts/ar.md +0 -142
- package/prompts/canvas.md +0 -28
- package/prompts/compose.ts +0 -46
- package/prompts/concept.md +0 -49
- package/prompts/core-design.md +0 -98
- package/prompts/core.md +0 -294
- package/prompts/design.md +0 -218
- package/prompts/dist/2d-game.md +0 -1567
- package/prompts/dist/3d-app.md +0 -1712
- package/prompts/dist/ar-app.md +0 -1585
- package/prompts/dist/concept.md +0 -49
- package/prompts/dist/design.md +0 -521
- package/prompts/dist/ui-app.md +0 -1175
- package/prompts/index.md +0 -39
- package/prompts/intake-prompt.md +0 -33
- package/prompts/namer-prompt.md +0 -12
- package/prompts/router-prompt.md +0 -50
- package/prompts/select.ts +0 -126
- package/prompts/ui-design.md +0 -203
- package/prompts/ui.md +0 -813
package/dist/global.d.ts
CHANGED
|
@@ -173,6 +173,8 @@ declare global {
|
|
|
173
173
|
const __channel: typeof SDK.__channel
|
|
174
174
|
const __compOp: typeof SDK.__compOp
|
|
175
175
|
const __compWrite: typeof SDK.__compWrite
|
|
176
|
+
const __pushChannel: typeof SDK.__pushChannel
|
|
177
|
+
const __pushEnable: typeof SDK.__pushEnable
|
|
176
178
|
const __rpc: typeof SDK.__rpc
|
|
177
179
|
const __serverOnly: typeof SDK.__serverOnly
|
|
178
180
|
const __uiMap: typeof SDK.__uiMap
|
|
@@ -478,10 +480,14 @@ declare global {
|
|
|
478
480
|
type Point = SDK.Point
|
|
479
481
|
type PresentOptions = SDK.PresentOptions
|
|
480
482
|
type Presentable = SDK.Presentable
|
|
483
|
+
type PushChannel<D extends Record<string, unknown> | undefined = undefined> = SDK.PushChannel<D>
|
|
481
484
|
type PushEvent = SDK.PushEvent
|
|
485
|
+
type PushMessage<D> = SDK.PushMessage<D>
|
|
486
|
+
type PushNotification<D> = SDK.PushNotification<D>
|
|
482
487
|
type PushPayload = SDK.PushPayload
|
|
483
488
|
type PushRegisterOptions = SDK.PushRegisterOptions
|
|
484
489
|
type PushStatus = SDK.PushStatus
|
|
490
|
+
type PushTarget = SDK.PushTarget
|
|
485
491
|
type QRScanner = SDK.QRScanner
|
|
486
492
|
type Quat = SDK.Quat
|
|
487
493
|
type RTCConfiguration = SDK.RTCConfiguration
|
|
@@ -651,7 +657,9 @@ declare global {
|
|
|
651
657
|
type UserLocationOptions = SDK.UserLocationOptions
|
|
652
658
|
type VRScene = SDK.VRScene
|
|
653
659
|
type Vec2 = SDK.Vec2
|
|
660
|
+
type Vec2Like = SDK.Vec2Like
|
|
654
661
|
type Vec3 = SDK.Vec3
|
|
662
|
+
type Vec3Like = SDK.Vec3Like
|
|
655
663
|
type Vehicle = SDK.Vehicle
|
|
656
664
|
type VideoPlayer = SDK.VideoPlayer
|
|
657
665
|
type Voice = SDK.Voice
|
|
@@ -672,10 +680,15 @@ declare global {
|
|
|
672
680
|
const channel: typeof SERVER.channel
|
|
673
681
|
const defineDb: typeof SERVER.defineDb
|
|
674
682
|
const model: typeof SERVER.model
|
|
683
|
+
const pushChannel: typeof SERVER.pushChannel
|
|
675
684
|
const ref: typeof SERVER.ref
|
|
676
685
|
const request: typeof SERVER.request
|
|
677
686
|
const t: typeof SERVER.t
|
|
678
687
|
type ApiError = SERVER.ApiError
|
|
688
|
+
type PushChannel<D extends Record<string, unknown> | undefined = undefined> = SERVER.PushChannel<D>
|
|
689
|
+
type PushMessage<D> = SERVER.PushMessage<D>
|
|
690
|
+
type PushNotification<D> = SERVER.PushNotification<D>
|
|
691
|
+
type PushTarget = SERVER.PushTarget
|
|
679
692
|
type StoredFile = SERVER.StoredFile
|
|
680
693
|
type StoredImage = SERVER.StoredImage
|
|
681
694
|
}
|
package/dist/host.d.ts
CHANGED
|
@@ -6,8 +6,11 @@
|
|
|
6
6
|
import type { SvgSource } from "./types/runtime/misc"
|
|
7
7
|
|
|
8
8
|
declare global {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
/** As in the browser, but the delay is REQUIRED (the native runtime throws without it) and no
|
|
10
|
+
* extra argument reaches the handler. Timers tick with the frame on every native host: one
|
|
11
|
+
* frame is the resolution. */
|
|
12
|
+
function setTimeout(handler: () => void, timeout: number): number
|
|
13
|
+
function setInterval(handler: () => void, timeout: number): number
|
|
11
14
|
function clearTimeout(id: number): void
|
|
12
15
|
function clearInterval(id: number): void
|
|
13
16
|
/** Per-frame loop, driven by the host (viewer RAF / desktop runTick). `dt` is **seconds** since
|
|
@@ -38,6 +41,9 @@ declare global {
|
|
|
38
41
|
/** Compile-time macro: `asset('./logo.svg')` yields the file as an SVG image source — for
|
|
39
42
|
* `UIImage(...)` and `bgImage`. */
|
|
40
43
|
function asset(path: `${string}.svg`): SvgSource
|
|
44
|
+
/** Compile-time macro: `asset('./levels.csv')` yields a text file's TEXT (.txt, .csv, .md, .css,
|
|
45
|
+
* .html, .xml, .yml — it ships inside the bundle). Parse it yourself. */
|
|
46
|
+
function asset(path: `${string}.${"txt" | "csv" | "md" | "css" | "html" | "xml" | "yml" | "yaml"}`): string
|
|
41
47
|
/** Compile-time macro: `asset('./hero.png')` is desugared by the bundler into the module import
|
|
42
48
|
* for that resource. The file must exist — a path that resolves to nothing fails the compile
|
|
43
49
|
* (`asset not found: ./hero.png (main.ts:3)`); there is no runtime fallback. Calls inside
|
|
@@ -36,6 +36,11 @@ export declare abstract class AspectHost<E extends EventMap = EventMap> extends
|
|
|
36
36
|
* child-management `add`/`remove` semantics some node kinds expose. */
|
|
37
37
|
removeAspect<A extends Aspect<any, any, any>>(ctor: AspectCtor<A>): this;
|
|
38
38
|
}
|
|
39
|
+
/** What a scene needs to carry systems: Scene and Scene2D implement it over the helpers below. Public
|
|
40
|
+
* (never stripped from the public types: the `System` type names it). */
|
|
41
|
+
export type SystemHost = {
|
|
42
|
+
readonly _systems: Map<Function, Aspect<any, any, any>>;
|
|
43
|
+
};
|
|
39
44
|
/**
|
|
40
45
|
* Base for everything you attach. `K` = accessor name (extracted by chisel for the runtime). `P` =
|
|
41
46
|
* the target node kind: `this.node` is typed to it, AND attaching to a wrong node is a compile error.
|
|
@@ -97,8 +97,9 @@ export declare class Physics2D extends Aspect<"physics", Node2D> {
|
|
|
97
97
|
static get gravity(): Vec2;
|
|
98
98
|
static set gravity(g: Vec2Like);
|
|
99
99
|
private static _gravity;
|
|
100
|
-
/** Whether this
|
|
101
|
-
*
|
|
100
|
+
/** Whether this host has 2D physics (a 2D engine built with CREATOR_2D_PHYSICS). False, never a
|
|
101
|
+
* throw, where there is no 2D engine at all (Web Lite, a 3d / core engine variant). It reports
|
|
102
|
+
* the build, not the world — there is nothing else to guard, since the world creates itself. */
|
|
102
103
|
static get supported(): boolean;
|
|
103
104
|
/** Render interpolation of body transforms between the fixed 60 Hz steps (global; default on). Turn
|
|
104
105
|
* off to save per-frame transform writes when you have many moving bodies / don't need >60 Hz
|
|
@@ -30,6 +30,9 @@ export declare class Scene2D implements Presentable {
|
|
|
30
30
|
readonly camera: Camera2D;
|
|
31
31
|
private static _active;
|
|
32
32
|
static get active(): Scene2D | null;
|
|
33
|
+
/** Whether this host has the 2D engine. False on Web Lite (UI and 3D only) and in a 3d / core
|
|
34
|
+
* engine variant of an app built with `lecodes app`; there `new Scene2D()` throws. */
|
|
35
|
+
static get supported(): boolean;
|
|
33
36
|
readonly _touchStartListeners: Array<(ev: TouchStartEvent<Node2D | null>) => void>;
|
|
34
37
|
/** Texture filter to (re)assert on open(); the sampler is global, so each scene reclaims it. */
|
|
35
38
|
private readonly _filter?;
|
|
@@ -47,6 +50,9 @@ export declare class Scene2D implements Presentable {
|
|
|
47
50
|
removeEventListener(channel: "click" | "touchstart", callback: (ev: any) => void): void;
|
|
48
51
|
add(...nodes: Node2D[]): this;
|
|
49
52
|
remove(...nodes: Node2D[]): this;
|
|
53
|
+
/** class → instance, the authoritative store (named accessors mirror this). Kept in the public
|
|
54
|
+
* types: it is what makes a Scene2D a `SystemHost` there. */
|
|
55
|
+
readonly _systems: Map<Function, Aspect<any, any, any>>;
|
|
50
56
|
/** Attach (and configure) a system, or reconfigure it if already present. Returns the scene typed
|
|
51
57
|
* as now-having it (`scene.system(Hud).hud`). A 3D `System<'x'>` (target Scene) is rejected here. */
|
|
52
58
|
system<Self extends TargetOf<A>, A extends Aspect<any, any, any>>(this: Self, ctor: AspectCtor<A>, opts?: Partial<A>): Self & FieldOf<A>;
|
package/dist/types/gl/Scene.d.ts
CHANGED
|
@@ -157,6 +157,9 @@ export declare class Scene implements Presentable {
|
|
|
157
157
|
set postProcessing(_: never);
|
|
158
158
|
private static _active;
|
|
159
159
|
static get active(): Scene | null;
|
|
160
|
+
/** Whether this host has the 3D engine. False where the bundle was marked `gl: disable` (no scene
|
|
161
|
+
* created anywhere in it) and in a 2d / core engine variant; there `new Scene()` throws. */
|
|
162
|
+
static get supported(): boolean;
|
|
160
163
|
constructor(options?: SceneOptions);
|
|
161
164
|
/** Runtime form of `renderScale` / `dynamicResolution` (a graphics-settings menu). `renderScale`
|
|
162
165
|
* 0.25–1; older hosts without the method ignore it. */
|
|
@@ -199,6 +202,9 @@ export declare class Scene implements Presentable {
|
|
|
199
202
|
setStencil(enabled: boolean): void;
|
|
200
203
|
add(...list: Node[]): this;
|
|
201
204
|
remove(...list: Node[]): this;
|
|
205
|
+
/** class → instance, the authoritative store (named accessors mirror this). Kept in the public
|
|
206
|
+
* types: it is what makes a Scene a `SystemHost` there. */
|
|
207
|
+
readonly _systems: Map<Function, Aspect<any, any, any>>;
|
|
202
208
|
/** Attach (and configure) a system, or reconfigure it if already present. Returns the scene typed
|
|
203
209
|
* as now-having it (`scene.system(Hud).hud`). A `System<'x', Scene2D>` is rejected here. */
|
|
204
210
|
system<Self extends TargetOf<A>, A extends Aspect<any, any, any>>(this: Self, ctor: AspectCtor<A>, opts?: Partial<A>): Self & FieldOf<A>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type FetchResponse, type File } from "../runtime/fetch";
|
|
2
|
+
import type { Canvas } from "../canvas/Canvas";
|
|
2
3
|
/** `Texture.load` options. */
|
|
3
4
|
export type TextureLoadOptions = {
|
|
4
5
|
/** `true` (default): colour, stored sRGB. `false`: data (normal map, mask, heightmap) — kept linear. */
|
|
@@ -30,13 +31,7 @@ export declare class Texture {
|
|
|
30
31
|
/** Vertical wrap mode (V). */
|
|
31
32
|
wrapT: number;
|
|
32
33
|
constructor(width: number, height: number, id: Handle | number);
|
|
33
|
-
static fromCanvas(canvas:
|
|
34
|
-
_bakeSurface(): number;
|
|
35
|
-
width: number;
|
|
36
|
-
height: number;
|
|
37
|
-
pixelRatio: number;
|
|
38
|
-
_tex3dId: number;
|
|
39
|
-
}): Texture;
|
|
34
|
+
static fromCanvas(canvas: Canvas): Texture;
|
|
40
35
|
/** A texture from raw pixels: `channels` (1–4, default 4) UBYTE per pixel, row-major, `width ×
|
|
41
36
|
* height × channels` bytes; `srgb` (default true for colour) picks the sRGB internal format —
|
|
42
37
|
* pass false for data (a heightmap, a mask). No mips. Throws on a host without the call. */
|
|
@@ -48,6 +48,9 @@ export declare class DynamicBoneCollider extends Aspect<"dynamicBoneCollider", N
|
|
|
48
48
|
}
|
|
49
49
|
export declare class DynamicBone extends Aspect<"dynamicBone", Node> {
|
|
50
50
|
static readonly aspect = "dynamicBone";
|
|
51
|
+
/** Whether this host simulates dynamic bones. False, never a throw, on Web Lite and in headless
|
|
52
|
+
* tests; there the aspect attaches, warns once, and `chain` stays empty. */
|
|
53
|
+
static get supported(): boolean;
|
|
51
54
|
/** Only these bones (by name) join the chain — the root always does, a bone left out takes its
|
|
52
55
|
* subtree with it. Default: the root's whole subtree. */
|
|
53
56
|
bones?: string[];
|
|
@@ -179,6 +179,9 @@ export type LocomotionEvents = {
|
|
|
179
179
|
};
|
|
180
180
|
export declare class Locomotion extends Aspect<"loco", Node, LocomotionEvents> {
|
|
181
181
|
static readonly aspect = "loco";
|
|
182
|
+
/** Whether this host runs the locomotion selector. False, never a throw, on Web Lite and in
|
|
183
|
+
* headless tests; there the aspect attaches, warns once, and the body stays `'idle'`. */
|
|
184
|
+
static get supported(): boolean;
|
|
182
185
|
/** The animator whose clips are shown. Default: the first one on this node or under it (a Model
|
|
183
186
|
* child), which is the usual character — a capsule node with the model inside. */
|
|
184
187
|
animator?: Animator;
|
|
@@ -85,7 +85,8 @@ export declare class Physics extends Aspect<"physics", Node> implements CompWrit
|
|
|
85
85
|
applyImpulseAt(v: Vec3Like, point: Vec3Like): this;
|
|
86
86
|
/** Configure gravity / limits. Call once before creating bodies. */
|
|
87
87
|
static configure(config?: PhysicsConfig): void;
|
|
88
|
-
/** Whether this
|
|
88
|
+
/** Whether this host has 3D physics (an engine built with CREATOR_GL_PHYSICS). False, never a
|
|
89
|
+
* throw, where there is no 3D engine at all. */
|
|
89
90
|
static get supported(): boolean;
|
|
90
91
|
/** Closest pickable body hit by the ray from `origin` along `dir` (up to `maxDist`), or null. */
|
|
91
92
|
static raycast(origin: Vec3Like, dir: Vec3Like, maxDist?: number): RayHit | null;
|
|
@@ -60,6 +60,10 @@ export interface RagdollHitOptions {
|
|
|
60
60
|
}
|
|
61
61
|
export declare class Ragdoll extends Aspect<"ragdoll", Node> {
|
|
62
62
|
static readonly aspect = "ragdoll";
|
|
63
|
+
/** Whether this host can drop a body: 3D physics with ragdoll parts. False, never a throw,
|
|
64
|
+
* without physics or on an older host. A host that has it can still refuse the parts
|
|
65
|
+
* (`activate()` returns false). */
|
|
66
|
+
static get supported(): boolean;
|
|
63
67
|
/** The parts: `'humanoid'` (default) finds the standard bones by name; a list places bodies on any
|
|
64
68
|
* bones — parents before children. */
|
|
65
69
|
parts: RagdollPart[] | "humanoid";
|
|
@@ -127,6 +127,10 @@ export interface AeroConfig {
|
|
|
127
127
|
}
|
|
128
128
|
export declare class Vehicle extends Aspect<"vehicle", Node> {
|
|
129
129
|
static readonly aspect = "vehicle";
|
|
130
|
+
/** Whether this host can drive a car: 3D physics with the vehicle model. False, never a throw,
|
|
131
|
+
* without physics or on an older host. A host that has it can still refuse a car's settings
|
|
132
|
+
* (`id` stays 0, with a warning). */
|
|
133
|
+
static get supported(): boolean;
|
|
130
134
|
/** Chassis mass in kg (default 1200). Wheels are massless in this model. */
|
|
131
135
|
mass: number;
|
|
132
136
|
/** Centre of mass height in chassis space (metres, negative = lower). Left out, it drops to halfway
|
package/dist/types/inject.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Mathf } from "./math/Mathf";
|
|
2
|
-
export { Vec2, Vec3 } from "./math/vec";
|
|
2
|
+
export { Vec2, Vec3, type Vec2Like, type Vec3Like } from "./math/vec";
|
|
3
3
|
export { Quat } from "./math/quat";
|
|
4
4
|
export { Mat4 } from "./math/mat4";
|
|
5
5
|
export { Color } from "./core/color";
|
|
@@ -22,9 +22,10 @@ export { device, type HapticStyle, type MotionOptions } from "./runtime/device";
|
|
|
22
22
|
export { Input, InputChannel, type InputKeyEvent, type InputGamepadEvent, type InputEventName, type GamepadState, type GamepadAxisName } from "./runtime/input";
|
|
23
23
|
export { WebSocket } from "./runtime/net";
|
|
24
24
|
export { Net, NetPlayer, Replicated, NetEntity, type NetMessage, type NetRole, type NetStatus, type NetEvents, type NetLaunch, type NetInput, type NetKind, type NetTransform, type NetCorrection } from "./net";
|
|
25
|
-
export { __rpc, __channel, __serverOnly, RpcError } from "./runtime/rpc";
|
|
25
|
+
export { __rpc, __channel, __pushChannel, __serverOnly, RpcError } from "./runtime/rpc";
|
|
26
26
|
export { resource, action, dataOf, failureOf, type Loaded, type Failure, type Resource, type Action } from "./runtime/resource";
|
|
27
27
|
export type { ChannelSubscription } from "./server/channel";
|
|
28
|
+
export type { PushChannel, PushMessage, PushNotification, PushTarget } from "./server/pushChannel";
|
|
28
29
|
export type { StoredFile, StoredImage } from "./server/files/models";
|
|
29
30
|
export { AudioPlayer, VideoPlayer } from "./runtime/media";
|
|
30
31
|
export { Sound, type SoundOptions } from "./audio/Sound";
|
|
@@ -76,7 +77,7 @@ export { ARScene, Anchor, ImageAnchor, ARPlane, type ARSceneOptions, type AROpen
|
|
|
76
77
|
export { AudioRecorder, type AudioRecorderEvents, type RecorderState, type RecordOptions, type Recording, type EndReason } from "./plugins/gen/audio-recorder/sdk/audio-recorder";
|
|
77
78
|
export { SpeechRecognizer, type SpeechRecognizerEvents, type SpeechOptions, type SpeechResult, type SpeechErrorCode } from "./plugins/gen/speech/sdk/speech";
|
|
78
79
|
export { MapView, type MapOptions, type MapStyle, type MapStyleName, type MapCamera, type MapTap, type LngLat, type CameraMove, type FitOptions, type MapPaddingValues, type MarkerItem, type MarkerTap, type MarkerLayer, type MarkerLayerOptions, type LineLayer, type LineLayerOptions, type UserLocationOptions, } from "./plugins/gen/map/sdk/map";
|
|
79
|
-
export { Push, type PushPayload, type PushStatus, type PushRegisterOptions, type PushEvent } from "./plugins/gen/push/sdk/push";
|
|
80
|
+
export { Push, __pushEnable, type PushPayload, type PushStatus, type PushRegisterOptions, type PushEvent } from "./plugins/gen/push/sdk/push";
|
|
80
81
|
export { Browser, WebView, type BrowserOpenOptions, type WebViewParams, type WebViewEvents } from "./plugins/gen/browser/sdk/browser";
|
|
81
82
|
export { RTCPeerConnection, MediaStream, MediaStreamTrack, RTCDataChannel, RTCRtpSender, RTCRtpReceiver, RTCRtpTransceiver, RTCSessionDescription, RTCIceCandidate, RTCEventTarget, mediaDevices, RTCVideoView, type RTCConfiguration, type RTCVideoViewOptions, type MediaStreamConstraints, type RTCIceCandidateInit, type RTCPeerConnectionIceEvent, type RTCTrackEvent, type RTCDataChannelEvent, type RTCMessageEvent, type RTCErrorEvent, type RTCEvent, type RTCEventListener, } from "./plugins/gen/webrtc/sdk/webrtc";
|
|
82
83
|
export { Service } from "./plugins/service";
|
package/dist/types/plugin.d.ts
CHANGED
|
@@ -23,6 +23,9 @@ export { Quat, type QuatLike } from "./math/quat";
|
|
|
23
23
|
export { Mat4 } from "./math/mat4";
|
|
24
24
|
export type { ClickEvent, TouchStartEvent } from "./runtime/touch";
|
|
25
25
|
export type { DismissOptions } from "./ui/presentable";
|
|
26
|
+
/** The seam the push plugin's wrapper installs its runtime on (src/runtime/pushSeam.ts): what the app's transport
|
|
27
|
+
* reads the device's address from, registers through, and a push channel's handlers are kept by. */
|
|
28
|
+
export { _pushRuntime, type PushRuntime } from "./runtime/pushSeam";
|
|
26
29
|
/** Signed 32-bit integer on the wire. */
|
|
27
30
|
export type i32 = number;
|
|
28
31
|
/** Double on the wire — also every integer that can leave 32 bits (a millisecond time stamp). */
|
|
@@ -4,6 +4,11 @@ export type PushEvent = keyof PushEvents;
|
|
|
4
4
|
/**
|
|
5
5
|
* Remote push notifications. `Push.isSupported` reports whether this host registered the
|
|
6
6
|
* service — check it before offering notification features.
|
|
7
|
+
*
|
|
8
|
+
* A project with a backend needs none of this: its `pushChannel()` exports are heard with their
|
|
9
|
+
* own `onTap` / `onMessage`, and the device is registered when the server asks (after a sign-in).
|
|
10
|
+
* `Push` is for the rest — a permission asked at a moment of the app's choosing, and the
|
|
11
|
+
* notifications sent outside a channel (a push key, `lecodes pn send`).
|
|
7
12
|
*/
|
|
8
13
|
export declare const Push: {
|
|
9
14
|
/** Whether this host registered a "push" service. */
|
|
@@ -15,9 +20,11 @@ export declare const Push: {
|
|
|
15
20
|
register(options?: PushRegisterOptions): Promise<PushRegistration>;
|
|
16
21
|
/** Remove this device's registration (the address stops receiving). */
|
|
17
22
|
unregister(): Promise<void>;
|
|
18
|
-
/** The
|
|
19
|
-
|
|
20
|
-
/** "message" = received while the app is open; "tap" = the user tapped one while it ran. */
|
|
23
|
+
/** The notifications sent outside a push channel: "tap" = tapped (the one that started the app
|
|
24
|
+
* too); "message" = arrived while the app is open (the app shows it, the host no banner). */
|
|
21
25
|
addEventListener(event: PushEvent, callback: (payload: PushPayload) => void): void;
|
|
22
26
|
removeEventListener(event: PushEvent, callback: (payload: PushPayload) => void): void;
|
|
23
27
|
};
|
|
28
|
+
/** Installs the push runtime for the SDK's transport and its push-channel proxies (lecodes-sdk/plugin
|
|
29
|
+
* `_pushRuntime`). A line of every server stub of a project with push channels — never app code. */
|
|
30
|
+
export declare const __pushEnable: () => void;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ServiceChannel } from "../../../../plugin";
|
|
2
|
-
import type { PushEvents, PushParams, PushPayload, PushRegisterOptions, PushRegistration, PushStatus } from "../contract";
|
|
2
|
+
import type { PushEvents, PushHandled, PushParams, PushPayload, PushRegisterOptions, PushRegistration, PushStatus } from "../contract";
|
|
3
3
|
/** What the halves register under. */
|
|
4
4
|
export declare const NAME = "push";
|
|
5
5
|
/** The contract's version: the highest `@since` of its members. */
|
|
6
|
-
export declare const VERSION =
|
|
6
|
+
export declare const VERSION = 2;
|
|
7
7
|
/** Permission + registration state. Never prompts. */
|
|
8
8
|
export declare const getStatus: (service: ServiceChannel<PushEvents>) => Promise<PushStatus>;
|
|
9
9
|
/** Ask for the permission (the first time) and register this device. Idempotent.
|
|
@@ -14,8 +14,12 @@ export declare const register: (service: ServiceChannel<PushEvents>, options?: P
|
|
|
14
14
|
export declare const unregister: (service: ServiceChannel<PushEvents>) => Promise<void>;
|
|
15
15
|
/** The notification that cold-started this world, or null. Stable across calls. */
|
|
16
16
|
export declare const getLaunch: (service: ServiceChannel<PushEvents>) => Promise<PushPayload | null>;
|
|
17
|
+
/** Which notifications the app handles itself in the foreground; the rest get the system banner.
|
|
18
|
+
* Until it is called nothing is handled.
|
|
19
|
+
* Contract version 2: an older half rejects the call — ask `supports("setMessageHandled")`. */
|
|
20
|
+
export declare const setMessageHandled: (service: ServiceChannel<PushEvents>, handled: PushHandled) => Promise<void>;
|
|
17
21
|
/** A method of the contract. */
|
|
18
|
-
export type Method = "getStatus" | "register" | "unregister" | "getLaunch";
|
|
22
|
+
export type Method = "getStatus" | "register" | "unregister" | "getLaunch" | "setMessageHandled";
|
|
19
23
|
/** Whether this host has the service "push" — and, given a method, a half new enough for it
|
|
20
24
|
* (a method added after the first version of the contract is tagged `@since`). */
|
|
21
25
|
export declare const supports: (method?: Method) => boolean;
|
|
@@ -32,4 +36,8 @@ export declare class PushBase extends ServiceChannel<PushEvents> {
|
|
|
32
36
|
unregister(): Promise<void>;
|
|
33
37
|
/** The notification that cold-started this world, or null. Stable across calls. */
|
|
34
38
|
getLaunch(): Promise<PushPayload | null>;
|
|
39
|
+
/** Which notifications the app handles itself in the foreground; the rest get the system banner.
|
|
40
|
+
* Until it is called nothing is handled.
|
|
41
|
+
* Contract version 2: an older half rejects the call — ask `supports("setMessageHandled")`. */
|
|
42
|
+
setMessageHandled(handled: PushHandled): Promise<void>;
|
|
35
43
|
}
|
|
@@ -43,8 +43,10 @@ export declare const app: {
|
|
|
43
43
|
sdkVersion: string;
|
|
44
44
|
/** The INSTALLED app: the store build this bundle runs in. After an over-the-air update the code
|
|
45
45
|
* is newer than the binary, so a feature that needs native support added in a later store build
|
|
46
|
-
* (a plugin, an SDK method) branches on `app.host.sdk` / `app.host.build` — and on
|
|
47
|
-
*
|
|
46
|
+
* (a plugin, an SDK method) branches on `app.host.sdk` / `app.host.build` — and on the feature's
|
|
47
|
+
* own check (`Push.isSupported`, `Physics.supported`), which is the final word. Not `typeof` of
|
|
48
|
+
* the global: every SDK wrapper is compiled into the bundle, so `typeof Push` is "object" on a
|
|
49
|
+
* host without the plugin. Minor and patch of the SDK never gate anything. */
|
|
48
50
|
readonly host: AppHost;
|
|
49
51
|
/** The RUNNING code: what the compiler stamped into this bundle's header. `updatedAt` is the
|
|
50
52
|
* compile time — what the updater compares before replacing a bundle (an older one never
|
|
@@ -12,6 +12,9 @@ export interface FetchResponse {
|
|
|
12
12
|
readonly status: number;
|
|
13
13
|
json<T = any>(): T;
|
|
14
14
|
text(): string;
|
|
15
|
+
/** The body's bytes, a copy — a binary format of your own (`asset('./levels/1.bin')`), parsed in
|
|
16
|
+
* code with a DataView. Synchronous, like `text()`. */
|
|
17
|
+
bytes(): Uint8Array;
|
|
15
18
|
/** @deprecated A no-op: the body is freed with the response's handle (owned handles). Apps written
|
|
16
19
|
* against the pre-owned SDK still call it after `text()` / `json()`; remove the call. */
|
|
17
20
|
dispose(): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The seam between the app's transport (./rpc.ts) and the push plugin's wrapper (src/plugins/gen/push/sdk/push.ts).
|
|
3
|
+
*
|
|
4
|
+
* A push channel (`pushChannel()` of a *.server.ts file — src/server/pushChannel.ts) is heard in the app through
|
|
5
|
+
* the plugin: its taps and foreground arrivals come off the plugin's service. The transport, for its part, tells
|
|
6
|
+
* the server the device's address (the `x-lecodes-push` header of every call) and registers the device when the
|
|
7
|
+
* server asks for it (the envelope's `push: true`). Neither may import the wrapper: an app without push channels
|
|
8
|
+
* would then carry the plugin. So the wrapper installs itself here — `__pushEnable()`, a line the compiler puts at
|
|
9
|
+
* the top of every server stub of a project with push channels — and the transport reads what is installed.
|
|
10
|
+
*/
|
|
11
|
+
export type PushRuntime = {
|
|
12
|
+
/** This device's address for the app, once known (after a registration, or the status of an earlier one). */
|
|
13
|
+
address(): string | null;
|
|
14
|
+
/** The server asked this device to register: once per run, prompt-free when the permission was given,
|
|
15
|
+
* nothing past a refusal. */
|
|
16
|
+
requestRegister(): void;
|
|
17
|
+
/** Hear the taps ("tap") or the foreground arrivals ("message") of one push channel, by its id. Returns the remover. */
|
|
18
|
+
on(kind: "tap" | "message", channel: string, handler: (payload: any) => void): () => void;
|
|
19
|
+
};
|
|
20
|
+
/** What the wrapper installed; null = the app has no push channels (or the plugin is not in the bundle). */
|
|
21
|
+
export declare const _pushRuntime: {
|
|
22
|
+
current: PushRuntime | null;
|
|
23
|
+
};
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* export const db = __serverOnly("schema.server.ts#db")
|
|
9
9
|
*
|
|
10
10
|
* Wire (implemented by the runner):
|
|
11
|
-
* POST <serverUrl>/api/<id> body {"args":[…]}, `authorization: Bearer <session>` when known
|
|
11
|
+
* POST <serverUrl>/api/<id> body {"args":[…]}, `authorization: Bearer <session>` when known,
|
|
12
|
+
* `x-lecodes-push: <address>` once the device registered for notifications
|
|
12
13
|
* — with a `File` among the arguments: multipart, the field `args` is
|
|
13
14
|
* that JSON with `{"$file": <i>}` where the file stood, `file<i>` the files
|
|
14
15
|
* → 200 {"ok":true,"result":…,"session"?:"…"} | {"ok":false,"status":n,"message":"…","session"?:"…"}
|
|
@@ -38,3 +39,16 @@ export declare const __channel: (serverUrl: string, id: string) => {
|
|
|
38
39
|
subscribe(...all: unknown[]): ChannelSubscription;
|
|
39
40
|
publish(): never;
|
|
40
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Build the client proxy of push channel `id` — what a `pushChannel()` export of a `*.server.ts` file is
|
|
44
|
+
* in the app (its type is the server's: src/server/pushChannel.ts). The notifications come off the push
|
|
45
|
+
* plugin, through the runtime its wrapper installed (`__pushEnable()`, the first line of the stubs of a
|
|
46
|
+
* project with push channels — ./pushSeam.ts): `onTap` hears this channel's taps (the one that started
|
|
47
|
+
* the app included), `onMessage` its arrivals while the app is in the foreground. On a host without the
|
|
48
|
+
* plugin a handler is recorded and never called, like the plugin's own listeners.
|
|
49
|
+
*/
|
|
50
|
+
export declare const __pushChannel: (serverUrl: string, id: string) => {
|
|
51
|
+
onTap: (handler: unknown) => ChannelSubscription;
|
|
52
|
+
onMessage: (handler: unknown) => ChannelSubscription;
|
|
53
|
+
send(): never;
|
|
54
|
+
};
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
declare const methods: {
|
|
2
2
|
getItem(key: string): string | null;
|
|
3
3
|
setItem(key: string, value: string): void;
|
|
4
4
|
removeItem(key: string): void;
|
|
5
5
|
};
|
|
6
|
+
export type LocalStorage = typeof methods & {
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
};
|
|
9
|
+
export declare const localStorage: LocalStorage;
|
|
10
|
+
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The two models sign-in adds to a database — `defineDb({...}).withAuth({ model: "User" })`:
|
|
3
3
|
*
|
|
4
|
-
* Session one device: the hash of its token,
|
|
4
|
+
* Session one device: the hash of its token, the user it is signed in as (none = a guest), and the
|
|
5
|
+
* device's push address when it told one (what a push channel's `send` reaches the user by)
|
|
5
6
|
* Identity one way a user signs in: `email:<address>` or `login:<name>` (with the password's hash
|
|
6
7
|
* when one is set) — several per user.
|
|
7
8
|
*
|
|
@@ -85,6 +86,17 @@ export declare const sessionFields: (userModel: string) => {
|
|
|
85
86
|
isId: false;
|
|
86
87
|
model: "";
|
|
87
88
|
}>;
|
|
89
|
+
/** The device's address at the platform's push relay (`x-lecodes-push` of its calls) — the session's own
|
|
90
|
+
* secret, like the token: never read back by a project (../push/host.ts sends by it). */
|
|
91
|
+
pushAddress: import("../db").Field<string, {
|
|
92
|
+
kind: "scalar";
|
|
93
|
+
scalar: "string";
|
|
94
|
+
optional: true;
|
|
95
|
+
hasDefault: false;
|
|
96
|
+
array: false;
|
|
97
|
+
isId: false;
|
|
98
|
+
model: "";
|
|
99
|
+
}>;
|
|
88
100
|
user: import("../db").Field<never, {
|
|
89
101
|
kind: "one";
|
|
90
102
|
scalar: "";
|
|
@@ -11,6 +11,8 @@ import type { RequestContext } from "../context";
|
|
|
11
11
|
export type AuthState = {
|
|
12
12
|
sessionId: number;
|
|
13
13
|
userId: number | null;
|
|
14
|
+
/** The push address of the device, as the session holds it after this request's header was read (null = none). */
|
|
15
|
+
pushAddress?: string | null;
|
|
14
16
|
/** A token to hand back to the client in this response (a new guest session, or a rotation). */
|
|
15
17
|
issuedToken?: string;
|
|
16
18
|
};
|
|
@@ -188,7 +188,13 @@ export type AggregateResult<TModel, T> = (T extends {
|
|
|
188
188
|
max: (F extends keyof TModel ? TModel[F] : never) | null;
|
|
189
189
|
} : {});
|
|
190
190
|
declare const __op: unique symbol;
|
|
191
|
-
|
|
191
|
+
/** What a query or an op offers of a promise: `then`, `catch`, `finally` — the runtime object has
|
|
192
|
+
* all three (`op()` / the collection builder below), so `db.x.insert(…).catch(…)` type-checks. */
|
|
193
|
+
export type Settles<T> = PromiseLike<T> & {
|
|
194
|
+
catch<R = never>(onRejected?: ((reason: any) => R | PromiseLike<R>) | null): Promise<T | R>;
|
|
195
|
+
finally(onFinally?: (() => void) | null): Promise<T>;
|
|
196
|
+
};
|
|
197
|
+
export type Op<T> = Settles<T> & {
|
|
192
198
|
readonly [__op]: T;
|
|
193
199
|
};
|
|
194
200
|
export type MarciOp = {
|
|
@@ -251,7 +257,7 @@ export type IdArg<I> = I | BareId<I>;
|
|
|
251
257
|
* it to `$transaction` batches it; placing it in another query's select makes it a sub-select. `Sel` is the
|
|
252
258
|
* projection: id + scalars until `select(...)` sets a shape.
|
|
253
259
|
*/
|
|
254
|
-
export interface Query<T extends ModelTypes, Sel = T["scalars"]> extends
|
|
260
|
+
export interface Query<T extends ModelTypes, Sel = T["scalars"]> extends Settles<Rows<T, Sel>[]> {
|
|
255
261
|
readonly [__op]: Rows<T, Sel>[];
|
|
256
262
|
readonly [__sub]: T["name"];
|
|
257
263
|
readonly [__sel]: Effective<T, Sel>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { t, model, defineDb, ref } from "./db";
|
|
2
2
|
export { ApiError } from "./errors";
|
|
3
3
|
export { channel } from "./channel";
|
|
4
|
+
export { pushChannel, type PushChannel, type PushMessage, type PushNotification, type PushTarget } from "./pushChannel";
|
|
4
5
|
export { request } from "./context";
|
|
5
6
|
export type { StoredFile, StoredImage } from "./files/models";
|
|
6
7
|
/** The value an SVG source is to the client (`assetIcon(…)` compiles to `SvgSource(…)`): a shared module of
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push channels: the server's notifications to a person's devices — the twin of ./channel.ts for what
|
|
3
|
+
* reaches someone while the app is closed. One export types both sides:
|
|
4
|
+
*
|
|
5
|
+
* export const orderShippedPushChannel = pushChannel<{ orderId: number }>() // pushes.server.ts
|
|
6
|
+
*
|
|
7
|
+
* await orderShippedPushChannel.send(order.owner, { title: "Order shipped", data: { orderId } }) // server
|
|
8
|
+
*
|
|
9
|
+
* orderShippedPushChannel.onTap(({ data }) => Router.push(OrderScreen(data.orderId))) // app
|
|
10
|
+
* orderShippedPushChannel.onMessage(({ title }) => toast(title))
|
|
11
|
+
*
|
|
12
|
+
* `send` reaches every device the user is signed in on. The devices are the sessions of the project's db
|
|
13
|
+
* with sign-in (`defineDb(...).withAuth(...)`): a session carries the address of its device — the app's
|
|
14
|
+
* transport tells it with every call, and the server asks the device to register when a signed-in
|
|
15
|
+
* session has none (the first response after a sign-in; the OS asks the permission then) — and a
|
|
16
|
+
* sign-out leaves the device on a guest session, which no `send` reaches. A user with no device is zero
|
|
17
|
+
* sends, not an error. `send` needs no request: a timer may call it.
|
|
18
|
+
*
|
|
19
|
+
* The server holds no push key: the host sends through the platform (./push/host.ts), reached here over
|
|
20
|
+
* the `globalThis.__lecodesPushSend` seam (the compiled bundle carries its own SDK copy — ./context.ts).
|
|
21
|
+
* A channel's identity is its export (`<path>#<name>`), assigned when the bundle is loaded
|
|
22
|
+
* (`loadServerModules`), and it travels in the notification: the app's side hears each channel's own.
|
|
23
|
+
*
|
|
24
|
+
* In the app the export is another object — the proxy `__pushChannel` of src/runtime/rpc.ts — which is
|
|
25
|
+
* why `onTap` / `onMessage` here only throw.
|
|
26
|
+
*/
|
|
27
|
+
import type { ChannelSubscription } from "./channel";
|
|
28
|
+
export type { ChannelSubscription };
|
|
29
|
+
/** Whom a notification goes to: a user id, or a row that has one (`db.auth.requireUser().select({ id: true })`, a relation). */
|
|
30
|
+
export type PushTarget = number | {
|
|
31
|
+
id: number;
|
|
32
|
+
};
|
|
33
|
+
/** What a notification shows, and what it carries for the app (`data`, the channel's type). */
|
|
34
|
+
export type PushMessage<D> = {
|
|
35
|
+
/** Up to 200 characters. */
|
|
36
|
+
title: string;
|
|
37
|
+
/** The second line, up to 1000 characters. */
|
|
38
|
+
body?: string;
|
|
39
|
+
/** A link for the app to open on a tap (`onTap` gets it — it is not opened by itself). */
|
|
40
|
+
url?: string;
|
|
41
|
+
/** The number on the app's icon (iOS; 0 clears it). */
|
|
42
|
+
badge?: number;
|
|
43
|
+
} & (undefined extends D ? {
|
|
44
|
+
data?: D;
|
|
45
|
+
} : {
|
|
46
|
+
data: D;
|
|
47
|
+
});
|
|
48
|
+
/** A notification as the app receives it: what was sent, and the channel it came through. */
|
|
49
|
+
export type PushNotification<D> = PushMessage<D> & {
|
|
50
|
+
channel: string;
|
|
51
|
+
};
|
|
52
|
+
export interface PushChannel<D extends Record<string, unknown> | undefined = undefined> {
|
|
53
|
+
/** Server: send `message` to every device `user` is signed in on (one id or several). Answers how many
|
|
54
|
+
* devices it went to — none is 0, not an error. */
|
|
55
|
+
send(user: PushTarget | PushTarget[], message: PushMessage<D>): Promise<{
|
|
56
|
+
sent: number;
|
|
57
|
+
}>;
|
|
58
|
+
/** App: a notification of this channel was tapped — while the app ran, or to start it. Lives until `close()`. */
|
|
59
|
+
onTap(handler: (notification: PushNotification<D>) => void): ChannelSubscription;
|
|
60
|
+
/** App: a notification of this channel arrived while the app was in the foreground: the app shows it
|
|
61
|
+
* (the host shows no banner); a channel without this handler gets the system banner. */
|
|
62
|
+
onMessage(handler: (notification: PushNotification<D>) => void): ChannelSubscription;
|
|
63
|
+
}
|
|
64
|
+
/** What the host reads of a push channel (src/server/runtime.ts). */
|
|
65
|
+
export type PushChannelRecord = {
|
|
66
|
+
/** set by the runtime: `<path>#<export>` */
|
|
67
|
+
__id: string | null;
|
|
68
|
+
readonly __pushChannel: true;
|
|
69
|
+
};
|
|
70
|
+
/** The host's sender (./push/host.ts): the channel, the users' ids, the message → how many devices. */
|
|
71
|
+
export type PushSender = (channelId: string, userIds: number[], message: PushMessage<any>) => Promise<{
|
|
72
|
+
sent: number;
|
|
73
|
+
}>;
|
|
74
|
+
/** Host hook (runner / local backend / test harness): where `send` delivers to. */
|
|
75
|
+
export declare const setPushSender: (sender: PushSender | null) => void;
|
|
76
|
+
/** The ids of `send`'s first argument, each once; throws on what is not a user. */
|
|
77
|
+
export declare const pushTargetIds: (user: unknown) => number[];
|
|
78
|
+
export declare const pushChannel: <D extends Record<string, unknown> | undefined = undefined>() => PushChannel<D>;
|
|
79
|
+
export declare const isPushChannel: (v: unknown) => v is PushChannelRecord;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ClickEvent as ClickEventType, TouchStartEvent as TouchStartEventType, LongPressEvent as LongPressEventType, MouseEnterEvent as MouseEnterEventType } from "../runtime/touch";
|
|
2
|
-
import { type ElementStyle, type ContainerStyle, type DrawableStyle, type UIChildArg, type UIContainerBase, type UINodeChild, type ChildrenFn, type BaseStyle, type Color } from "./UINode";
|
|
3
|
-
export type UIButtonStyle = ElementStyle & DrawableStyle & ContainerStyle & {
|
|
2
|
+
import { type ElementStyle, type ContainerStyle, type DrawableStyle, type TextStyle, type UIChildArg, type UIContainerBase, type UINodeChild, type ChildrenFn, type BaseStyle, type Color } from "./UINode";
|
|
3
|
+
export type UIButtonStyle = ElementStyle & DrawableStyle & ContainerStyle & TextStyle & {
|
|
4
4
|
rippleColor?: Color | "default";
|
|
5
5
|
};
|
|
6
6
|
/** A tappable container — row + centered children by default. Press feedback via the `$pressed`
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { type ChildrenFn, type ContainerStyle, type DrawableStyle, type ElementStyle, type UIChildArg, type UIContainerBase, type UINodeChild } from "./UINode";
|
|
2
|
-
|
|
1
|
+
import { type ChildrenFn, type ContainerStyle, type DrawableStyle, type ElementStyle, type TextStyle, type UIChildArg, type UIContainerBase, type UINodeChild } from "./UINode";
|
|
2
|
+
/** A container's style: its box and layout, plus the text props (`color`, `fontSize`, `textWrap` …)
|
|
3
|
+
* the texts inside inherit from it. */
|
|
4
|
+
export type UIContainerStyle = ElementStyle & DrawableStyle & ContainerStyle & TextStyle;
|
|
3
5
|
/** A vertical flex container — children stack top to bottom. */
|
|
4
6
|
export interface UIColumn extends UIContainerBase<UIContainerStyle> {
|
|
5
7
|
readonly type: "column";
|
|
@@ -73,7 +73,7 @@ export type DrawableStyle = {
|
|
|
73
73
|
};
|
|
74
74
|
/** Flex-layout props of a container (how it lays out its children). */
|
|
75
75
|
export type ContainerStyle = {
|
|
76
|
-
flexDirection?: "row" | "column";
|
|
76
|
+
flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";
|
|
77
77
|
justifyContent?: "flex-start" | "center" | "flex-end" | "space-between" | "space-evenly";
|
|
78
78
|
alignItems?: "flex-start" | "center" | "flex-end" | "stretch";
|
|
79
79
|
gap?: UIValue;
|
|
@@ -138,7 +138,7 @@ export type ElementStyle = PaddingStyle & MarginStyle & BaseStyle & PositionStyl
|
|
|
138
138
|
flex?: number | string;
|
|
139
139
|
flexGrow?: number;
|
|
140
140
|
flexShrink?: number;
|
|
141
|
-
|
|
141
|
+
flexBasis?: UIValue | `${number}%` | "auto";
|
|
142
142
|
alignSelf?: "flex-start" | "center" | "flex-end" | "stretch";
|
|
143
143
|
display?: "none" | "flex";
|
|
144
144
|
};
|