@opsydyn/effect-three-foldkit 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +99 -2
  4. package/dist/assets.d.ts +53 -0
  5. package/dist/assets.d.ts.map +1 -0
  6. package/dist/dom/animationFrames.d.ts +12 -0
  7. package/dist/dom/animationFrames.d.ts.map +1 -0
  8. package/dist/dom/canvas.d.ts +26 -0
  9. package/dist/dom/canvas.d.ts.map +1 -0
  10. package/dist/dom/latch.d.ts +15 -0
  11. package/dist/dom/latch.d.ts.map +1 -0
  12. package/dist/dom/models.d.ts +10 -0
  13. package/dist/dom/models.d.ts.map +1 -0
  14. package/dist/dom/overlays.d.ts +24 -0
  15. package/dist/dom/overlays.d.ts.map +1 -0
  16. package/dist/dom/pointer.d.ts +49 -0
  17. package/dist/dom/pointer.d.ts.map +1 -0
  18. package/dist/dom/postprocessing.d.ts +22 -0
  19. package/dist/dom/postprocessing.d.ts.map +1 -0
  20. package/dist/dom/property.d.ts +15 -0
  21. package/dist/dom/property.d.ts.map +1 -0
  22. package/dist/dom/reconciled.d.ts +10 -0
  23. package/dist/dom/reconciled.d.ts.map +1 -0
  24. package/dist/dom/renderSettings.d.ts +58 -0
  25. package/dist/dom/renderSettings.d.ts.map +1 -0
  26. package/dist/dom/typedScenes.d.ts +14 -0
  27. package/dist/dom/typedScenes.d.ts.map +1 -0
  28. package/dist/dom/updates.d.ts +8 -0
  29. package/dist/dom/updates.d.ts.map +1 -0
  30. package/dist/dom/viewport.d.ts +40 -0
  31. package/dist/dom/viewport.d.ts.map +1 -0
  32. package/dist/dom/webgl.d.ts +12 -0
  33. package/dist/dom/webgl.d.ts.map +1 -0
  34. package/dist/dom/webgpu.d.ts +23 -0
  35. package/dist/dom/webgpu.d.ts.map +1 -0
  36. package/dist/dom/webgpuPostprocessing.d.ts +4 -0
  37. package/dist/dom/webgpuPostprocessing.d.ts.map +1 -0
  38. package/dist/dom/xr.d.ts +53 -0
  39. package/dist/dom/xr.d.ts.map +1 -0
  40. package/dist/dom/xrGlide.d.ts +49 -0
  41. package/dist/dom/xrGlide.d.ts.map +1 -0
  42. package/dist/dom/xrHub.d.ts +45 -0
  43. package/dist/dom/xrHub.d.ts.map +1 -0
  44. package/dist/dom/xrInputs.d.ts +40 -0
  45. package/dist/dom/xrInputs.d.ts.map +1 -0
  46. package/dist/dom/xrSpaces.d.ts +33 -0
  47. package/dist/dom/xrSpaces.d.ts.map +1 -0
  48. package/dist/dom/xrTarget.d.ts +36 -0
  49. package/dist/dom/xrTarget.d.ts.map +1 -0
  50. package/dist/element.d.ts +771 -0
  51. package/dist/element.d.ts.map +1 -0
  52. package/dist/environment.d.ts +64 -0
  53. package/dist/environment.d.ts.map +1 -0
  54. package/dist/index.d.ts +32 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +2037 -0
  57. package/dist/index.js.map +38 -0
  58. package/dist/mount.d.ts +14 -0
  59. package/dist/mount.d.ts.map +1 -0
  60. package/dist/overlayView.d.ts +23 -0
  61. package/dist/overlayView.d.ts.map +1 -0
  62. package/dist/view.d.ts +179 -0
  63. package/dist/view.d.ts.map +1 -0
  64. package/dist/xr.d.ts +34 -0
  65. package/dist/xr.d.ts.map +1 -0
  66. package/package.json +72 -4
  67. package/src/assets.ts +151 -0
  68. package/src/dom/animationFrames.ts +32 -0
  69. package/src/dom/canvas.ts +54 -0
  70. package/src/dom/latch.ts +36 -0
  71. package/src/dom/models.ts +37 -0
  72. package/src/dom/overlays.ts +63 -0
  73. package/src/dom/pointer.ts +163 -0
  74. package/src/dom/postprocessing.ts +116 -0
  75. package/src/dom/property.ts +43 -0
  76. package/src/dom/reconciled.ts +51 -0
  77. package/src/dom/renderSettings.ts +117 -0
  78. package/src/dom/typedScenes.ts +21 -0
  79. package/src/dom/updates.ts +14 -0
  80. package/src/dom/viewport.ts +97 -0
  81. package/src/dom/webgl.ts +216 -0
  82. package/src/dom/webgpu.ts +204 -0
  83. package/src/dom/webgpuPostprocessing.ts +95 -0
  84. package/src/dom/xr.ts +211 -0
  85. package/src/dom/xrGlide.ts +114 -0
  86. package/src/dom/xrHub.ts +118 -0
  87. package/src/dom/xrInputs.ts +309 -0
  88. package/src/dom/xrSpaces.ts +287 -0
  89. package/src/dom/xrTarget.ts +71 -0
  90. package/src/element.ts +114 -0
  91. package/src/environment.ts +78 -0
  92. package/src/index.ts +71 -0
  93. package/src/mount.ts +305 -0
  94. package/src/overlayView.ts +71 -0
  95. package/src/view.ts +254 -0
  96. package/src/xr.ts +36 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,56 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (2026-10-18)
4
+
5
+ ### Features
6
+
7
+ - **effect-three-foldkit:** Foldkit adapter with WebGL renderer and browser tests ([5e2816d](https://github.com/opsydyn/fold-kit-experiments/commit/5e2816d4a46138777db0cb656a9c3436328c8be4))
8
+ - **effect-three-foldkit:** load textures and glTF models as Effects ([604fec2](https://github.com/opsydyn/fold-kit-experiments/commit/604fec2946b1eca818c3e783aab42d2c35454a7c))
9
+ - **effect-three-foldkit:** pixel ratio range and device ratio following ([58f8c30](https://github.com/opsydyn/fold-kit-experiments/commit/58f8c300aa0b4b22aae6bb932cc0aa2f91cc0120))
10
+ - **effect-three:** a rigid body per instance ([cc39435](https://github.com/opsydyn/fold-kit-experiments/commit/cc39435b878c781c7bf35e00e4b50ddc6d92b035))
11
+ - **effect-three:** a WebGPU renderer ([94a0964](https://github.com/opsydyn/fold-kit-experiments/commit/94a0964c723c9c8bea555a0054d52c2224fcc00c))
12
+ - **effect-three:** after R5 — WebGPU, render kits, glide, physics groups, XR spaces ([e5bde71](https://github.com/opsydyn/fold-kit-experiments/commit/e5bde71212353879d74aa32567c3eb9cbbeb38ac))
13
+ - **effect-three:** basic, lambert, phong, standard, physical and normal materials ([5baa690](https://github.com/opsydyn/fold-kit-experiments/commit/5baa690ef51dce7c1ae9ea53cfc0b6c70b9565c3))
14
+ - **effect-three:** benchmarks, API reports, package checks and CI browser tests ([5640b2d](https://github.com/opsydyn/fold-kit-experiments/commit/5640b2dc2a078642f15f157fa77b491e1443305d))
15
+ - **effect-three:** borrowed objects and lent textures ([6e4c010](https://github.com/opsydyn/fold-kit-experiments/commit/6e4c010bc21da24aadea61bee76b3a39963cda4a))
16
+ - **effect-three:** camera auto-rotate, and damping for view cameras ([c563b69](https://github.com/opsydyn/fold-kit-experiments/commit/c563b697753d8d2c0eed05ecfc935ad0d48f693a))
17
+ - **effect-three:** close the parity gaps and prepare the packages for npm ([994fe5d](https://github.com/opsydyn/fold-kit-experiments/commit/994fe5dd640583c787746a95e8465d8f051d78df))
18
+ - **effect-three:** colliders of a body's own, motors, contact forces and debug lines ([2a16c9e](https://github.com/opsydyn/fold-kit-experiments/commit/2a16c9e0f8432872e008bbd747eede1472c6ba44))
19
+ - **effect-three:** collision groups and colliders named in collisions ([9531a01](https://github.com/opsydyn/fold-kit-experiments/commit/9531a01f54e9e19b8ccc301152167d0ac52c3229))
20
+ - **effect-three:** declarative, diffed instancing ([26f70b3](https://github.com/opsydyn/fold-kit-experiments/commit/26f70b3ea5f20d5d4c33e36d3056bb15d2053334))
21
+ - **effect-three:** demo app, package builds and visual tests ([1649d49](https://github.com/opsydyn/fold-kit-experiments/commit/1649d496c3387eb63233665da4ccc6e1def2aa64))
22
+ - **effect-three:** Drei's shader grid, centring and environment presets ([a9467c7](https://github.com/opsydyn/fold-kit-experiments/commit/a9467c7580e24c0e93ee6742bb71ebd1da08a5e5))
23
+ - **effect-three:** eased transitions and sphere, plane and cylinder geometry ([26187f1](https://github.com/opsydyn/fold-kit-experiments/commit/26187f12e8ffed91993802c0128e2be03ea3ba41))
24
+ - **effect-three:** environment lighting and a shadow catcher ([023d2de](https://github.com/opsydyn/fold-kit-experiments/commit/023d2dedc8ab7b6a46a6ef23a1dc0f364af80816))
25
+ - **effect-three:** event bubbling paths, interactive groups and drag capture ([546a946](https://github.com/opsydyn/fold-kit-experiments/commit/546a94631923532bf5c11ff5b4ad7b19be64195e))
26
+ - **effect-three:** every hit carries the pointer's world-space ray ([a7b3a46](https://github.com/opsydyn/fold-kit-experiments/commit/a7b3a46aa09eecaa04d7c73158b5fbf388a12cb6))
27
+ - **effect-three:** frame-rate monitoring and render resolution ([64f9027](https://github.com/opsydyn/fold-kit-experiments/commit/64f902794d58bc5ef7bfbb19c0e2cbfa753e6f8b))
28
+ - **effect-three:** full pointer event set with R3F semantics ([d9c6366](https://github.com/opsydyn/fold-kit-experiments/commit/d9c6366931c5e6c7414ce3a4a04bd1ef8da6b019))
29
+ - **effect-three:** HTML overlays at points in the scene ([d0d016f](https://github.com/opsydyn/fold-kit-experiments/commit/d0d016f1896eb05927f154b0941662b7afc6112e))
30
+ - **effect-three:** immersive sessions (WebXR) ([9e003d1](https://github.com/opsydyn/fold-kit-experiments/commit/9e003d125813e2ce72477fd544242bc5b03cac73))
31
+ - **effect-three:** joints, and bodies no longer remade by rounding ([66ebf4d](https://github.com/opsydyn/fold-kit-experiments/commit/66ebf4d0a4bcd580699e9a7f371919397e95585c))
32
+ - **effect-three:** label colour ranges, curves, materials and layout ([ad9942e](https://github.com/opsydyn/fold-kit-experiments/commit/ad9942e49a540ab346a62fa00481c8c4d40ede11))
33
+ - **effect-three:** lent geometries and XR detected meshes ([832388b](https://github.com/opsydyn/fold-kit-experiments/commit/832388bbe6833d248d1d437f01c6e1a31aba08ce))
34
+ - **effect-three:** multiple views into one canvas ([b732a7c](https://github.com/opsydyn/fold-kit-experiments/commit/b732a7c4b6ddb50f846f71d4fa4401786a76d2a3))
35
+ - **effect-three:** orbit controls as data ([067af99](https://github.com/opsydyn/fold-kit-experiments/commit/067af99a443c1c3000bfb3e424ae43e5995366d0))
36
+ - **effect-three:** orthographic camera ([ac05a7e](https://github.com/opsydyn/fold-kit-experiments/commit/ac05a7e60307150e7707533b9ee14457ec5110ab))
37
+ - **effect-three:** physics as data, simulated by Rapier ([dd99e1c](https://github.com/opsydyn/fold-kit-experiments/commit/dd99e1cbde789e5b578ec6b28278893e5725b326))
38
+ - **effect-three:** post-processing effects ([1e2aa60](https://github.com/opsydyn/fold-kit-experiments/commit/1e2aa60533696b4db9158fd3de5d978bc601a063))
39
+ - **effect-three:** registered behaviours as data ([68eef53](https://github.com/opsydyn/fold-kit-experiments/commit/68eef530b7f43cb59ac45822064b0d1518887cc4))
40
+ - **effect-three:** render frames on demand ([9df4a06](https://github.com/opsydyn/fold-kit-experiments/commit/9df4a06adc9493a64fd0ef183e562c06568285fd))
41
+ - **effect-three:** render textures as data ([cbc5f3d](https://github.com/opsydyn/fold-kit-experiments/commit/cbc5f3d54a844ea623c28b9223a0561586771737))
42
+ - **effect-three:** scaffold Effect-native Three.js packages with Phase 0 ADRs ([02fa947](https://github.com/opsydyn/fold-kit-experiments/commit/02fa9476801e8609e311174023016b262e108427))
43
+ - **effect-three:** shadows and scene render settings ([4140595](https://github.com/opsydyn/fold-kit-experiments/commit/41405952fbe709ab6453f51b9cfd53b7e1adb40e))
44
+ - **effect-three:** sky and grid staging ([03e9f4f](https://github.com/opsydyn/fold-kit-experiments/commit/03e9f4f5c81a6dbe2a0e29720f768380ff86e737))
45
+ - **effect-three:** text geometry from lent typeface fonts ([c573453](https://github.com/opsydyn/fold-kit-experiments/commit/c573453ae3acef5356a184eb3030495ed08389af))
46
+ - **effect-three:** update telemetry, shared samples package and apps/web samples ([f7cd64d](https://github.com/opsydyn/fold-kit-experiments/commit/f7cd64da19496e6137d8daa669ada99cae01d546))
47
+ - **effect-three:** XR controllers, and VR in the toybox ([861f008](https://github.com/opsydyn/fold-kit-experiments/commit/861f0082819ad3b1898be9e86dd9c537de637cee))
48
+ - **effect-three:** XR hover and drag, hands, sticks, AR surfaces ([35597b9](https://github.com/opsydyn/fold-kit-experiments/commit/35597b937b2721b823040b2c67468d6ab9224fd0))
49
+ - **effect-three:** XR spaces, anchors, planes and DOM overlay ([0041c7c](https://github.com/opsydyn/fold-kit-experiments/commit/0041c7c9ebbe066f2c2300ae23283dfa68cc7451))
50
+ - **effect-three:** zoom to cursor, arrow keys and camera fitting ([e14224b](https://github.com/opsydyn/fold-kit-experiments/commit/e14224b5dc11ac1d371ce1061ad41ca73879fc6f))
51
+
52
+ ### Bug Fixes
53
+
54
+ - **effect-three-foldkit:** build the troika package before typechecking tests ([31df93f](https://github.com/opsydyn/fold-kit-experiments/commit/31df93f215dbedf865410e5384a21307ab367404))
55
+ - **effect-three-foldkit:** draw real WebGPU in Linux e2e ([fdf82e7](https://github.com/opsydyn/fold-kit-experiments/commit/fdf82e7815a901d09bea5fbd50769f398eded5c6))
56
+ - **effect-three-foldkit:** draw real WebGPU in Linux e2e ([186db41](https://github.com/opsydyn/fold-kit-experiments/commit/186db41bf649888f31e83c49db5bd4c23facd0e6))
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alan P Currie
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,100 @@
1
- # Temporary Holding Version
1
+ # @opsydyn/effect-three-foldkit
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A thin Foldkit adapter for [`@opsydyn/effect-three`](../effect-three/README.md): derive a Three.js scene from your Model, get pointer interaction back as your own typed Messages, and let Foldkit's runtime own the scene's lifetime.
4
+
5
+ > Status: `0.x`, released with the core at one version ([Stability](../effect-three/README.md#stability), [Limits](../effect-three/README.md#limits)). The API is documented in [`etc/effect-three-foldkit.api.md`](etc/effect-three-foldkit.api.md). Live samples are in `apps/web` at `/effect-three` and on the effect-three promo site (`apps/three-promo`); their source is in [`packages/effect-three-samples`](../effect-three-samples/).
6
+
7
+ ```sh
8
+ npm install @opsydyn/effect-three-foldkit @opsydyn/effect-three effect foldkit three
9
+ ```
10
+
11
+ ## Use it
12
+
13
+ ```ts
14
+ // entry: once per application
15
+ import * as EffectThreeFoldkit from '@opsydyn/effect-three-foldkit';
16
+
17
+ export const environment = EffectThreeFoldkit.makeEnvironment(window);
18
+ export const sceneMount = EffectThreeFoldkit.makeSceneMount(environment);
19
+ ```
20
+
21
+ ```ts
22
+ // message.ts
23
+ export const Message = defineMessageUnion({
24
+ ClickedCube: { key: Schema.String },
25
+ ReceivedSceneLifecycle: { lifecycle: EffectThreeFoldkit.SceneLifecycle },
26
+ });
27
+
28
+ // view.ts
29
+ EffectThreeFoldkit.view(
30
+ {
31
+ scene: sceneFor(model), // plain data derived from the Model
32
+ mount: sceneMount,
33
+ className: styles.scene, // the element needs a size
34
+ onLifecycle: (lifecycle) => Message.ReceivedSceneLifecycle({ lifecycle }),
35
+ onClick: ({ key }) => Message.ClickedCube({ key }),
36
+ },
37
+ h,
38
+ );
39
+ ```
40
+
41
+ - **Updates are in place.** Foldkit hands the element a new scene on every render, and the core diffs it, so unchanged scenes cost no host changes and changed ones reuse their three.js objects.
42
+ - **Animation never touches the Model.** Behaviours such as `spin` run in the frame loop, outside Foldkit's `update`.
43
+ - **Events are typed and opt-in:** `onClick`, `onDoubleClick`, `onContextMenu`, `onPointerDown`, `onPointerUp`, `onPointerEnter`, `onPointerMove`, `onPointerLeave`, `onPointerMissed`, `onWheel`, `onDrag`, `onDragEnd`, `onGesture`, `onCollision`, `onContactForce`, `onMeasured`, `onXRSession`, `onXRStick`, `onXRButton`, `onXRSurface`, `onPerformanceChange`, `onError` and `onReconciled`. Only the handlers you pass are bound. Hits carry the mesh key (and instance), world-space point, distance, face normal and uv.
44
+ - **Controls:** with `scene({ gestures: 'scene' })`, `onGesture` reports drags, the wheel and pinches; `orbit(model.camera, gesture)` moves a camera kept in the Model ([ADR-006](../../docs/effect-three/adr/006-controls-as-data.md)).
45
+ - **HTML overlays:** `overlays: [{ overlay, content }]` places Model-rendered HTML at points in the scene every drawn frame, as Drei's `Html`.
46
+ - **Groups and drags:** hits carry their ancestor `path`, and an `interactive` group makes every mesh inside it pickable. A press on a mesh captures the pointer, so `onDrag` keeps firing off the mesh and off the canvas; pair its `ray` with `pointOnPlane` to drag along a plane.
47
+ - **Pixel ratio:** `makeEnvironment(window, { pixelRatio: [1, 2] })` takes a fixed ratio or a `[min, max]` range around the device's (the default is `[1, 2]`, as React Three Fiber's `dpr`), and re-measures when the device ratio changes.
48
+ - **Assets:** `environment.assets.loadModel(id, url)`, `loadTexture(id, url)`, `loadFont(id, url)` and `loadEnvironment(id, url)` load glTF models, textures, typeface fonts and HDR panoramas as Effects for Commands (settle them into `AsyncData`), lend them to the store, and own them: loading an id again replaces and disposes the old asset, and `unload(id)` frees it. Show a model with `borrowed({ id, animation: play('wave') })`; use a texture with `map: id`, a font with `text({ font: id })`, a panorama with `environment({ map: id })` (Drei's presets: `environmentPresetUrl('city')`).
49
+ - **Engines:** `makeEnvironment(window, { physics: loadRapier(), labels: troikaLabels() })` adds the Rapier physics engine ([`effect-three-rapier`](../effect-three-rapier/README.md); scenes wait for it to load) and the troika label engine ([`effect-three-troika`](../effect-three-troika/README.md)). Without them, bodies stay put and labels are empty.
50
+ - **XR:** `environment.xr.supported(mode)`, `enter(mode)` and `exit` are Effects for Commands; `enter` (from a click) presents the mounted scene that describes `xr`, in VR or AR. Controllers and hands hover, click and drag; sticks, buttons and AR surfaces arrive through `onXRStick`, `onXRButton` and `onXRSurface` ([ADR-008](../../docs/effect-three/adr/008-immersive-sessions.md)).
51
+ - **Browser defaults:** a context menu over an interactive mesh keeps the browser's menu shut; elsewhere it opens as usual. Wheel listening is passive, so the page still scrolls.
52
+ - **Update telemetry:** `onReconciled` reports what each update did (created, updated, moved, removed, replaced, reordered) and the GPU resources held afterwards. It fires at startup and after updates that changed something, never for no-ops, so storing it in the Model can't loop.
53
+ - **Lifecycle:** `StartedScene` once the scene is running, or `FailedScene { reason }` (malformed or invalid scene, or no WebGL2).
54
+
55
+ ## What the Mount handles
56
+
57
+ | Concern | Behaviour |
58
+ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
59
+ | Unmount | Releases the renderer, the WebGL context (`forceContextLoss`), GPU resources, pointer listeners, observers and the frame subscription. |
60
+ | Resize | `ResizeObserver` updates the camera aspect and drawing buffer; device pixel ratio is capped at 2. |
61
+ | Off-screen | `IntersectionObserver` pauses frames while the element isn't visible. |
62
+ | Reduced motion | `prefers-reduced-motion: reduce` freezes behaviours; frames still render. |
63
+ | DevTools time travel | While Foldkit reports the view as `Paused`, pointer input and scene events are dropped. |
64
+ | Validation | Scenes passed through `view` are type-checked at compile time and skip runtime validation. Any other value assigned to the element is Schema-decoded, and failures arrive as `onError` with `MalformedScene`. |
65
+
66
+ `<effect-three-scene>` is never registered with `customElements`, so there's nothing to re-register under HMR or guard during SSR. See [ADR-002](../../docs/effect-three/adr/002-foldkit-adapter-seam.md).
67
+
68
+ ## Options
69
+
70
+ `makeEnvironment(window, options)` takes:
71
+
72
+ - `renderer`: a renderer factory per canvas: `webglRendererFactory` (the default) or `webgpuRendererFactory` (three's `WebGPURenderer`, with its WebGL 2 backend as fallback; labels are not drawn under it), or your own for test instrumentation (spread the factory you wrap, so its render kit comes along);
73
+ - `pixelRatio`: fixed, or `[min, max]` around the device's;
74
+ - `behaviours`: behaviours scenes may name with `behave(name)`, beside `float`;
75
+ - `physics`: a physics engine, or the promise of one (`loadRapier()`);
76
+ - `labels`: a label engine (`troikaLabels()`).
77
+
78
+ ## Development
79
+
80
+ ```sh
81
+ bun run test # unit tests
82
+ bun run test:e2e # Playwright in headless Chromium with SwiftShader
83
+ bun run check # strict lint
84
+ bun run build # dist JS and declarations
85
+ bun run api:check # public API report
86
+ ```
87
+
88
+ The browser tests prove the vertical slice end to end:
89
+
90
+ - typed click Messages;
91
+ - animation with zero `update` calls;
92
+ - in-place updates (pixel checks);
93
+ - full release on unmount, with listeners read through the Chrome DevTools Protocol;
94
+ - 20 mount/unmount cycles without WebGL context warnings;
95
+ - golden frames on a paused fake clock (`UPDATE_GOLDENS=1` rewrites them);
96
+ - three's renderer memory returning to baseline;
97
+ - the time-travel pause gate;
98
+ - contact shadows and the shader grid, by pixel;
99
+ - troika labels drawn once their font loads, and redrawn on change;
100
+ - WebXR sessions under Meta's IWER: presenting from the origin, controller hover, drag, sticks and buttons, tracked hands and pinches, and AR hit tests against a synthetic floor.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Loading textures, glTF models and typeface fonts by URL, as Effects an application runs
3
+ * from a Foldkit Command and settles into `AsyncData`. Each asset is lent to the shared
4
+ * resource store under an id: materials use a texture with `map: id`, a `borrowed({ id })`
5
+ * node shows a model, and `text({ font: id })` geometry draws with a font. The environment owns what it loads: loading an id again replaces and disposes
6
+ * the earlier asset, and `unload` or the environment's `dispose` frees it.
7
+ *
8
+ * @module
9
+ */
10
+ import type { ResourceStore } from '@opsydyn/effect-three';
11
+ import { Effect } from 'effect';
12
+ declare const AssetLoadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
13
+ readonly _tag: "AssetLoadError";
14
+ } & Readonly<A>;
15
+ /** An asset could not be fetched or decoded. */
16
+ export declare class AssetLoadError extends AssetLoadError_base<{
17
+ readonly url: string;
18
+ readonly cause: unknown;
19
+ }> {
20
+ }
21
+ /** What a loaded model offers: named parts to match hits against, and animation clips. */
22
+ export type ModelInfo = {
23
+ readonly id: string;
24
+ /** Names of the objects inside the model, as hits report them in `part`. */
25
+ readonly parts: ReadonlyArray<string>;
26
+ /** Names of the model's animation clips. */
27
+ readonly clips: ReadonlyArray<string>;
28
+ };
29
+ /** Creates the asset loader for a store. One per environment. */
30
+ export declare const makeAssets: (store: ResourceStore) => {
31
+ /** Loads a colour texture (sRGB) and lends it under `id`. Succeeds with the id. */
32
+ loadTexture: (id: string, url: string) => Effect.Effect<string, AssetLoadError, never>;
33
+ /** Loads a glTF or GLB model and lends its scene under `id`, with its clips. */
34
+ loadModel: (id: string, url: string) => Effect.Effect<ModelInfo, AssetLoadError, never>;
35
+ /**
36
+ * Loads an equirectangular HDR panorama (`.hdr`, three.js's `HDRLoader`) and lends it
37
+ * under `id` for `environment({ map: id })`. Succeeds with the id. Image panoramas
38
+ * load with `loadTexture`; the scene maps them for reflection.
39
+ */
40
+ loadEnvironment: (id: string, url: string) => Effect.Effect<string, AssetLoadError, never>;
41
+ /**
42
+ * Loads a typeface JSON font (three.js's `FontLoader` format, as Drei's `Text3D` takes)
43
+ * and lends it under `id`. Succeeds with the id.
44
+ */
45
+ loadFont: (id: string, url: string) => Effect.Effect<string, AssetLoadError, never>;
46
+ /** Withdraws and disposes the asset loaded under `id`, if any. */
47
+ unload: (id: string) => Effect.Effect<void, never, never>;
48
+ /** Withdraws and disposes every loaded asset. */
49
+ dispose: () => void;
50
+ };
51
+ export type Assets = ReturnType<typeof makeAssets>;
52
+ export {};
53
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAQ,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;AActC,gDAAgD;AAChD,qBAAa,cAAe,SAAQ,oBAAmC;IACrE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;CAAG;AAEL,0FAA0F;AAC1F,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,4CAA4C;IAC5C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACvC,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,UAAU,UAAW,aAAa;IA4D3C,mFAAmF;IACnF,WAAW,OAAO,MAAM,OAAO,MAAM;IAOrC,gFAAgF;IAChF,SAAS,OAAO,MAAM,OAAO,MAAM;IAOnC;;;;OAIG;IACH,eAAe,OAAO,MAAM,OAAO,MAAM;IAOzC;;;OAGG;IACH,QAAQ,OAAO,MAAM,OAAO,MAAM;IAOlC,kEAAkE;IAClE,MAAM,OAAO,MAAM;IAKnB,iDAAiD;IACjD,OAAO,QApDc,IAAI;CAsD5B,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * A `requestAnimationFrame` scheduler shared by every scene on the page: one browser
3
+ * callback per frame, running only while at least one scene is subscribed.
4
+ *
5
+ * @module
6
+ */
7
+ import type { FrameScheduler } from '@opsydyn/effect-three';
8
+ /** The part of `Window` the scheduler needs. */
9
+ export type AnimationFrameHost = Pick<Window, 'requestAnimationFrame' | 'cancelAnimationFrame'>;
10
+ /** Creates a shared animation-frame scheduler for `host` (normally `window`). */
11
+ export declare const animationFrameScheduler: (host: AnimationFrameHost) => FrameScheduler;
12
+ //# sourceMappingURL=animationFrames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animationFrames.d.ts","sourceRoot":"","sources":["../../src/dom/animationFrames.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,gDAAgD;AAChD,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,EAAE,uBAAuB,GAAG,sBAAsB,CAAC,CAAC;AAEhG,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,SAAU,kBAAkB,KAAG,cAmBlE,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The canvas a scene draws into, and DOM event dispatch from scene events.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Op, ResourceStore, SceneEvent } from '@opsydyn/effect-three';
7
+ import { type SceneError } from '../element.ts';
8
+ import type { Latch } from './latch.ts';
9
+ /** Creates a canvas filling `host` and appends it. */
10
+ export declare const appendCanvas: (host: Element) => HTMLCanvasElement;
11
+ /** Dispatches a scene event as the element's typed DOM event. */
12
+ export declare const dispatchSceneEvent: (element: Element, event: SceneEvent) => void;
13
+ /** Dispatches a rejected scene update as a `scene-error` event. */
14
+ export declare const dispatchSceneError: (element: Element, error: SceneError) => void;
15
+ /** Thunk builders, so Effect code can run DOM work with `Effect.sync(thunk)`. */
16
+ export declare const canvasIn: (host: Element) => () => HTMLCanvasElement;
17
+ export declare const removal: (node: ChildNode) => () => void;
18
+ /** Dispatches only while `live` is open: events are dropped during time-travel pause. */
19
+ export declare const sceneEventDispatch: (element: Element, live: Latch) => (event: SceneEvent) => () => void;
20
+ export declare const sceneErrorDispatch: (element: Element) => (error: SceneError) => () => void;
21
+ /**
22
+ * Dispatches a `scene-reconciled` summary when an update changed something. Updates with
23
+ * no operations dispatch nothing, so an app storing the summary in its Model can't loop.
24
+ */
25
+ export declare const reconciledDispatch: (element: Element, store: ResourceStore) => (ops: ReadonlyArray<Op>) => () => void;
26
+ //# sourceMappingURL=canvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas.d.ts","sourceRoot":"","sources":["../../src/dom/canvas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE3E,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,sDAAsD;AACtD,eAAO,MAAM,YAAY,SAAU,OAAO,KAAG,iBAS5C,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,YAAa,OAAO,SAAS,UAAU,KAAG,IAExE,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,kBAAkB,YAAa,OAAO,SAAS,UAAU,KAAG,IAExE,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,QAAQ,SAAU,OAAO,4BAA6B,CAAC;AACpE,eAAO,MAAM,OAAO,SAAU,SAAS,eAAwB,CAAC;AAChE,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,YAAa,OAAO,QAAQ,KAAK,aAAa,UAAU,eAEtF,CAAC;AACF,eAAO,MAAM,kBAAkB,YAAa,OAAO,aAAa,UAAU,eACtC,CAAC;AAErC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,YACnB,OAAO,SAAS,aAAa,WAAW,aAAa,CAAC,EAAE,CAAC,eAKlE,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * A boolean read synchronously by DOM callbacks and written by Effect code.
3
+ *
4
+ * @module
5
+ */
6
+ export type Latch = {
7
+ readonly isOpen: () => boolean;
8
+ readonly set: (open: boolean) => void;
9
+ };
10
+ export declare const createLatch: (open: boolean) => Latch;
11
+ /** Calls `route` only while `latch` is open, returning what it routed (nothing when shut). */
12
+ export declare const routedWhileOpen: <A, B>(latch: Latch, route: (value: A) => ReadonlyArray<B>) => (value: A) => ReadonlyArray<B>;
13
+ /** A thunk calling `f(value)`, so Effect code can write `Effect.sync(applying(f, value))`. */
14
+ export declare const applying: <A, B>(f: (value: A) => B, value: A) => () => B;
15
+ //# sourceMappingURL=latch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"latch.d.ts","sourceRoot":"","sources":["../../src/dom/latch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,OAAO,KAAG,KAQ3C,CAAC;AAIF,8FAA8F;AAC9F,eAAO,MAAM,eAAe,GACzB,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,aAClD,CAAC,KAAG,aAAa,CAAC,CAAC,CAG1B,CAAC;AAEJ,8FAA8F;AAC9F,eAAO,MAAM,QAAQ,GAClB,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,WAC/B,CACM,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Plain three.js helpers for loaded models.
3
+ *
4
+ * @module
5
+ */
6
+ import { type Object3D } from 'three';
7
+ /** Disposes a loaded model's GPU resources: it was ours, not the application's. */
8
+ export declare const disposeModel: (root: Object3D) => void;
9
+ export declare const namesIn: (root: Object3D) => ReadonlyArray<string>;
10
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/dom/models.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAuB,KAAK,QAAQ,EAAW,MAAM,OAAO,CAAC;AAoBpE,mFAAmF;AACnF,eAAO,MAAM,YAAY,SAAU,QAAQ,KAAG,IAE7C,CAAC;AAEF,eAAO,MAAM,OAAO,SAAU,QAAQ,KAAG,aAAa,CAAC,MAAM,CAM5D,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Moves the application's overlay HTML to where the scene placed each overlay, as Drei's
3
+ * `Html` does every frame (`src/web/Html.tsx` at `bf6f4ad`): a translate to the point,
4
+ * the distance scale, centring, the depth's z-index, and hiding when not visible.
5
+ *
6
+ * @module
7
+ */
8
+ import type { OverlayPlacement } from '@opsydyn/effect-three';
9
+ /** The data attribute naming the overlay an element's HTML belongs to. */
10
+ export declare const overlayData: {
11
+ readonly key: 'effect-three-overlay';
12
+ readonly attribute: 'data-effect-three-overlay';
13
+ };
14
+ export type OverlayWriter = {
15
+ /** Takes the latest placements and writes them. */
16
+ readonly place: (placements: ReadonlyArray<OverlayPlacement>) => void;
17
+ /** Writes the latest placements again, for overlay elements the view has just made. */
18
+ readonly rewrite: () => void;
19
+ };
20
+ /** Creates the writer for overlays rendered inside `host`. */
21
+ export declare const createOverlayWriter: (host: Element) => OverlayWriter;
22
+ /** Makes the scene element the overlays' containing block, unless it already is one. */
23
+ export declare const containOverlays: (host: Element) => () => void;
24
+ //# sourceMappingURL=overlays.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlays.d.ts","sourceRoot":"","sources":["../../src/dom/overlays.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,0EAA0E;AAC1E,eAAO,MAAM,WAAW;aACtB,GAAG,EAAE,sBAAsB;aAC3B,SAAS,EAAE,2BAA2B;CAC9B,CAAC;AAkBX,MAAM,MAAM,aAAa,GAAG;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACtE,uFAAuF;IACvF,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,mBAAmB,SAAU,OAAO,KAAG,aAiBnD,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,eAAe,SAAU,OAAO,WAAS,IAGrD,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * DOM pointer events to the kernel's normalised device coordinates.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Gestures, PointerInput, SceneEvent } from '@opsydyn/effect-three';
7
+ /** The part of `DOMRect` the conversion needs. */
8
+ export type Rect = {
9
+ readonly left: number;
10
+ readonly top: number;
11
+ readonly width: number;
12
+ readonly height: number;
13
+ };
14
+ /** Client coordinates to NDC: x and y in [-1, 1], y up. A zero-sized rect maps to the centre. */
15
+ export declare const toNdc: (rect: Rect, clientX: number, clientY: number) => {
16
+ readonly x: number;
17
+ readonly y: number;
18
+ };
19
+ /**
20
+ * Converts a DOM pointer, mouse or wheel event into kernel input, or `undefined` for
21
+ * other event types. Pointer cancel is treated as leaving the surface.
22
+ */
23
+ export declare const toPointerInput: (event: MouseEvent, rect: Rect) => PointerInput | undefined;
24
+ /** True when a press landed on an interactive mesh, which then captures the pointer. */
25
+ export declare const capturesPointer: (events: ReadonlyArray<SceneEvent>) => boolean;
26
+ /** True when the scene handled a context-menu input, so the browser menu should not open. */
27
+ export declare const claimsContextMenu: (events: ReadonlyArray<SceneEvent>) => boolean;
28
+ /**
29
+ * Forwards pointer, mouse and wheel input from `element`. `onInput` returns the scene
30
+ * events it produced. By default the page keeps its gestures: wheel and touch scroll it,
31
+ * and the browser's menu opens except over an interactive mesh that handles it. A press
32
+ * on a mesh captures the pointer.
33
+ *
34
+ * While `claimsGestures()` is true the scene owns them, as three.js's `OrbitControls` does
35
+ * when connected: every press captures the pointer, the wheel does not scroll the page,
36
+ * and the context menu stays shut (the right button pans). Returns a function that
37
+ * removes every listener.
38
+ */
39
+ export declare const listenForPointer: (element: HTMLElement, onInput: (input: PointerInput) => ReadonlyArray<SceneEvent>, claimsGestures?: () => boolean) => (() => void);
40
+ /** Whatever reports the scene's claim on gestures: its graph. */
41
+ type GestureOwner = {
42
+ readonly gestures: () => Gestures;
43
+ };
44
+ /** Whether the scene currently claims the pointer's gestures. */
45
+ export declare const claimsGestures: (owner: GestureOwner) => () => boolean;
46
+ /** Lets the browser pan and zoom on touch, or not while the scene claims gestures. */
47
+ export declare const touchActionSync: (element: HTMLElement, owner: GestureOwner) => () => void;
48
+ export {};
49
+ //# sourceMappingURL=pointer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../../src/dom/pointer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAa,YAAY,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE3F,kDAAkD;AAClD,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,KAAK,SACV,IAAI,WACD,MAAM,WACN,MAAM,KACd;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CAM1C,CAAC;AAmBF;;;GAGG;AACH,eAAO,MAAM,cAAc,UAAW,UAAU,QAAQ,IAAI,KAAG,YAAY,GAAG,SAsC7E,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,eAAe,WAAY,aAAa,CAAC,UAAU,CAAC,KAAG,OACd,CAAC;AAEvD,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB,WAAY,aAAa,CAAC,UAAU,CAAC,KAAG,OAChB,CAAC;AAavD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,YAClB,WAAW,WACX,CAAC,KAAK,EAAE,YAAY,KAAK,aAAa,CAAC,UAAU,CAAC,mBAC3C,MAAM,OAAO,KAC5B,CAAC,MAAM,IAAI,CA2Bb,CAAC;AAEF,iEAAiE;AACjE,KAAK,YAAY,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,QAAQ,CAAA;CAAE,CAAC;AAE1D,iEAAiE;AACjE,eAAO,MAAM,cAAc,UAAW,YAAY,WAAS,OAAuC,CAAC;AAEnG,sFAAsF;AACtF,eAAO,MAAM,eAAe,YAAa,WAAW,SAAS,YAAY,WAAS,IAGjF,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Post-processing for the WebGL renderer: three.js's `EffectComposer`, built from the
3
+ * scene's `render.effects` and rebuilt only when they change. With no effects the scene
4
+ * renders straight to the screen and no composer exists.
5
+ *
6
+ * The composer renders into a multisampled target, so antialiasing survives, and ends
7
+ * with three's `OutputPass`, which applies tone mapping and the output colour space.
8
+ *
9
+ * @module
10
+ */
11
+ import { type PostEffect } from '@opsydyn/effect-three';
12
+ import { type Camera, type Scene, type WebGLRenderer } from 'three';
13
+ export type PostProcessing = {
14
+ /** Rebuilds the passes when `effects` differ from the current ones. */
15
+ readonly configure: (effects: ReadonlyArray<PostEffect>) => void;
16
+ readonly setSize: (width: number, height: number, pixelRatio: number) => void;
17
+ /** Renders through the effects; returns false when there are none to apply. */
18
+ readonly render: (scene: Scene, camera: Camera) => boolean;
19
+ readonly dispose: () => void;
20
+ };
21
+ export declare const createPostProcessing: (renderer: WebGLRenderer) => PostProcessing;
22
+ //# sourceMappingURL=postprocessing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postprocessing.d.ts","sourceRoot":"","sources":["../../src/dom/postprocessing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EACL,KAAK,MAAM,EAGX,KAAK,KAAK,EAGV,KAAK,aAAa,EAEnB,MAAM,OAAO,CAAC;AAgCf,MAAM,MAAM,cAAc,GAAG;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACjE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9E,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,oBAAoB,aAAc,aAAa,KAAG,cAsD9D,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Intercepts the property Foldkit's CustomElement factory sets on every render, so a
3
+ * Mount can see new values without an update hook (ADR-002).
4
+ *
5
+ * @module
6
+ */
7
+ export type PropertyInterception = {
8
+ /** The value present when interception began (set by the first render). */
9
+ readonly initial: unknown;
10
+ /** Restores a plain data property holding the latest value. */
11
+ readonly restore: () => void;
12
+ };
13
+ /** Calls `onSet` for every assignment to `element[key]`. */
14
+ export declare const interceptProperty: (element: object, key: string, onSet: (value: unknown) => void) => PropertyInterception;
15
+ //# sourceMappingURL=property.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"property.d.ts","sourceRoot":"","sources":["../../src/dom/property.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,oBAAoB,GAAG;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,iBAAiB,YACnB,MAAM,OACV,MAAM,SACJ,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAC9B,oBAuBF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Summaries of scene updates, for the `scene-reconciled` event.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Op, ResourceStats } from '@opsydyn/effect-three';
7
+ import type { ReconciledDetail } from '../element.ts';
8
+ /** Counts operations by kind and snapshots resource counters. */
9
+ export declare const summarise: (ops: ReadonlyArray<Op>, stats: ResourceStats) => ReconciledDetail;
10
+ //# sourceMappingURL=reconciled.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciled.d.ts","sourceRoot":"","sources":["../../src/dom/reconciled.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,iEAAiE;AACjE,eAAO,MAAM,SAAS,QAAS,aAAa,CAAC,EAAE,CAAC,SAAS,aAAa,KAAG,gBAwCxE,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { type Object3D, type WebGLRenderer } from 'three';
2
+ import type { WebGPURenderer } from 'three/webgpu';
3
+ /**
4
+ * Shadow map types by React Three Fiber's names (`core/configuration.ts` at `d74622e`).
5
+ * three 0.186 folded PCF soft into PCF (softness is per light), so `soft` maps to PCF
6
+ * here; R3F's PCFSoftShadowMap would only log a removal warning on this version.
7
+ */
8
+ export declare const shadowTypes: {
9
+ basic: 0;
10
+ percentage: 1;
11
+ soft: 1;
12
+ variance: 3;
13
+ };
14
+ export declare const toneMappings: {
15
+ none: 0;
16
+ linear: 1;
17
+ reinhard: 2;
18
+ cineon: 3;
19
+ aces: 4;
20
+ agx: 6;
21
+ neutral: 7;
22
+ };
23
+ export declare const colorSpaces: {
24
+ srgb: "srgb";
25
+ linear: "srgb-linear";
26
+ };
27
+ /**
28
+ * Flags every material in the scene for recompilation. three.js keeps a shader built
29
+ * with shadows sampling its last shadow map after `shadowMap.enabled` turns off (and
30
+ * without shadows after it turns on) until its material is updated.
31
+ */
32
+ export declare const recompileMaterials: (scene: Object3D) => void;
33
+ /** What presenting a renderer in WebXR uses; three's WebGL and WebGPU renderers both have it. */
34
+ export type PresentableRenderer = {
35
+ readonly xr: {
36
+ enabled: boolean;
37
+ readonly isPresenting: boolean;
38
+ setReferenceSpaceType: (type: XRReferenceSpaceType) => void;
39
+ setFramebufferScaleFactor: (scale: number) => void;
40
+ setSession: (session: XRSession) => Promise<void>;
41
+ getReferenceSpace: () => XRReferenceSpace | null;
42
+ setReferenceSpace: (space: XRReferenceSpace) => void;
43
+ getEnvironmentBlendMode: () => XREnvironmentBlendMode | undefined;
44
+ };
45
+ /**
46
+ * Hands the session's frames to `callback` (`null` stops), set before the session starts:
47
+ * WebGL's `xr.setAnimationLoop`, or WebGPU's `setAnimationLoop`, which its XR manager
48
+ * captures when the session starts. It may also be called outside the session.
49
+ */
50
+ readonly setXrLoop: (callback: ((time: number, frame?: XRFrame) => void) | null) => void;
51
+ };
52
+ export declare const registerPresentable: (canvas: HTMLCanvasElement, renderer: WebGLRenderer | WebGPURenderer, presenting: PresentableRenderer) => void;
53
+ export declare const forgetPresentable: (canvas: HTMLCanvasElement) => void;
54
+ /** The three.js renderer drawing into `canvas` (WebGL or WebGPU), if one does. */
55
+ export declare const threeRendererOf: (canvas: HTMLCanvasElement) => WebGLRenderer | WebGPURenderer | undefined;
56
+ /** The three.js renderer drawing into `canvas`, if one does. */
57
+ export declare const presentableRendererOf: (canvas: HTMLCanvasElement) => PresentableRenderer | undefined;
58
+ //# sourceMappingURL=renderSettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderSettings.d.ts","sourceRoot":"","sources":["../../src/dom/renderSettings.ts"],"names":[],"mappings":"AAQA,OAAO,EAWL,KAAK,QAAQ,EAOb,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,WAAW;;;;;CAKoD,CAAC;AAE7E,eAAO,MAAM,YAAY;;;;;;;;CAQqC,CAAC;AAE/D,eAAO,MAAM,WAAW;;;CAGoC,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,UAAW,QAAQ,KAAG,IAMpD,CAAC;AAEF,iGAAiG;AACjG,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EAAE,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;QAC/B,qBAAqB,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;QAC5D,yBAAyB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QACnD,UAAU,EAAE,CAAC,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,iBAAiB,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAC;QACjD,iBAAiB,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;QACrD,uBAAuB,EAAE,MAAM,sBAAsB,GAAG,SAAS,CAAC;KACnE,CAAC;IACF;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;CAC1F,CAAC;AAOF,eAAO,MAAM,mBAAmB,WACtB,iBAAiB,YACf,aAAa,GAAG,cAAc,cAC5B,mBAAmB,KAC9B,IAGF,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAY,iBAAiB,KAAG,IAG7D,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,eAAe,WAClB,iBAAiB,KACxB,aAAa,GAAG,cAAc,GAAG,SAAgC,CAAC;AAErE,gEAAgE;AAChE,eAAO,MAAM,qBAAqB,WAAY,iBAAiB,KAAG,mBAAmB,GAAG,SAC/D,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Scenes that reached the element through the typed `view` helper. TypeScript already
3
+ * checked them against `SceneDescription`, so the Mount can skip the Schema decode (about
4
+ * 0.6 ms per render for 1,000 meshes). Any other value assigned to the element's `scene`
5
+ * property is still decoded.
6
+ *
7
+ * @module
8
+ */
9
+ import type { SceneDescription } from '@opsydyn/effect-three';
10
+ /** Records a compile-time-checked scene and returns it unchanged. */
11
+ export declare const markTyped: (scene: SceneDescription) => SceneDescription;
12
+ /** The scene, if this exact value came through `markTyped`. */
13
+ export declare const typedScene: (value: unknown) => SceneDescription | undefined;
14
+ //# sourceMappingURL=typedScenes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typedScenes.d.ts","sourceRoot":"","sources":["../../src/dom/typedScenes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,qEAAqE;AACrE,eAAO,MAAM,SAAS,UAAW,gBAAgB,KAAG,gBAGnD,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,UAAU,UAAW,OAAO,KAAG,gBAAgB,GAAG,SACa,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * What follows a scene update in the DOM.
3
+ *
4
+ * @module
5
+ */
6
+ /** After an update: report it, then run each follow-up step in order. */
7
+ export declare const afterUpdate: <A>(report: (value: A) => () => void, steps: ReadonlyArray<() => void>) => (value: A) => () => void;
8
+ //# sourceMappingURL=updates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updates.d.ts","sourceRoot":"","sources":["../../src/dom/updates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,yEAAyE;AACzE,eAAO,MAAM,WAAW,GACrB,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,IAAI,SAAS,aAAa,CAAC,MAAM,IAAI,CAAC,aAC9D,CAAC,WACL,IAGH,CAAC"}