@solidrt/flux-types 0.0.48 → 0.0.50

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/gui/gpu.d.ts CHANGED
@@ -397,9 +397,25 @@ declare module "flux:gpu" {
397
397
  * depth-tested additive pass usually pairs with `depthWrite: false`; with
398
398
  * writes on, unsorted geometry depth-rejects its own later fragments and
399
399
  * accumulation becomes draw-order-dependent. That pairing is the app's to
400
- * state - neither option implies the other.
401
- */
402
- export type BlendMode = "none" | "add"
400
+ * state - neither option implies the other. "multiply" scales
401
+ * (glBlendFunc(DST_COLOR, ZERO)): each fragment multiplies what is already
402
+ * in the target, all four channels, so it darkens where "add" brightens -
403
+ * a projected shadow, a dust pass. Order-independent like "add", same
404
+ * `depthWrite: false` pairing. On the premultiplied target a uniform factor
405
+ * across rgb and alpha fades the existing pixels; alpha 1 with rgb below 1
406
+ * darkens color only - so a strength-weighted shadow is
407
+ * `vec4(mix(vec3(1.0), shadowColor, strength), 1.0)`, not alpha =
408
+ * strength (that fades instead). "alpha" composites OVER
409
+ * (glBlendFunc(ONE, ONE_MINUS_SRC_ALPHA)): classic translucency, with the
410
+ * fragment written premultiplied like every target pixel -
411
+ * `vec4(color * a, a)`, never straight rgb with a loose alpha. It is the
412
+ * one order-DEPENDENT mode: the result follows draw-list order, so
413
+ * translucent geometry must land back-to-front - by draw-list ordering
414
+ * (`before`, `setDrawOrder`) or a sorting layer above - and normally after
415
+ * the opaque draws with `depthWrite: false`, so it depth-tests against them
416
+ * without occluding what it only tints. Nothing sorts for you here.
417
+ */
418
+ export type BlendMode = "none" | "add" | "multiply" | "alpha"
403
419
  /**
404
420
  * Face culling for a pipeline's draws. "none" (default) rasters both faces
405
421
  * - the two-sided fallback open surfaces need. "back" discards faces wound
@@ -5,15 +5,44 @@
5
5
  // module; requestFrame here only schedules a future frame.
6
6
 
7
7
  declare module "flux:rendertree" {
8
- /** Font options for {@link measureText}. */
8
+ /** Font options for {@link measureText} and {@link prepareText}. */
9
9
  export interface MeasureTextOptions {
10
10
  fontFamily?: "sans" | "serif" | "mono" | (string & {})
11
11
  fontSize?: number
12
12
  fontStyle?: "normal" | "italic"
13
13
  fontWeight?: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
14
+ lineHeight?: number
15
+ /** measureText only. */
14
16
  maxLines?: number
15
17
  }
16
18
 
19
+ /**
20
+ * One wrap unit (a word plus its trailing whitespace, or an empty unit at
21
+ * a blank line) of a {@link prepareText} result: everything the engine
22
+ * knows about it, for app-side line breaking.
23
+ */
24
+ export interface TextUnit {
25
+ /** The unit's text without its break characters. */
26
+ text: string
27
+ /** Offsets into the prepared text (JS string indexing), break characters included: the ranges tile the text. */
28
+ start: number
29
+ end: number
30
+ /** Horizontal extent including trailing whitespace: what the next unit's pen position advances by. */
31
+ advance: number
32
+ /** Ink extent without trailing whitespace: what the unit needs at the end of a line. */
33
+ width: number
34
+ ascent: number
35
+ descent: number
36
+ /** The unit ends at a hard line break (newline). */
37
+ hardBreak: boolean
38
+ }
39
+
40
+ /** The wrap units of a text in one font, shaped once. Plain data; layout is arithmetic over `units`. */
41
+ export interface PreparedText {
42
+ text: string
43
+ units: TextUnit[]
44
+ }
45
+
17
46
  /** Create the window root node with the given id. */
18
47
  export function createRoot(id: number): void
19
48
  /** Create a node of `kind` (the primitive element name) with the given id. */
@@ -61,9 +90,11 @@ declare module "flux:rendertree" {
61
90
  /** Request that a frame be rendered soon (coalesced by the demand-driven loop). */
62
91
  export function requestFrame(): void
63
92
  /**
64
- * Lay out, paint and submit the whole tree to the screen now (one frame). The
65
- * direct draw path for a flux + alloy app; requestFrame only schedules a
66
- * future frame and leaves the actual draw to the runner.
93
+ * Put the current tree on screen now (one frame). The direct draw path for
94
+ * a flux + alloy app; requestFrame only schedules a future frame and leaves
95
+ * the actual draw to the runner. When nothing changed since the last call
96
+ * the retained frame is re-presented instead of laid out and painted again;
97
+ * changed texture contents (uploads, camera frames) still show either way.
67
98
  */
68
99
  export function render(): void
69
100
  /**
@@ -71,6 +102,12 @@ declare module "flux:rendertree" {
71
102
  * adding it to the tree.
72
103
  */
73
104
  export function measureText(text: string, options?: MeasureTextOptions): { width: number, height: number }
105
+ /**
106
+ * Segment `text` into wrap units and shape each in the given font (through
107
+ * the shared word cache), for laying lines out in app code; see
108
+ * layoutNextLine in @solidrt/core. Single style; `maxLines` is ignored.
109
+ */
110
+ export function prepareText(text: string, options?: MeasureTextOptions): PreparedText
74
111
  /**
75
112
  * The node's bounding box from the most recent layout, relative to its
76
113
  * nearest positioning context (an ancestor with an explicit
package/gui/video.d.ts ADDED
@@ -0,0 +1,48 @@
1
+ // Video playback (gui-enabled runtime only). The imperative primitive;
2
+ // @solidrt/core wraps it with SolidJS reactivity. There is no video element:
3
+ // the player's `texture` id is displayed with <texture>/<d-texture>, and a
4
+ // richer Video component composes in a higher layer.
5
+
6
+ declare module "flux:video" {
7
+ import type { TextureId } from "flux:gpu"
8
+
9
+ /** An opened video: the frame texture plus controls bound to it. */
10
+ type VideoPlayer = {
11
+ /**
12
+ * GPU texture id decoded frames are uploaded into (use as a texture
13
+ * source). Holds the current frame; black until playback starts.
14
+ */
15
+ texture: TextureId
16
+ /** Frame width in pixels. */
17
+ width: number
18
+ /** Frame height in pixels. */
19
+ height: number
20
+ /** Duration in seconds. */
21
+ duration: number
22
+ /** Whether the file has a playable audio track. */
23
+ hasAudio: boolean
24
+ /** Start or resume playback. */
25
+ play(): void
26
+ /** Pause playback (the current frame stays displayed). */
27
+ pause(): void
28
+ /** Whether playback is running. */
29
+ playing(): boolean
30
+ /** Presentation time of the displayed frame, in seconds. */
31
+ currentTime(): number
32
+ /** Whether the last frame has been displayed. */
33
+ finished(): boolean
34
+ /** Stop playback and release the decoder, texture, and audio sink. */
35
+ close(): void
36
+ }
37
+
38
+ /**
39
+ * Open a video file (MP4 with H.264 video; AAC audio plays, other audio
40
+ * tracks are ignored). The path resolves like file() paths (through the
41
+ * app's assets in a packed app). Playback starts paused; call `play()`.
42
+ * Rejects when the file is unreadable or its codec unsupported.
43
+ *
44
+ * The built-in software decoder does not decode B-frames; encode dev
45
+ * content with `-bf 0` until the platform hardware decoders land.
46
+ */
47
+ export function open(path: string): Promise<VideoPlayer>
48
+ }
package/index.d.ts CHANGED
@@ -11,6 +11,7 @@
11
11
  /// <reference path="./modules/mdns.d.ts" />
12
12
  /// <reference path="./modules/wasm.d.ts" />
13
13
  /// <reference path="./modules/ffi.d.ts" />
14
+ /// <reference path="./modules/isolate.d.ts" />
14
15
 
15
16
  // Web-standard globals. The runtime is QuickJS, not a browser or Node, so it
16
17
  // ships no lib.dom / @types/bun: these declarations are the sole source for
@@ -32,6 +33,7 @@
32
33
  /// <reference path="./gui/microphone.d.ts" />
33
34
  /// <reference path="./gui/audio.d.ts" />
34
35
  /// <reference path="./gui/gpu.d.ts" />
36
+ /// <reference path="./gui/video.d.ts" />
35
37
  /// <reference path="./gui/raf.d.ts" />
36
38
 
37
39
  declare let Flux: {
package/modules/ffi.d.ts CHANGED
@@ -5,12 +5,26 @@ declare module "flux:ffi" {
5
5
  * loss). A number is also accepted where an i64 or ptr is expected.
6
6
  */
7
7
  type FfiValue = number | bigint
8
+ /**
9
+ * What a `symbols.*` call accepts per argument. Where a `ptr` is declared,
10
+ * an ArrayBuffer or typed array may be passed instead of an address: its
11
+ * data pointer (view offset respected) is handed to the native call and the
12
+ * buffer stays valid for the call's duration, so native code may read from
13
+ * and write into it (out-parameters, result buffers). Do not keep such an
14
+ * address past the call. A detached buffer throws.
15
+ */
16
+ type FfiArg = FfiValue | ArrayBuffer | ArrayBufferView
8
17
  type FfiTypeName = "i32" | "i64" | "f32" | "f64" | "ptr"
9
18
 
10
- /** One symbol declaration. `returns` defaults to "void". */
19
+ /**
20
+ * One symbol declaration. `returns` defaults to "void". A missing symbol
21
+ * fails the load unless `optional` is set, in which case its `symbols`
22
+ * entry is `undefined` (test for it before calling).
23
+ */
11
24
  type SymbolDecl = {
12
25
  args: FfiTypeName[]
13
26
  returns?: FfiTypeName | "void"
27
+ optional?: boolean
14
28
  }
15
29
 
16
30
  /** The symbols to resolve at load time, keyed by exported name. */
@@ -19,7 +33,9 @@ declare module "flux:ffi" {
19
33
  /**
20
34
  * A JS function backing a minted C function pointer. Called synchronously
21
35
  * while a `symbols.*` call is on the stack; its return value is coerced to
22
- * the callback's declared result type ("void" ignores it). A throw cannot
36
+ * the callback's declared result type ("void" ignores it). Unlike a call
37
+ * argument, a callback may not return a buffer as a ptr (the address would
38
+ * dangle once the callback returns). A throw cannot
23
39
  * abort the native frame: the callback returns zeroes, the native call runs
24
40
  * to completion, and the exception is rethrown after it returns.
25
41
  */
@@ -27,7 +43,8 @@ declare module "flux:ffi" {
27
43
 
28
44
  /**
29
45
  * A native shared library. The native counterpart of `flux:wasm`'s Module:
30
- * declare what you need up front, every declared symbol must resolve.
46
+ * declare what you need up front, every declared symbol must resolve
47
+ * (unless marked optional).
31
48
  *
32
49
  * There is NO sandbox: the library runs with full process rights, loading
33
50
  * runs its constructors, and a declared signature that does not match the
@@ -37,14 +54,15 @@ declare module "flux:ffi" {
37
54
  /**
38
55
  * Load a shared library from bytes (e.g. a bundled binary import; written
39
56
  * to a temp file behind the scenes) or a filesystem path, and resolve
40
- * every declared symbol. A missing symbol throws.
57
+ * every declared symbol. A missing symbol throws unless declared
58
+ * `optional`.
41
59
  */
42
60
  constructor(source: Uint8Array | ArrayBuffer | string, symbols: Symbols)
43
61
  /**
44
62
  * The declared symbols as bound JS functions, keyed by name. Destructure
45
63
  * once and reuse: the object is rebuilt on each access.
46
64
  */
47
- readonly symbols: Record<string, (...args: FfiValue[]) => FfiValue | undefined>
65
+ readonly symbols: Record<string, (...args: FfiArg[]) => FfiValue | undefined>
48
66
  /**
49
67
  * Mint a C function pointer (returned as a BigInt address) that invokes
50
68
  * `func` when the library calls it during a `symbols.*` call. Callbacks
@@ -53,11 +71,22 @@ declare module "flux:ffi" {
53
71
  */
54
72
  callback(func: CallbackFunction, decl: SymbolDecl): bigint
55
73
  /**
56
- * Copy `len` bytes out of process memory at `ptr`. No bounds checking is
57
- * possible: a bad pointer is undefined behavior.
74
+ * Copy `count` elements out of process memory at `ptr`, in native byte
75
+ * order. Without `type` (or with "u8") that is `count` bytes as a
76
+ * Uint8Array; with an ffi type name it is `count` elements as the matching
77
+ * typed array. No bounds checking is possible: a bad pointer is undefined
78
+ * behavior.
79
+ */
80
+ readMemory(ptr: FfiValue, count: number, type?: "u8"): Uint8Array
81
+ readMemory(ptr: FfiValue, count: number, type: "i32"): Int32Array
82
+ readMemory(ptr: FfiValue, count: number, type: "i64"): BigInt64Array
83
+ readMemory(ptr: FfiValue, count: number, type: "f32"): Float32Array
84
+ readMemory(ptr: FfiValue, count: number, type: "f64"): Float64Array
85
+ readMemory(ptr: FfiValue, count: number, type: "ptr"): BigUint64Array
86
+ /**
87
+ * Copy the bytes of a typed array or ArrayBuffer into process memory at
88
+ * `ptr`. Same caveat as readMemory.
58
89
  */
59
- readMemory(ptr: FfiValue, len: number): Uint8Array
60
- /** Copy `bytes` into process memory at `ptr`. Same caveat as readMemory. */
61
- writeMemory(ptr: FfiValue, bytes: Uint8Array | ArrayBuffer): void
90
+ writeMemory(ptr: FfiValue, bytes: ArrayBufferView | ArrayBuffer): void
62
91
  }
63
92
  }
@@ -0,0 +1,73 @@
1
+ declare module "flux:isolate" {
2
+ /**
3
+ * A value that can cross to or from an isolate: null (undefined becomes
4
+ * null), boolean, number, string, any typed-array view (arrives as a copy
5
+ * of the same kind: a Float32Array stays a Float32Array) or ArrayBuffer
6
+ * (arrives as a Uint8Array copy), arrays and plain objects of these.
7
+ * Anything else (functions, class instances, Date/Map/Set, BigInt, symbols)
8
+ * throws a TypeError as an argument and rejects the call as a result.
9
+ */
10
+ type Sendable =
11
+ | null
12
+ | undefined
13
+ | boolean
14
+ | number
15
+ | string
16
+ | ArrayBuffer
17
+ | ArrayBufferView
18
+ | Sendable[]
19
+ | { [key: string]: Sendable }
20
+
21
+ /** Options for {@link isolate}. */
22
+ type IsolateOptions = {
23
+ /** The child's `flux:process` `argv`. Default `[]`. */
24
+ args?: string[]
25
+ }
26
+
27
+ /**
28
+ * The isolate view of a module's exports: every function returns a Promise
29
+ * of what it returns in the isolate (an async function stays as it is); an
30
+ * async generator returns a stream to iterate with `for await` (one item is
31
+ * pulled per step; `break` ends the generator in the isolate); plus
32
+ * `terminate()`. Non-function exports are not reachable.
33
+ */
34
+ type Isolated<T> = {
35
+ [K in keyof T as T[K] extends (...args: any[]) => any ? K : never]: T[K] extends (...args: infer A) => infer R
36
+ ? 0 extends 1 & R // an `any` result (untyped module) is a plain call, not a stream
37
+ ? (...args: A) => Promise<any>
38
+ : R extends AsyncIterable<infer Y>
39
+ ? (...args: A) => AsyncIterableIterator<Y>
40
+ : (...args: A) => Promise<Awaited<R>>
41
+ : never
42
+ } & {
43
+ /**
44
+ * Kill the child now: busy JS is interrupted, the child runtime is
45
+ * dropped, pending and later calls reject. A handle that never called
46
+ * anything never spawned.
47
+ */
48
+ terminate(): void
49
+ }
50
+
51
+ /**
52
+ * A handle on an isolate module: a `"use isolate"` module in a SolidRT
53
+ * project (id = its path relative to the source root, without extension),
54
+ * or `<id>.js` next to the entry under standalone flux. Each property is
55
+ * an async function that runs the export of that name in a second runtime
56
+ * on its own thread (own heap, own event loop, the non-gui `flux:*`
57
+ * modules). Arguments and results are copied ({@link Sendable}).
58
+ *
59
+ * The child starts on the first call and lives until `terminate()` or the
60
+ * parent's end; module state persists between calls; each `isolate()` call
61
+ * is its own instance. Calls start in call order and run concurrently, as
62
+ * the same functions would in-process: a sync export runs to completion
63
+ * before anything else (one thread), an async export lets other calls and
64
+ * stream steps run at each `await`; an export that must not interleave with
65
+ * itself serialises inside the module. A throw in the export rejects that
66
+ * call (a throw in a generator rejects the pending step); an uncaught error
67
+ * that ends the child rejects pending and later calls with a message naming
68
+ * it. Awaiting a stream call rejects; iterating a plain call rejects. An
69
+ * open stream keeps both runtimes alive until it ends, `break`s, or the
70
+ * child is terminated. Reserved names: `terminate`, `then`.
71
+ */
72
+ export function isolate<T = Record<string, (...args: any[]) => any>>(id: string, opts?: IsolateOptions): Isolated<T>
73
+ }
package/modules/wasm.d.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  // There is no `WebAssembly` global in flux; this module is the entire wasm
2
- // surface. Imports must be scalar-signature functions only (no imported
2
+ // surface. Modules run in a pure interpreter (wasmi, no JIT), so this is a
3
+ // portability tool - one compiled module runs on every flux target with no
4
+ // native binaries or dlopen - not a speed tool. Tight typed compute runs
5
+ // somewhat faster than the same loop in JavaScript (a small constant
6
+ // factor, nowhere near browser wasm speed), and every host call costs
7
+ // extra marshalling, so call-heavy code can end up slower.
8
+ // Imports must be scalar-signature functions only (no imported
3
9
  // memory, globals or tables), which constrains the toolchain on the other
4
10
  // side: default emscripten output imports its memory and is rejected, while
5
11
  // `emcc -sSTANDALONE_WASM=1 --no-entry` produces a module that fits.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/flux-types",
3
- "version": "0.0.48",
3
+ "version": "0.0.50",
4
4
  "license": "MIT",
5
5
  "author": "Antoine van Wel",
6
6
  "types": "index.d.ts",