@realitycollective/service-framework-three 1.0.2-preview.2 → 1.0.2

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/CHANGELOG.md CHANGED
@@ -4,12 +4,15 @@ Change log for the Reality Collective Service Framework for TypeScript. All pack
4
4
 
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Preview builds are not listed separately. The entry for a version accumulates while its previews are published, and is dated when that version is released.
6
6
 
7
- ## [1.0.2]
7
+ ## [1.0.2] - 2026-10-01
8
8
 
9
9
  A native platform, beside IWSDK, three.js and Babylon.js, and byte I/O that works the same on the web and on a native host.
10
10
 
11
11
  ### Added
12
12
 
13
+ - A native test harness in `harness/native`, a small app for the conversion pipeline that runs on a Quest headset. In `kits` mode it runs `runtimeAdapterContractCases()`, `renderTickContractCases()` and `hostIOContractCases()` over `NativeRuntimeAdapter` and `createNativeHostIO`, plus a boot with no global `AbortController`, against the shell's test host, or this repository's reference fake under Node. In `play` mode it logs session, visibility, pause, focus, capability and telemetry changes from the live host, and reads a packed file through `HostIO`. `npm run harness:compile` typechecks and bundles it through the engine and browser-global gates and compiles it to Hermes bytecode; CI compiles it and never runs it.
14
+ - `@realitycollective/service-framework-iwsdk` - IWSDK 1.0.0's player rig: `world.player` is the `XROrigin` itself (an `Object3D` with the head as its `head` child), not an entity carrying `object3D`. `IWSDKPlayerLike` now accepts both shapes (`IWSDKPlayerEntityLike`, `IWSDKXROriginLike`), `playerRig` and `playerHead` read either, and `recentre()` moves a 1.0 rig; an IWSDK 1.0 `World` type-checks against `IWSDKWorldLike` again.
15
+ - `@realitycollective/service-framework` - `RuntimeAdapterDriver.sessionStart` states the mode-switch semantics the contract case relies on: called while a session is live, the host hands over the new session once the adapter has ended the old one itself, so a driver whose host starts sessions at once queues the start until the adapter's `endSession` completes or its next request arrives.
13
16
  - `FrameInfo.frame`, the binding's frame count from 1: the same number the `renderTick` context carries for that frame. The native host's frames, the IWSDK bridge and the three.js and Babylon.js owned loops all set it from the one counter they already kept for `renderTick`, and `emitFrame` takes it as an optional third argument, so a client that needs a frame number reads one clock instead of counting frames again. Additive: a frame an app emits itself without one carries none.
14
17
  - `@realitycollective/service-framework-native` - `NativeSessionInfo.features`, the WebXR feature names the session enabled (`"hand-tracking"`, `"plane-detection"` and the rest), which the capabilities read as the IWSDK adapter reads `enabledFeatures`; `NativeHost.input`, the `input` slice's `onSourcesChanged` signal and source kinds; `NativeHost.onSessionRefused`, the app's way to say it will not start a requested session; and the `manager` option, the service manager whose focus and pause signals follow the session.
15
18
  - `@realitycollective/service-framework-native`, the binding for a native XR app that embeds a JavaScript engine such as Hermes. The app owns the session, the frame loop, rendering and physics, and installs one host object, `globalThis.__rcHost`, before it evaluates the bundle. Everything crosses that object as plain values. `NativeRuntimeAdapter` publishes the app's frames and session through the same `RuntimeAdapter` seam as the other bindings, with the session facet, and passes `runtimeAdapterContractCases()`. It derives capabilities from the OpenXR session state, the enabled extensions, system hand tracking support and the blend mode. It keeps the same sticky `setCapabilities` override, `clearCapabilityOverrides()` and `refreshCapabilities()` the other adapters have. Given a `scheduler`, it emits `renderTick` with `source: "native"`. `createNativeHostIO()` returns a `HostIO` over the host's `io` slice. The host object's shape was proven on a Quest 3 and in the visionOS Simulator by the team that built the first native host. The package README documents it, including the slices the other families' native packages read.
@@ -35,6 +38,7 @@ A native platform, beside IWSDK, three.js and Babylon.js, and byte I/O that work
35
38
  - `@realitycollective/service-framework-native` - a refused session request resolves with the app's reason, `"denied"`, `"unsupported"` or `"error"`, at once. Before this only `"timeout"` and `"error"` could be reached, so a dismissed permission prompt waited ten seconds and read as a timeout.
36
39
  - `@realitycollective/service-framework-native` - every member of `NativeHost` and `NativeSessionInfo` states its units and meaning: milliseconds and seconds on `onFrame`, what counts as live, what the blend mode must reflect, and what each signal triggers.
37
40
  - **Behaviour change on every platform:** `session.request(mode)` while a session is already active is now a no-op only when `mode` matches the live session. A different mode ends the live session first and then requests the new one ("end-and-request"), instead of the previous no-op that always resolved `{ ok: true }` regardless of the mode asked for. A session the adapter did not itself request - already active at construction, or started through a host's own UI - has no known mode, so a request against it is treated as a switch and goes through the same end-and-request path.
41
+ - Dependencies on other Reality Collective repositories now follow one rule, checked by `scripts/rc-dependencies.mjs`. Going into `main`, each names the release npm tags `latest` and never a preview. Going into any other branch, each names the newest version on npm, release or preview. The rule covers every `package.json` in the repository (published packages, demos, harnesses and examples) and every copy `package-lock.json` records. A range passes only when its lowest version is the target, so `^0.1.8` passes for 0.1.8 and `^0.1.4` does not. CI runs it before the install, against the branch a pull request targets, and the publish workflow runs it before publishing. `release.mjs status` reports it. `release.mjs prepare` stops before cutting a release when a dependency names an unreleased preview of another repository, because that repository has to release first, and moves any range that is only behind. Other dependencies are out of scope. The script stays identical across the Reality Collective repositories.
38
42
 
39
43
  ### Fixed
40
44
 
@@ -110,5 +114,6 @@ First release. Six packages, published together.
110
114
  - `@realitycollective/service-framework-iwsdk` - Meta IWSDK (WebXR) bindings. IWSDK owns its own render loop, so this package is a passive frame source: one system relays each frame to services and maps `visibilityState` onto focus and pause, so services pause when the headset comes off. Services depend only on `RuntimeAdapter`, never on `@iwsdk/core`.
111
115
  - A worked example in every package's `Examples/` folder, and two runnable Vite apps in `runtime-examples/`.
112
116
 
117
+ [1.0.2]: https://github.com/realitycollective/com.realitycollective.service-framework.ts/releases/tag/v1.0.2
113
118
  [1.0.1]: https://github.com/realitycollective/com.realitycollective.service-framework.ts/releases/tag/v1.0.1
114
119
  [1.0.0]: https://github.com/realitycollective/com.realitycollective.service-framework.ts/releases/tag/v1.0.0
package/README.md CHANGED
@@ -90,7 +90,9 @@ This differs from IWSDK and native, which serve nothing but a live XR session: t
90
90
  | `timeout` | nothing arrived within `timeoutMs` (default 10000) |
91
91
  | `error` | anything else, with the original error attached |
92
92
 
93
- `getState()` walks `"none"` -> `"requesting"` -> `"active"` -> `"ending"` -> `"none"`. `end()` calls `session.end()` and resolves once the session is gone. `onVisibilityChange` maps the session's `visibilitychange` onto `"visible"`, `"visible-blurred"` and `"hidden"`, and reports `"non-immersive"` whenever there is no session. A value the adapter does not recognise is reported as `"hidden"`, because treating an unknown state as visible would keep game logic running when it should not.
93
+ `getState()` walks `"none"` -> `"requesting"` -> `"active"` -> `"ending"` -> `"none"`. `isSupported(mode)` reads `navigator.xr.isSessionSupported`, and resolves `false` where there is no `navigator.xr`. `end()` calls `session.end()` and resolves once the session is gone. `onVisibilityChange` maps the session's `visibilitychange` onto `"visible"`, `"visible-blurred"` and `"hidden"`, and reports `"non-immersive"` whenever there is no session. A value the adapter does not recognise is reported as `"hidden"`, because treating an unknown state as visible would keep game logic running when it should not.
94
+
95
+ `recentre()` makes the viewer's current floor position and yaw the new origin by offsetting the renderer's reference space, using the core's `recentreOffset` rule. It does nothing when there is no live frame or reference space, or no `XRRigidTransform` to build the offset with (the `rigidTransform` option supplies one outside a browser).
94
96
 
95
97
  `sessionInit` supplies the `XRSessionInit` per mode - required and optional features - and is called once per request. The default sends none.
96
98
 
@@ -124,7 +126,7 @@ A desktop build with no headset needs no special case. `request` returns `{ ok:
124
126
  | `AnimationLoopHostLike` | interface | Anything with `setAnimationLoop`. |
125
127
  | `FIRST_FRAME_DELTA_MS` | const | 16 - the delta reported for the first frame. |
126
128
  | `WebXRRuntimeAdapter` | class | `RuntimeAdapter` over WebXR; `start`, `stop`, `tick`, `emitFrame`, `getSession`, `refreshCapabilities`, `setCapabilities`, `clearCapabilityOverrides`, `session`, `dispose`. |
127
- | `WebXRRuntimeAdapterOptions` | interface | `{ xr, xrSystem?, host?, scheduler?, sessionInit?, manager? }`. |
129
+ | `WebXRRuntimeAdapterOptions` | interface | `{ xr, xrSystem?, host?, scheduler?, sessionInit?, manager?, rigidTransform? }`. |
128
130
  | `WebXRManagerLike` | interface | The slice of `renderer.xr` the adapter drives. |
129
131
  | `WebXRSystemLike` | interface | The slice of `navigator.xr` it negotiates through. |
130
132
  | `WebXRSessionLike` | interface | The slice of `XRSession` it reads. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realitycollective/service-framework-three",
3
- "version": "1.0.2-preview.2",
3
+ "version": "1.0.2",
4
4
  "description": "three.js render-loop bindings for the Reality Collective TypeScript Service Framework.",
5
5
  "author": "Reality Collective",
6
6
  "license": "MIT",
@@ -24,7 +24,10 @@
24
24
  "threejs",
25
25
  "render-loop",
26
26
  "realitycollective",
27
- "typescript"
27
+ "typescript",
28
+ "webxr",
29
+ "runtime-adapter",
30
+ "session"
28
31
  ],
29
32
  "repository": {
30
33
  "type": "git",
@@ -35,7 +38,7 @@
35
38
  "url": "https://github.com/realitycollective/com.realitycollective.service-framework.ts/issues"
36
39
  },
37
40
  "dependencies": {
38
- "@realitycollective/service-framework": "^1.0.2-preview.2"
41
+ "@realitycollective/service-framework": "^1.0.2"
39
42
  },
40
43
  "scripts": {
41
44
  "build": "tsc -p tsconfig.build.json",