lecodes-sdk 2.1.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/global.d.ts +8 -0
- package/dist/types/core/signals.d.ts +6 -0
- package/dist/types/inject.d.ts +1 -0
- package/dist/types/runtime/resource.d.ts +49 -0
- package/dist/types/server/db/marci/query.d.ts +4 -0
- package/dist/types/server/db/types.d.ts +3 -3
- package/dist/types/server/files/models.d.ts +7 -0
- package/dist/types/ui/UIInput.d.ts +7 -0
- package/dist/types/ui/UIVirtualizedList.d.ts +13 -20
- package/dist/types/ui/autofocus.d.ts +1 -0
- package/dist/types/version.d.ts +1 -1
- package/dist/types.json +1 -1
- package/package.json +2 -2
- package/prompts/core.md +1 -0
- package/prompts/ui.md +4 -5
- package/src/chisel.ts +5 -2
- package/src/core/signals.ts +28 -0
- package/src/inject.ts +2 -0
- package/src/runtime/resource.ts +96 -0
- package/src/server/db/marci/query.ts +9 -1
- package/src/server/db/types.ts +3 -3
- package/src/server/files/models.ts +5 -0
- package/src/ui/UIInput.ts +11 -1
- package/src/ui/UINode.ts +1 -0
- package/src/ui/UIScreen.ts +2 -1
- package/src/ui/UIVirtualizedList.ts +47 -68
- package/src/ui/autofocus.ts +54 -0
- package/src/version.ts +1 -1
package/dist/global.d.ts
CHANGED
|
@@ -159,6 +159,7 @@ declare global {
|
|
|
159
159
|
const __rpc: typeof SDK.__rpc
|
|
160
160
|
const __serverOnly: typeof SDK.__serverOnly
|
|
161
161
|
const __uiMap: typeof SDK.__uiMap
|
|
162
|
+
const action: typeof SDK.action
|
|
162
163
|
const animate: typeof SDK.animate
|
|
163
164
|
const app: typeof SDK.app
|
|
164
165
|
const audio: typeof SDK.audio
|
|
@@ -168,6 +169,7 @@ declare global {
|
|
|
168
169
|
const computed: typeof SDK.computed
|
|
169
170
|
const cubicBezier: typeof SDK.cubicBezier
|
|
170
171
|
const curve: typeof SDK.curve
|
|
172
|
+
const dataOf: typeof SDK.dataOf
|
|
171
173
|
const date: typeof SDK.date
|
|
172
174
|
const defineMaterial: typeof SDK.defineMaterial
|
|
173
175
|
const defineScene: typeof SDK.defineScene
|
|
@@ -182,6 +184,7 @@ declare global {
|
|
|
182
184
|
const easeOut: typeof SDK.easeOut
|
|
183
185
|
const effect: typeof SDK.effect
|
|
184
186
|
const encodeCells: typeof SDK.encodeCells
|
|
187
|
+
const failureOf: typeof SDK.failureOf
|
|
185
188
|
const fetch: typeof SDK.fetch
|
|
186
189
|
const fetchLocal: typeof SDK.fetchLocal
|
|
187
190
|
const files: typeof SDK.files
|
|
@@ -199,6 +202,7 @@ declare global {
|
|
|
199
202
|
const registerEditorWindow: typeof SDK.registerEditorWindow
|
|
200
203
|
const registerFont: typeof SDK.registerFont
|
|
201
204
|
const resolveTire: typeof SDK.resolveTire
|
|
205
|
+
const resource: typeof SDK.resource
|
|
202
206
|
const rot180: typeof SDK.rot180
|
|
203
207
|
const rot270: typeof SDK.rot270
|
|
204
208
|
const rot90: typeof SDK.rot90
|
|
@@ -212,6 +216,7 @@ declare global {
|
|
|
212
216
|
const toast: typeof SDK.toast
|
|
213
217
|
const use: typeof SDK.use
|
|
214
218
|
type ARScene<T extends ARMode = "default"> = SDK.ARScene<T>
|
|
219
|
+
type Action<A extends unknown[], R> = SDK.Action<A, R>
|
|
215
220
|
type ActiveClip = SDK.ActiveClip
|
|
216
221
|
type AeroConfig = SDK.AeroConfig
|
|
217
222
|
type AnimateOptions<T extends AnimateValue> = SDK.AnimateOptions<T>
|
|
@@ -288,6 +293,7 @@ declare global {
|
|
|
288
293
|
type EditorWindowFn = SDK.EditorWindowFn
|
|
289
294
|
type EngineConfig = SDK.EngineConfig
|
|
290
295
|
type EventMap = SDK.EventMap
|
|
296
|
+
type Failure = SDK.Failure
|
|
291
297
|
type Feet = SDK.Feet
|
|
292
298
|
type FeetOptions = SDK.FeetOptions
|
|
293
299
|
type FetchResponse = SDK.FetchResponse
|
|
@@ -337,6 +343,7 @@ declare global {
|
|
|
337
343
|
type LineLayerOptions = SDK.LineLayerOptions
|
|
338
344
|
type LitMaterialDef = SDK.LitMaterialDef
|
|
339
345
|
type LngLat = SDK.LngLat
|
|
346
|
+
type Loaded<T> = SDK.Loaded<T>
|
|
340
347
|
type LoadedScene<D extends SceneDef> = SDK.LoadedScene<D>
|
|
341
348
|
type LoadedScene2d<D extends Scene2dDef> = SDK.LoadedScene2d<D>
|
|
342
349
|
type Locale = SDK.Locale
|
|
@@ -436,6 +443,7 @@ declare global {
|
|
|
436
443
|
type RagdollPart = SDK.RagdollPart
|
|
437
444
|
type Ray = SDK.Ray
|
|
438
445
|
type Replicated = SDK.Replicated
|
|
446
|
+
type Resource<T> = SDK.Resource<T>
|
|
439
447
|
type ReverbParams = SDK.ReverbParams
|
|
440
448
|
type ReverbPreset = SDK.ReverbPreset
|
|
441
449
|
type RibbonOptions = SDK.RibbonOptions
|
|
@@ -4,6 +4,12 @@ export interface Signal<T> {
|
|
|
4
4
|
value: T;
|
|
5
5
|
/** Read without subscribing the current effect/computed. */
|
|
6
6
|
peek(): T;
|
|
7
|
+
/**
|
|
8
|
+
* Kept on the device under `key`: what the last run left there replaces the initial value (when
|
|
9
|
+
* it is there and reads as JSON), and every write is saved. JSON values only — a date, a class
|
|
10
|
+
* instance or a function does not survive the round trip. `signal<Line[]>([]).stored("cart")`.
|
|
11
|
+
*/
|
|
12
|
+
stored(key: string): Signal<T>;
|
|
7
13
|
}
|
|
8
14
|
export interface Computed<T> {
|
|
9
15
|
readonly value: T;
|
package/dist/types/inject.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export { Input, InputChannel, type InputKeyEvent, type InputGamepadEvent, type I
|
|
|
22
22
|
export { WebSocket } from "./runtime/net";
|
|
23
23
|
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";
|
|
24
24
|
export { __rpc, __channel, __serverOnly, RpcError } from "./runtime/rpc";
|
|
25
|
+
export { resource, action, dataOf, failureOf, type Loaded, type Failure, type Resource, type Action } from "./runtime/resource";
|
|
25
26
|
export type { ChannelSubscription } from "./server/channel";
|
|
26
27
|
export type { StoredFile, StoredImage } from "./server/files/models";
|
|
27
28
|
export { AudioPlayer, VideoPlayer } from "./runtime/media";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type Computed } from "../core/signals";
|
|
2
|
+
/** Why a call failed: the server's refusal in its words — or `offline`, the request never reached
|
|
3
|
+
* it (then `message` is the transport's note, not something to show; say it in your own words). */
|
|
4
|
+
export type Failure = {
|
|
5
|
+
readonly message: string;
|
|
6
|
+
readonly offline: boolean;
|
|
7
|
+
};
|
|
8
|
+
/** What was asked of the server, at any moment: one value a screen draws in its three states. */
|
|
9
|
+
export type Loaded<T> = {
|
|
10
|
+
readonly state: "loading";
|
|
11
|
+
} | {
|
|
12
|
+
readonly state: "ready";
|
|
13
|
+
readonly data: T;
|
|
14
|
+
} | ({
|
|
15
|
+
readonly state: "failed";
|
|
16
|
+
} & Failure);
|
|
17
|
+
/** The data once it is there; `otherwise` until then. */
|
|
18
|
+
export declare const dataOf: <T>(loaded: Loaded<T>, otherwise: T) => T;
|
|
19
|
+
/** The failure, or null while there is none. */
|
|
20
|
+
export declare const failureOf: <T>(loaded: Loaded<T>) => Failure | null;
|
|
21
|
+
export interface Resource<T> {
|
|
22
|
+
/** The request now — read in an effect, a computed or a binding, the screen follows it. */
|
|
23
|
+
readonly value: Loaded<T>;
|
|
24
|
+
/** Read without subscribing. */
|
|
25
|
+
peek(): Loaded<T>;
|
|
26
|
+
/** Ask again. What is shown stays until the answer. */
|
|
27
|
+
reload(): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* What `load` answers, as a `Loaded` signal: asked at once, again when a signal `load` read changes
|
|
31
|
+
* and on `reload()`. An answer that arrives after a newer request was made is dropped. While the
|
|
32
|
+
* data is asked for again, what is there stays. With `initial` — rows the bundle carries — the data
|
|
33
|
+
* is ready from the start and the server's answer replaces it; a failure then leaves it as it is,
|
|
34
|
+
* since what is shown is real.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resource<T>(load: () => Promise<T>, options?: {
|
|
37
|
+
initial?: T;
|
|
38
|
+
}): Resource<T>;
|
|
39
|
+
export type Action<A extends unknown[], R> = ((...args: A) => Promise<R | null>) & {
|
|
40
|
+
/** True while a call runs; a call made meanwhile is ignored (it resolves to null). */
|
|
41
|
+
readonly busy: Computed<boolean>;
|
|
42
|
+
/** Why the last call failed; null when it did not. Cleared as a call starts. */
|
|
43
|
+
readonly error: Computed<Failure | null>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Something the person does that the server must carry out. Resolves to what the server answered,
|
|
47
|
+
* or null when the call failed (then `error` says why) or was ignored while busy.
|
|
48
|
+
*/
|
|
49
|
+
export declare function action<A extends unknown[], R>(run: (...args: A) => Promise<R>): Action<A, R>;
|
|
@@ -282,6 +282,10 @@ export interface Query<T extends ModelTypes, Sel = T["scalars"]> extends Promise
|
|
|
282
282
|
}>;
|
|
283
283
|
aggregate<A extends T["aggregate"]>(query: A): Op<AggregateResult<T["model"], A>> & Sub<T["name"], NoInfer<A>>;
|
|
284
284
|
insert(data: T["insert"]): Op<T["id"]>;
|
|
285
|
+
/** The new row by `select`'s shape — its defaults, dates and files as stored: one call, nothing to read back. */
|
|
286
|
+
insert<S extends T["query"]>(data: T["insert"], options: {
|
|
287
|
+
select: S;
|
|
288
|
+
}): Promise<Rows<T, S>>;
|
|
285
289
|
update(id: IdArg<T["id"]>, data: T["update"]): Op<void>;
|
|
286
290
|
/** Applies `data` to every row the chain's `where` matches (all rows without one); resolves to the number of rows. */
|
|
287
291
|
updateMany(data: T["update"]): Op<number>;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { Field, FieldMeta } from "./fields";
|
|
10
10
|
import type { IdentityPublicFields, SessionPublicFields } from "../auth/models";
|
|
11
|
-
import type {
|
|
11
|
+
import type { FileWrite, StoredFile } from "../files/models";
|
|
12
12
|
import type { CompareNumValue, CompareRefListValue, CompareRefValue, CompareStrValue, CompareValue, CustomSearchValue, FullTextSearch, JsonCondition, JsonPathWhere, Op, PrimitiveListUpdate, Query as MarciQuery, RefListUpdate, RefListUpdateOrdered, RefUpdate, RefUpdateStruct, Rows, Sub, UpdateNumValue, VectorSearch, WhereValue } from "./marci/query";
|
|
13
13
|
export type Fields = Record<string, Field<any, any>>;
|
|
14
14
|
export type Model<F extends Fields = Fields> = {
|
|
@@ -66,7 +66,7 @@ export type Scalars<S, N extends keyof S> = Pick<Row<S, N>, (ScalarKeys<FieldsOf
|
|
|
66
66
|
export type ScalarSelect<S, N extends keyof S> = {
|
|
67
67
|
[K in (ScalarKeys<FieldsOf<S[N]>> | keyof Id<S, N>) & keyof Row<S, N>]: true;
|
|
68
68
|
};
|
|
69
|
-
type FieldInsert<S, Fld, M extends FieldMeta = MetaOf<Fld>> = M["kind"] extends "one" ? Nullable<M, Id<S, ModelName<S, Fld>>> : M["kind"] extends "many" | "list" ? Id<S, ModelName<S, Fld>>[] : M["kind"] extends "struct" ? Nullable<M, StructInsert<S, StructFieldsOf<Fld>>> : M["kind"] extends "file" ? Nullable<M, Arr<M,
|
|
69
|
+
type FieldInsert<S, Fld, M extends FieldMeta = MetaOf<Fld>> = M["kind"] extends "one" ? Nullable<M, Id<S, ModelName<S, Fld>>> : M["kind"] extends "many" | "list" ? Id<S, ModelName<S, Fld>>[] : M["kind"] extends "struct" ? Nullable<M, StructInsert<S, StructFieldsOf<Fld>>> : M["kind"] extends "file" ? Nullable<M, Arr<M, FileWrite>> : Nullable<M, Arr<M, TsOf<Fld>>>;
|
|
70
70
|
type RequiredKeys<F extends Fields> = {
|
|
71
71
|
[K in keyof F]: K extends IdKeys<F> ? never : MetaOf<F[K]>["optional"] extends true ? never : MetaOf<F[K]>["hasDefault"] extends true ? never : MetaOf<F[K]>["kind"] extends "many" | "list" ? never : MetaOf<F[K]>["kind"] extends "file" ? (MetaOf<F[K]>["array"] extends true ? never : K) : K;
|
|
72
72
|
}[keyof F];
|
|
@@ -80,7 +80,7 @@ type InsertOf<S, F extends Fields> = Simplify<{
|
|
|
80
80
|
}>;
|
|
81
81
|
export type Insert<S, N extends keyof S> = InsertOf<S, FieldsOf<S[N]>>;
|
|
82
82
|
type StructInsert<S, F extends Fields> = InsertOf<S, F>;
|
|
83
|
-
type FieldUpdate<S, Fld, M extends FieldMeta = MetaOf<Fld>> = M["kind"] extends "one" ? Nullable<M, RefUpdate<Id<S, ModelName<S, Fld>>>> : M["kind"] extends "many" ? RefListUpdate<Id<S, ModelName<S, Fld>>> : M["kind"] extends "list" ? RefListUpdateOrdered<Id<S, ModelName<S, Fld>>> : M["kind"] extends "struct" ? RefUpdateStruct<StructInsert<S, StructFieldsOf<Fld>>, UpdateOf<S, StructFieldsOf<Fld>>> | null : M["kind"] extends "file" ? Nullable<M, Arr<M,
|
|
83
|
+
type FieldUpdate<S, Fld, M extends FieldMeta = MetaOf<Fld>> = M["kind"] extends "one" ? Nullable<M, RefUpdate<Id<S, ModelName<S, Fld>>>> : M["kind"] extends "many" ? RefListUpdate<Id<S, ModelName<S, Fld>>> : M["kind"] extends "list" ? RefListUpdateOrdered<Id<S, ModelName<S, Fld>>> : M["kind"] extends "struct" ? RefUpdateStruct<StructInsert<S, StructFieldsOf<Fld>>, UpdateOf<S, StructFieldsOf<Fld>>> | null : M["kind"] extends "file" ? Nullable<M, Arr<M, FileWrite | StoredFile>> : M["array"] extends true ? TsOf<Fld>[] | PrimitiveListUpdate<TsOf<Fld>> : Nullable<M, TsOf<Fld> | (IsNum<M> extends true ? UpdateNumValue : never)>;
|
|
84
84
|
type UpdateOf<S, F extends Fields> = {
|
|
85
85
|
[K in Exclude<keyof F, IdKeys<F>>]?: FieldUpdate<S, F[K]>;
|
|
86
86
|
};
|
|
@@ -44,6 +44,13 @@ export type UploadedFile = {
|
|
|
44
44
|
readonly size: number;
|
|
45
45
|
readonly type: string;
|
|
46
46
|
};
|
|
47
|
+
/** What a file field is written with. A project's own type check sees the endpoint's `File` as the
|
|
48
|
+
* app's (global.d.ts: a name and a size — the type is read from the bytes on arrival), so the write
|
|
49
|
+
* asks for no more; what arrives is an `UploadedFile`. */
|
|
50
|
+
export type FileWrite = {
|
|
51
|
+
readonly name: string;
|
|
52
|
+
readonly size: number;
|
|
53
|
+
};
|
|
47
54
|
/** One `t.file()` field of the schema; `image` = it is a `t.image()`, with its rule. */
|
|
48
55
|
export type FileField = {
|
|
49
56
|
model: string;
|
|
@@ -29,6 +29,13 @@ type InputStyle = {
|
|
|
29
29
|
* still work in both modes. Scrolling never dismisses the keyboard on any setting.
|
|
30
30
|
*/
|
|
31
31
|
keyboardDismiss?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Takes the focus when its screen opens — the keyboard is up from the first moment. For a
|
|
34
|
+
* screen made for typing: a composer, a chat, a search, a one-field form; not the first field
|
|
35
|
+
* of a long form. Once per input (a screen shown again does not take the keyboard back); one
|
|
36
|
+
* per screen. The SDK's own behaviour over `focus()`: a design tool shows the screen as it opens.
|
|
37
|
+
*/
|
|
38
|
+
autofocus?: boolean;
|
|
32
39
|
/** Hard cap on the text length — enforced by the host while typing/pasting. */
|
|
33
40
|
maxLength?: number;
|
|
34
41
|
/** Auto-capitalization hint; omitted = platform default. */
|
|
@@ -7,6 +7,11 @@ export type UIVirtualizedListStyle = DrawableStyle & ElementStyle & {
|
|
|
7
7
|
keyboardDismissMode?: "interactive" | "scroll" | "none";
|
|
8
8
|
};
|
|
9
9
|
export interface VListConfig<T> {
|
|
10
|
+
/** The rows, read reactively: the list follows the signals this reads, the way a container's
|
|
11
|
+
* function children do. Rows are told apart by `keyOf`; a row whose item is another object
|
|
12
|
+
* re-renders. Appended rows and rows added at the start are told from a rewrite (a chat at
|
|
13
|
+
* its bottom follows what is appended; older history above moves nothing). */
|
|
14
|
+
data: () => T[];
|
|
10
15
|
/** Stable unique key of an item. */
|
|
11
16
|
keyOf: (item: T) => string;
|
|
12
17
|
/** Subtree factory — called when the item enters the window; the subtree lives until it
|
|
@@ -23,20 +28,9 @@ export interface VListConfig<T> {
|
|
|
23
28
|
inverted?: boolean;
|
|
24
29
|
}
|
|
25
30
|
/** A windowed (virtualized) list: only the items near the viewport are mounted — for long feeds
|
|
26
|
-
* and chats.
|
|
31
|
+
* and chats. Fed by `data`, a function over signals. */
|
|
27
32
|
export interface UIVirtualizedList<T = unknown> extends UIElementBase<UIVirtualizedListStyle> {
|
|
28
33
|
readonly type: "vlist";
|
|
29
|
-
/** Replace the data wholesale — vanished keys are unmounted by the window sync. */
|
|
30
|
-
setData(items: T[]): this;
|
|
31
|
-
/** Append items to the end (auto-scrolls when `inverted` and resting at the bottom). */
|
|
32
|
-
append(...items: T[]): this;
|
|
33
|
-
/** Insert at the start WITHOUT a scroll jump (the runtime compensates the offset). */
|
|
34
|
-
prepend(...items: T[]): this;
|
|
35
|
-
/** Update items with the same keys: mounted ones re-render; the cached height persists until
|
|
36
|
-
* re-measured. */
|
|
37
|
-
update(...items: T[]): this;
|
|
38
|
-
/** Remove items by key. */
|
|
39
|
-
removeByKey(...keys: string[]): this;
|
|
40
34
|
/** Number of data items (mounted or not). */
|
|
41
35
|
readonly itemCount: number;
|
|
42
36
|
/** The data item under `key`, if any. */
|
|
@@ -62,6 +56,7 @@ export declare class VListElement<T> extends Element<"vlist"> implements UIVirtu
|
|
|
62
56
|
private readonly erl;
|
|
63
57
|
private readonly strl;
|
|
64
58
|
private _refreshCallback?;
|
|
59
|
+
private keys;
|
|
65
60
|
private items;
|
|
66
61
|
private mounted;
|
|
67
62
|
private keyOf;
|
|
@@ -74,12 +69,10 @@ export declare class VListElement<T> extends Element<"vlist"> implements UIVirtu
|
|
|
74
69
|
private _inited;
|
|
75
70
|
constructor(config: VListConfig<T>);
|
|
76
71
|
private _ensure;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
update(...items: T[]): this;
|
|
82
|
-
removeByKey(...keys: string[]): this;
|
|
72
|
+
/** The data as it is now against what the runtime holds: rows added at the end or at the start
|
|
73
|
+
* are inserts (the runtime anchors the scroll: a chat follows an append, history above moves
|
|
74
|
+
* nothing), rows gone are removals, anything else a rewrite of the keys (measured heights stay). */
|
|
75
|
+
private _apply;
|
|
83
76
|
get itemCount(): number;
|
|
84
77
|
getItem(key: string): T | undefined;
|
|
85
78
|
scrollTo(offset: number, animated?: boolean): void;
|
|
@@ -90,6 +83,6 @@ export declare class VListElement<T> extends Element<"vlist"> implements UIVirtu
|
|
|
90
83
|
onEndReached(thresholdPx: number, callback: () => void): this;
|
|
91
84
|
onStartReached(thresholdPx: number, callback: () => void): this;
|
|
92
85
|
}
|
|
93
|
-
/** Create a virtualized list from a config (`keyOf` + `render` + `estimatedHeight`
|
|
94
|
-
*
|
|
86
|
+
/** Create a virtualized list from a config (`data` + `keyOf` + `render` + `estimatedHeight`
|
|
87
|
+
* required). Give it a size (`flexGrow: 1` as a screen body). */
|
|
95
88
|
export declare function UIVirtualizedList<T>(config: VListConfig<T>): UIVirtualizedList<T>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "2.
|
|
1
|
+
export declare const SDK_VERSION = "2.2.1";
|
|
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
|