Implement standalone control server

This commit is contained in:
Max Goodhart
2025-06-14 06:46:27 +00:00
parent ec6b7bd360
commit 9ded048667
29 changed files with 3414 additions and 415 deletions

View File

@@ -1,6 +1,6 @@
import { Rectangle } from 'electron'
import type { Rectangle } from 'electron'
import { isEqual } from 'lodash-es'
import { ContentKind } from './types'
import type { ContentKind } from './types.ts'
export interface ViewPos extends Rectangle {
/**

View File

@@ -1,4 +1,5 @@
export * from './colors'
export * from './geometry'
export * from './roles'
export * from './types'
export * from './colors.ts'
export * from './geometry.ts'
export * from './roles.ts'
export * from './stateDiff.ts'
export * from './types.ts'

View File

@@ -1,6 +1,12 @@
export const validRoles = ['local', 'admin', 'operator', 'monitor'] as const
export const validRolesSet = new Set(validRoles)
const adminActions = ['dev-tools', 'browse', 'edit-tokens'] as const
const adminActions = [
'dev-tools',
'browse',
'create-invite',
'delete-token',
] as const
const operatorActions = [
'set-listening-view',

View File

@@ -0,0 +1,6 @@
import * as jsondiffpatch from 'jsondiffpatch'
export const stateDiff = jsondiffpatch.create({
objectHash: (obj: any, idx) => obj._id || `$$index:${idx}`,
omitRemovedValues: true,
})

View File

@@ -1,4 +1,5 @@
import { ViewContent, ViewPos } from './geometry'
import type { ViewContent, ViewPos } from './geometry.ts'
import type { StreamwallRole } from './roles.ts'
export interface StreamWindowConfig {
gridCount: number
@@ -75,13 +76,35 @@ export interface StreamDelayStatus {
state: string
}
export type AuthTokenKind = 'invite' | 'session' | 'streamwall'
export interface AuthTokenInfo {
tokenId: string
kind: AuthTokenKind
role: StreamwallRole
name: string
}
export interface StreamwallState {
identity: {
role: StreamwallRole
}
auth?: {
invites: AuthTokenInfo[]
sessions: AuthTokenInfo[]
}
config: StreamWindowConfig
streams: StreamList
customStreams: StreamList
views: ViewState[]
streamdelay: StreamDelayStatus | null
}
type MessageMeta = {
id: number
clientId: string
}
export type ControlCommand =
| { type: 'set-listening-view'; viewIdx: number | null }
| {
@@ -100,3 +123,12 @@ export type ControlCommand =
| { type: 'set-stream-running'; isStreamRunning: boolean }
| { type: 'create-invite'; role: string; name: string }
| { type: 'delete-token'; tokenId: string }
export type ControlUpdate = {
type: 'state'
state: StreamwallState
}
export type ControlCommandMessage = MessageMeta & ControlCommand
export type ControlUpdateMessage = MessageMeta & ControlUpdate