@voltro/plugin-rooms 0.0.0-stage → 0.88.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.
- package/CHANGELOG.md +24492 -0
- package/LICENSE +61 -0
- package/README.md +9204 -2
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +12496 -0
- package/dist/actor.js +1473 -0
- package/dist/apiBinding.js +677 -0
- package/dist/apiRegistryBinding.js +398 -0
- package/dist/apiReservations.js +432 -0
- package/dist/baselines.js +72 -0
- package/dist/bots.d.ts +1485 -0
- package/dist/bots.js +562 -0
- package/dist/catalog.js +79 -0
- package/dist/checkpointJson.js +23 -0
- package/dist/checkpointStore.js +385 -0
- package/dist/client.js +55 -0
- package/dist/clockSync.js +50 -0
- package/dist/collision.js +155 -0
- package/dist/commandDelivery.js +100 -0
- package/dist/commandRecord.js +10 -0
- package/dist/commandWithdrawal.js +182 -0
- package/dist/connection.js +496 -0
- package/dist/controlCarrier.js +374 -0
- package/dist/controlRegistry.js +78 -0
- package/dist/controlTarget.js +44 -0
- package/dist/controlTransport.js +573 -0
- package/dist/developmentBinding.js +112 -0
- package/dist/directory.js +322 -0
- package/dist/directoryProjection.js +116 -0
- package/dist/errors.d.ts +125 -0
- package/dist/errors.js +52 -0
- package/dist/fixed.d.ts +284 -0
- package/dist/fixed.js +10 -0
- package/dist/fixed32.js +133 -0
- package/dist/fixedCollision.js +59 -0
- package/dist/fixedCollision32.js +108 -0
- package/dist/fixedMath.js +55 -0
- package/dist/fixedRaw.js +10 -0
- package/dist/fixedSlabs.js +33 -0
- package/dist/fixedTrig.js +47 -0
- package/dist/fixedTrig32.js +37 -0
- package/dist/fixedVectors.js +112 -0
- package/dist/fixedVectors32.js +94 -0
- package/dist/fixedWide.js +49 -0
- package/dist/fixedWords.js +45 -0
- package/dist/gateway.js +56 -0
- package/dist/geometry-retention-app/rooms.geometryJournalRetention.workflow.server.tsx +4 -0
- package/dist/geometry-retention-app/rooms.geometryJournalRetention.workflow.tsx +14 -0
- package/dist/geometry-worker/worker.d.mts +2 -0
- package/dist/geometry-worker/worker.mjs +50 -0
- package/dist/geometry.d.ts +2249 -0
- package/dist/geometry.js +40 -0
- package/dist/geometryActivation.js +81 -0
- package/dist/geometryActorInventory.js +107 -0
- package/dist/geometryAdminClient.js +86 -0
- package/dist/geometryAdminData.js +31 -0
- package/dist/geometryAdminFixtures.js +49 -0
- package/dist/geometryAdminPorts.js +4 -0
- package/dist/geometryAdminRpc.js +57 -0
- package/dist/geometryAdminRpcRoutes.js +48 -0
- package/dist/geometryAdminSchemas.js +38 -0
- package/dist/geometryAdministration.js +189 -0
- package/dist/geometryAdministrationPorts.js +4 -0
- package/dist/geometryApiBinding.js +164 -0
- package/dist/geometryAppStorage.js +57 -0
- package/dist/geometryArtifacts.js +197 -0
- package/dist/geometryAssetBundle.js +116 -0
- package/dist/geometryAssetClient.js +24 -0
- package/dist/geometryAssetData.js +105 -0
- package/dist/geometryAssetHttp.js +122 -0
- package/dist/geometryAssetPorts.js +4 -0
- package/dist/geometryAssetRpc.js +29 -0
- package/dist/geometryAssetRpcRoutes.js +39 -0
- package/dist/geometryAssetStorageGrant.js +102 -0
- package/dist/geometryBoxOverlap.js +109 -0
- package/dist/geometryCatalogueDigest.js +110 -0
- package/dist/geometryCellCoverage.js +84 -0
- package/dist/geometryCellLoader.js +27 -0
- package/dist/geometryChannel.js +133 -0
- package/dist/geometryChunkHttp.js +53 -0
- package/dist/geometryChunkLeases.js +21 -0
- package/dist/geometryClient.d.ts +1429 -0
- package/dist/geometryClient.js +148 -0
- package/dist/geometryClientChunks.js +329 -0
- package/dist/geometryClientDelta.js +24 -0
- package/dist/geometryClientHttp.js +36 -0
- package/dist/geometryClientInterest.js +108 -0
- package/dist/geometryClientStatic.js +33 -0
- package/dist/geometryCms.d.ts +763 -0
- package/dist/geometryCms.js +216 -0
- package/dist/geometryCommitCoordinator.js +240 -0
- package/dist/geometryCompactionFixture.js +83 -0
- package/dist/geometryCompactionStrategies.js +37 -0
- package/dist/geometryConnectionClient.js +22 -0
- package/dist/geometryDerivationFixtures.js +140 -0
- package/dist/geometryDerivationStrategies.js +26 -0
- package/dist/geometryDigest.js +12 -0
- package/dist/geometryEditChannel.js +69 -0
- package/dist/geometryEditIngress.js +262 -0
- package/dist/geometryEdits.js +365 -0
- package/dist/geometryEnvelope.js +40 -0
- package/dist/geometryGridRaycast.js +91 -0
- package/dist/geometryGridSweep.js +91 -0
- package/dist/geometryHeightfield.js +165 -0
- package/dist/geometryHeightfieldRaycast.js +73 -0
- package/dist/geometryHeightfieldSweep.js +84 -0
- package/dist/geometryHeightfieldVolume.js +44 -0
- package/dist/geometryHost.js +321 -0
- package/dist/geometryHostDirectory.js +206 -0
- package/dist/geometryHostMutations.js +136 -0
- package/dist/geometryHostStreams.js +123 -0
- package/dist/geometryHttpBody.js +75 -0
- package/dist/geometryHttpRoutes.js +111 -0
- package/dist/geometryImportGltf.js +299 -0
- package/dist/geometryImportLdtk.js +53 -0
- package/dist/geometryImportPng.js +143 -0
- package/dist/geometryImportPublication.js +66 -0
- package/dist/geometryImportTiled.js +38 -0
- package/dist/geometryImportTiles.js +135 -0
- package/dist/geometryImportVox.js +129 -0
- package/dist/geometryImportedSource.js +100 -0
- package/dist/geometryInspectEndpoint.js +247 -0
- package/dist/geometryInspection.js +91 -0
- package/dist/geometryInstall.js +120 -0
- package/dist/geometryJournalArchiveData.js +20 -0
- package/dist/geometryJournalArchiveIndex.js +329 -0
- package/dist/geometryJournalArchiveTable.js +20 -0
- package/dist/geometryJournalCompaction.js +99 -0
- package/dist/geometryJournalPatch.js +46 -0
- package/dist/geometryJournalRetention.js +111 -0
- package/dist/geometryJournalRetentionSchemas.js +35 -0
- package/dist/geometryJournalRetentionSweep.js +111 -0
- package/dist/geometryJournalRetentionWorkflow.js +27 -0
- package/dist/geometryJournalRetentionWorkflowData.js +30 -0
- package/dist/geometryJournalStorage.js +147 -0
- package/dist/geometryLoader.js +117 -0
- package/dist/geometryManifest.js +112 -0
- package/dist/geometryManifestChannel.js +92 -0
- package/dist/geometryManifestClient.js +121 -0
- package/dist/geometryManifestData.js +48 -0
- package/dist/geometryManifestPorts.js +4 -0
- package/dist/geometryManifestPublication.js +108 -0
- package/dist/geometryManifestSource.js +67 -0
- package/dist/geometryMigrationJournal.js +13 -0
- package/dist/geometryMigrationStrategies.js +6 -0
- package/dist/geometryMigrations.js +322 -0
- package/dist/geometryNativeMetadata.js +51 -0
- package/dist/geometryPatch.js +169 -0
- package/dist/geometryPersistence.js +448 -0
- package/dist/geometryPersistenceCapture.js +68 -0
- package/dist/geometryPersistenceData.js +139 -0
- package/dist/geometryPersistencePorts.js +4 -0
- package/dist/geometryPlayerAdmission.js +33 -0
- package/dist/geometryPlayerEditOwner.js +264 -0
- package/dist/geometryPlayerEdits.js +48 -0
- package/dist/geometryPrepared.js +187 -0
- package/dist/geometryPrivacyFence.js +23 -0
- package/dist/geometryProceduralPublication.js +90 -0
- package/dist/geometryProceduralWorker.js +163 -0
- package/dist/geometryPublication.js +109 -0
- package/dist/geometryRayAlgebra.js +115 -0
- package/dist/geometryReadClient.js +156 -0
- package/dist/geometryReadPorts.js +4 -0
- package/dist/geometryReadRpc.js +26 -0
- package/dist/geometryReadRpcRoutes.js +46 -0
- package/dist/geometryReliablePublication.js +81 -0
- package/dist/geometryReloadPorts.js +45 -0
- package/dist/geometryReloadSource.js +277 -0
- package/dist/geometryRenderCache.js +164 -0
- package/dist/geometryRenderLod.js +101 -0
- package/dist/geometryRollback.js +124 -0
- package/dist/geometryRollbackCoordinator.js +202 -0
- package/dist/geometryRollbackPorts.js +45 -0
- package/dist/geometryRollbackSource.js +208 -0
- package/dist/geometryRollbackStore.js +197 -0
- package/dist/geometrySchemas.js +26 -0
- package/dist/geometryServer.d.ts +2766 -0
- package/dist/geometryServer.js +62 -0
- package/dist/geometryShapeRaycast.js +110 -0
- package/dist/geometryShapeSegments.js +33 -0
- package/dist/geometryShapes.js +222 -0
- package/dist/geometrySnapshot.js +75 -0
- package/dist/geometrySnapshotChannel.js +159 -0
- package/dist/geometrySnapshotClient.js +158 -0
- package/dist/geometrySnapshotPreparation.js +75 -0
- package/dist/geometrySnapshotServer.js +190 -0
- package/dist/geometrySqlOwner.js +20 -0
- package/dist/geometryStorage.js +126 -0
- package/dist/geometryStorageGrant.js +68 -0
- package/dist/geometryStorageIdentity.js +8 -0
- package/dist/geometryTileArtifact.js +9 -0
- package/dist/geometryTileCodec.js +193 -0
- package/dist/geometryTileCollision.js +95 -0
- package/dist/geometryTileNavigation.js +127 -0
- package/dist/geometryTileView.js +34 -0
- package/dist/geometryVersionActivation.js +113 -0
- package/dist/geometryVersionClient.js +237 -0
- package/dist/geometryVersionCompare.js +39 -0
- package/dist/geometryVersionMigration.js +105 -0
- package/dist/geometryVoxel.js +252 -0
- package/dist/geometryWorldEntitySubject.js +31 -0
- package/dist/geometryWorldExtent.js +11 -0
- package/dist/geometryWorldMetadata.js +37 -0
- package/dist/geometryWorldStrategyFixtures.js +126 -0
- package/dist/geometryWorldView.js +306 -0
- package/dist/host.js +127 -0
- package/dist/hostBinding.js +276 -0
- package/dist/hostCellObservation.js +113 -0
- package/dist/hostClientCapacity.js +89 -0
- package/dist/hostCommandScope.js +63 -0
- package/dist/hostController.js +3093 -0
- package/dist/hostDeployment.js +64 -0
- package/dist/hostDrain.js +151 -0
- package/dist/hostDrainPorts.js +4 -0
- package/dist/hostDriver.js +178 -0
- package/dist/hostLane.js +287 -0
- package/dist/hostListener.js +78 -0
- package/dist/hostListenerBinding.js +18 -0
- package/dist/hostLoopObservation.js +89 -0
- package/dist/hostMetrics.js +55 -0
- package/dist/hostRegistryBinding.js +417 -0
- package/dist/hostSelection.js +15 -0
- package/dist/hostShutdown.js +46 -0
- package/dist/hostTurnObservation.js +52 -0
- package/dist/identities.js +3 -0
- package/dist/index.d.ts +8632 -0
- package/dist/index.js +231 -0
- package/dist/inputReceipts.js +62 -0
- package/dist/inputRedundancy.js +54 -0
- package/dist/inspect.js +237 -0
- package/dist/lockstep.d.ts +436 -0
- package/dist/lockstep.js +381 -0
- package/dist/lockstepAdmission.js +261 -0
- package/dist/lockstepAdmissionCodec.js +93 -0
- package/dist/lockstepAdmissionPorts.js +4 -0
- package/dist/lockstepClientSession.js +577 -0
- package/dist/lockstepDefinition.js +147 -0
- package/dist/lockstepHostLoop.js +242 -0
- package/dist/lockstepInitialAdmission.js +66 -0
- package/dist/lockstepInitialStrategyFixtures.js +44 -0
- package/dist/lockstepJournal.js +394 -0
- package/dist/lockstepJournalCodec.js +253 -0
- package/dist/lockstepJournalPorts.js +4 -0
- package/dist/lockstepJournalRebuild.js +207 -0
- package/dist/lockstepJournalRows.js +56 -0
- package/dist/lockstepMembers.js +130 -0
- package/dist/lockstepMessages.js +46 -0
- package/dist/lockstepOwnedRoom.js +763 -0
- package/dist/lockstepPolicies.js +83 -0
- package/dist/lockstepReact.js +46 -0
- package/dist/lockstepRecoveryTruth.js +120 -0
- package/dist/lockstepRosterConfig.js +31 -0
- package/dist/lockstepSeed.js +11 -0
- package/dist/lockstepSeedFixture.js +19 -0
- package/dist/lockstepServer.d.ts +3897 -0
- package/dist/lockstepServer.js +324 -0
- package/dist/lockstepServerConfig.js +100 -0
- package/dist/lockstepServerRoles.js +402 -0
- package/dist/lockstepServerStrategyFixtures.js +32 -0
- package/dist/lockstepStrategies.js +5 -0
- package/dist/lockstepStrategyFixtures.js +136 -0
- package/dist/lockstepTerminal.js +89 -0
- package/dist/lockstepTerminalPorts.js +4 -0
- package/dist/lockstepTransport.js +772 -0
- package/dist/lockstepTransportConfig.js +31 -0
- package/dist/lockstepWireRoster.js +33 -0
- package/dist/matchRoomProvider.js +31 -0
- package/dist/matchRooms.js +18 -0
- package/dist/membershipObserver.js +46 -0
- package/dist/moderation.js +97 -0
- package/dist/movementSpecials.js +103 -0
- package/dist/ownership.js +16 -0
- package/dist/ownershipWithdrawal.js +17 -0
- package/dist/pcg32.js +95 -0
- package/dist/ports.d.ts +1241 -0
- package/dist/ports.js +10 -0
- package/dist/quaternion.js +69 -0
- package/dist/react.d.ts +406 -0
- package/dist/react.js +108 -0
- package/dist/reaper-app/rooms.reaper.workflow.server.tsx +5 -0
- package/dist/reaper-app/rooms.reaper.workflow.tsx +13 -0
- package/dist/reaper.js +242 -0
- package/dist/reaperSchemas.js +41 -0
- package/dist/reaperWorkflow.js +69 -0
- package/dist/recovery.js +188 -0
- package/dist/recoverySeats.js +25 -0
- package/dist/replay.d.ts +273 -0
- package/dist/replay.js +484 -0
- package/dist/replayPorts.js +4 -0
- package/dist/replayRecording.js +66 -0
- package/dist/replaySchema.js +156 -0
- package/dist/replayStorage.d.ts +149 -0
- package/dist/replayStorage.js +484 -0
- package/dist/reservationBatch.js +421 -0
- package/dist/reservationSchemas.js +16 -0
- package/dist/reservations.js +258 -0
- package/dist/reservePort.js +68 -0
- package/dist/resolvedOptions.js +3 -0
- package/dist/room.d.ts +1006 -0
- package/dist/room.js +283 -0
- package/dist/roomAccessSweep.js +94 -0
- package/dist/roomAppCommandControl.js +58 -0
- package/dist/roomAuthoringStrategy.js +16 -0
- package/dist/roomErasure.js +197 -0
- package/dist/roomPoolRuntimeDefaults.js +23 -0
- package/dist/roomPoolSelection.js +18 -0
- package/dist/roomPoolTopology.js +211 -0
- package/dist/rpc.d.ts +551 -0
- package/dist/rpc.js +111 -0
- package/dist/rpcClient.js +151 -0
- package/dist/rpcRoutes.js +27 -0
- package/dist/runtime.js +1122 -0
- package/dist/schemaHistory.js +97 -0
- package/dist/seatStore.js +150 -0
- package/dist/seatStrategyFixtures.js +51 -0
- package/dist/seatSubject.js +31 -0
- package/dist/seats.js +129 -0
- package/dist/serverSession.js +810 -0
- package/dist/serverSessionConfig.js +42 -0
- package/dist/sessionAdmission.js +52 -0
- package/dist/sidecarAdmission.js +102 -0
- package/dist/sidecarConfig.js +115 -0
- package/dist/sidecarConfigPublication.js +63 -0
- package/dist/sidecarHostListener.js +207 -0
- package/dist/sidecarIpc.js +204 -0
- package/dist/sidecarPeer.js +309 -0
- package/dist/sidecarProcessPort.js +27 -0
- package/dist/sidecarRuntime.js +167 -0
- package/dist/sidecarSelection.js +141 -0
- package/dist/sidecarWire.js +177 -0
- package/dist/sidecarWrites.js +162 -0
- package/dist/simulation.d.ts +391 -0
- package/dist/simulation.js +281 -0
- package/dist/simulationAuthoring.js +28 -0
- package/dist/simulationBytes.js +26 -0
- package/dist/simulationConformance.js +304 -0
- package/dist/simulationInputHistoryCapture.js +34 -0
- package/dist/simulationInputHistoryWire.js +192 -0
- package/dist/simulationOptionsWire.js +77 -0
- package/dist/simulationRecoveryWire.js +133 -0
- package/dist/simulationReplay.js +126 -0
- package/dist/simulationSnapshotWire.js +111 -0
- package/dist/simulationState.js +177 -0
- package/dist/snapshotBlob.js +125 -0
- package/dist/snapshotBlobCleanup.js +92 -0
- package/dist/snapshotBlobIndex.js +37 -0
- package/dist/snapshotBudget.js +79 -0
- package/dist/snapshotChain.js +184 -0
- package/dist/snapshotErasure.js +171 -0
- package/dist/snapshotInspection.js +104 -0
- package/dist/snapshotSegmentBlobs.js +57 -0
- package/dist/snapshotUploads.js +165 -0
- package/dist/socketTransport.js +252 -0
- package/dist/spatial.js +103 -0
- package/dist/spectatorPolicy.js +25 -0
- package/dist/spectatorProducer.js +88 -0
- package/dist/startFailureCause.js +3 -0
- package/dist/stateCodec.js +657 -0
- package/dist/strategies.d.ts +210 -0
- package/dist/strategies.js +8 -0
- package/dist/strategiesServer.d.ts +286 -0
- package/dist/strategiesServer.js +11 -0
- package/dist/strategyFixtures.js +181 -0
- package/dist/streamFraming.js +121 -0
- package/dist/streamTransport.js +265 -0
- package/dist/subjectAdmission.js +49 -0
- package/dist/subjectPrivacy.js +280 -0
- package/dist/subjectPrivacyBinding.js +89 -0
- package/dist/systemManifest.js +181 -0
- package/dist/tables.js +158 -0
- package/dist/testHarness.js +88 -0
- package/dist/testing.d.ts +3684 -0
- package/dist/testing.js +220 -0
- package/dist/testingPorts.js +270 -0
- package/dist/testingServer.d.ts +4060 -0
- package/dist/testingServer.js +18 -0
- package/dist/transform.d.ts +692 -0
- package/dist/transform.js +216 -0
- package/dist/transform3d.js +117 -0
- package/dist/transformCollection.js +23 -0
- package/dist/transformCollection3d.js +23 -0
- package/dist/transformCollectionCore.js +155 -0
- package/dist/transformFrames.js +120 -0
- package/dist/transformPrediction3d.js +126 -0
- package/dist/transformRules.js +122 -0
- package/dist/transformSchemas.js +19 -0
- package/dist/transport.js +31 -0
- package/dist/transportAuthoring.js +28 -0
- package/dist/transportCleanup.js +21 -0
- package/dist/transportConformance.js +123 -0
- package/dist/transportConnector.js +81 -0
- package/dist/transportEndpoints.js +37 -0
- package/dist/transportsServer.d.ts +5515 -0
- package/dist/transportsServer.js +6 -0
- package/dist/viewProjection.js +15 -0
- package/dist/web.d.ts +2286 -0
- package/dist/web.js +517 -0
- package/dist/webTransportClient.js +172 -0
- package/dist/wire.d.ts +992 -0
- package/dist/wire.js +491 -0
- package/dist/withdrawalPort.js +27 -0
- package/dist/world.d.ts +1894 -0
- package/dist/world.js +332 -0
- package/dist/worldActorReceipts.js +47 -0
- package/dist/worldActorTransferSnapshot.js +13 -0
- package/dist/worldAdmissionPending.js +7 -0
- package/dist/worldBoundaryCoordinator.js +147 -0
- package/dist/worldCatalog.js +80 -0
- package/dist/worldCellAllocation.js +202 -0
- package/dist/worldCellDestination.js +67 -0
- package/dist/worldCells.js +488 -0
- package/dist/worldChange.js +31 -0
- package/dist/worldClient.js +663 -0
- package/dist/worldClientControl.js +140 -0
- package/dist/worldClientPendingInput.js +15 -0
- package/dist/worldClientRpc.js +132 -0
- package/dist/worldClientRpcRoutes.js +42 -0
- package/dist/worldClientSchemas.js +27 -0
- package/dist/worldCommands.js +139 -0
- package/dist/worldData.js +41 -0
- package/dist/worldDefaultBinding.js +376 -0
- package/dist/worldDefaultGroupAdmission.js +81 -0
- package/dist/worldDefaultGroupAppServices.js +30 -0
- package/dist/worldDefaultGroupCompensation.js +108 -0
- package/dist/worldDefaultGroupContinuation.js +95 -0
- package/dist/worldDefaultGroupControl.js +71 -0
- package/dist/worldDefaultGroupMembers.js +84 -0
- package/dist/worldDefaultGroups.js +20 -0
- package/dist/worldDefaultPending.js +78 -0
- package/dist/worldDefaultService.js +244 -0
- package/dist/worldEntities.js +2979 -0
- package/dist/worldEntityCodec.js +20 -0
- package/dist/worldEntityHandoffView.js +153 -0
- package/dist/worldGeometry.js +169 -0
- package/dist/worldGhostAdmission.js +64 -0
- package/dist/worldGhostDestination.js +117 -0
- package/dist/worldGhostGateway.js +131 -0
- package/dist/worldGhostHandshake.js +107 -0
- package/dist/worldGhostHost.js +41 -0
- package/dist/worldGhostIngress.js +131 -0
- package/dist/worldGhostNeighborhood.js +69 -0
- package/dist/worldGhostNeighbors.js +85 -0
- package/dist/worldGhostOutbound.js +109 -0
- package/dist/worldGhostPublisher.js +215 -0
- package/dist/worldGhostReceiver.js +212 -0
- package/dist/worldGhostSender.js +145 -0
- package/dist/worldGhostSocket.js +77 -0
- package/dist/worldGhostWire.js +171 -0
- package/dist/worldGroupCommand.js +48 -0
- package/dist/worldGroupDeadline.js +114 -0
- package/dist/worldGroupPreparation.js +114 -0
- package/dist/worldGroupReadyControl.js +127 -0
- package/dist/worldGroupSupervisor.js +119 -0
- package/dist/worldHandoffMetrics.js +58 -0
- package/dist/worldHandoffView.js +99 -0
- package/dist/worldHostSource.js +68 -0
- package/dist/worldInspectEndpoint.js +249 -0
- package/dist/worldInspection.js +108 -0
- package/dist/worldInstanceAdmission.js +30 -0
- package/dist/worldInstanceAllocation.js +115 -0
- package/dist/worldInstanceDestination.js +63 -0
- package/dist/worldInstanceExpiry.js +281 -0
- package/dist/worldInstanceExpirySupervisor.js +87 -0
- package/dist/worldInstanceLifecycle.js +102 -0
- package/dist/worldInstanceState.js +51 -0
- package/dist/worldInstances.js +477 -0
- package/dist/worldJoin.js +55 -0
- package/dist/worldLayers.js +150 -0
- package/dist/worldLeases.js +77 -0
- package/dist/worldManifest.js +24 -0
- package/dist/worldMovement.js +62 -0
- package/dist/worldPersistence.js +133 -0
- package/dist/worldProjection.js +220 -0
- package/dist/worldReact.js +109 -0
- package/dist/worldRecoveryActor.js +34 -0
- package/dist/worldReturnAnchor.js +48 -0
- package/dist/worldRoomHooks.js +56 -0
- package/dist/worldRoomPool.js +26 -0
- package/dist/worldRoomSteps.js +132 -0
- package/dist/worldSeatBinding.js +35 -0
- package/dist/worldServer.d.ts +6936 -0
- package/dist/worldServer.js +48 -0
- package/dist/worldSourceSeatPending.js +8 -0
- package/dist/worldStrategyFixtures.js +163 -0
- package/dist/worldTesting.js +26 -0
- package/dist/worldTransitionDefaults.js +197 -0
- package/dist/worldTransitionExecutor.js +518 -0
- package/dist/worldTransitionGroup.js +112 -0
- package/dist/worldTransitionPhysicalSteps.js +39 -0
- package/dist/worldTransitionResolver.js +227 -0
- package/dist/worldTransitionSeatGroup.js +63 -0
- package/dist/worldTransitionSeats.js +259 -0
- package/dist/worldTransitionState.js +94 -0
- package/dist/worldTransitions.js +100 -0
- package/package.json +189 -4
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { BudgetExceeded as e, ProtocolError as t, RoomForbidden as n, RoomFull as r, RoomGone as i, RoomPoolWaking as a } from "./errors.js";
|
|
2
|
+
import { roomHostTransportEndpoints as o } from "./transportEndpoints.js";
|
|
3
|
+
import { ROOMS_TABLE as s, ROOM_CREATIONS_TABLE as c, ROOM_HOSTS_TABLE as l } from "./identities.js";
|
|
4
|
+
import { canonicalRoomJson as u } from "./checkpointJson.js";
|
|
5
|
+
import { RoomDirectoryPort as d } from "./ports.js";
|
|
6
|
+
import { captureAdmittedRoomPoolTopology as f, resolveRoomPool as p } from "./roomPoolTopology.js";
|
|
7
|
+
import { resolveRoomHostSelection as m } from "./hostSelection.js";
|
|
8
|
+
import { resolveRoomPoolHostSelection as h } from "./roomPoolSelection.js";
|
|
9
|
+
import { and as g, eq as _, generateId as v, gt as y, or as b } from "@voltro/database";
|
|
10
|
+
import { Effect as x, Layer as S } from "effect";
|
|
11
|
+
import { createHash as C } from "node:crypto";
|
|
12
|
+
import { registerWakeup as w } from "@voltro/runtime";
|
|
13
|
+
// src/directory.ts
|
|
14
|
+
var T = "room-pool", E = 5e3;
|
|
15
|
+
function D(e) {
|
|
16
|
+
throw new t({ detail: e });
|
|
17
|
+
}
|
|
18
|
+
var O = (e) => typeof e == "number" && Number.isSafeInteger(e) && e >= 0 ? e : D("Invalid durable directory counter"), k = (e) => typeof e == "string" && e.trim() && e.length <= 191 ? e : D("Invalid directory identity"), A = (e) => {
|
|
19
|
+
let t = e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : NaN;
|
|
20
|
+
return Number.isFinite(t) ? t : D("Invalid durable directory timestamp");
|
|
21
|
+
}, j = (e) => !e || typeof e != "object" || Array.isArray(e) ? D("Directory metadata must be an object") : structuredClone(e), M = (e) => typeof e.locked == "boolean" ? Object.freeze({
|
|
22
|
+
id: k(e.id),
|
|
23
|
+
name: k(e.name),
|
|
24
|
+
hostId: k(e.hostId),
|
|
25
|
+
tenantId: k(e.tenantId),
|
|
26
|
+
metadata: j(e.metadata),
|
|
27
|
+
clients: O(e.clients),
|
|
28
|
+
maxClients: O(e.maxClients),
|
|
29
|
+
locked: e.locked,
|
|
30
|
+
epoch: O(e.epoch),
|
|
31
|
+
...e.pool == null ? {} : { pool: k(e.pool) }
|
|
32
|
+
}) : D("Invalid durable Room listing"), N = (e) => {
|
|
33
|
+
let t = e.load;
|
|
34
|
+
if (!t || !Number.isFinite(t.cpu) || t.cpu < 0 || t.cpu > 1 || typeof e.ready != "boolean") return D("Invalid durable host load");
|
|
35
|
+
let n = e.pool !== null && e.pool !== void 0, r = e.clientCapacity !== null && e.clientCapacity !== void 0;
|
|
36
|
+
if (n !== r || r && O(e.clientCapacity) < 1) return D("Invalid durable host pool capacity");
|
|
37
|
+
let i = o(e.publicAddress, e.webTransportAddress, e.webTransportCertificateHash);
|
|
38
|
+
return Object.freeze({
|
|
39
|
+
id: k(e.id),
|
|
40
|
+
address: i.ws,
|
|
41
|
+
...i.wt === void 0 ? {} : { webTransportAddress: i.wt },
|
|
42
|
+
...i.wtCertificateHash === void 0 ? {} : { webTransportCertificateHash: i.wtCertificateHash },
|
|
43
|
+
region: k(e.region),
|
|
44
|
+
...n ? {
|
|
45
|
+
pool: k(e.pool),
|
|
46
|
+
clientCapacity: O(e.clientCapacity)
|
|
47
|
+
} : {},
|
|
48
|
+
capacity: O(e.capacity),
|
|
49
|
+
rooms: O(t.rooms),
|
|
50
|
+
clients: O(t.clients),
|
|
51
|
+
cpu: t.cpu,
|
|
52
|
+
lastHeartbeatAt: A(e.lastHeartbeatAt),
|
|
53
|
+
ready: e.ready,
|
|
54
|
+
...e.instanceId !== null && e.instanceId !== void 0 ? { membership: {
|
|
55
|
+
instanceId: k(e.instanceId),
|
|
56
|
+
startedAt: A(e.membershipStartedAt)
|
|
57
|
+
} } : {}
|
|
58
|
+
});
|
|
59
|
+
}, P = (a) => x.tryPromise({
|
|
60
|
+
try: a,
|
|
61
|
+
catch: (a) => a instanceof t || a instanceof e || a instanceof n || a instanceof r || a instanceof i ? a : new t({ detail: "Durable Room directory operation failed" })
|
|
62
|
+
}), F = (e, t, n, r, i = !1) => e.query({
|
|
63
|
+
table: t,
|
|
64
|
+
predicate: n,
|
|
65
|
+
order: [{
|
|
66
|
+
column: "id",
|
|
67
|
+
direction: "asc"
|
|
68
|
+
}],
|
|
69
|
+
take: r,
|
|
70
|
+
skip: void 0,
|
|
71
|
+
projection: void 0,
|
|
72
|
+
...i ? { lock: "update" } : {}
|
|
73
|
+
}), I = (d, S) => {
|
|
74
|
+
let I = S.pools === void 0 ? void 0 : f(S.pools), L = S.maxHosts ?? 256, R = S.maxHostCapacity ?? 4096, z = S.maxListedRooms ?? 256;
|
|
75
|
+
(![
|
|
76
|
+
L,
|
|
77
|
+
R,
|
|
78
|
+
z
|
|
79
|
+
].every((e) => Number.isSafeInteger(e) && e > 0) || !Number.isFinite(S.heartbeatTtlMs) || S.heartbeatTtlMs <= 0) && D("Invalid directory budgets");
|
|
80
|
+
let B = () => {
|
|
81
|
+
let e = S.epochNow();
|
|
82
|
+
return Number.isFinite(e) && e >= 0 && e <= 864e13 ? e : D("Invalid directory wall clock");
|
|
83
|
+
}, V = (e) => (O(e.rooms), O(e.clients), (!Number.isFinite(e.cpu) || e.cpu < 0 || e.cpu > 1) && D("Host CPU load must be measured between zero and one"), { ...e }), H = (t, n) => P(async () => {
|
|
84
|
+
n === void 0 || I && Object.hasOwn(I.pools, n) && I.pools[n].regions.includes(t) || D("Unknown host pool or region");
|
|
85
|
+
let r = await F(d, l, g(_("region", k(t)), _("ready", !0), _("draining", !1), y("lastHeartbeatAt", new Date(B() - S.heartbeatTtlMs)), ...n === void 0 ? I ? [] : [_("pool", null)] : [_("pool", n)]), L + 1);
|
|
86
|
+
if (r.length > L) throw new e({
|
|
87
|
+
budget: "listedHosts",
|
|
88
|
+
limit: L
|
|
89
|
+
});
|
|
90
|
+
return r.map(N);
|
|
91
|
+
});
|
|
92
|
+
return Object.freeze({
|
|
93
|
+
register: (n) => {
|
|
94
|
+
let r = Object.getOwnPropertyDescriptor(n, "webTransportAddress"), i = Object.getOwnPropertyDescriptor(n, "webTransportCertificateHash");
|
|
95
|
+
if (r && (!("value" in r) || !r.enumerable) || !r && "webTransportAddress" in n || i && (!("value" in i) || !i.enumerable) || !i && "webTransportCertificateHash" in n) return x.fail(new t({ detail: "Room host native endpoint requires own routing data" }));
|
|
96
|
+
let a;
|
|
97
|
+
try {
|
|
98
|
+
a = o(n.address, r?.value, i?.value);
|
|
99
|
+
} catch {
|
|
100
|
+
return x.fail(new t({ detail: "Room host endpoints are malformed" }));
|
|
101
|
+
}
|
|
102
|
+
return P(async () => {
|
|
103
|
+
n.ready !== void 0 && typeof n.ready != "boolean" && D("Invalid host readiness admission");
|
|
104
|
+
let t = O(n.capacity);
|
|
105
|
+
if (t < 1 || t > R) throw new e({
|
|
106
|
+
budget: "hostCapacity",
|
|
107
|
+
limit: R
|
|
108
|
+
});
|
|
109
|
+
let r = Object.getOwnPropertyDescriptor(n, "pool"), i = Object.getOwnPropertyDescriptor(n, "clientCapacity");
|
|
110
|
+
(r && (!r.enumerable || !("value" in r)) || i && (!i.enumerable || !("value" in i)) || !r && "pool" in n || !i && "clientCapacity" in n) && D("Host pool registration requires own data");
|
|
111
|
+
let o = null, s = null;
|
|
112
|
+
if (I) {
|
|
113
|
+
o = k(r?.value), s = O(i?.value);
|
|
114
|
+
let e = Object.hasOwn(I.pools, o) ? I.pools[o] : void 0;
|
|
115
|
+
(!e || !e.regions.includes(n.region) || s < 1 || e.capacity && (t !== e.capacity.rooms || s !== e.capacity.clients)) && D("Host registration does not match its declared pool capacity or region");
|
|
116
|
+
} else (r?.value !== void 0 || i?.value !== void 0) && D("Host pool registration requires an admitted topology");
|
|
117
|
+
let c = B(), u = v({
|
|
118
|
+
kind: "typeid",
|
|
119
|
+
prefix: "rhost"
|
|
120
|
+
}, l);
|
|
121
|
+
n.membership && (!Number.isSafeInteger(n.membership.startedAt) || n.membership.startedAt < 0 || n.membership.startedAt > 864e13) && D("Invalid host membership process identity");
|
|
122
|
+
let f = {
|
|
123
|
+
id: u,
|
|
124
|
+
publicAddress: a.ws,
|
|
125
|
+
webTransportAddress: a.wt ?? null,
|
|
126
|
+
webTransportCertificateHash: a.wtCertificateHash ?? null,
|
|
127
|
+
region: k(n.region),
|
|
128
|
+
capacity: t,
|
|
129
|
+
pool: o,
|
|
130
|
+
clientCapacity: s,
|
|
131
|
+
ready: n.ready ?? !0,
|
|
132
|
+
draining: !1,
|
|
133
|
+
load: V(n.load),
|
|
134
|
+
heartbeatRevision: 1,
|
|
135
|
+
lastHeartbeatAt: new Date(c),
|
|
136
|
+
startedAt: new Date(c),
|
|
137
|
+
instanceId: n.membership ? k(n.membership.instanceId) : null,
|
|
138
|
+
membershipStartedAt: n.membership ? new Date(n.membership.startedAt) : null
|
|
139
|
+
};
|
|
140
|
+
return await d.insert(l, f), N(f);
|
|
141
|
+
});
|
|
142
|
+
},
|
|
143
|
+
heartbeat: (e, t) => P(() => d.transactional(async (n) => {
|
|
144
|
+
let r = (await F(n, l, _("id", k(e)), 1, !0))[0];
|
|
145
|
+
if (!r) throw new i({ roomId: "host" });
|
|
146
|
+
let a = O(r.heartbeatRevision);
|
|
147
|
+
if (a >= 2 ** 53 - 1 && D("Host heartbeat revision is exhausted"), await n.updateMany("_voltro_room_hosts", {
|
|
148
|
+
load: V(t),
|
|
149
|
+
lastHeartbeatAt: new Date(B()),
|
|
150
|
+
heartbeatRevision: a + 1
|
|
151
|
+
}, { where: g(_("id", e), _("heartbeatRevision", a)) }) !== 1) throw new i({ roomId: "host" });
|
|
152
|
+
})),
|
|
153
|
+
setReady: (e, t) => P(() => d.transactional(async (n) => {
|
|
154
|
+
typeof t != "boolean" && D("Invalid host readiness admission");
|
|
155
|
+
let r = (await F(n, l, _("id", k(e)), 1, !0))[0];
|
|
156
|
+
if (!r) throw new i({ roomId: "host" });
|
|
157
|
+
if (t && r.draining === !0 && D("A draining Host cannot reopen routing admission"), r.ready === t) return;
|
|
158
|
+
typeof r.ready != "boolean" && D("Invalid durable host readiness");
|
|
159
|
+
let a = O(r.heartbeatRevision);
|
|
160
|
+
if (a >= 2 ** 53 - 1 && D("Host heartbeat revision is exhausted"), await n.updateMany("_voltro_room_hosts", {
|
|
161
|
+
ready: t,
|
|
162
|
+
lastHeartbeatAt: new Date(B()),
|
|
163
|
+
heartbeatRevision: a + 1
|
|
164
|
+
}, { where: g(_("id", e), _("ready", r.ready)) }) !== 1) throw new i({ roomId: "host" });
|
|
165
|
+
})),
|
|
166
|
+
hosts: H,
|
|
167
|
+
observeOwnership: (e, t) => x.uninterruptible(P(() => d.transactional(async (n) => {
|
|
168
|
+
let r = (await n.query({
|
|
169
|
+
table: s,
|
|
170
|
+
predicate: g(_("id", k(e)), _("tenantId", k(t))),
|
|
171
|
+
order: [],
|
|
172
|
+
take: 1,
|
|
173
|
+
skip: void 0,
|
|
174
|
+
projection: [
|
|
175
|
+
"id",
|
|
176
|
+
"tenantId",
|
|
177
|
+
"hostId",
|
|
178
|
+
"epoch",
|
|
179
|
+
"state"
|
|
180
|
+
],
|
|
181
|
+
lock: "update"
|
|
182
|
+
}))[0];
|
|
183
|
+
if (!r) return null;
|
|
184
|
+
let i = O(r.epoch), a = r.state;
|
|
185
|
+
return i < 1 || a !== "creating" && a !== "live" && a !== "orphaned" && a !== "faulted" && a !== "disposed" && a !== "hibernating" && a !== "hibernated" || (a === "hibernated" ? r.hostId !== null : r.hostId === null) ? D("Invalid durable Room ownership observation") : Object.freeze({
|
|
186
|
+
roomId: k(r.id),
|
|
187
|
+
tenantId: k(r.tenantId),
|
|
188
|
+
hostId: a === "hibernated" ? null : k(r.hostId),
|
|
189
|
+
epoch: i,
|
|
190
|
+
state: a
|
|
191
|
+
});
|
|
192
|
+
}))),
|
|
193
|
+
selectHost: (e, n) => x.gen(function* () {
|
|
194
|
+
let i = yield* x.try({
|
|
195
|
+
try: () => {
|
|
196
|
+
if (I) return n ? p(I, n.name, n.tenantId, e, n.pool).name : D("Pooled host selection requires room and tenant routing");
|
|
197
|
+
if (n?.pool !== void 0) return D("Explicit pool routing requires an admitted topology");
|
|
198
|
+
},
|
|
199
|
+
catch: () => new t({ detail: "Room pool routing could not be admitted" })
|
|
200
|
+
}), o = yield* H(e, i), s = yield* x.try({
|
|
201
|
+
try: () => I ? h(I, o.map((e) => e.pool === void 0 || e.clientCapacity === void 0 ? D("Pooled directory contains an incomplete host registration") : e), n.name, n.tenantId, e, n.pool, S.poolSelectHost ?? (S.strategies?.selectHost === void 0 ? void 0 : (e, t) => {
|
|
202
|
+
let n = S.strategies.selectHost(e, t);
|
|
203
|
+
return n === null ? null : n;
|
|
204
|
+
})) : m(o, e, S.strategies?.selectHost),
|
|
205
|
+
catch: () => new t({ detail: "Room host selection strategy failed" })
|
|
206
|
+
});
|
|
207
|
+
if (!s) {
|
|
208
|
+
let s = i === void 0 ? void 0 : I?.pools[i];
|
|
209
|
+
return i !== void 0 && o.length === 0 && s?.scaling.scaleToZero === !0 ? (yield* x.tryPromise({
|
|
210
|
+
try: () => w(d, {
|
|
211
|
+
tenantId: n.tenantId,
|
|
212
|
+
kind: T,
|
|
213
|
+
refId: `${i}/${e}`,
|
|
214
|
+
wakeAt: new Date(S.epochNow())
|
|
215
|
+
}),
|
|
216
|
+
catch: () => new t({ detail: "Room pool wake could not be recorded" })
|
|
217
|
+
}), yield* x.fail(new a({
|
|
218
|
+
pool: i,
|
|
219
|
+
retryAfterMs: E
|
|
220
|
+
}))) : yield* x.fail(new r({ roomId: "host" }));
|
|
221
|
+
}
|
|
222
|
+
return s;
|
|
223
|
+
}),
|
|
224
|
+
createOwnedRoom: (e, n) => {
|
|
225
|
+
let a, o;
|
|
226
|
+
try {
|
|
227
|
+
let e = Object.getOwnPropertyDescriptor(n, "creationKey");
|
|
228
|
+
(e && (!("value" in e) || !e.enumerable) || !e && "creationKey" in n) && D("Room creation key must be own server data"), o = e ? k(e.value) : void 0, o !== void 0 && !/^[a-f0-9]{64}$/.test(o) && D("Room creation key requires a server digest"), o !== void 0 && n.staged !== !0 && D("Idempotent Room creation requires staged publication"), a = structuredClone(n);
|
|
229
|
+
} catch {
|
|
230
|
+
return x.fail(new t({ detail: "Invalid captured Room creation request" }));
|
|
231
|
+
}
|
|
232
|
+
return P(() => d.transactional(async (t) => {
|
|
233
|
+
let n = B(), d = (await F(t, l, _("id", k(e)), 1, !0))[0];
|
|
234
|
+
if (!d || d.ready !== !0 || d.draining === !0 || A(d.lastHeartbeatAt) <= n - S.heartbeatTtlMs) throw new i({ roomId: "host" });
|
|
235
|
+
let f = null;
|
|
236
|
+
I ? (f = p(I, a.name, a.tenantId, k(d.region), a.pool).name, (d.pool !== f || O(d.clientCapacity) < 1) && D("Room creation target is outside its admitted pool")) : (d.pool != null || a.pool !== void 0) && D("Pooled Room creation requires an admitted topology");
|
|
237
|
+
let m = o === void 0 ? void 0 : C("sha256").update(u({
|
|
238
|
+
tenantId: k(a.tenantId),
|
|
239
|
+
name: k(a.name),
|
|
240
|
+
pool: f,
|
|
241
|
+
maxClients: a.maxClients,
|
|
242
|
+
metadata: j(a.metadata),
|
|
243
|
+
options: a.options ?? null,
|
|
244
|
+
private: a.private,
|
|
245
|
+
staged: !0
|
|
246
|
+
})).digest("hex");
|
|
247
|
+
if (o !== void 0) {
|
|
248
|
+
let n = await F(t, c, g(_("tenantId", k(a.tenantId)), _("requestKey", o)), 2, !0);
|
|
249
|
+
if (n.length > 1 && D("Ambiguous Room creation receipt"), n.length) {
|
|
250
|
+
let r = n[0];
|
|
251
|
+
(r.requestHash !== m || r.tenantId !== a.tenantId || r.requestKey !== o) && D("Room creation retry changed its original input");
|
|
252
|
+
let i = await F(t, s, _("id", k(r.roomId)), 2, !0), c = i[0];
|
|
253
|
+
return i.length === 1 && c && c.tenantId === a.tenantId && c.hostId === e && c.name === a.name && (c.pool ?? null) === f && c.epoch === 1 && ["creating", "live"].includes(String(c.state)) || D("Room creation retry requires its original active owner"), M(c);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
let h = O(d.capacity);
|
|
257
|
+
if ((h < 1 || h > R) && D("Invalid durable host capacity"), (await F(t, "_voltro_rooms", g(_("hostId", e), b(_("state", "live"), _("state", "creating"), _("state", "hibernating"))), h + 1)).length >= h) throw new r({ roomId: "host" });
|
|
258
|
+
let y = O(a.maxClients);
|
|
259
|
+
(y < 1 || typeof a.private != "boolean") && D("Invalid Room creation options");
|
|
260
|
+
let x = v({
|
|
261
|
+
kind: "typeid",
|
|
262
|
+
prefix: "room"
|
|
263
|
+
}, s), w = {
|
|
264
|
+
id: x,
|
|
265
|
+
name: k(a.name),
|
|
266
|
+
hostId: e,
|
|
267
|
+
pool: f,
|
|
268
|
+
tenantId: k(a.tenantId),
|
|
269
|
+
metadata: j(a.metadata),
|
|
270
|
+
options: structuredClone(a.options ?? null),
|
|
271
|
+
locked: !1,
|
|
272
|
+
private: a.private,
|
|
273
|
+
clients: 0,
|
|
274
|
+
maxClients: y,
|
|
275
|
+
epoch: 1,
|
|
276
|
+
state: a.staged ? "creating" : "live",
|
|
277
|
+
createdAt: new Date(n),
|
|
278
|
+
updatedAt: new Date(n)
|
|
279
|
+
};
|
|
280
|
+
return await t.insert(s, w), o !== void 0 && await t.insert(c, {
|
|
281
|
+
id: v({
|
|
282
|
+
kind: "typeid",
|
|
283
|
+
prefix: "rcreate"
|
|
284
|
+
}, c),
|
|
285
|
+
tenantId: w.tenantId,
|
|
286
|
+
requestKey: o,
|
|
287
|
+
requestHash: m,
|
|
288
|
+
roomId: x,
|
|
289
|
+
createdAt: new Date(n)
|
|
290
|
+
}), M(w);
|
|
291
|
+
}));
|
|
292
|
+
},
|
|
293
|
+
abandonCreation: (e, t, r) => P(async () => {
|
|
294
|
+
if (await d.updateMany("_voltro_rooms", {
|
|
295
|
+
state: "disposed",
|
|
296
|
+
updatedAt: new Date(B())
|
|
297
|
+
}, { where: g(_("id", k(t)), _("hostId", k(e)), _("tenantId", k(r)), _("epoch", 1), _("state", "creating"), _("clients", 0)) }) !== 1) throw new n({ roomId: t });
|
|
298
|
+
}),
|
|
299
|
+
unregister: (e) => P(() => d.transactional(async (t) => {
|
|
300
|
+
if ((await F(t, "_voltro_room_hosts", _("id", k(e)), 1, !0))[0]) {
|
|
301
|
+
if ((await F(t, "_voltro_rooms", g(_("hostId", e), b(_("state", "live"), _("state", "creating"), _("state", "hibernating"))), 1)).length) return D("A host with authoritative active rooms cannot unregister");
|
|
302
|
+
await t.deleteMany(l, { where: _("id", e) });
|
|
303
|
+
}
|
|
304
|
+
})),
|
|
305
|
+
list: (t, n, r) => P(async () => {
|
|
306
|
+
if (!Number.isSafeInteger(r) || r < 1 || r > z) throw new e({
|
|
307
|
+
budget: "listedRooms",
|
|
308
|
+
limit: z
|
|
309
|
+
});
|
|
310
|
+
return (await F(d, s, g(_("tenantId", k(t)), _("name", k(n)), _("state", "live"), _("private", !1)), r)).map(M);
|
|
311
|
+
}),
|
|
312
|
+
setListing: (e, t, r, i, a) => P(async () => {
|
|
313
|
+
if ((O(i) < 1 || typeof a.locked != "boolean" || typeof a.private != "boolean") && D("Invalid listing options"), await d.updateMany("_voltro_rooms", {
|
|
314
|
+
metadata: j(a.metadata),
|
|
315
|
+
locked: a.locked,
|
|
316
|
+
private: a.private,
|
|
317
|
+
updatedAt: new Date(B())
|
|
318
|
+
}, { where: g(_("id", k(t)), _("tenantId", k(r)), _("hostId", k(e)), _("epoch", i), _("state", "live")) }) !== 1) throw new n({ roomId: t });
|
|
319
|
+
})
|
|
320
|
+
});
|
|
321
|
+
}, L = (e, t) => S.succeed(d, I(e, t));
|
|
322
|
+
export { T as ROOM_POOL_WAKE, E as ROOM_POOL_WAKE_RETRY_MS, I as dataStoreRoomDirectory, M as decodeRoomDirectoryListing, L as roomDirectoryLayer };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { BudgetExceeded as e, ProtocolError as t } from "./errors.js";
|
|
2
|
+
import { Effect as n, Option as r } from "effect";
|
|
3
|
+
import { HotError as i, readHotStoreWithFallback as a } from "@voltro/kv/hot/contract";
|
|
4
|
+
// src/directoryProjection.ts
|
|
5
|
+
var o = (e) => {
|
|
6
|
+
if (typeof e != "string" || !e.trim() || e.length > 191) throw new t({ detail: "Invalid directory projection identity" });
|
|
7
|
+
return e;
|
|
8
|
+
}, s = (e) => {
|
|
9
|
+
if (!e || typeof e != "object" || Array.isArray(e)) throw new t({ detail: "Invalid directory projection configuration" });
|
|
10
|
+
let n = o(e.tenantId), r = e.namespace, i = e.maxEntries ?? 256, a = e.maxPayloadBytes ?? 65536, s = e.onUnavailable ?? "fail";
|
|
11
|
+
if (typeof r != "string" || !/^[a-zA-Z0-9][a-zA-Z0-9:_-]{0,95}$/.test(r) || !Number.isSafeInteger(e.ttlMs) || e.ttlMs < 1 || !Number.isSafeInteger(i) || i < 1 || !Number.isSafeInteger(a) || a < 1 || s !== "fail" && s !== "degrade") throw new t({ detail: "Invalid directory projection budgets or policy" });
|
|
12
|
+
return Object.freeze({
|
|
13
|
+
tenantId: n,
|
|
14
|
+
namespace: r,
|
|
15
|
+
maxEntries: i,
|
|
16
|
+
maxPayloadBytes: a,
|
|
17
|
+
onUnavailable: s,
|
|
18
|
+
ttlMs: e.ttlMs
|
|
19
|
+
});
|
|
20
|
+
}, c = (e) => {
|
|
21
|
+
if (!e || typeof e != "object" || Array.isArray(e)) throw new t({ detail: "Malformed directory projection hint" });
|
|
22
|
+
let n = o(Reflect.get(e, "id")), r = o(Reflect.get(e, "hostId")), i = Reflect.get(e, "epoch"), a = Reflect.get(e, "clients"), s = Reflect.get(e, "maxClients"), c = Reflect.get(e, "locked");
|
|
23
|
+
if (typeof i != "number" || !Number.isSafeInteger(i) || i < 1 || typeof a != "number" || !Number.isSafeInteger(a) || a < 0 || typeof s != "number" || !Number.isSafeInteger(s) || s < 1 || a > s || typeof c != "boolean") throw new t({ detail: "Malformed directory projection counters" });
|
|
24
|
+
return Object.freeze({
|
|
25
|
+
id: n,
|
|
26
|
+
hostId: r,
|
|
27
|
+
epoch: i,
|
|
28
|
+
clients: a,
|
|
29
|
+
maxClients: s,
|
|
30
|
+
locked: c
|
|
31
|
+
});
|
|
32
|
+
}, l = (l, u, d) => {
|
|
33
|
+
let { tenantId: f, namespace: p, maxEntries: m, maxPayloadBytes: h, onUnavailable: g, ttlMs: _ } = s(d), v = (e) => `${p}:directory:${Buffer.from(JSON.stringify([f, e]), "utf8").toString("base64url")}`, y = (r) => l.list(f, r, m).pipe(n.flatMap((i) => n.try({
|
|
34
|
+
try: () => {
|
|
35
|
+
if (i.length > m) throw new e({
|
|
36
|
+
budget: "directoryProjectionEntries",
|
|
37
|
+
limit: m
|
|
38
|
+
});
|
|
39
|
+
let n = /* @__PURE__ */ new Set(), a = i.map((e) => {
|
|
40
|
+
if (e.tenantId !== f || e.name !== r) throw new t({ detail: "Directory source escaped its tenant/name scope" });
|
|
41
|
+
let i = c(e);
|
|
42
|
+
if (n.has(i.id)) throw new t({ detail: "Duplicate directory projection identity" });
|
|
43
|
+
return n.add(i.id), i;
|
|
44
|
+
});
|
|
45
|
+
return Object.freeze(a.sort((e, t) => e.id < t.id ? -1 : +(e.id > t.id)));
|
|
46
|
+
},
|
|
47
|
+
catch: (n) => n instanceof e ? n : new t({ detail: "Directory source admission failed" })
|
|
48
|
+
}))), b = (e, r) => n.try({
|
|
49
|
+
try: () => {
|
|
50
|
+
if (Buffer.byteLength(r, "utf8") > h) throw Error("payload budget");
|
|
51
|
+
let t = JSON.parse(r);
|
|
52
|
+
if (!t || typeof t != "object" || Array.isArray(t) || Reflect.get(t, "version") !== 1 || Reflect.get(t, "tenantId") !== f || Reflect.get(t, "name") !== e) throw Error("scope");
|
|
53
|
+
let n = Reflect.get(t, "entries");
|
|
54
|
+
if (!Array.isArray(n) || n.length > m) throw Error("entry budget");
|
|
55
|
+
let i = /* @__PURE__ */ new Set(), a = n.map((e) => {
|
|
56
|
+
let t = c(e);
|
|
57
|
+
if (i.has(t.id)) throw Error("duplicate");
|
|
58
|
+
return i.add(t.id), t;
|
|
59
|
+
});
|
|
60
|
+
return Object.freeze(a.sort((e, t) => e.id < t.id ? -1 : +(e.id > t.id)));
|
|
61
|
+
},
|
|
62
|
+
catch: () => new t({ detail: "Cached directory hint payload failed admission" })
|
|
63
|
+
}), x = (e, r) => n.try({
|
|
64
|
+
try: () => o(e),
|
|
65
|
+
catch: () => new t({ detail: "Invalid directory projection room name" })
|
|
66
|
+
}).pipe(n.flatMap(r)), S = (e, t) => t.pipe(n.mapError((t) => t._tag === "HotError" ? new i({
|
|
67
|
+
operation: e,
|
|
68
|
+
key: "roomDirectory",
|
|
69
|
+
reason: t.reason
|
|
70
|
+
}) : t));
|
|
71
|
+
return Object.freeze({
|
|
72
|
+
hints: (t, i = m) => S("directoryRead", x(t, (t) => n.gen(function* () {
|
|
73
|
+
if (!Number.isSafeInteger(i) || i < 1 || i > m) return yield* n.fail(new e({
|
|
74
|
+
budget: "directoryProjectionRead",
|
|
75
|
+
limit: m
|
|
76
|
+
}));
|
|
77
|
+
let o = yield* a({
|
|
78
|
+
store: u,
|
|
79
|
+
onUnavailable: g,
|
|
80
|
+
read: (e) => e.hget(v(t), "payload", { consistency: "primary" }).pipe(n.map((e) => ({
|
|
81
|
+
kind: "hot",
|
|
82
|
+
value: e
|
|
83
|
+
}))),
|
|
84
|
+
fallback: () => y(t).pipe(n.map((e) => ({
|
|
85
|
+
kind: "sql",
|
|
86
|
+
value: e
|
|
87
|
+
})))
|
|
88
|
+
}), s = o.kind === "sql" ? o.value : r.isNone(o.value) ? yield* y(t) : yield* b(t, o.value.value);
|
|
89
|
+
return Object.freeze(s.slice(0, i));
|
|
90
|
+
}))),
|
|
91
|
+
rebuildFromSource: (t) => S("directoryRebuild", x(t, (t) => n.gen(function* () {
|
|
92
|
+
let r = yield* y(t), i = JSON.stringify({
|
|
93
|
+
version: 1,
|
|
94
|
+
tenantId: f,
|
|
95
|
+
name: t,
|
|
96
|
+
entries: r
|
|
97
|
+
});
|
|
98
|
+
return Buffer.byteLength(i, "utf8") > h ? yield* n.fail(new e({
|
|
99
|
+
budget: "directoryProjectionPayloadBytes",
|
|
100
|
+
limit: h
|
|
101
|
+
})) : (yield* u.hset(v(t), { payload: i }, { ttlMs: _ }), Object.freeze({ entries: r.length }));
|
|
102
|
+
}))),
|
|
103
|
+
invalidate: (e) => S("directoryInvalidate", x(e, (e) => u.delete(v(e)).pipe(n.asVoid)))
|
|
104
|
+
});
|
|
105
|
+
}, u = async (e, n, r) => {
|
|
106
|
+
if (!e.connectionRegistry || !e.hotStore || r.availabilityRole !== void 0 && !e.connectionAvailability) throw new t({ detail: "Directory projection requires the app-owned connection registry and tenant HotStore port" });
|
|
107
|
+
let i = o(r.tenantId), a = r.availabilityRole === void 0 ? "fail" : e.connectionAvailability(r.availabilityRole);
|
|
108
|
+
if (a !== "fail" && a !== "degrade") throw new t({ detail: "Directory projection connection policy was not admitted" });
|
|
109
|
+
let c = s({
|
|
110
|
+
...r,
|
|
111
|
+
tenantId: i,
|
|
112
|
+
onUnavailable: a
|
|
113
|
+
});
|
|
114
|
+
return l(n, await e.hotStore({ tenantId: i }), c);
|
|
115
|
+
};
|
|
116
|
+
export { u as bindRoomDirectoryProjection, l as makeRoomDirectoryProjection };
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import { YieldableError } from 'effect/Cause';
|
|
3
|
+
|
|
4
|
+
export declare class BudgetExceeded extends BudgetExceeded_base {
|
|
5
|
+
get message(): string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare const BudgetExceeded_base: Schema.Class<BudgetExceeded, Schema.TaggedStruct<"BudgetExceeded", {
|
|
9
|
+
readonly budget: Schema.String;
|
|
10
|
+
readonly limit: Schema.Number;
|
|
11
|
+
}>, YieldableError>;
|
|
12
|
+
|
|
13
|
+
export declare class NotRoomMember extends NotRoomMember_base {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const NotRoomMember_base: Schema.Class<NotRoomMember, Schema.TaggedStruct<"NotRoomMember", {
|
|
17
|
+
readonly sessionId: Schema.String;
|
|
18
|
+
}>, YieldableError>;
|
|
19
|
+
|
|
20
|
+
export declare class ProtocolError extends ProtocolError_base {
|
|
21
|
+
get message(): string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare const ProtocolError_base: Schema.Class<ProtocolError, Schema.TaggedStruct<"ProtocolError", {
|
|
25
|
+
readonly detail: Schema.String;
|
|
26
|
+
}>, YieldableError>;
|
|
27
|
+
|
|
28
|
+
export declare class RoomAuthoringError extends RoomAuthoringError_base {
|
|
29
|
+
get message(): string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare const RoomAuthoringError_base: Schema.Class<RoomAuthoringError, Schema.TaggedStruct<"RoomAuthoringError", {
|
|
33
|
+
readonly room: Schema.String;
|
|
34
|
+
readonly detail: Schema.String;
|
|
35
|
+
}>, YieldableError>;
|
|
36
|
+
|
|
37
|
+
export declare class RoomForbidden extends RoomForbidden_base {
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare const RoomForbidden_base: Schema.Class<RoomForbidden, Schema.TaggedStruct<"RoomForbidden", {
|
|
41
|
+
readonly roomId: Schema.String;
|
|
42
|
+
}>, YieldableError>;
|
|
43
|
+
|
|
44
|
+
export declare class RoomFull extends RoomFull_base {
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
declare const RoomFull_base: Schema.Class<RoomFull, Schema.TaggedStruct<"RoomFull", {
|
|
48
|
+
readonly roomId: Schema.String;
|
|
49
|
+
}>, YieldableError>;
|
|
50
|
+
|
|
51
|
+
export declare class RoomGone extends RoomGone_base {
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare const RoomGone_base: Schema.Class<RoomGone, Schema.TaggedStruct<"RoomGone", {
|
|
55
|
+
readonly roomId: Schema.String;
|
|
56
|
+
}>, YieldableError>;
|
|
57
|
+
|
|
58
|
+
/** Durable work/capacity is still owned; this is backpressure, not completion. */
|
|
59
|
+
export declare class RoomHibernatePending extends RoomHibernatePending_base {
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare const RoomHibernatePending_base: Schema.Class<RoomHibernatePending, Schema.TaggedStruct<"RoomHibernatePending", {
|
|
63
|
+
readonly roomId: Schema.String;
|
|
64
|
+
}>, YieldableError>;
|
|
65
|
+
|
|
66
|
+
export declare class RoomLocked extends RoomLocked_base {
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
declare const RoomLocked_base: Schema.Class<RoomLocked, Schema.TaggedStruct<"RoomLocked", {
|
|
70
|
+
readonly roomId: Schema.String;
|
|
71
|
+
}>, YieldableError>;
|
|
72
|
+
|
|
73
|
+
/** The pool has no host because it scaled to zero; one is starting. Reserve again after `retryAfterMs`. */
|
|
74
|
+
export declare class RoomPoolWaking extends RoomPoolWaking_base {
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
declare const RoomPoolWaking_base: Schema.Class<RoomPoolWaking, Schema.TaggedStruct<"RoomPoolWaking", {
|
|
78
|
+
readonly pool: Schema.String;
|
|
79
|
+
readonly retryAfterMs: Schema.Number;
|
|
80
|
+
}>, YieldableError>;
|
|
81
|
+
|
|
82
|
+
/** New Room reservations are closed for this caller (maintenance, a kill switch...): the app's
|
|
83
|
+
* `admission` refused. `until`: epoch ms when they reopen, if known; `messageKey`: the app's text. */
|
|
84
|
+
export declare class RoomsClosed extends RoomsClosed_base {
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
declare const RoomsClosed_base: Schema.Class<RoomsClosed, Schema.TaggedStruct<"RoomsClosed", {
|
|
88
|
+
readonly until: Schema.NullOr<Schema.Number>;
|
|
89
|
+
readonly messageKey: Schema.String;
|
|
90
|
+
}>, YieldableError>;
|
|
91
|
+
|
|
92
|
+
export declare class SeatExpired extends SeatExpired_base {
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
declare const SeatExpired_base: Schema.Class<SeatExpired, Schema.TaggedStruct<"SeatExpired", {
|
|
96
|
+
readonly sessionId: Schema.String;
|
|
97
|
+
}>, YieldableError>;
|
|
98
|
+
|
|
99
|
+
export declare class SimulationConformanceDivergence extends SimulationConformanceDivergence_base {
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
declare const SimulationConformanceDivergence_base: Schema.Class<SimulationConformanceDivergence, Schema.TaggedStruct<"SimulationConformanceDivergence", {
|
|
103
|
+
readonly tick: Schema.Int;
|
|
104
|
+
readonly phase: Schema.Literals<readonly ["repeat", "rollback", "provided-trace"]>;
|
|
105
|
+
readonly component: Schema.Literals<readonly ["schemaHash", "hash", "rng"]>;
|
|
106
|
+
}>, YieldableError>;
|
|
107
|
+
|
|
108
|
+
export declare class SimulationConformanceFailure extends SimulationConformanceFailure_base {
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
declare const SimulationConformanceFailure_base: Schema.Class<SimulationConformanceFailure, Schema.TaggedStruct<"SimulationConformanceFailure", {
|
|
112
|
+
readonly tick: Schema.Int;
|
|
113
|
+
readonly phase: Schema.Literals<readonly ["repeat", "rollback", "trace"]>;
|
|
114
|
+
readonly operation: Schema.Literals<readonly ["init", "step", "replay"]>;
|
|
115
|
+
}>, YieldableError>;
|
|
116
|
+
|
|
117
|
+
/** A World transition asked for inside the World's `transitionCooldownMs`; retry after `retryAfterMs`. */
|
|
118
|
+
export declare class WorldTransitionCooldown extends WorldTransitionCooldown_base {
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
declare const WorldTransitionCooldown_base: Schema.Class<WorldTransitionCooldown, Schema.TaggedStruct<"WorldTransitionCooldown", {
|
|
122
|
+
readonly retryAfterMs: Schema.Number;
|
|
123
|
+
}>, YieldableError>;
|
|
124
|
+
|
|
125
|
+
export { }
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Schema as e } from "effect";
|
|
2
|
+
// src/errors.ts
|
|
3
|
+
var t = class extends e.TaggedError()("RoomAuthoringError", {
|
|
4
|
+
room: e.String,
|
|
5
|
+
detail: e.String
|
|
6
|
+
}) {
|
|
7
|
+
get message() {
|
|
8
|
+
return this.detail;
|
|
9
|
+
}
|
|
10
|
+
}, n = class extends e.TaggedError()("ProtocolError", { detail: e.String }) {
|
|
11
|
+
get message() {
|
|
12
|
+
return this.detail;
|
|
13
|
+
}
|
|
14
|
+
}, r = class extends e.TaggedError()("SimulationConformanceDivergence", {
|
|
15
|
+
tick: e.Int,
|
|
16
|
+
phase: e.Literals([
|
|
17
|
+
"repeat",
|
|
18
|
+
"rollback",
|
|
19
|
+
"provided-trace"
|
|
20
|
+
]),
|
|
21
|
+
component: e.Literals([
|
|
22
|
+
"schemaHash",
|
|
23
|
+
"hash",
|
|
24
|
+
"rng"
|
|
25
|
+
])
|
|
26
|
+
}) {}, i = class extends e.TaggedError()("SimulationConformanceFailure", {
|
|
27
|
+
tick: e.Int,
|
|
28
|
+
phase: e.Literals([
|
|
29
|
+
"repeat",
|
|
30
|
+
"rollback",
|
|
31
|
+
"trace"
|
|
32
|
+
]),
|
|
33
|
+
operation: e.Literals([
|
|
34
|
+
"init",
|
|
35
|
+
"step",
|
|
36
|
+
"replay"
|
|
37
|
+
])
|
|
38
|
+
}) {}, a = class extends e.TaggedError()("RoomHibernatePending", { roomId: e.String }) {}, o = class extends e.TaggedError()("WorldTransitionCooldown", { retryAfterMs: e.Number }) {}, s = class extends e.TaggedError()("RoomsClosed", {
|
|
39
|
+
until: e.NullOr(e.Number),
|
|
40
|
+
messageKey: e.String
|
|
41
|
+
}) {}, c = class extends e.TaggedError()("RoomFull", { roomId: e.String }) {}, l = class extends e.TaggedError()("RoomPoolWaking", {
|
|
42
|
+
pool: e.String,
|
|
43
|
+
retryAfterMs: e.Number
|
|
44
|
+
}) {}, u = class extends e.TaggedError()("RoomLocked", { roomId: e.String }) {}, d = class extends e.TaggedError()("RoomGone", { roomId: e.String }) {}, f = class extends e.TaggedError()("RoomForbidden", { roomId: e.String }) {}, p = class extends e.TaggedError()("SeatExpired", { sessionId: e.String }) {}, m = class extends e.TaggedError()("NotRoomMember", { sessionId: e.String }) {}, h = class extends e.TaggedError()("BudgetExceeded", {
|
|
45
|
+
budget: e.String,
|
|
46
|
+
limit: e.Number
|
|
47
|
+
}) {
|
|
48
|
+
get message() {
|
|
49
|
+
return `Room budget ${this.budget} exceeded (limit ${this.limit})`;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
export { h as BudgetExceeded, m as NotRoomMember, n as ProtocolError, t as RoomAuthoringError, f as RoomForbidden, c as RoomFull, d as RoomGone, a as RoomHibernatePending, u as RoomLocked, l as RoomPoolWaking, s as RoomsClosed, p as SeatExpired, r as SimulationConformanceDivergence, i as SimulationConformanceFailure, o as WorldTransitionCooldown };
|