@glassly/engine 0.3.2-beta.572 → 0.3.2-beta.597
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 +1 -1
- package/build/engine.d.ts +15 -1
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +7 -3
- package/build/engine.js.map +1 -1
- package/build/facades/dev.d.ts +2 -2
- package/build/facades/dev.d.ts.map +1 -1
- package/build/facades/dev.js +2 -2
- package/build/facades/dev.js.map +1 -1
- package/build/facades/glasses.d.ts +20 -0
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +21 -0
- package/build/facades/glasses.js.map +1 -1
- package/build/facades/pairing.js +1 -1
- package/build/facades/pairing.js.map +1 -1
- package/build/facades/reports.js +2 -2
- package/build/facades/reports.js.map +1 -1
- package/build/facades/session.d.ts +1 -1
- package/build/facades/session.js +2 -2
- package/build/facades/session.js.map +1 -1
- package/build/generated/releaseMetadata.js +3 -3
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/index.d.ts +3 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -1
- package/build/index.js.map +1 -1
- package/build/runtime/bootstrap.d.ts +2 -2
- package/build/runtime/bootstrap.d.ts.map +1 -1
- package/build/runtime/bootstrap.js.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.d.ts +2 -2
- package/build/services/CloudAudioSubscriptionSync.js +2 -2
- package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
- package/build/services/CloudClientService.d.ts +2 -2
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +4 -4
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/CloudTranscriptE2EMetrics.d.ts +2 -2
- package/build/services/CloudTranscriptE2EMetrics.d.ts.map +1 -1
- package/build/services/CloudTranscriptE2EMetrics.js +3 -3
- package/build/services/CloudTranscriptE2EMetrics.js.map +1 -1
- package/build/services/DeviceEventRouter.d.ts.map +1 -1
- package/build/services/DeviceEventRouter.js +5 -0
- package/build/services/DeviceEventRouter.js.map +1 -1
- package/build/services/GestureDotsService.d.ts +9 -9
- package/build/services/GestureDotsService.d.ts.map +1 -1
- package/build/services/GestureDotsService.js +75 -50
- package/build/services/GestureDotsService.js.map +1 -1
- package/build/services/GlassesTouchInput.d.ts +1 -1
- package/build/services/GlassesTouchInput.d.ts.map +1 -1
- package/build/services/GlassesTouchInput.js +7 -4
- package/build/services/GlassesTouchInput.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +1 -1
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +26 -7
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.d.ts +5 -2
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.js +7 -3
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
- package/build/services/PhonePhotoCoordinator.d.ts +1 -1
- package/build/services/PhonePhotoCoordinator.js +4 -4
- package/build/services/PhonePhotoCoordinator.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts +1 -1
- package/build/services/PhoneStreamCoordinator.js +1 -1
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/SupportProfileSync.d.ts +1 -1
- package/build/services/SupportProfileSync.js +2 -2
- package/build/services/SupportProfileSync.js.map +1 -1
- package/build/services/TranscriptionRouting.d.ts +6 -1
- package/build/services/TranscriptionRouting.d.ts.map +1 -1
- package/build/services/TranscriptionRouting.js +7 -3
- package/build/services/TranscriptionRouting.js.map +1 -1
- package/build/services/cloudStreamApi.d.ts +2 -2
- package/build/services/cloudStreamApi.js +2 -2
- package/build/services/cloudStreamApi.js.map +1 -1
- package/build/services/gestureDotGlyphs.d.ts +1 -1
- package/build/services/gestureDotGlyphs.d.ts.map +1 -1
- package/build/services/gestureDotGlyphs.js +5 -0
- package/build/services/gestureDotGlyphs.js.map +1 -1
- package/build/services/neuralBand/MetaAuth.d.ts +31 -0
- package/build/services/neuralBand/MetaAuth.d.ts.map +1 -0
- package/build/services/neuralBand/MetaAuth.js +161 -0
- package/build/services/neuralBand/MetaAuth.js.map +1 -0
- package/build/services/neuralBand/NeuralBandInput.d.ts +50 -0
- package/build/services/neuralBand/NeuralBandInput.d.ts.map +1 -0
- package/build/services/neuralBand/NeuralBandInput.js +114 -0
- package/build/services/neuralBand/NeuralBandInput.js.map +1 -0
- package/build/services/neuralBand/NeuralBandSettingsSync.d.ts +3 -0
- package/build/services/neuralBand/NeuralBandSettingsSync.d.ts.map +1 -0
- package/build/services/neuralBand/NeuralBandSettingsSync.js +52 -0
- package/build/services/neuralBand/NeuralBandSettingsSync.js.map +1 -0
- package/build/services/neuralBand/sha256.d.ts +7 -0
- package/build/services/neuralBand/sha256.d.ts.map +1 -0
- package/build/services/neuralBand/sha256.js +68 -0
- package/build/services/neuralBand/sha256.js.map +1 -0
- package/build/services/soniox/SonioxRealtimeClient.d.ts +2 -2
- package/build/services/soniox/SonioxRealtimeClient.js +2 -2
- package/build/services/soniox/SonioxRealtimeClient.js.map +1 -1
- package/build/services/soniox/SonioxTokenAssembler.d.ts +1 -1
- package/build/services/soniox/SonioxTokenAssembler.js +1 -1
- package/build/services/soniox/SonioxTokenAssembler.js.map +1 -1
- package/build/stores/cloudClientStatus.js +1 -1
- package/build/stores/cloudClientStatus.js.map +1 -1
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +25 -7
- package/build/stores/settings.js.map +1 -1
- package/build/types/enums.d.ts +2 -1
- package/build/types/enums.d.ts.map +1 -1
- package/build/types/enums.js +1 -0
- package/build/types/enums.js.map +1 -1
- package/build/utils/cloudClient/cloudSecureStore.js +2 -2
- package/build/utils/cloudClient/cloudSecureStore.js.map +1 -1
- package/package.json +7 -7
- package/src/engine.ts +7 -3
- package/src/facades/dev.ts +2 -2
- package/src/facades/glasses.ts +27 -0
- package/src/facades/pairing.ts +1 -1
- package/src/facades/reports.ts +2 -2
- package/src/facades/session.ts +2 -2
- package/src/generated/releaseMetadata.ts +3 -3
- package/src/index.ts +15 -1
- package/src/runtime/bootstrap.ts +2 -2
- package/src/services/CloudAudioSubscriptionSync.ts +2 -2
- package/src/services/CloudClientService.ts +4 -4
- package/src/services/CloudTranscriptE2EMetrics.ts +3 -3
- package/src/services/DeviceEventRouter.ts +5 -0
- package/src/services/GestureDotsService.ts +72 -49
- package/src/services/GlassesTouchInput.ts +13 -5
- package/src/services/LocalMiniappRuntime.ts +46 -24
- package/src/services/LocalSttFallbackCoordinator.ts +18 -4
- package/src/services/PhonePhotoCoordinator.ts +4 -4
- package/src/services/PhoneStreamCoordinator.ts +1 -1
- package/src/services/SupportProfileSync.ts +2 -2
- package/src/services/TranscriptionRouting.ts +12 -4
- package/src/services/cloudStreamApi.ts +3 -3
- package/src/services/gestureDotGlyphs.ts +6 -1
- package/src/services/neuralBand/MetaAuth.ts +192 -0
- package/src/services/neuralBand/NeuralBandInput.ts +148 -0
- package/src/services/neuralBand/NeuralBandSettingsSync.ts +63 -0
- package/src/services/neuralBand/sha256.ts +70 -0
- package/src/services/soniox/SonioxRealtimeClient.ts +2 -2
- package/src/services/soniox/SonioxTokenAssembler.ts +1 -1
- package/src/stores/cloudClientStatus.ts +1 -1
- package/src/stores/settings.ts +25 -7
- package/src/types/enums.ts +1 -0
- package/src/utils/cloudClient/cloudSecureStore.ts +2 -2
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Meta Neural Band's own event streams, past the gestures that ride `touch_event`:
|
|
3
|
+
* claim progress (for the pairing screens), the handwriting model (typed into the
|
|
4
|
+
* miniapp keyboard stream as synthesized key presses) and the air mouse (forwarded
|
|
5
|
+
* to miniapps on the pointer stream).
|
|
6
|
+
*/
|
|
7
|
+
import type {NeuralBandClaimEvent, NeuralBandHandwritingEvent, NeuralBandPointerEvent} from "@glassly/bluetooth-sdk"
|
|
8
|
+
import {MiniappStreamType} from "@glassly/miniapp"
|
|
9
|
+
|
|
10
|
+
import type {KeyboardEventPayload} from "../GlassesKeyboardInput"
|
|
11
|
+
import localMiniappRuntime from "../LocalMiniappRuntime"
|
|
12
|
+
|
|
13
|
+
export interface NeuralBandClaimStatus {
|
|
14
|
+
stage: "idle" | "progress" | "completed" | "failed"
|
|
15
|
+
message?: string
|
|
16
|
+
sessionExpired: boolean
|
|
17
|
+
bandName?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface NeuralBandHandwritingStatus {
|
|
21
|
+
phase: "idle" | "preparing" | "ready" | "restoring" | "finished"
|
|
22
|
+
message: string
|
|
23
|
+
problem?: string
|
|
24
|
+
/** The last text the band produced since handwriting was switched on. */
|
|
25
|
+
text: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface NeuralBandInputOptions {
|
|
29
|
+
forward?: (stream: string, payload: unknown) => void
|
|
30
|
+
now?: () => number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const MODIFIERS = {shift: false, ctrl: false, alt: false, meta: false}
|
|
34
|
+
|
|
35
|
+
/** One handwriting change as the key presses that would have typed it. */
|
|
36
|
+
export function keyEventsForTextChange(previous: string, next: string, timestamp: number): KeyboardEventPayload[] {
|
|
37
|
+
let common = 0
|
|
38
|
+
while (common < previous.length && common < next.length && previous[common] === next[common]) common++
|
|
39
|
+
const events: KeyboardEventPayload[] = []
|
|
40
|
+
const press = (key: string, code: string, text?: string) => {
|
|
41
|
+
events.push({phase: "down", key, code, modifiers: MODIFIERS, text, repeat: false, timestamp})
|
|
42
|
+
events.push({phase: "up", key, code, modifiers: MODIFIERS, repeat: false, timestamp})
|
|
43
|
+
}
|
|
44
|
+
for (let i = common; i < previous.length; i++) press("Backspace", "Backspace")
|
|
45
|
+
for (const char of Array.from(next.slice(common))) {
|
|
46
|
+
if (char === "\n") press("Enter", "Enter")
|
|
47
|
+
else if (char === " ") press(" ", "Space", " ")
|
|
48
|
+
else press(char, codeFor(char), char)
|
|
49
|
+
}
|
|
50
|
+
return events
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function codeFor(char: string): string {
|
|
54
|
+
if (/^[a-z]$/i.test(char)) return `Key${char.toUpperCase()}`
|
|
55
|
+
if (/^[0-9]$/.test(char)) return `Digit${char}`
|
|
56
|
+
return "Unidentified"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export class NeuralBandInput {
|
|
60
|
+
private claim: NeuralBandClaimStatus = {stage: "idle", sessionExpired: false}
|
|
61
|
+
private handwriting: NeuralBandHandwritingStatus = {phase: "idle", message: "", text: ""}
|
|
62
|
+
private claimListeners = new Set<(status: NeuralBandClaimStatus) => void>()
|
|
63
|
+
private handwritingListeners = new Set<(status: NeuralBandHandwritingStatus) => void>()
|
|
64
|
+
private readonly forward: (stream: string, payload: unknown) => void
|
|
65
|
+
private readonly now: () => number
|
|
66
|
+
|
|
67
|
+
constructor(options: NeuralBandInputOptions = {}) {
|
|
68
|
+
this.forward = options.forward ?? ((stream, payload) => localMiniappRuntime.forwardEvent(stream, payload))
|
|
69
|
+
this.now = options.now ?? (() => Date.now())
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
claimStatus(): NeuralBandClaimStatus {
|
|
73
|
+
return this.claim
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
onClaimStatus(cb: (status: NeuralBandClaimStatus) => void): () => void {
|
|
77
|
+
this.claimListeners.add(cb)
|
|
78
|
+
return () => this.claimListeners.delete(cb)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
handwritingStatus(): NeuralBandHandwritingStatus {
|
|
82
|
+
return this.handwriting
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
onHandwritingStatus(cb: (status: NeuralBandHandwritingStatus) => void): () => void {
|
|
86
|
+
this.handwritingListeners.add(cb)
|
|
87
|
+
return () => this.handwritingListeners.delete(cb)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** A new pairing attempt starts from a clean slate. */
|
|
91
|
+
resetClaim(): void {
|
|
92
|
+
this.setClaim({stage: "idle", sessionExpired: false})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
handleClaim(event: NeuralBandClaimEvent): void {
|
|
96
|
+
this.setClaim({
|
|
97
|
+
stage: event.stage,
|
|
98
|
+
message: event.message,
|
|
99
|
+
sessionExpired: event.sessionExpired === true,
|
|
100
|
+
bandName: event.bandName,
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
handleHandwriting(event: NeuralBandHandwritingEvent): void {
|
|
105
|
+
if (event.kind === "state") {
|
|
106
|
+
const text = event.phase === "preparing" ? "" : this.handwriting.text
|
|
107
|
+
this.setHandwriting({phase: event.phase, message: event.message, problem: event.problem, text})
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
const previous = this.handwriting.text
|
|
111
|
+
if (event.text !== previous) {
|
|
112
|
+
for (const key of keyEventsForTextChange(previous, event.text, this.now())) {
|
|
113
|
+
this.forward(MiniappStreamType.KEYBOARD_EVENT, key)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
this.setHandwriting({...this.handwriting, text: event.text})
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
handlePointer(event: NeuralBandPointerEvent): void {
|
|
120
|
+
if (event.kind === "move") {
|
|
121
|
+
this.forward(MiniappStreamType.POINTER_EVENT, {
|
|
122
|
+
kind: "move",
|
|
123
|
+
dx: event.dx,
|
|
124
|
+
dy: event.dy,
|
|
125
|
+
timestamp: event.timestamp,
|
|
126
|
+
})
|
|
127
|
+
} else {
|
|
128
|
+
this.forward(MiniappStreamType.POINTER_EVENT, {
|
|
129
|
+
kind: "buttons",
|
|
130
|
+
buttons: event.buttons,
|
|
131
|
+
timestamp: event.timestamp,
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private setClaim(status: NeuralBandClaimStatus): void {
|
|
137
|
+
this.claim = status
|
|
138
|
+
for (const cb of this.claimListeners) cb(status)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private setHandwriting(status: NeuralBandHandwritingStatus): void {
|
|
142
|
+
this.handwriting = status
|
|
143
|
+
for (const cb of this.handwritingListeners) cb(status)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const neuralBandInput = new NeuralBandInput()
|
|
148
|
+
export default neuralBandInput
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pushes the Neural Band's user settings (air mouse, wearing hand) to the native
|
|
3
|
+
* controller: when the band connects, and whenever either setting changes while
|
|
4
|
+
* it is connected. The native side keeps nothing across connections.
|
|
5
|
+
*/
|
|
6
|
+
import BluetoothSdk from "@glassly/bluetooth-sdk/internal"
|
|
7
|
+
|
|
8
|
+
import {useGlassesStore} from "../../stores/glasses"
|
|
9
|
+
import {SETTINGS, useSettingsStore} from "../../stores/settings"
|
|
10
|
+
import {ControllerTypes} from "../../types/enums"
|
|
11
|
+
|
|
12
|
+
let unsubscribers: (() => void)[] = []
|
|
13
|
+
|
|
14
|
+
function bandConnected(): boolean {
|
|
15
|
+
const glasses = useGlassesStore.getState()
|
|
16
|
+
const settings = useSettingsStore.getState()
|
|
17
|
+
return (
|
|
18
|
+
glasses.controllerConnected === true &&
|
|
19
|
+
glasses.controllerFullyBooted === true &&
|
|
20
|
+
settings.getSetting(SETTINGS.default_controller.key) === ControllerTypes.NEURAL_BAND
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function pushAirMouse(): void {
|
|
25
|
+
if (!bandConnected()) return
|
|
26
|
+
const enabled = useSettingsStore.getState().getSetting(SETTINGS.neural_band_air_mouse.key) === true
|
|
27
|
+
void BluetoothSdk.neuralBandSetPointer(enabled).catch((err) =>
|
|
28
|
+
console.warn("NeuralBandSettingsSync: air mouse push failed:", err),
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function pushHand(): void {
|
|
33
|
+
if (!bandConnected()) return
|
|
34
|
+
const hand = useSettingsStore.getState().getSetting(SETTINGS.neural_band_hand.key) === "left" ? "left" : "right"
|
|
35
|
+
void BluetoothSdk.neuralBandSetHand(hand).catch((err) =>
|
|
36
|
+
console.warn("NeuralBandSettingsSync: hand push failed:", err),
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function startNeuralBandSettingsSync(): void {
|
|
41
|
+
if (unsubscribers.length > 0) return
|
|
42
|
+
let wasConnected = bandConnected()
|
|
43
|
+
unsubscribers = [
|
|
44
|
+
useGlassesStore.subscribe(
|
|
45
|
+
(s) => s.controllerConnected === true && s.controllerFullyBooted === true,
|
|
46
|
+
() => {
|
|
47
|
+
const connected = bandConnected()
|
|
48
|
+
if (connected && !wasConnected) {
|
|
49
|
+
pushAirMouse()
|
|
50
|
+
pushHand()
|
|
51
|
+
}
|
|
52
|
+
wasConnected = connected
|
|
53
|
+
},
|
|
54
|
+
),
|
|
55
|
+
useSettingsStore.subscribe((s) => s.getSetting(SETTINGS.neural_band_air_mouse.key), pushAirMouse),
|
|
56
|
+
useSettingsStore.subscribe((s) => s.getSetting(SETTINGS.neural_band_hand.key), pushHand),
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function stopNeuralBandSettingsSync(): void {
|
|
61
|
+
for (const unsubscribe of unsubscribers) unsubscribe()
|
|
62
|
+
unsubscribers = []
|
|
63
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SHA-256 over a UTF-8 string, hex encoded. The Meta sign-in callback carries the
|
|
3
|
+
* first 16 hex digits of the request token's digest; nothing else here needs a
|
|
4
|
+
* hash, and the app ships no crypto dependency, so this stays small and local.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const K = new Uint32Array([
|
|
8
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,
|
|
9
|
+
0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
|
10
|
+
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,
|
|
11
|
+
0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
12
|
+
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
|
|
13
|
+
0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
|
14
|
+
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
|
|
15
|
+
0xc67178f2,
|
|
16
|
+
])
|
|
17
|
+
|
|
18
|
+
function rotr(x: number, n: number): number {
|
|
19
|
+
return (x >>> n) | (x << (32 - n))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function sha256Hex(text: string): string {
|
|
23
|
+
const bytes = new TextEncoder().encode(text)
|
|
24
|
+
const bitLength = bytes.length * 8
|
|
25
|
+
const padded = new Uint8Array(Math.ceil((bytes.length + 9) / 64) * 64)
|
|
26
|
+
padded.set(bytes)
|
|
27
|
+
padded[bytes.length] = 0x80
|
|
28
|
+
const view = new DataView(padded.buffer)
|
|
29
|
+
view.setUint32(padded.length - 8, Math.floor(bitLength / 0x100000000))
|
|
30
|
+
view.setUint32(padded.length - 4, bitLength >>> 0)
|
|
31
|
+
|
|
32
|
+
const h = new Uint32Array([
|
|
33
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
|
34
|
+
])
|
|
35
|
+
const w = new Uint32Array(64)
|
|
36
|
+
for (let offset = 0; offset < padded.length; offset += 64) {
|
|
37
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4)
|
|
38
|
+
for (let i = 16; i < 64; i++) {
|
|
39
|
+
const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3)
|
|
40
|
+
const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10)
|
|
41
|
+
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0
|
|
42
|
+
}
|
|
43
|
+
let [a, b, c, d, e, f, g, hh] = h
|
|
44
|
+
for (let i = 0; i < 64; i++) {
|
|
45
|
+
const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)
|
|
46
|
+
const ch = (e & f) ^ (~e & g)
|
|
47
|
+
const t1 = (hh + s1 + ch + K[i] + w[i]) >>> 0
|
|
48
|
+
const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)
|
|
49
|
+
const maj = (a & b) ^ (a & c) ^ (b & c)
|
|
50
|
+
const t2 = (s0 + maj) >>> 0
|
|
51
|
+
hh = g
|
|
52
|
+
g = f
|
|
53
|
+
f = e
|
|
54
|
+
e = (d + t1) >>> 0
|
|
55
|
+
d = c
|
|
56
|
+
c = b
|
|
57
|
+
b = a
|
|
58
|
+
a = (t1 + t2) >>> 0
|
|
59
|
+
}
|
|
60
|
+
h[0] = (h[0] + a) >>> 0
|
|
61
|
+
h[1] = (h[1] + b) >>> 0
|
|
62
|
+
h[2] = (h[2] + c) >>> 0
|
|
63
|
+
h[3] = (h[3] + d) >>> 0
|
|
64
|
+
h[4] = (h[4] + e) >>> 0
|
|
65
|
+
h[5] = (h[5] + f) >>> 0
|
|
66
|
+
h[6] = (h[6] + g) >>> 0
|
|
67
|
+
h[7] = (h[7] + hh) >>> 0
|
|
68
|
+
}
|
|
69
|
+
return Array.from(h, (word) => word.toString(16).padStart(8, "0")).join("")
|
|
70
|
+
}
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* machinery) or `@soniox/web` (MediaStream capture): the wire protocol is one
|
|
11
11
|
* JSON config message, then binary PCM frames up / JSON token results down.
|
|
12
12
|
* Protocol shape mirrors the vendored SDK's buildConfigMessage /
|
|
13
|
-
* parseResultMessage (cloud
|
|
14
|
-
* implementation: cloud
|
|
13
|
+
* parseResultMessage (cloud runtime's provider is the reference
|
|
14
|
+
* implementation: cloud/packages/runtime/src/services/audio/providers/soniox.ts).
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import {BgTimer} from "../../utils/timers"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* SonioxTokenAssembler
|
|
3
3
|
*
|
|
4
4
|
* Pure port of the cloud Soniox provider's utterance assembly
|
|
5
|
-
* (cloud
|
|
5
|
+
* (cloud/packages/runtime/src/services/audio/providers/soniox.ts). Soniox
|
|
6
6
|
* emits a rolling token window that is re-finalized/compacted across results;
|
|
7
7
|
* this class turns that stream into stable interim/final utterances:
|
|
8
8
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloud-client runtime status store — moved into engine so engine owns the
|
|
3
|
-
* cloud
|
|
3
|
+
* cloud runtime status (connection status + audio transport). Re-exported
|
|
4
4
|
* through the host's `@/stores/cloudClientStatus` shim so the app keeps its
|
|
5
5
|
* imports, and surfaced as `engine.stores.cloudClientStatus`.
|
|
6
6
|
*/
|
package/src/stores/settings.ts
CHANGED
|
@@ -262,7 +262,7 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
262
262
|
saveOnServer: false,
|
|
263
263
|
persist: true,
|
|
264
264
|
},
|
|
265
|
-
// Cloud
|
|
265
|
+
// Cloud endpoint OVERRIDES. Empty = no override; cloudClient's resolveUrl
|
|
266
266
|
// owns the full precedence (override -> env -> Metro-derived dev default).
|
|
267
267
|
// The value may be an explicit URL or the METRO_AUTO sentinel ("my dev
|
|
268
268
|
// laptop", resolved live from Metro so it survives network changes). Never
|
|
@@ -284,7 +284,7 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
284
284
|
persist: true,
|
|
285
285
|
resetOnBuildEnvChange: true,
|
|
286
286
|
},
|
|
287
|
-
// Bookmarked Cloud
|
|
287
|
+
// Bookmarked Cloud endpoint pairs. Each entry is {label, coreUrl,
|
|
288
288
|
// runtimeUrl} — core + runtime are saved together because they are always
|
|
289
289
|
// applied as a matched set (presets fill both; Save & Test verifies both).
|
|
290
290
|
saved_cloud_url_pairs: {
|
|
@@ -411,7 +411,7 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
411
411
|
persist: true,
|
|
412
412
|
},
|
|
413
413
|
location_tier: {key: "location_tier", defaultValue: () => "", writable: true, saveOnServer: true, persist: true},
|
|
414
|
-
// Volatile bearer synced to Bluetooth for glasses-side Cloud
|
|
414
|
+
// Volatile bearer synced to Bluetooth for glasses-side Cloud calls. The
|
|
415
415
|
// key name is kept for BLE compatibility, but the value must never be loaded
|
|
416
416
|
// from or saved to the legacy Cloud V1 settings store.
|
|
417
417
|
core_token: {key: "core_token", defaultValue: () => "", writable: true, saveOnServer: false, persist: false},
|
|
@@ -744,10 +744,10 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
744
744
|
},
|
|
745
745
|
// Debug: route the R1 ring through the glasses (advStart + RING_CONNECT_INFO,
|
|
746
746
|
// events forwarded by the CFW) instead of the phone link. OFF by default:
|
|
747
|
-
// the ring
|
|
748
|
-
//
|
|
749
|
-
//
|
|
750
|
-
//
|
|
747
|
+
// the ring is a direct phone link whether or not a G2 is paired, which is
|
|
748
|
+
// how the Faceclaw reference client runs it. Synced to the Bluetooth SDK,
|
|
749
|
+
// which re-routes a connected ring on change. Device-local debug knob, so
|
|
750
|
+
// not saved on the server.
|
|
751
751
|
ring_via_glasses: {
|
|
752
752
|
key: "ring_via_glasses",
|
|
753
753
|
defaultValue: () => false,
|
|
@@ -755,6 +755,24 @@ export const SETTINGS: Record<string, Setting> = {
|
|
|
755
755
|
saveOnServer: false,
|
|
756
756
|
persist: true,
|
|
757
757
|
},
|
|
758
|
+
// Meta Neural Band: the air mouse streams the band's orientation at 128 Hz, so it
|
|
759
|
+
// stays off unless asked for. The band side is pushed when the band connects.
|
|
760
|
+
neural_band_air_mouse: {
|
|
761
|
+
key: "neural_band_air_mouse",
|
|
762
|
+
defaultValue: () => false,
|
|
763
|
+
writable: true,
|
|
764
|
+
saveOnServer: false,
|
|
765
|
+
persist: true,
|
|
766
|
+
},
|
|
767
|
+
// Which wrist wears the band: flips the air mouse's forearm axis and is written
|
|
768
|
+
// to the band's own hand setting on connect.
|
|
769
|
+
neural_band_hand: {
|
|
770
|
+
key: "neural_band_hand",
|
|
771
|
+
defaultValue: () => "right",
|
|
772
|
+
writable: true,
|
|
773
|
+
saveOnServer: false,
|
|
774
|
+
persist: true,
|
|
775
|
+
},
|
|
758
776
|
// Maximum rate at which display updates leave the phone for the glasses.
|
|
759
777
|
// The Bluetooth SDK paces every scene frame and legacy layout to this,
|
|
760
778
|
// coalescing faster updates last-wins; clears bypass it. No effect on G2
|
package/src/types/enums.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MMKV-backed KeyValueStore for @glassly/cloud-client — moved into engine so
|
|
3
|
-
* engine owns the cloud
|
|
3
|
+
* engine owns the cloud credential storage (the v2 refresh token, so a
|
|
4
4
|
* relaunch does not force a new login). A dedicated MMKV instance keeps
|
|
5
|
-
* cloud
|
|
5
|
+
* cloud credentials out of the app's general store. Re-exported through the
|
|
6
6
|
* host's `@/utils/cloudClient/MmkvSecureStore` shim.
|
|
7
7
|
*
|
|
8
8
|
* NOTE: MMKV is not hardware-backed. Before production handling of the
|