@solidrt/flux-types 0.0.51 → 0.0.52
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/README.md +3 -3
- package/gui/camera.d.ts +4 -3
- package/gui/gpu.d.ts +151 -24
- package/gui/rendertree.d.ts +20 -0
- package/gui/spatial.d.ts +188 -0
- package/index.d.ts +4 -1
- package/modules/fs.d.ts +33 -0
- package/modules/http.d.ts +3 -3
- package/modules/net.d.ts +2 -0
- package/modules/process.d.ts +36 -0
- package/modules/subprocess.d.ts +9 -0
- package/modules/tty.d.ts +69 -0
- package/package.json +1 -1
- package/standards/crypto.d.ts +18 -0
package/README.md
CHANGED
|
@@ -46,12 +46,12 @@ rely on must be named.
|
|
|
46
46
|
|
|
47
47
|
- `Flux` global (`version`, `capabilities`).
|
|
48
48
|
- `flux:*` modules: `flux:http`, `flux:fs`, `flux:sqlite`, `flux:subprocess`,
|
|
49
|
-
`flux:p2p`, `flux:net`, `flux:mdns`, `flux:process`, `flux:path`, `flux:wasm`, `flux:ffi`,
|
|
49
|
+
`flux:p2p`, `flux:net`, `flux:mdns`, `flux:process`, `flux:tty`, `flux:path`, `flux:wasm`, `flux:ffi`,
|
|
50
50
|
and (on a gui-enabled runtime)
|
|
51
|
-
`flux:camera`, `flux:microphone`, `flux:audio`, `flux:gpu`.
|
|
51
|
+
`flux:camera`, `flux:microphone`, `flux:audio`, `flux:gpu`, `flux:spatial`.
|
|
52
52
|
- Web-standard globals: `console`, `fetch` + `Headers`/`Request`/`Response`,
|
|
53
53
|
`setTimeout`/`setInterval`/`queueMicrotask`, `performance`, `WebSocket`,
|
|
54
|
-
`TextEncoder`/`TextDecoder`. These are deliberate subsets matching exactly what
|
|
54
|
+
`TextEncoder`/`TextDecoder`, `crypto.subtle.digest`. These are deliberate subsets matching exactly what
|
|
55
55
|
the runtime implements.
|
|
56
56
|
- GUI globals (gui-enabled runtime only): `requestAnimationFrame` /
|
|
57
57
|
`cancelAnimationFrame` (web-standard names, so kept global).
|
package/gui/camera.d.ts
CHANGED
|
@@ -65,9 +65,10 @@ declare module "flux:camera" {
|
|
|
65
65
|
* if permission is denied, and resolves once the first frame is ready. On
|
|
66
66
|
* Linux a session that delivers neither within 10 seconds rejects with a
|
|
67
67
|
* timeout error and releases the device (a wedged capture backend would
|
|
68
|
-
* otherwise hold it and never settle).
|
|
69
|
-
*
|
|
70
|
-
*
|
|
68
|
+
* otherwise hold it and never settle). The first open also starts the
|
|
69
|
+
* camera subsystem and waits for it (on every platform, up to 10 seconds,
|
|
70
|
+
* then rejects with a timeout), so there is no need to poll listCameras
|
|
71
|
+
* before opening.
|
|
71
72
|
*/
|
|
72
73
|
export function open(options?: CameraOpenOptions): Promise<CameraSession>
|
|
73
74
|
/**
|
package/gui/gpu.d.ts
CHANGED
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
// they return.
|
|
18
18
|
//
|
|
19
19
|
// Sampling is a per-texture property declared at creation: every create path
|
|
20
|
-
// accepts `{ filter?, wrap? }` ("linear"/"nearest", "clamp"/"repeat"
|
|
21
|
-
// defaults linear + clamp for every origin). The state
|
|
22
|
-
// everywhere it is sampled - shader passes and `<texture>`
|
|
23
|
-
// and survives id-stable resizes. It cannot be changed after
|
|
24
|
-
//
|
|
20
|
+
// accepts `{ filter?, wrap?, mipmap? }` ("linear"/"nearest", "clamp"/"repeat",
|
|
21
|
+
// boolean; defaults linear + clamp + no mips for every origin). The state
|
|
22
|
+
// follows the id everywhere it is sampled - shader passes and `<texture>`
|
|
23
|
+
// display alike - and survives id-stable resizes. It cannot be changed after
|
|
24
|
+
// creation. `mipmap: true` keeps a mip chain on the id, regenerated after
|
|
25
|
+
// every upload or render, so shader sampling minifies without aliasing.
|
|
25
26
|
//
|
|
26
27
|
// Compositing several targets is a render-tree job, not a shader one: stack
|
|
27
28
|
// `<texture>` elements and set their `blendMode` (the full Skia set, e.g.
|
|
@@ -103,8 +104,9 @@ declare module "flux:gpu" {
|
|
|
103
104
|
* call site: a name with no active uniform, a value whose length does not
|
|
104
105
|
* fit the declared type, a `sampler2D` named here (samplers bind via
|
|
105
106
|
* `textures`), or a value that is not a number / number array throws.
|
|
106
|
-
*
|
|
107
|
-
*
|
|
107
|
+
* A uniform that is declared but optimized out by the compiler is accepted
|
|
108
|
+
* with a warning and the write is skipped, so one param object can drive
|
|
109
|
+
* shader variants that do not all use every uniform.
|
|
108
110
|
* An `undefined` value is skipped, so conditional spreads stay usable.
|
|
109
111
|
*/
|
|
110
112
|
export type ShaderParams = Record<string, number | number[]>
|
|
@@ -118,8 +120,29 @@ declare module "flux:gpu" {
|
|
|
118
120
|
* sampler2D inputs AND `<texture src>` display (a "nearest" texture
|
|
119
121
|
* upscales with hard pixels on screen - the pixel-art path). `wrap` only
|
|
120
122
|
* matters to shaders sampling outside 0..1; the display draw never tiles.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
+
*
|
|
124
|
+
* `mipmap` (default false) keeps a mip chain on the id: rebuilt by the
|
|
125
|
+
* runtime after every upload (data textures) and every render (targets,
|
|
126
|
+
* automatically - nothing to schedule), and used by shader sampling when
|
|
127
|
+
* the texture is minified (trilinear for "linear", per-level nearest for
|
|
128
|
+
* "nearest"). Without it minification skips texels and aliases. Only
|
|
129
|
+
* shader sampling minifies through the chain; the `<texture>` display
|
|
130
|
+
* draw samples the full-size level. Regeneration is one GPU pass per
|
|
131
|
+
* upload or render, so a per-frame texture pays it per frame.
|
|
132
|
+
*/
|
|
133
|
+
export type SamplerOptions = { filter?: FilterMode; wrap?: WrapMode; mipmap?: boolean }
|
|
134
|
+
/**
|
|
135
|
+
* One `textures` binding value: a texture id, sampled with the texture's
|
|
136
|
+
* own declared state, or `{ id, filter?, wrap? }` to sample that id with a
|
|
137
|
+
* different filter and/or wrap in this binding only (blur a "nearest"
|
|
138
|
+
* atlas linearly; tile a clamped target in one consumer). The override is
|
|
139
|
+
* a per-pass deviation: the texture's own state stays what `<texture>`
|
|
140
|
+
* paints and what every binding without an override uses. `mipmap` is
|
|
141
|
+
* not overridable - the chain either exists on the id or it does not.
|
|
142
|
+
*/
|
|
143
|
+
export type TextureBinding = TextureId | { id: TextureId; filter?: FilterMode; wrap?: WrapMode }
|
|
144
|
+
/** Sampler2D inputs by uniform name; see {@link TextureBinding}. */
|
|
145
|
+
export type TextureBindings = Record<string, TextureBinding>
|
|
123
146
|
/**
|
|
124
147
|
* A free-form debug name every create accepts (WebGPU's label): surfaced by
|
|
125
148
|
* the dev server's GPU inventory (get_gpu_resources) and in engine log
|
|
@@ -243,7 +266,7 @@ declare module "flux:gpu" {
|
|
|
243
266
|
width: number,
|
|
244
267
|
height: number,
|
|
245
268
|
params?: ShaderParams | null,
|
|
246
|
-
opts?: { textures?:
|
|
269
|
+
opts?: { textures?: TextureBindings } & SamplerOptions & LabelOption,
|
|
247
270
|
): TextureId
|
|
248
271
|
/**
|
|
249
272
|
* Compile a single shader stage from raw GLSL ES: the primitive under
|
|
@@ -314,9 +337,12 @@ declare module "flux:gpu" {
|
|
|
314
337
|
* entry's buffer, from record 0 (ES 3.0 has no base instance), so
|
|
315
338
|
* several independently culled groups cannot share one buffer as
|
|
316
339
|
* sub-ranges: give each group its own `instanceBuffer` and entry, and
|
|
317
|
-
* cull it by `instanceCount`.
|
|
340
|
+
* cull it by `instanceCount`. Each attribute's `slot` (default 0)
|
|
341
|
+
* picks a buffer of the entry's `instanceBuffers` list (see
|
|
342
|
+
* {@link InstanceAttribute}); a pipeline using only slot 0 binds via
|
|
343
|
+
* the plain `instanceBuffer` key.
|
|
318
344
|
*/
|
|
319
|
-
instanceAttributes?:
|
|
345
|
+
instanceAttributes?: InstanceAttribute[]
|
|
320
346
|
topology?: Topology
|
|
321
347
|
blend?: BlendMode
|
|
322
348
|
cull?: CullMode
|
|
@@ -368,6 +394,18 @@ declare module "flux:gpu" {
|
|
|
368
394
|
* read-modify-write of its own pixels (decay, blur, simulation) still
|
|
369
395
|
* ping-pongs across two manual targets - a pass can never sample the
|
|
370
396
|
* texture it writes.
|
|
397
|
+
*
|
|
398
|
+
* `samples` (1, 2, 4 or 8; default 1) multisamples the target's storage:
|
|
399
|
+
* edges of filled geometry get coverage-weighted AA instead of binary
|
|
400
|
+
* jaggies. Storage only - the texture id still names a single-sample
|
|
401
|
+
* image, so display, sampling, `readTexture` and `copyTexture` are
|
|
402
|
+
* unaffected. The count is clamped to the device maximum and a
|
|
403
|
+
* configuration the driver refuses falls back to single-sample with a
|
|
404
|
+
* warning (read the effective value off the resource inventory). Cannot
|
|
405
|
+
* combine with `loadOp: "load"` (throws): multisampled storage cannot
|
|
406
|
+
* load the previous contents. Tiled mobile GPUs resolve in-tile
|
|
407
|
+
* (EXT_multisampled_render_to_texture); everywhere else a resolve blit
|
|
408
|
+
* follows each pass.
|
|
371
409
|
*/
|
|
372
410
|
export function createShaderTarget(
|
|
373
411
|
pipeline: RenderPipelineId,
|
|
@@ -375,12 +413,16 @@ declare module "flux:gpu" {
|
|
|
375
413
|
height: number,
|
|
376
414
|
params?: ShaderParams | null,
|
|
377
415
|
opts?: {
|
|
378
|
-
textures?:
|
|
416
|
+
textures?: TextureBindings
|
|
379
417
|
buffer?: BufferId
|
|
380
418
|
instanceBuffer?: BufferId
|
|
419
|
+
/** One buffer per instance slot of the pipeline (index = the
|
|
420
|
+
* attributes' `slot`); pass this OR `instanceBuffer`, not both. */
|
|
421
|
+
instanceBuffers?: BufferId[]
|
|
381
422
|
clearColor?: [number, number, number, number]
|
|
382
423
|
render?: "auto" | "manual"
|
|
383
424
|
loadOp?: "clear" | "load"
|
|
425
|
+
samples?: 1 | 2 | 4 | 8
|
|
384
426
|
} & (DrawRange | (IndexBinding & IndexRange)) &
|
|
385
427
|
SamplerOptions &
|
|
386
428
|
LabelOption,
|
|
@@ -392,6 +434,16 @@ declare module "flux:gpu" {
|
|
|
392
434
|
* immediately.
|
|
393
435
|
*/
|
|
394
436
|
export function destroyProgram(id: ProgramId): void
|
|
437
|
+
/**
|
|
438
|
+
* The vertex attributes a linked program actually reads (name and format),
|
|
439
|
+
* as the compiler left them: an `in` the vertex stage never uses is not
|
|
440
|
+
* listed, and a type no layout can feed (a matrix, an integer vector) is
|
|
441
|
+
* rejected at linkProgram. This is the list a pipeline over the program
|
|
442
|
+
* must cover between `attributes` and `instanceAttributes` - an uncovered
|
|
443
|
+
* or mis-formatted one throws at createRenderPipeline. Answered locally,
|
|
444
|
+
* no GPU round trip.
|
|
445
|
+
*/
|
|
446
|
+
export function programAttributes(program: ProgramId): VertexAttribute[]
|
|
395
447
|
export type Topology = "points" | "lines" | "line-strip" | "triangles" | "triangle-strip"
|
|
396
448
|
/**
|
|
397
449
|
* Blending for a pipeline's own draw. "none" (default) overwrites:
|
|
@@ -443,6 +495,17 @@ declare module "flux:gpu" {
|
|
|
443
495
|
* shader's `in` declarations.
|
|
444
496
|
*/
|
|
445
497
|
export type VertexAttribute = { name: string; format: "f32" | "vec2" | "vec3" | "vec4" }
|
|
498
|
+
/**
|
|
499
|
+
* One float attribute of a per-instance record. `slot` (default 0) picks
|
|
500
|
+
* which buffer of the entry's `instanceBuffers` list the attribute
|
|
501
|
+
* fetches from: attributes sharing a slot interleave into one record in
|
|
502
|
+
* list order, distinct slots are distinct buffers with their own strides
|
|
503
|
+
* - which is what lets two writers own instance data independently (a
|
|
504
|
+
* core-written pose buffer beside an app-written style buffer). Slots
|
|
505
|
+
* must be dense from 0, at most 4; a single-slot pipeline (every `slot`
|
|
506
|
+
* omitted) binds via the plain `instanceBuffer` key.
|
|
507
|
+
*/
|
|
508
|
+
export type InstanceAttribute = VertexAttribute & { slot?: number }
|
|
446
509
|
/**
|
|
447
510
|
* A pipeline target's draw as data, WebGPU-style: `firstVertex` +
|
|
448
511
|
* `vertexCount` pick the vertex range `[firstVertex, firstVertex +
|
|
@@ -492,6 +555,28 @@ declare module "flux:gpu" {
|
|
|
492
555
|
* there is no base vertex (ES 3.0, like ES 3.0's missing base instance).
|
|
493
556
|
*/
|
|
494
557
|
export type IndexRange = { firstIndex?: number; indexCount?: number; instanceCount?: number }
|
|
558
|
+
/**
|
|
559
|
+
* A draw entry's buffer swap: each key present re-points that role of the
|
|
560
|
+
* entry at another {@link createBuffer} buffer, absent keys keep their
|
|
561
|
+
* current buffer. Replace-only - the roles an entry fills are pipeline
|
|
562
|
+
* layout state (`attributes` needs a `buffer`, `instanceAttributes` an
|
|
563
|
+
* `instanceBuffer`) and indexing is its draw vocabulary, so naming a role
|
|
564
|
+
* the entry does not fill throws; `indexBuffer` travels with
|
|
565
|
+
* `indexFormat` as at create. The entry's current range is kept and
|
|
566
|
+
* rechecked against the new buffers' sizes: a swap to a buffer too small
|
|
567
|
+
* for the live range throws (shrink the range first); a larger buffer
|
|
568
|
+
* never does. This is the growth primitive: a population outgrowing its
|
|
569
|
+
* instance buffer creates a larger one, writes it, swaps, and destroys
|
|
570
|
+
* the old (the entry holds the old buffer alive until the swap lands, so
|
|
571
|
+
* either order is safe). `instanceBuffer` swaps slot 0;
|
|
572
|
+
* `instanceBuffers` swaps every slot at once and must fill exactly the
|
|
573
|
+
* slots the entry fills (pass one spelling or the other).
|
|
574
|
+
*/
|
|
575
|
+
export type BufferUpdate = {
|
|
576
|
+
buffer?: BufferId
|
|
577
|
+
instanceBuffer?: BufferId
|
|
578
|
+
instanceBuffers?: BufferId[]
|
|
579
|
+
} & ({} | IndexBinding)
|
|
495
580
|
|
|
496
581
|
/**
|
|
497
582
|
* Compile a GLSL ES vertex+fragment pipeline into an offscreen texture of
|
|
@@ -531,12 +616,15 @@ declare module "flux:gpu" {
|
|
|
531
616
|
height: number,
|
|
532
617
|
params?: ShaderParams | null,
|
|
533
618
|
opts?: {
|
|
534
|
-
textures?:
|
|
619
|
+
textures?: TextureBindings
|
|
535
620
|
attributes?: VertexAttribute[]
|
|
536
621
|
buffer?: BufferId
|
|
537
622
|
/** See {@link createRenderPipeline}'s `instanceAttributes`. */
|
|
538
|
-
instanceAttributes?:
|
|
623
|
+
instanceAttributes?: InstanceAttribute[]
|
|
539
624
|
instanceBuffer?: BufferId
|
|
625
|
+
/** One buffer per instance slot (index = the attributes' `slot`);
|
|
626
|
+
* pass this OR `instanceBuffer`, not both. */
|
|
627
|
+
instanceBuffers?: BufferId[]
|
|
540
628
|
topology?: Topology
|
|
541
629
|
depth?: boolean
|
|
542
630
|
depthWrite?: boolean
|
|
@@ -545,6 +633,7 @@ declare module "flux:gpu" {
|
|
|
545
633
|
clearColor?: [number, number, number, number]
|
|
546
634
|
render?: "auto" | "manual"
|
|
547
635
|
loadOp?: "clear" | "load"
|
|
636
|
+
samples?: 1 | 2 | 4 | 8
|
|
548
637
|
} & (DrawRange | (IndexBinding & IndexRange)) &
|
|
549
638
|
SamplerOptions &
|
|
550
639
|
LabelOption,
|
|
@@ -605,9 +694,13 @@ declare module "flux:gpu" {
|
|
|
605
694
|
* (On a manual target nothing renders here; the range applies at its next
|
|
606
695
|
* {@link renderTarget}.) An indexed target takes the {@link IndexRange}
|
|
607
696
|
* spelling instead, bounds-checked against its index buffer; the pair
|
|
608
|
-
* that does not match the target's mode throws.
|
|
697
|
+
* that does not match the target's mode throws. Buffer keys
|
|
698
|
+
* ({@link BufferUpdate}) swap the target's buffers in the same call: the
|
|
699
|
+
* merged range is checked against the swapped buffers, so one call grows a
|
|
700
|
+
* buffer and extends the range into it, and a call that throws changes
|
|
701
|
+
* nothing (range and buffers commit together or not at all).
|
|
609
702
|
*/
|
|
610
|
-
export function setDraw(id: TextureId, draw: DrawRange | IndexRange): void
|
|
703
|
+
export function setDraw(id: TextureId, draw: (DrawRange | IndexRange) & BufferUpdate): void
|
|
611
704
|
/**
|
|
612
705
|
* Create a draw target: a render target whose contents are an ordered,
|
|
613
706
|
* mutable LIST of draws - one render clears once, then executes every
|
|
@@ -623,6 +716,10 @@ declare module "flux:gpu" {
|
|
|
623
716
|
* occlusion work. It is the storage half of the depth story; whether an
|
|
624
717
|
* entry tests/writes depth is its pipeline's `depth`/`depthWrite` state,
|
|
625
718
|
* and adding a depth-testing pipeline to a target without storage throws.
|
|
719
|
+
* `depth: "texture"` is the same storage as a SAMPLEABLE depth texture
|
|
720
|
+
* with an id of its own - {@link depthTexture} - for shadow maps,
|
|
721
|
+
* depth-of-field, SSAO; it cannot combine with `samples` (a multisampled
|
|
722
|
+
* depth texture is not sampleable; the create throws).
|
|
626
723
|
*
|
|
627
724
|
* `params` seeds the target's SHARED params - the target-level values
|
|
628
725
|
* every entry reads, the same live channel {@link setTargetParams} drives
|
|
@@ -638,8 +735,9 @@ declare module "flux:gpu" {
|
|
|
638
735
|
* "auto"` target re-renders exactly when its entries or their inputs
|
|
639
736
|
* change - a static scene costs zero passes, however many entries it
|
|
640
737
|
* holds, and one render is ONE pass however many entries it draws.
|
|
641
|
-
* `render: "manual"
|
|
642
|
-
* {@link createShaderTarget}. With no entries a render is the clear
|
|
738
|
+
* `render: "manual"`, `loadOp: "load"` and `samples` compose exactly as
|
|
739
|
+
* on {@link createShaderTarget}. With no entries a render is the clear
|
|
740
|
+
* alone.
|
|
643
741
|
* Returns a texture id (display, resize, destroy like any target; entries
|
|
644
742
|
* die with it).
|
|
645
743
|
*/
|
|
@@ -648,14 +746,34 @@ declare module "flux:gpu" {
|
|
|
648
746
|
height: number,
|
|
649
747
|
params?: ShaderParams | null,
|
|
650
748
|
opts?: {
|
|
651
|
-
depth?: boolean
|
|
652
|
-
textures?:
|
|
749
|
+
depth?: boolean | "texture"
|
|
750
|
+
textures?: TextureBindings
|
|
653
751
|
clearColor?: [number, number, number, number]
|
|
654
752
|
render?: "auto" | "manual"
|
|
655
753
|
loadOp?: "clear" | "load"
|
|
754
|
+
samples?: 1 | 2 | 4 | 8
|
|
656
755
|
} & SamplerOptions &
|
|
657
756
|
LabelOption,
|
|
658
757
|
): TextureId
|
|
758
|
+
/**
|
|
759
|
+
* The depth texture of a draw target created with `depth: "texture"`: a
|
|
760
|
+
* texture id of its own, stable for the target's life (a
|
|
761
|
+
* {@link setTargetSize} follows the color), holding the target's depth
|
|
762
|
+
* after every render - 24-bit window depth in 0..1, read as `.r` from a
|
|
763
|
+
* `sampler2D`. Bind it anywhere a texture binds ({@link setTargetTextures}
|
|
764
|
+
* for a whole scene target, an entry's `textures`, a fragment target's
|
|
765
|
+
* inputs); the dependency graph treats a binding to it as a binding to its
|
|
766
|
+
* target, so the depth pass renders first and a target sampling its own
|
|
767
|
+
* depth throws. SAMPLER-ONLY: it is not an upload texture and not a
|
|
768
|
+
* readback source (`readTexture`/`copyTexture` throw - render it through a
|
|
769
|
+
* pass to read it), its sampling is fixed at `nearest`/`clamp` (a depth
|
|
770
|
+
* texture is only complete at nearest without a comparison mode - filter
|
|
771
|
+
* in the shader, e.g. a PCF loop), and it dies with its target
|
|
772
|
+
* (`destroyTexture` on it throws). Displaying it via `<texture src>`
|
|
773
|
+
* shows the depth in the red channel. Throws for a target without texture
|
|
774
|
+
* depth.
|
|
775
|
+
*/
|
|
776
|
+
export function depthTexture(target: TextureId): TextureId
|
|
659
777
|
/**
|
|
660
778
|
* Append a draw entry to a draw target: `pipeline` draws `opts.buffer`
|
|
661
779
|
* (required when the pipeline declares attributes) with its own `params`
|
|
@@ -690,9 +808,12 @@ declare module "flux:gpu" {
|
|
|
690
808
|
pipeline: RenderPipelineId,
|
|
691
809
|
params?: ShaderParams | null,
|
|
692
810
|
opts?: {
|
|
693
|
-
textures?:
|
|
811
|
+
textures?: TextureBindings
|
|
694
812
|
buffer?: BufferId
|
|
695
813
|
instanceBuffer?: BufferId
|
|
814
|
+
/** One buffer per instance slot of the pipeline (index = the
|
|
815
|
+
* attributes' `slot`); pass this OR `instanceBuffer`, not both. */
|
|
816
|
+
instanceBuffers?: BufferId[]
|
|
696
817
|
before?: DrawId
|
|
697
818
|
} & (DrawRange | (IndexBinding & IndexRange)),
|
|
698
819
|
): DrawId
|
|
@@ -760,7 +881,7 @@ declare module "flux:gpu" {
|
|
|
760
881
|
* everywhere it is declared, and each entry's effective inputs (its own
|
|
761
882
|
* plus the applicable shared ones) must fit the device's texture units.
|
|
762
883
|
*/
|
|
763
|
-
export function setTargetTextures(target: TextureId, textures:
|
|
884
|
+
export function setTargetTextures(target: TextureId, textures: TextureBindings): void
|
|
764
885
|
/**
|
|
765
886
|
* Resize a render target of any kind in place and re-render it: the id,
|
|
766
887
|
* compiled programs, last-applied params, sampler bindings, and draw
|
|
@@ -775,13 +896,19 @@ declare module "flux:gpu" {
|
|
|
775
896
|
* validation, and cycle rules. Entries bind independently - two entries
|
|
776
897
|
* may bind the same uniform name to different sources.
|
|
777
898
|
*/
|
|
778
|
-
export function setDrawTextures(target: TextureId, draw: DrawId, textures:
|
|
899
|
+
export function setDrawTextures(target: TextureId, draw: DrawId, textures: TextureBindings): void
|
|
779
900
|
/**
|
|
780
901
|
* Update one draw entry's draw range: {@link setDraw} addressed to a
|
|
781
902
|
* single entry, same partial merge, bounds validation, and vocabulary
|
|
782
903
|
* rule (an indexed entry speaks {@link IndexRange}).
|
|
783
904
|
*/
|
|
784
905
|
export function setDrawRange(target: TextureId, draw: DrawId, update: DrawRange | IndexRange): void
|
|
906
|
+
/**
|
|
907
|
+
* Swap one draw entry's buffers: the {@link BufferUpdate} half of
|
|
908
|
+
* {@link setDraw} addressed to a single entry, same replace-only rule and
|
|
909
|
+
* range recheck.
|
|
910
|
+
*/
|
|
911
|
+
export function setDrawBuffers(target: TextureId, draw: DrawId, update: BufferUpdate): void
|
|
785
912
|
/**
|
|
786
913
|
* Reorder a draw target's list. `order` must name every current entry
|
|
787
914
|
* exactly once - a full permutation of the live {@link DrawId}s; a
|
package/gui/rendertree.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// module; requestFrame here only schedules a future frame.
|
|
6
6
|
|
|
7
7
|
declare module "flux:rendertree" {
|
|
8
|
+
import type { TextureId } from "flux:gpu"
|
|
8
9
|
/** Font options for {@link measureText} and {@link prepareText}. */
|
|
9
10
|
export interface MeasureTextOptions {
|
|
10
11
|
fontFamily?: "sans" | "serif" | "mono" | (string & {})
|
|
@@ -77,6 +78,13 @@ declare module "flux:rendertree" {
|
|
|
77
78
|
|
|
78
79
|
/** Create the window root node with the given id. */
|
|
79
80
|
export function createRoot(id: number): void
|
|
81
|
+
/**
|
|
82
|
+
* Make `id`, an existing window node, the root again. Creating a window
|
|
83
|
+
* takes the root over, so this is the way back to an earlier window without
|
|
84
|
+
* recreating it (render()'s error boundary swapping the app's window back
|
|
85
|
+
* in on reset). No-op for the current root or an unknown id.
|
|
86
|
+
*/
|
|
87
|
+
export function setRoot(id: number): void
|
|
80
88
|
/** Create a node of `kind` (the primitive element name) with the given id. Throws an `Error` for a name that is not an element. */
|
|
81
89
|
export function createNode(id: number, kind: string): void
|
|
82
90
|
/** Insert `nodeId` under `parentId`, before `anchorId` if given (else appended). */
|
|
@@ -170,6 +178,18 @@ declare module "flux:rendertree" {
|
|
|
170
178
|
* semantics), for comparing against pointer event coordinates.
|
|
171
179
|
*/
|
|
172
180
|
export function getBoundingBoxViewport(id: number): { x: number, y: number, width: number, height: number } | null
|
|
181
|
+
/**
|
|
182
|
+
* The texture id of a snapshot repaint boundary's retained rasterization
|
|
183
|
+
* (its subtree's pixels at display scale, premultiplied, top-left origin,
|
|
184
|
+
* cropped to the layout box). Allocated on the first call and stable for
|
|
185
|
+
* the node's lifetime; it is re-pointed at the current pixels after every
|
|
186
|
+
* rasterization, so consumers never rebind. Before the first paint the id
|
|
187
|
+
* has no pixels yet (a `<texture>` measures 0x0, a shader pass skips the
|
|
188
|
+
* binding). Owned by the boundary: `destroyTexture` on it throws, and an
|
|
189
|
+
* unmounted boundary releases it through the deferred-destroy path. Throws
|
|
190
|
+
* if the node is not a snapshot boundary.
|
|
191
|
+
*/
|
|
192
|
+
export function snapshotTexture(id: number): TextureId
|
|
173
193
|
/**
|
|
174
194
|
* Parses a CSS color string (hex, rgb()/rgba(), hsl()/hsla(), hwb(),
|
|
175
195
|
* named colors) into packed 0xRRGGBBAA form (which the color property
|
package/gui/spatial.d.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// The spatial core (gui-enabled runtime only): a native transform hierarchy
|
|
2
|
+
// whose flush recomputes only the subtrees that changed and writes the
|
|
3
|
+
// results to draw sinks - a draw entry's `uModel` (+ `uNormal`) params and
|
|
4
|
+
// its instance count as the visibility switch. Generic on purpose: no camera,
|
|
5
|
+
// mesh or light concept. @solidrt/3d is the first consumer; any draw-list
|
|
6
|
+
// user with a tree of transforms (a 2D sprite scene, a skeleton) is the same
|
|
7
|
+
// shape. Node ids are plain numbers, generation-tagged and never reused, so
|
|
8
|
+
// a destroyed node's id throws everywhere.
|
|
9
|
+
//
|
|
10
|
+
// A transform argument is one Float32Array of 10: position xyz, unit
|
|
11
|
+
// quaternion xyzw, scale xyz. Writes queue the node; nothing reaches the
|
|
12
|
+
// GPU until flush(). worldMatrix() reads through pending writes.
|
|
13
|
+
|
|
14
|
+
declare module "flux:spatial" {
|
|
15
|
+
import type { BufferId, DrawId, TextureId } from "flux:gpu"
|
|
16
|
+
|
|
17
|
+
export type NodeId = number & { readonly __spatialNode: unique symbol }
|
|
18
|
+
|
|
19
|
+
/** A new root node. `visible: false` hides the node's whole subtree. */
|
|
20
|
+
export function createNode(transform: Float32Array, visible: boolean): NodeId
|
|
21
|
+
/** Free a node; its children become roots. A bound sink is dropped
|
|
22
|
+
* without a write (removing the entry is the caller's job). */
|
|
23
|
+
export function destroyNode(node: NodeId): void
|
|
24
|
+
/** Re-parent (null = make a root). Throws on a cycle. */
|
|
25
|
+
export function setParent(node: NodeId, parent: NodeId | null): void
|
|
26
|
+
/** Replace the local transform (compare before calling; an unchanged
|
|
27
|
+
* write still queues the node). Never consults or cancels transition
|
|
28
|
+
* tracks: a running track overwrites a raw write at the next frame
|
|
29
|
+
* (last write wins - the producer rule). */
|
|
30
|
+
export function setTransform(node: NodeId, transform: Float32Array): void
|
|
31
|
+
/**
|
|
32
|
+
* One node-transition spec, the element `transition` vocabulary minus
|
|
33
|
+
* the lifecycle conveniences: `{ duration }` / `{ duration, bounce }`
|
|
34
|
+
* is a spring (the default kind; retargets keep position and velocity,
|
|
35
|
+
* rotation springs keep angular velocity along the geodesic),
|
|
36
|
+
* `{ duration, curve }` a tween (rotation tweens slerp the geodesic;
|
|
37
|
+
* retargets restart from the current value), or the shorthand string
|
|
38
|
+
* `"<duration>ms [curve]"`. Durations in ms; no delay, from or exit.
|
|
39
|
+
*/
|
|
40
|
+
export type NodeTransitionSpec =
|
|
41
|
+
| { duration: number; bounce?: number }
|
|
42
|
+
| { duration: number; curve: "linear" | "ease" | "ease-in" | "ease-out" | "ease-in-out" | [number, number, number, number] }
|
|
43
|
+
| string
|
|
44
|
+
/** The declaration setTransition takes: a spec per transform component
|
|
45
|
+
* plus `all` as a catch-all (per-component entries win). */
|
|
46
|
+
export interface NodeTransition {
|
|
47
|
+
position?: NodeTransitionSpec
|
|
48
|
+
rotation?: NodeTransitionSpec
|
|
49
|
+
scale?: NodeTransitionSpec
|
|
50
|
+
all?: NodeTransitionSpec
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Declare (or with null clear) the node's transitions: with a config
|
|
54
|
+
* set, writeTransform animates instead of snapping. A bare string is
|
|
55
|
+
* the `all` catch-all. Clearing cancels the node's running tracks in
|
|
56
|
+
* place - it keeps its mid-flight transform, no settled events fire,
|
|
57
|
+
* and later writes snap. Replacing a config affects future writes only.
|
|
58
|
+
*/
|
|
59
|
+
export function setTransition(node: NodeId, transition: NodeTransition | string | null): void
|
|
60
|
+
/**
|
|
61
|
+
* Replace the local transform THROUGH the transition declaration: a
|
|
62
|
+
* declared component animates toward the written value (the write is a
|
|
63
|
+
* target), an undeclared one snaps. Without a declaration this is
|
|
64
|
+
* setTransform. A component matching its running track's target is
|
|
65
|
+
* left alone, so rewriting the whole array to move one component never
|
|
66
|
+
* restarts the others. Each settled component fires one
|
|
67
|
+
* "spatialTransitionEnd" engine event (srt:events), payload
|
|
68
|
+
* `{ node, component: "position" | "rotation" | "scale" }`.
|
|
69
|
+
*/
|
|
70
|
+
export function writeTransform(node: NodeId, transform: Float32Array): void
|
|
71
|
+
export function setVisible(node: NodeId, visible: boolean): void
|
|
72
|
+
/**
|
|
73
|
+
* Route the node's world matrix to one draw entry's `uModel` (and
|
|
74
|
+
* `uNormal`, the inverse-transpose, when `normal`). Validated like
|
|
75
|
+
* setDrawParams: the entry must exist and declare those uniforms. The
|
|
76
|
+
* entry is assumed switched off (instanceCount 0); the next flush turns it
|
|
77
|
+
* on with `count` when the node is shown, and off again when hidden.
|
|
78
|
+
* One draw sink PER TARGET: binding on a target the node already draws
|
|
79
|
+
* into replaces that sink, binding on another target adds one - a mesh
|
|
80
|
+
* drawn by a scene and by each of its views is one node with one flush.
|
|
81
|
+
*/
|
|
82
|
+
export function bindDraw(node: NodeId, target: TextureId, draw: DrawId, normal: boolean, count: number): void
|
|
83
|
+
/** Remove the node's draw sink on `target`, or every draw sink without
|
|
84
|
+
* one. Issues no write: the entries are the caller's to remove. */
|
|
85
|
+
export function unbindDraw(node: NodeId, target?: TextureId): void
|
|
86
|
+
/** Change every bound entry's "on" count (an instanced mesh's record
|
|
87
|
+
* count); written at once to the entries currently on. */
|
|
88
|
+
export function setDrawCount(node: NodeId, count: number): void
|
|
89
|
+
/** Fill `out` (a Float32Array of 16, column-major) with the node's world
|
|
90
|
+
* matrix as the tree stands now, pending writes included. */
|
|
91
|
+
export function worldMatrix(node: NodeId, out: Float32Array): void
|
|
92
|
+
/** Effective visibility (every ancestor visible too) as of the last flush. */
|
|
93
|
+
export function shown(node: NodeId): boolean
|
|
94
|
+
/** Recompute every changed subtree and write the sinks; requests a frame
|
|
95
|
+
* when anything was written. */
|
|
96
|
+
export function flush(): void
|
|
97
|
+
|
|
98
|
+
export type ShapeId = number & { readonly __spatialShape: unique symbol }
|
|
99
|
+
|
|
100
|
+
/** One hit of raycast(), nearest first. `face`/`uv`/`normal` are present
|
|
101
|
+
* for nodes with a shape (uv only when the shape has UVs); a node with
|
|
102
|
+
* bounds but no shape reports its local box, distance and point only. */
|
|
103
|
+
export type Hit = {
|
|
104
|
+
node: NodeId
|
|
105
|
+
/** World units along the normalized ray. */
|
|
106
|
+
distance: number
|
|
107
|
+
point: [number, number, number]
|
|
108
|
+
/** World-space geometric normal, facing the ray. */
|
|
109
|
+
normal?: [number, number, number]
|
|
110
|
+
/** Triangle index into the shape's index list. */
|
|
111
|
+
face?: number
|
|
112
|
+
uv?: [number, number]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Set (null clears) the node's LOCAL tight box [minX, minY, minZ, maxX,
|
|
116
|
+
* maxY, maxZ]. With one the node is in the picking index: its world box
|
|
117
|
+
* follows the flush; hidden nodes stay in and are skipped at query time. */
|
|
118
|
+
export function setBounds(node: NodeId, bounds: Float32Array | null): void
|
|
119
|
+
/**
|
|
120
|
+
* Triangle data for the picking narrowphase, one copy shared by every
|
|
121
|
+
* node that references it: positions read from an interleaved vertex
|
|
122
|
+
* array (`stride` floats per vertex, xyz at `posOffset`, uv at
|
|
123
|
+
* `uvOffset`, -1 for none) and a Uint16Array/Uint32Array triangle list.
|
|
124
|
+
* Throws on out-of-range indices.
|
|
125
|
+
*/
|
|
126
|
+
export function createShape(vertices: Float32Array, stride: number, posOffset: number, uvOffset: number, indices: Uint16Array | Uint32Array): ShapeId
|
|
127
|
+
/** Free a shape; nodes still referencing it fall back to their box. */
|
|
128
|
+
export function destroyShape(shape: ShapeId): void
|
|
129
|
+
export function setShape(node: NodeId, shape: ShapeId | null): void
|
|
130
|
+
/** Every shown node with bounds the ray strikes, nearest first. The
|
|
131
|
+
* direction need not be normalized; distances are world units. Reads
|
|
132
|
+
* the index as of the last flush. */
|
|
133
|
+
export function raycast(origin: Float32Array, direction: Float32Array): Hit[]
|
|
134
|
+
/**
|
|
135
|
+
* Every shown node with bounds whose local box, carried through its
|
|
136
|
+
* world transform, overlaps the world-axis box `bounds` (a Float32Array
|
|
137
|
+
* of 6: [minX, minY, minZ, maxX, maxY, maxZ]; touching counts, a point
|
|
138
|
+
* is min == max). Tested by separating axes, so a rotated flat rect -
|
|
139
|
+
* the 2d marquee case - tests exactly, never by its world AABB.
|
|
140
|
+
* Unordered; reads the index as of the last flush, like raycast.
|
|
141
|
+
*/
|
|
142
|
+
export function overlap(bounds: Float32Array): NodeId[]
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Route the world DIRECTION of the node's local `vector` (a
|
|
146
|
+
* Float32Array of 3) into
|
|
147
|
+
* vec3 slot `index` of the `len`-float shared array param `name` on a
|
|
148
|
+
* draw target: the flush writes `normalize(worldRotation * v)` there
|
|
149
|
+
* and re-sends the whole array when any slot changes; unbound slots are
|
|
150
|
+
* zeros. Every sink naming the same param shares one array (`len` must
|
|
151
|
+
* agree); what the slots mean - light directions, an emitter axis - is
|
|
152
|
+
* the caller's business, packed alongside its own non-spatial params.
|
|
153
|
+
* One slot sink per target, like bindDraw: rebinding on the same target
|
|
154
|
+
* replaces that sink (the abandoned slot zeroes), another target adds one.
|
|
155
|
+
*/
|
|
156
|
+
export function bindDirectionSlot(node: NodeId, target: TextureId, name: string, len: number, index: number, vector: Float32Array): void
|
|
157
|
+
/** Remove the node's slot sink on `target`, or every slot sink without
|
|
158
|
+
* one (the abandoned slots zero at the next flush). */
|
|
159
|
+
export function unbindSlot(node: NodeId, target?: TextureId): void
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Route the node's world pose to record slot `index` of vertex buffer
|
|
163
|
+
* `buffer` used as an instance buffer: the flush writes the 5 floats
|
|
164
|
+
* [x, y, angle, sx, sy] (world xy translation, rotation of the local x
|
|
165
|
+
* axis in the world xy plane, xy scale with sy negated when the matrix
|
|
166
|
+
* mirrors) at float offset index * 5. Writes batch: however many bound
|
|
167
|
+
* nodes moved, each flush issues at most one coalesced write per
|
|
168
|
+
* buffer, so producer-driven populations cost one buffer write per
|
|
169
|
+
* frame. A hidden node's slot zeroes (zero scale collapses the
|
|
170
|
+
* instance); so does an unbound or destroyed node's. Validated at bind
|
|
171
|
+
* time: the buffer must exist and the slot must fit its byte size.
|
|
172
|
+
* Rebinding replaces the node's record sink; the abandoned slot zeroes.
|
|
173
|
+
*/
|
|
174
|
+
export function bindPoseRecord(node: NodeId, buffer: BufferId, index: number): void
|
|
175
|
+
/** Remove the node's record sink (its slot zeroes at the next flush). */
|
|
176
|
+
export function unbindRecord(node: NodeId): void
|
|
177
|
+
/**
|
|
178
|
+
* Move every record sink on buffer `old` to buffer `new`, slot indices
|
|
179
|
+
* untouched: the growth swap. The whole used range republishes into
|
|
180
|
+
* `new` at the next flush, so a population outgrowing its buffer swaps
|
|
181
|
+
* in a larger one with one call and one bulk write instead of a
|
|
182
|
+
* bindPoseRecord per node (pair it with the draw entry's own buffer
|
|
183
|
+
* swap, setDraw's `instanceBuffers`). Throws when nothing is bound to
|
|
184
|
+
* `old`, when `new` does not exist or cannot hold every bound slot, or
|
|
185
|
+
* when `new` already carries record sinks.
|
|
186
|
+
*/
|
|
187
|
+
export function retargetRecords(old: BufferId, next: BufferId): void
|
|
188
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference path="./modules/process.d.ts" />
|
|
2
|
+
/// <reference path="./modules/tty.d.ts" />
|
|
2
3
|
/// <reference path="./modules/path.d.ts" />
|
|
3
4
|
/// <reference path="./modules/http.d.ts" />
|
|
4
5
|
/// <reference path="./modules/fs.d.ts" />
|
|
@@ -15,7 +16,7 @@
|
|
|
15
16
|
|
|
16
17
|
// Web-standard globals. The runtime is QuickJS, not a browser or Node, so it
|
|
17
18
|
// ships no lib.dom / @types/bun: these declarations are the sole source for
|
|
18
|
-
// console, fetch, the Fetch types, timers, WebSocket,
|
|
19
|
+
// console, fetch, the Fetch types, timers, WebSocket, the encoders, and crypto.
|
|
19
20
|
/// <reference path="./standards/console.d.ts" />
|
|
20
21
|
/// <reference path="./standards/time.d.ts" />
|
|
21
22
|
/// <reference path="./standards/text.d.ts" />
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
/// <reference path="./standards/fetch.d.ts" />
|
|
24
25
|
/// <reference path="./standards/websocket.d.ts" />
|
|
25
26
|
/// <reference path="./standards/abort.d.ts" />
|
|
27
|
+
/// <reference path="./standards/crypto.d.ts" />
|
|
26
28
|
|
|
27
29
|
// GUI capabilities (present only on a gui-enabled runtime). rendertree/camera/
|
|
28
30
|
// microphone/gpu are flux:* modules like the rest; requestAnimationFrame stays a
|
|
@@ -34,6 +36,7 @@
|
|
|
34
36
|
/// <reference path="./gui/microphone.d.ts" />
|
|
35
37
|
/// <reference path="./gui/audio.d.ts" />
|
|
36
38
|
/// <reference path="./gui/gpu.d.ts" />
|
|
39
|
+
/// <reference path="./gui/spatial.d.ts" />
|
|
37
40
|
/// <reference path="./gui/video.d.ts" />
|
|
38
41
|
/// <reference path="./gui/raf.d.ts" />
|
|
39
42
|
|
package/modules/fs.d.ts
CHANGED
|
@@ -34,6 +34,24 @@ declare module "flux:fs" {
|
|
|
34
34
|
write(data: string | Uint8Array): Promise<void>
|
|
35
35
|
/** Append `data` to the end of the file, creating it if missing. */
|
|
36
36
|
append(data: string | Uint8Array): Promise<void>
|
|
37
|
+
/** Remove the file. A missing file is not an error. */
|
|
38
|
+
remove(): Promise<void>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* One change under a watched directory. `path` is the absolute path of the
|
|
43
|
+
* entry. `rename` names the path a file now has (the target of a rename:
|
|
44
|
+
* an editor's atomic save shows up as one); the old name of a rename
|
|
45
|
+
* arrives as `remove`.
|
|
46
|
+
*/
|
|
47
|
+
type WatchEvent = {
|
|
48
|
+
kind: "create" | "modify" | "remove" | "rename"
|
|
49
|
+
path: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type WatchOptions = {
|
|
53
|
+
/** Watch the whole tree below the directory too. Default false. */
|
|
54
|
+
recursive?: boolean
|
|
37
55
|
}
|
|
38
56
|
|
|
39
57
|
type FluxDir = {
|
|
@@ -47,6 +65,13 @@ declare module "flux:fs" {
|
|
|
47
65
|
* already exists.
|
|
48
66
|
*/
|
|
49
67
|
create(): Promise<void>
|
|
68
|
+
/**
|
|
69
|
+
* Watch the directory for changes, calling `callback` for each one.
|
|
70
|
+
* Events are raw and undebounced: one save usually arrives as several,
|
|
71
|
+
* so coalesce them yourself. The watch keeps the process alive until the
|
|
72
|
+
* returned function is called. Throws if the directory does not exist.
|
|
73
|
+
*/
|
|
74
|
+
watch(callback: (event: WatchEvent) => void, options?: WatchOptions): () => void
|
|
50
75
|
}
|
|
51
76
|
|
|
52
77
|
/**
|
|
@@ -66,4 +91,12 @@ declare module "flux:fs" {
|
|
|
66
91
|
* @param path Path to the directory.
|
|
67
92
|
*/
|
|
68
93
|
export function dir(path: string): FluxDir
|
|
94
|
+
/**
|
|
95
|
+
* The canonical absolute path: symlinks resolved, `.`/`..` collapsed, the
|
|
96
|
+
* spelling the OS reports (no `\\?\` prefix on Windows). Rejects if the
|
|
97
|
+
* path does not exist.
|
|
98
|
+
*
|
|
99
|
+
* @param path Path to a file or directory.
|
|
100
|
+
*/
|
|
101
|
+
export function realpath(path: string): Promise<string>
|
|
69
102
|
}
|
package/modules/http.d.ts
CHANGED
|
@@ -149,7 +149,7 @@ declare module "flux:http" {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
type Server = {
|
|
152
|
-
/** The bound port. */
|
|
152
|
+
/** The bound port (the OS-assigned one when `port` was 0 or omitted). */
|
|
153
153
|
readonly port: number
|
|
154
154
|
/** The bound host/interface. */
|
|
155
155
|
readonly host: string
|
|
@@ -191,8 +191,8 @@ declare module "flux:http" {
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
type ServeOptions = {
|
|
194
|
-
/** Port to listen on. */
|
|
195
|
-
port
|
|
194
|
+
/** Port to listen on. 0 or omitted picks a free port; read it back from `server.port`. */
|
|
195
|
+
port?: number
|
|
196
196
|
/** Hostname/interface to bind. Defaults to "0.0.0.0" (all interfaces). */
|
|
197
197
|
host?: string
|
|
198
198
|
/**
|
package/modules/net.d.ts
CHANGED
|
@@ -43,6 +43,8 @@ declare module "flux:net" {
|
|
|
43
43
|
mac: string | null
|
|
44
44
|
/** Whether the interface is up. */
|
|
45
45
|
up: boolean
|
|
46
|
+
/** Whether it holds the default route (the interface other hosts reach). */
|
|
47
|
+
default: boolean
|
|
46
48
|
/** Whether it is a loopback interface. */
|
|
47
49
|
loopback: boolean
|
|
48
50
|
/** Whether it supports multicast. */
|
package/modules/process.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ declare module "flux:process" {
|
|
|
6
6
|
* argument.
|
|
7
7
|
*/
|
|
8
8
|
export let argv: string[]
|
|
9
|
+
/** The OS process id of this process (what a registry record or a `kill` names). */
|
|
10
|
+
export let pid: number
|
|
9
11
|
/** The host OS: "darwin", "win32", "linux", "android", ... */
|
|
10
12
|
export let platform: string
|
|
11
13
|
/** The CPU architecture: "x64", "arm64", ... */
|
|
@@ -16,6 +18,40 @@ declare module "flux:process" {
|
|
|
16
18
|
* provided for now.)
|
|
17
19
|
*/
|
|
18
20
|
export function memoryUsage(): { rss: number }
|
|
21
|
+
/**
|
|
22
|
+
* The current user's home directory, or `null` when the environment does
|
|
23
|
+
* not name one (HOME on unix, USERPROFILE on Windows).
|
|
24
|
+
*/
|
|
25
|
+
export function homedir(): string | null
|
|
26
|
+
/**
|
|
27
|
+
* The path of the running executable, or `null` when the OS cannot name it
|
|
28
|
+
* (Node's is always a string). What a dev tool spawns through
|
|
29
|
+
* `flux:subprocess` to start another instance of the runtime it runs in.
|
|
30
|
+
* In a packed app this is the app itself: spawning it launches that app,
|
|
31
|
+
* not a bare runtime.
|
|
32
|
+
*/
|
|
33
|
+
export let execPath: string | null
|
|
34
|
+
/**
|
|
35
|
+
* Terminate another process. Portable (SIGKILL / TerminateProcess), so
|
|
36
|
+
* there is no signal argument, unlike Node's `process.kill(pid, signal)`.
|
|
37
|
+
*
|
|
38
|
+
* @param pid The OS process id.
|
|
39
|
+
* @returns `true` when the process was terminated; `false` when it does not
|
|
40
|
+
* exist or the OS refused.
|
|
41
|
+
*/
|
|
42
|
+
export function kill(pid: number): boolean
|
|
43
|
+
/**
|
|
44
|
+
* Whether a process with `pid` exists. The `process.kill(pid, 0)` idiom
|
|
45
|
+
* under its own name. A zombie (exited, not yet reaped) counts as gone.
|
|
46
|
+
*
|
|
47
|
+
* @param pid The OS process id.
|
|
48
|
+
*/
|
|
49
|
+
export function alive(pid: number): boolean
|
|
50
|
+
/**
|
|
51
|
+
* The process environment, snapshotted when the module is evaluated: a
|
|
52
|
+
* plain object, not Node's live and writable `process.env`.
|
|
53
|
+
*/
|
|
54
|
+
export let env: Record<string, string | undefined>
|
|
19
55
|
/**
|
|
20
56
|
* Listen for an OS signal. The callback receives the signal name. Returns an
|
|
21
57
|
* unsubscribe function. Unix only; a no-op elsewhere.
|
package/modules/subprocess.d.ts
CHANGED
|
@@ -14,6 +14,15 @@ declare module "flux:subprocess" {
|
|
|
14
14
|
* as UTF-8 strings.
|
|
15
15
|
*/
|
|
16
16
|
encoding?: "buffer" | "utf8"
|
|
17
|
+
/**
|
|
18
|
+
* `spawn()` only: the child outlives this engine and this process. It is
|
|
19
|
+
* never killed on drop or reload, has no stdin/stdout/stderr pipes (all
|
|
20
|
+
* null: `stdout`/`stderr` iterate to nothing, `write` fails) and runs in
|
|
21
|
+
* its own process group, so a Ctrl+C to the parent does not reach it.
|
|
22
|
+
* `pid`, `kill()` and `status()` still work. Cannot combine with `stdin`.
|
|
23
|
+
* What a dev tool uses to launch another runtime instance.
|
|
24
|
+
*/
|
|
25
|
+
detached?: boolean
|
|
17
26
|
}
|
|
18
27
|
|
|
19
28
|
/** The buffered result of a child run to completion via {@link Command.output}. */
|
package/modules/tty.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
declare module "flux:tty" {
|
|
2
|
+
/**
|
|
3
|
+
* Whether stdin is a terminal this process can use. False for a pipe, a
|
|
4
|
+
* file, or no stdin at all (a GUI launch), the cases where nobody is there
|
|
5
|
+
* to prompt; on unix also false for a job backgrounded from an interactive
|
|
6
|
+
* shell (`cmd &`), which still has the terminal as stdin but would be
|
|
7
|
+
* stopped by job control the moment it touched it.
|
|
8
|
+
*/
|
|
9
|
+
export let isTTY: boolean
|
|
10
|
+
/** One key press in raw mode (see {@link setRawMode}). */
|
|
11
|
+
export interface Key {
|
|
12
|
+
/**
|
|
13
|
+
* Node's keypress names: "return", "backspace", "tab", "escape",
|
|
14
|
+
* "delete", "insert", "up", "down", "left", "right", "home", "end",
|
|
15
|
+
* "pageup", "pagedown", "space", "f1".."f12", or the lowercase letter
|
|
16
|
+
* or symbol typed.
|
|
17
|
+
*/
|
|
18
|
+
name: string
|
|
19
|
+
/** The character typed, with its case, for a printable key; else undefined. */
|
|
20
|
+
char: string | undefined
|
|
21
|
+
ctrl: boolean
|
|
22
|
+
/** Alt (Option) held. */
|
|
23
|
+
meta: boolean
|
|
24
|
+
shift: boolean
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Listen for input on stdin. `"line"` delivers one line per call as the
|
|
28
|
+
* terminal's own line discipline hands it over (cooked mode: the terminal
|
|
29
|
+
* does the editing), with the newline stripped; `"key"` delivers one key
|
|
30
|
+
* press per call while raw mode is on (and nothing arrives as a line
|
|
31
|
+
* then); `"close"` fires once when stdin reaches end of file (Ctrl-D in
|
|
32
|
+
* cooked mode, or the pipe closing). A listener holds the process alive
|
|
33
|
+
* until it unsubscribes; after `"close"` nothing can come, so every tty
|
|
34
|
+
* listener is dropped then, and a later `on` registers nothing. stdin is
|
|
35
|
+
* read once per process: a second engine in the same process (an isolate)
|
|
36
|
+
* gets no input.
|
|
37
|
+
*
|
|
38
|
+
* @param event `"line"`, `"key"` or `"close"`.
|
|
39
|
+
* @param callback Receives the line text or the {@link Key}; nothing for
|
|
40
|
+
* `"close"`.
|
|
41
|
+
* @returns An unsubscribe function.
|
|
42
|
+
*/
|
|
43
|
+
export function on(event: "line", callback: (line: string) => void): () => void
|
|
44
|
+
export function on(event: "key", callback: (key: Key) => void): () => void
|
|
45
|
+
export function on(event: "close", callback: () => void): () => void
|
|
46
|
+
/**
|
|
47
|
+
* Like {@link on}, but the listener fires at most once and then unsubscribes.
|
|
48
|
+
*/
|
|
49
|
+
export function once(event: "line", callback: (line: string) => void): () => void
|
|
50
|
+
export function once(event: "key", callback: (key: Key) => void): () => void
|
|
51
|
+
export function once(event: "close", callback: () => void): () => void
|
|
52
|
+
/**
|
|
53
|
+
* Switch the terminal's raw mode: no echo, no line editing, no signal keys
|
|
54
|
+
* (Ctrl-C arrives as a key), and stdin delivers `"key"` events instead of
|
|
55
|
+
* `"line"`s. The change applies from the next read: a line the terminal
|
|
56
|
+
* is already collecting is delivered as a line. Turn it off before
|
|
57
|
+
* exiting; the runtime also restores the terminal on exit and on a panic,
|
|
58
|
+
* but not on a kill. Throws when stdin is not a terminal.
|
|
59
|
+
*
|
|
60
|
+
* While raw, `console.log` output still breaks lines correctly (the
|
|
61
|
+
* runtime writes "\r\n"); your own {@link write} calls must use "\r\n".
|
|
62
|
+
*/
|
|
63
|
+
export function setRawMode(on: boolean): void
|
|
64
|
+
/**
|
|
65
|
+
* Write `text` to stdout as is and flush: no newline appended, unlike
|
|
66
|
+
* `console.log`. What a prompt needs.
|
|
67
|
+
*/
|
|
68
|
+
export function write(text: string): void
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// crypto. The Web Crypto surface flux provides: `subtle.digest` only. No key
|
|
2
|
+
// material, no encryption, no random: an app hashes bytes (content
|
|
3
|
+
// addressing, integrity checks) and the rest of the standard waits for a need.
|
|
4
|
+
|
|
5
|
+
interface SubtleCrypto {
|
|
6
|
+
/**
|
|
7
|
+
* Hash `data` (a Uint8Array or ArrayBuffer) with `algorithm`, one of
|
|
8
|
+
* "SHA-256", "SHA-384", "SHA-512" (as a string or `{ name }`). Resolves to
|
|
9
|
+
* the digest as an ArrayBuffer. Other algorithms (SHA-1 included) reject.
|
|
10
|
+
*/
|
|
11
|
+
digest(algorithm: string | { name: string }, data: Uint8Array | ArrayBuffer): Promise<ArrayBuffer>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface Crypto {
|
|
15
|
+
readonly subtle: SubtleCrypto
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare var crypto: Crypto
|