extract realm specific handling into #realm

+1
package.json
··· 16 16 "type": "module", 17 17 "imports": { 18 18 "#common/*": "./src/common/*", 19 + "#realm/*": "./src/realm/*", 19 20 "#client/*": "./src/client/*", 20 21 "#server/*": "./src/server/*", 21 22 "#skypod/*": "./src/skypod/*"
+1 -1
src/client/components/messenger.tsx
··· 1 1 import {useSignal} from '@preact/signals' 2 2 import {useCallback} from 'preact/hooks' 3 3 4 - import {useRealmIdentity} from '#client/realm/context-identity' 5 4 import {useDatabase} from '#client/root/context-database' 6 5 import {useSkypod} from '#client/skypod/context' 6 + import {useRealmIdentity} from '#realm/client/context-identity' 7 7 8 8 export const Messenger: preact.FunctionComponent = () => { 9 9 const {useDbSignal} = useDatabase()
+3 -3
src/client/components/peer-list.tsx
··· 1 1 import {useSignal, useSignalEffect} from '@preact/signals' 2 2 3 - import {useRealmConnection} from '#client/realm/context-connection' 4 - import {PeerState} from '#client/realm/types' 5 - import {IdentID} from '#common/protocol' 3 + import {useRealmConnection} from '#realm/client/context-connection' 4 + import {PeerState} from '#realm/client/types' 5 + import {IdentID} from '#realm/protocol/index' 6 6 7 7 export const PeerList: preact.FunctionComponent = () => { 8 8 const connection = useRealmConnection()
+5 -5
src/client/page-app.tsx
··· 1 - import {RealmConnectionManager} from '#client/realm/cmpnt-connection-manager' 1 + import {DatabaseProvider} from '#client/root/context-database' 2 + import {SkypodProvider} from '#client/skypod/context' 3 + import {RealmConnectionManager} from '#realm/client/cmpnt-connection-manager' 2 4 import { 3 5 RealmConnectionFallbackProps, 4 6 RealmConnectionProvider, 5 - } from '#client/realm/context-connection' 6 - import {RealmIdentityFallbackProps, RealmIdentityProvider} from '#client/realm/context-identity' 7 - import {DatabaseProvider} from '#client/root/context-database' 8 - import {SkypodProvider} from '#client/skypod/context' 7 + } from '#realm/client/context-connection' 8 + import {RealmIdentityFallbackProps, RealmIdentityProvider} from '#realm/client/context-identity' 9 9 10 10 import {DebugNuke} from './components/debug-nuke' 11 11 import {Messenger} from './components/messenger'
+1 -1
src/client/realm/cmpnt-connection-manager.tsx src/realm/client/cmpnt-connection-manager.tsx
··· 4 4 5 5 import {generateSignableJwt} from '#common/crypto/jwks' 6 6 import {jwtSchema} from '#common/crypto/jwts' 7 - import {RealmBrand} from '#common/protocol' 7 + import {RealmBrand} from '#realm/protocol/index' 8 8 9 9 import {useRealmConnection} from './context-connection' 10 10 import {useRealmIdentity} from './context-identity'
src/client/realm/context-connection.tsx src/realm/client/context-connection.tsx
+2 -2
src/client/realm/context-identity.tsx src/realm/client/context-identity.tsx
··· 5 5 import {useDatabase} from '#client/root/context-database' 6 6 import {generateSigningJwkPair} from '#common/crypto/jwks' 7 7 import {normalizeProtocolError, ProtocolError} from '#common/errors' 8 - import {IdentBrand, IdentID} from '#common/protocol' 9 - import {ClockState, ClockStorage, LogicalClock} from '#common/protocol/logical-clock' 8 + import {IdentBrand, IdentID} from '#realm/protocol/index' 9 + import {ClockState, ClockStorage, LogicalClock} from '#realm/protocol/logical-clock' 10 10 11 11 import {RealmIdentity} from './service-identity' 12 12
+3 -3
src/client/realm/service-connection-peer.ts src/realm/client/service-connection-peer.ts
··· 3 3 4 4 import {BlockingQueue} from '#common/async/blocking-queue' 5 5 import {sleep} from '#common/async/sleep' 6 - import * as protocol from '#common/protocol' 7 - import {IdentID} from '#common/protocol' 8 - import {DeviceCaps, DeviceInfo} from '#common/protocol/device' 6 + import {DeviceCaps, DeviceInfo} from '#realm/protocol/device' 7 + import * as protocol from '#realm/protocol/index' 8 + import {IdentID} from '#realm/protocol/index' 9 9 10 10 import {RealmSyncManager} from './service-connection-sync' 11 11
+2 -2
src/client/realm/service-connection-sync.ts src/realm/client/service-connection-sync.ts
··· 1 1 import {Database, StoredAction} from '#client/root/service-database' 2 - import {IdentID} from '#common/protocol' 3 - import {LCTimestamp, LogicalClock} from '#common/protocol/logical-clock' 2 + import {IdentID} from '#realm/protocol/index' 3 + import {LCTimestamp, LogicalClock} from '#realm/protocol/logical-clock' 4 4 import {DeviceScanner} from './service-device' 5 5 6 6 export class RealmSyncManager {
+4 -3
src/client/realm/service-connection.ts src/realm/client/service-connection.ts
··· 7 7 import {generateSignableJwt, jwkImport} from '#common/crypto/jwks' 8 8 import {jwtPayload, verifyJwtToken} from '#common/crypto/jwts' 9 9 import {normalizeError, normalizeProtocolError, ProtocolError} from '#common/errors' 10 - import * as protocol from '#common/protocol' 11 - import {IdentID, RealmID} from '#common/protocol' 12 - import {LogicalClock} from '#common/protocol/logical-clock' 13 10 import {streamSocketJson, takeSocketJson} from '#common/socket' 11 + 12 + import {IdentID, RealmID} from '#realm/protocol/brands' 13 + import * as protocol from '#realm/protocol/index' 14 + import {LogicalClock} from '#realm/protocol/logical-clock' 14 15 15 16 import {Database} from '#client/root/service-database' 16 17
+1 -1
src/client/realm/service-device.ts src/realm/client/service-device.ts
··· 1 - import {DeviceCaps, DeviceInfo} from '#common/protocol/device' 1 + import {DeviceCaps, DeviceInfo} from '#realm/protocol/device' 2 2 3 3 export class DeviceScanner { 4 4 #caps: DeviceCaps
+1 -1
src/client/realm/service-identity.ts src/realm/client/service-identity.ts
··· 1 1 import {JWK, jwkExport} from '#common/crypto/jwks' 2 - import {IdentID} from '#common/protocol' 2 + import {IdentID} from '#realm/protocol/index' 3 3 4 4 import {Signable} from './types' 5 5
+1 -1
src/client/realm/types.ts src/realm/client/types.ts
··· 1 - import {IdentID, RealmID} from '#common/protocol' 1 + import {IdentID, RealmID} from '#realm/protocol/index' 2 2 3 3 /** identity info for connecting to a realm */ 4 4 export interface ConnectionIdentity {
+2 -2
src/client/root/service-database.ts
··· 1 1 import Dexie, {Collection, IndexableType, type Table} from 'dexie' 2 2 3 3 import {JWK} from '#common/crypto/jwks' 4 - import {IdentID, RealmID} from '#common/protocol' 5 - import {LCTimestamp, LogicalClock} from '#common/protocol/logical-clock' 4 + import {IdentID, RealmID} from '#realm/protocol/index' 5 + import {LCTimestamp, LogicalClock} from '#realm/protocol/logical-clock' 6 6 import {Feed, FeedEntry, Lock} from '#skypod/schema' 7 7 8 8 export interface LocalIdentity {
+4 -4
src/client/skypod/context.tsx
··· 2 2 import {useContext, useEffect, useRef} from 'preact/hooks' 3 3 import {z} from 'zod/v4' 4 4 5 - import {IdentID} from '#common/protocol' 5 + import {IdentID} from '#realm/protocol/index' 6 6 import {Action, ActionMap, ActionOpts, actionSchema} from '#skypod/actions' 7 7 import {feedSchema} from '#skypod/schema' 8 8 9 - import {useRealmConnection} from '#client/realm/context-connection' 10 - import {useRealmIdentity} from '#client/realm/context-identity' 11 9 import {useDatabase} from '#client/root/context-database' 10 + import {useRealmConnection} from '#realm/client/context-connection' 11 + import {useRealmIdentity} from '#realm/client/context-identity' 12 12 13 - import {LogicalClock} from '#common/protocol/logical-clock' 13 + import {LogicalClock} from '#realm/protocol/logical-clock' 14 14 import FeedFetchWorker from './feed-fetch.worker?worker' 15 15 16 16 export type MiddlewareFn = (
+2 -2
src/client/skypod/feed-fetch.worker.ts
··· 3 3 4 4 import {Database} from '#client/root/service-database' 5 5 import {normalizeProtocolError} from '#common/errors' 6 - import {IdentBrand, IdentID} from '#common/protocol' 7 - import {LCTimestamp, LogicalClock} from '#common/protocol/logical-clock' 6 + import {IdentBrand, IdentID} from '#realm/protocol/index' 7 + import {LCTimestamp, LogicalClock} from '#realm/protocol/logical-clock' 8 8 9 9 const msgStartSchema = z.object({ 10 10 msg: z.literal('start'),
+1 -1
src/cmd/register-ident.ts
··· 1 1 #!/usr/bin/env node 2 2 3 3 import {generateSignableJwt, generateSigningJwkPair, jwkExport} from '#common/crypto/jwks' 4 - import {IdentBrand, RealmBrand} from '#common/protocol' 4 + import {IdentBrand, RealmBrand} from '#realm/protocol/index' 5 5 6 6 async function generateRegistrationJWT(realm?: string) { 7 7 const keypair = await generateSigningJwkPair()
+1 -1
src/cmd/server.ts
··· 2 2 import {fileURLToPath} from 'url' 3 3 import {parseArgs} from 'util' 4 4 5 + import {ensureRealmMap} from '#realm/server/state' 5 6 import {buildServer} from '#server/index' 6 - import {ensureRealmMap} from '#server/routes-socket/state' 7 7 8 8 const __filename = fileURLToPath(import.meta.url) 9 9 const __dirname = dirname(__filename)
-21
src/common/protocol.ts
··· 1 1 import {z} from 'zod/v4' 2 - import {ProtocolError} from './errors' 3 - import {errorMessageSchema} from './protocol/schema' 4 - 5 - export * from './protocol/brands' 6 - export * from './protocol/messages' 7 2 8 3 /** a zod transformer for parsing json */ 9 4 export const parseJson = z.transform<string, unknown>((input, ctx) => { ··· 19 14 return z.NEVER 20 15 } 21 16 }) 22 - 23 - export function makeError( 24 - error: ProtocolError, 25 - detail: string, 26 - seq?: number, 27 - ): z.infer<typeof errorMessageSchema> { 28 - return { 29 - typ: 'err', 30 - msg: error.message, 31 - seq, 32 - dat: { 33 - code: error.status, 34 - detail, 35 - }, 36 - } 37 - }
src/common/protocol/brands.ts src/realm/protocol/brands.ts
src/common/protocol/device.ts src/realm/protocol/device.ts
+1 -1
src/common/protocol/logical-clock.ts src/realm/protocol/logical-clock.ts
··· 1 - import {IdentBrand, IdentID} from '#common/protocol/brands' 1 + import {IdentBrand, IdentID} from '#realm/protocol/brands' 2 2 import {z} from 'zod/v4' 3 3 4 4 export interface ClockStorage {
src/common/protocol/messages.ts src/realm/protocol/messages.ts
src/common/protocol/schema.ts src/realm/protocol/schema.ts
+24
src/realm/protocol/index.ts
··· 1 + import {z} from 'zod/v4' 2 + 3 + import {ProtocolError} from '#common/errors' 4 + 5 + import {errorMessageSchema} from './schema' 6 + 7 + export * from './brands' 8 + export * from './messages' 9 + 10 + export function makeError( 11 + error: ProtocolError, 12 + detail: string, 13 + seq?: number, 14 + ): z.infer<typeof errorMessageSchema> { 15 + return { 16 + typ: 'err', 17 + msg: error.message, 18 + seq, 19 + dat: { 20 + code: error.status, 21 + detail, 22 + }, 23 + } 24 + }
+1 -1
src/server/index.ts
··· 3 3 4 4 import {WebSocketServer} from 'ws' 5 5 6 + import {socketHandler} from '#realm/server/handler' 6 7 import {apiRouter} from './routes-api/middleware' 7 8 import {notFoundHandler} from './routes-error' 8 - import {socketHandler} from './routes-socket/handler' 9 9 import {makeSpaMiddleware, makeStaticMiddleware} from './routes-static' 10 10 11 11 /**
+3 -3
src/server/realm-storage.ts src/realm/realm-storage.ts
··· 4 4 import {z} from 'zod/v4' 5 5 6 6 import {jwkExport, jwkImport, type JWK} from '#common/crypto/jwks' 7 - import {IdentBrand, IdentID, RealmBrand, RealmID} from '#common/protocol' 8 - import {LCTimestamp, LogicalClock} from '#common/protocol/logical-clock' 9 - import {actionMessageSchema} from '#common/protocol/schema' 10 7 import {StrictMap} from '#common/strict-map' 8 + import {IdentBrand, IdentID, RealmBrand, RealmID} from '#realm/protocol/index' 9 + import {LCTimestamp, LogicalClock} from '#realm/protocol/logical-clock' 10 + import {actionMessageSchema} from '#realm/protocol/schema' 11 11 12 12 export type IncomingAction = z.infer<typeof actionMessageSchema> 13 13 export type StoredAction = z.infer<typeof storedActionSchema>
+2 -2
src/server/routes-socket/handler-preauth.ts src/realm/server/handler-preauth.ts
··· 4 4 import {JWK, jwkExport, jwkImport} from '#common/crypto/jwks' 5 5 import {jwtPayload, jwtSchema, JWTToken, verifyJwtToken} from '#common/crypto/jwts' 6 6 import {normalizeError, ProtocolError} from '#common/errors' 7 + import {takeSocket} from '#common/socket' 7 8 import { 8 9 IdentBrand, 9 10 IdentID, ··· 11 12 PreauthResponse, 12 13 RealmBrand, 13 14 RealmID, 14 - } from '#common/protocol' 15 - import {takeSocket} from '#common/socket' 15 + } from '#realm/protocol/index' 16 16 17 17 import * as realms from './state' 18 18
+6 -4
src/server/routes-socket/handler-realm.ts src/realm/server/handler-realm.ts
··· 3 3 4 4 import {jwkExport} from '#common/crypto/jwks' 5 5 import {normalizeProtocolError, ProtocolError} from '#common/errors' 6 - import * as protocol from '#common/protocol' 7 - import {actionMessageSchema} from '#common/protocol/schema' 6 + import {parseJson} from '#common/protocol' 8 7 import {streamSocket} from '#common/socket' 9 8 10 - import * as realm from '#server/routes-socket/state' 9 + import * as protocol from '#realm/protocol/index' 10 + import {actionMessageSchema} from '#realm/protocol/schema' 11 + 12 + import * as realm from '#realm/server/state' 11 13 12 14 // what can the server handle? 13 15 const incomingMessageSchema = z.union([ ··· 30 32 realmBroadcast(auth, await buildRtcPeerJoined(auth)) 31 33 32 34 try { 33 - const incomingParser = protocol.parseJson.pipe(incomingMessageSchema) 35 + const incomingParser = parseJson.pipe(incomingMessageSchema) 34 36 for await (const msg of streamSocket(ws, {signal})) { 35 37 try { 36 38 const data = await incomingParser.parseAsync(msg)
src/server/routes-socket/handler.ts src/realm/server/handler.ts
+3 -3
src/server/routes-socket/state.ts src/realm/server/state.ts
··· 1 1 import WebSocket from 'isomorphic-ws' 2 2 3 - import {IdentID, RealmID} from '#common/protocol' 4 - import {DeviceCaps, DeviceInfo} from '#common/protocol/device' 5 3 import {StrictMap} from '#common/strict-map' 4 + import {DeviceCaps, DeviceInfo} from '#realm/protocol/device' 5 + import {IdentID, RealmID} from '#realm/protocol/index' 6 6 7 - import {RealmStorage} from '#server/realm-storage' 7 + import {RealmStorage} from '#realm/realm-storage' 8 8 9 9 /** An authenticated identity; only handed out in response to successful authentication. */ 10 10 export interface AuthenticatedIdentity {
+1 -1
src/skypod/actions-feed.ts
··· 1 - import {makeActionSchema} from '#common/protocol/schema' 1 + import {makeActionSchema} from '#realm/protocol/schema' 2 2 import {z} from 'zod/v4' 3 3 4 4 import {feedSchema, lockSchema} from './schema'
+1 -1
src/skypod/actions-feedentry.ts
··· 1 - import {makeActionSchema} from '#common/protocol/schema' 1 + import {makeActionSchema} from '#realm/protocol/schema' 2 2 import {z} from 'zod/v4' 3 3 4 4 export const patchActionSchema = makeActionSchema(
+2 -2
src/skypod/actions.ts
··· 1 - import {LCTimestamp} from '#common/protocol/logical-clock' 2 - import {actionOptionsSchema} from '#common/protocol/schema' 1 + import {LCTimestamp} from '#realm/protocol/logical-clock' 2 + import {actionOptionsSchema} from '#realm/protocol/schema' 3 3 import {z} from 'zod/v4' 4 4 5 5 import {feedActionSchemas} from './actions-feed'
+2 -2
src/skypod/schema.ts
··· 1 - import {IdentBrand} from '#common/protocol/brands' 2 - import {LogicalClock} from '#common/protocol/logical-clock' 1 + import {IdentBrand} from '#realm/protocol/brands' 2 + import {LogicalClock} from '#realm/protocol/logical-clock' 3 3 import {z} from 'zod/v4' 4 4 5 5 // lock schema for distributed work coordination
+1
tsconfig.json
··· 25 25 "baseUrl": ".", 26 26 "paths": { 27 27 "#common/*": ["./src/common/*"], 28 + "#realm/*": ["./src/realm/*"], 28 29 "#client/*": ["./src/client/*"], 29 30 "#server/*": ["./src/server/*"], 30 31 "#skypod/*": ["./src/skypod/*"]