@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,2979 @@
|
|
|
1
|
+
import { WORLD_INSTANCES_TABLE as e } from "./worldInstanceState.js";
|
|
2
|
+
import { BudgetExceeded as t, ProtocolError as n } from "./errors.js";
|
|
3
|
+
import { captureWorldData as r } from "./worldData.js";
|
|
4
|
+
import { worldBoundsShareEdge as i } from "./worldTransitions.js";
|
|
5
|
+
import { worldTransitionPhases as a, worldTransitionRequest as o } from "./worldCommands.js";
|
|
6
|
+
import { ROOMS_TABLE as s, ROOM_SEATS_TABLE as c, WORLD_TRANSITIONS_TABLE as l } from "./identities.js";
|
|
7
|
+
import { captureWorldCatalog as u, worldCellAt as d } from "./world.js";
|
|
8
|
+
import { captureWorldTargetSeatBinding as f, worldTargetSeatBindingFromReceipt as p } from "./worldSeatBinding.js";
|
|
9
|
+
import { captureRoomSessionAdmissionEvidence as m } from "./sessionAdmission.js";
|
|
10
|
+
import { lockRoomReservationOwners as h } from "./hostClientCapacity.js";
|
|
11
|
+
import { assertWorldRoomPool as g } from "./worldRoomPool.js";
|
|
12
|
+
import { WORLD_CELLS_TABLE as _ } from "./worldCells.js";
|
|
13
|
+
import { canAdvanceWorldTransition as ee, worldTransitionsTable as v } from "./worldTransitionState.js";
|
|
14
|
+
import { makeWorldHandoffMetrics as y } from "./worldHandoffMetrics.js";
|
|
15
|
+
import { captureWorldEntityReturnAnchor as b } from "./worldReturnAnchor.js";
|
|
16
|
+
import { captureWorldGroupCommand as te, captureWorldGroupCommandReceipt as ne, worldGroupCommandKey as re, worldGroupCommandRequestId as ie } from "./worldGroupCommand.js";
|
|
17
|
+
import { assertRoomReservationBatchSeatReceipt as x, roomReservationBatchSessionIdentity as ae } from "./reservationBatch.js";
|
|
18
|
+
import { captureWorldTransitionGroup as oe, captureWorldTransitionGroupReceipt as se, worldTransitionGroupFromRecords as S, worldTransitionGroupReceipts as ce } from "./worldTransitionGroup.js";
|
|
19
|
+
import { worldTransitionSeatBatch as le, worldTransitionSeatRequestId as ue } from "./worldTransitionSeatGroup.js";
|
|
20
|
+
import { captureWorldRecoveryActor as de } from "./worldRecoveryActor.js";
|
|
21
|
+
import { captureWorldActorTransferSnapshot as fe } from "./worldActorTransferSnapshot.js";
|
|
22
|
+
import { and as C, eq as w, generateId as pe, gt as me, id as T, inSet as he, integer as ge, json as _e, lt as ve, neq as ye, table as be, text as E, timestamp as xe } from "@voltro/database";
|
|
23
|
+
import { Effect as D, Result as Se } from "effect";
|
|
24
|
+
import { createHash as Ce } from "node:crypto";
|
|
25
|
+
// src/worldEntities.ts
|
|
26
|
+
var O = "_voltro_world_entities", k = "_voltro_world_journal", we = be(O, {
|
|
27
|
+
id: T({ prefix: "went" }),
|
|
28
|
+
tenantId: E().maxLength(191),
|
|
29
|
+
entityId: E().maxLength(191),
|
|
30
|
+
subjectId: E().maxLength(191).nullable(),
|
|
31
|
+
subjectKind: E().maxLength(8).nullable(),
|
|
32
|
+
kind: E().maxLength(120),
|
|
33
|
+
worldId: E().maxLength(120),
|
|
34
|
+
zoneId: E().maxLength(120),
|
|
35
|
+
cellId: E().maxLength(191),
|
|
36
|
+
layer: ge(),
|
|
37
|
+
roomId: E().maxLength(191),
|
|
38
|
+
epoch: ge(),
|
|
39
|
+
revision: ge(),
|
|
40
|
+
data: _e(),
|
|
41
|
+
updatedAt: xe(),
|
|
42
|
+
returnAnchor: _e().nullable(),
|
|
43
|
+
activeTransitionId: E().maxLength(191).nullable(),
|
|
44
|
+
transitionedAt: xe().nullable(),
|
|
45
|
+
transitionRecordedAt: xe().nullable()
|
|
46
|
+
}).unique("byWorldEntity", ["tenantId", "entityId"]).index([
|
|
47
|
+
"tenantId",
|
|
48
|
+
"subjectId",
|
|
49
|
+
"subjectKind"
|
|
50
|
+
]).index([
|
|
51
|
+
"tenantId",
|
|
52
|
+
"worldId",
|
|
53
|
+
"zoneId",
|
|
54
|
+
"cellId",
|
|
55
|
+
"layer"
|
|
56
|
+
]).index(["tenantId", "roomId"]), Te = be(k, {
|
|
57
|
+
id: T({ prefix: "wjour" }),
|
|
58
|
+
tenantId: E().maxLength(191),
|
|
59
|
+
entityId: E().maxLength(191),
|
|
60
|
+
revision: ge(),
|
|
61
|
+
subjectId: E().maxLength(191).nullable(),
|
|
62
|
+
subjectKind: E().maxLength(8).nullable(),
|
|
63
|
+
operation: E().maxLength(16),
|
|
64
|
+
snapshot: _e(),
|
|
65
|
+
createdAt: xe(),
|
|
66
|
+
requestKey: E().maxLength(64).nullable(),
|
|
67
|
+
requestDigest: E().maxLength(64).nullable()
|
|
68
|
+
}).unique("byWorldEntityRevision", [
|
|
69
|
+
"tenantId",
|
|
70
|
+
"entityId",
|
|
71
|
+
"revision"
|
|
72
|
+
]).index([
|
|
73
|
+
"tenantId",
|
|
74
|
+
"subjectId",
|
|
75
|
+
"subjectKind"
|
|
76
|
+
]).index([
|
|
77
|
+
"tenantId",
|
|
78
|
+
"entityId",
|
|
79
|
+
"createdAt"
|
|
80
|
+
]).index(["requestKey"]), A = Object.freeze([we, Te]), Ee = Object.freeze([...A, v]);
|
|
81
|
+
function j(e) {
|
|
82
|
+
throw new n({ detail: e });
|
|
83
|
+
}
|
|
84
|
+
var M = (e, t = 191) => typeof e == "string" && e.length <= t && /^[A-Za-z0-9][A-Za-z0-9_.:-]*$/.test(e) ? e : j("Invalid World entity identity"), N = (e, t = 1) => typeof e == "number" && Number.isSafeInteger(e) && e >= t && e <= 2147483647 ? e : j("Invalid World entity integer"), P = (e, t) => {
|
|
85
|
+
e && typeof e == "object" && Object.getPrototypeOf(e) === Object.prototype || j("World entity input requires plain own data");
|
|
86
|
+
for (let n of Reflect.ownKeys(e)) {
|
|
87
|
+
let r = Object.getOwnPropertyDescriptor(e, n);
|
|
88
|
+
typeof n == "string" && t.includes(n) && r?.enumerable && "value" in r || j("Invalid World entity field");
|
|
89
|
+
}
|
|
90
|
+
}, De = (e) => Object.freeze({
|
|
91
|
+
tenantId: M(e.tenantId),
|
|
92
|
+
entityId: M(e.entityId)
|
|
93
|
+
}), Oe = (e) => e === null ? null : (P(e, ["id", "kind"]), e.kind !== "user" && e.kind !== "guest" && j("Invalid World entity Subject kind"), Object.freeze({
|
|
94
|
+
id: M(e.id),
|
|
95
|
+
kind: e.kind
|
|
96
|
+
})), ke = (e) => C(w("tenantId", e.tenantId), w("entityId", e.entityId)), Ae = (e) => Array.isArray(e) ? e.map(Ae) : typeof e == "object" && e ? Object.fromEntries(Object.entries(e).sort(([e], [t]) => e < t ? -1 : +(e > t)).map(([e, t]) => [e, Ae(t)])) : e, F = (e, t, n = !1) => e.query({
|
|
97
|
+
table: O,
|
|
98
|
+
predicate: ke(t),
|
|
99
|
+
order: [],
|
|
100
|
+
take: 2,
|
|
101
|
+
skip: void 0,
|
|
102
|
+
projection: void 0,
|
|
103
|
+
...n ? { lock: "update" } : {}
|
|
104
|
+
}), I = (e) => D.uninterruptible(D.tryPromise({
|
|
105
|
+
try: e,
|
|
106
|
+
catch: (e) => e instanceof n || e instanceof t ? e : new n({ detail: "World entity SQL operation remains incomplete" })
|
|
107
|
+
})), je = (v, T) => {
|
|
108
|
+
P(T, [
|
|
109
|
+
"worlds",
|
|
110
|
+
"epochNow",
|
|
111
|
+
"maxDataBytes",
|
|
112
|
+
"maxJournalBytes",
|
|
113
|
+
"maxPrivacyEntities",
|
|
114
|
+
"maxPrivacyJournal",
|
|
115
|
+
"maxBatchRows",
|
|
116
|
+
"authorize",
|
|
117
|
+
"quiesceSubject",
|
|
118
|
+
"transitions",
|
|
119
|
+
"reconcileRecovery"
|
|
120
|
+
]);
|
|
121
|
+
let ge = y(), _e = u(T.worlds), be = new Map(_e.map((e) => [e.name, e])), E = N(T.maxDataBytes), xe = N(T.maxJournalBytes), we = N(T.maxPrivacyEntities), Te = N(T.maxPrivacyJournal), A = N(T.maxBatchRows), Ee = T.epochNow, je = T.authorize, Me = T.quiesceSubject, Ne = T.reconcileRecovery;
|
|
122
|
+
Ne !== void 0 && typeof Ne != "function" && j("World recovery requires an actual compensation function");
|
|
123
|
+
let L = T.transitions;
|
|
124
|
+
L !== void 0 && (P(L, [
|
|
125
|
+
"maxPrivacyRows",
|
|
126
|
+
"authorize",
|
|
127
|
+
"groups"
|
|
128
|
+
]), (N(L.maxPrivacyRows) === 2147483647 || typeof L.authorize != "function") && j("World transition state requires bounded privacy and actual authorization"));
|
|
129
|
+
let Pe = L?.maxPrivacyRows, Fe = L?.authorize, R;
|
|
130
|
+
if (L?.groups !== void 0) {
|
|
131
|
+
P(L.groups, [
|
|
132
|
+
"maxRows",
|
|
133
|
+
"authorize",
|
|
134
|
+
"readiness",
|
|
135
|
+
"proceed"
|
|
136
|
+
]);
|
|
137
|
+
let e = N(L.groups.maxRows);
|
|
138
|
+
(e > A || typeof L.groups.authorize != "function") && j("World transition groups require actual bounded authority");
|
|
139
|
+
let t;
|
|
140
|
+
L.groups.readiness !== void 0 && (P(L.groups.readiness, ["confirm"]), typeof L.groups.readiness.confirm != "function" && j("World group readiness requires actual session confirmation"), t = Object.freeze({ confirm: L.groups.readiness.confirm }));
|
|
141
|
+
let n;
|
|
142
|
+
L.groups.proceed !== void 0 && (P(L.groups.proceed, ["authorize"]), typeof L.groups.proceed.authorize != "function" && j("World proceed requires explicit group authority"), n = Object.freeze({ authorize: L.groups.proceed.authorize })), R = Object.freeze({
|
|
143
|
+
maxRows: e,
|
|
144
|
+
authorize: L.groups.authorize,
|
|
145
|
+
...t === void 0 ? {} : { readiness: t },
|
|
146
|
+
...n === void 0 ? {} : { proceed: n }
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
be.size && typeof Ee == "function" && typeof je == "function" && typeof Me == "function" && we !== 2147483647 && Te !== 2147483647 && A !== 2147483647 || j("World entity store requires complete configuration and privacy coordination");
|
|
150
|
+
let z = (e) => be.get(e) ?? j("Unconfigured World entity World"), B = () => {
|
|
151
|
+
let e = Ee();
|
|
152
|
+
return (!Number.isSafeInteger(e) || e < 0 || e > 864e13) && j("Invalid World entity clock"), e;
|
|
153
|
+
}, V = (e) => {
|
|
154
|
+
P(e, [
|
|
155
|
+
"worldId",
|
|
156
|
+
"zoneId",
|
|
157
|
+
"at",
|
|
158
|
+
"layer",
|
|
159
|
+
"roomId",
|
|
160
|
+
"epoch"
|
|
161
|
+
]);
|
|
162
|
+
let t = M(e.worldId, 120), n = M(e.zoneId, 120), r = d(z(t), {
|
|
163
|
+
zone: n,
|
|
164
|
+
at: e.at
|
|
165
|
+
});
|
|
166
|
+
return Object.freeze({
|
|
167
|
+
worldId: t,
|
|
168
|
+
zoneId: n,
|
|
169
|
+
at: Object.freeze([e.at[0], e.at[1]]),
|
|
170
|
+
cellId: r.id,
|
|
171
|
+
layer: N(e.layer),
|
|
172
|
+
roomId: M(e.roomId),
|
|
173
|
+
epoch: N(e.epoch)
|
|
174
|
+
});
|
|
175
|
+
}, Ie = (e) => b(e, _e), H = (e) => {
|
|
176
|
+
let t = e.returnAnchor == null ? void 0 : Ie(e.returnAnchor);
|
|
177
|
+
t && (t.instanceRoomId !== e.roomId || t.enteredRevision > Number(e.revision) || t.source.worldId !== e.worldId) && j("World return anchor escaped its instance entity");
|
|
178
|
+
let n = e.subjectId, i = e.subjectKind, a = M(e.worldId, 120), o = z(a), s = M(e.zoneId, 120), c = M(e.cellId), l = o.zones.find((e) => e.id === s);
|
|
179
|
+
l || j("Unconfigured persisted World entity zone");
|
|
180
|
+
let u = c.split(":"), f = Number(u[1]), p = Number(u[2]);
|
|
181
|
+
(u.length !== 3 || u[0] !== s || !Number.isSafeInteger(f) || f < 0 || String(f) !== u[1] || !Number.isSafeInteger(p) || p < 0 || String(p) !== u[2]) && j("Invalid persisted World entity cell");
|
|
182
|
+
let m = l.cells?.size ?? Math.max(l.bounds[1][0] - l.bounds[0][0], l.bounds[1][1] - l.bounds[0][1]);
|
|
183
|
+
d(o, {
|
|
184
|
+
zone: s,
|
|
185
|
+
at: [l.bounds[0][0] + f * m, l.bounds[0][1] + p * m]
|
|
186
|
+
}).id !== c && j("Persisted World entity cell escaped configured geometry"), n === null != (i === null) && j("Contradictory World entity Subject");
|
|
187
|
+
let h = e.updatedAt instanceof Date ? e.updatedAt.getTime() : typeof e.updatedAt == "string" ? Date.parse(e.updatedAt) : NaN;
|
|
188
|
+
return (!Number.isSafeInteger(h) || h < 0) && j("Invalid persisted World entity time"), Object.freeze({
|
|
189
|
+
...t ? { returnAnchor: t } : {},
|
|
190
|
+
tenantId: M(e.tenantId),
|
|
191
|
+
entityId: M(e.entityId),
|
|
192
|
+
subject: n === null ? null : Oe({
|
|
193
|
+
id: M(n),
|
|
194
|
+
kind: i
|
|
195
|
+
}),
|
|
196
|
+
kind: M(e.kind, 120),
|
|
197
|
+
worldId: a,
|
|
198
|
+
zoneId: s,
|
|
199
|
+
cellId: c,
|
|
200
|
+
layer: N(e.layer),
|
|
201
|
+
roomId: M(e.roomId),
|
|
202
|
+
epoch: N(e.epoch),
|
|
203
|
+
revision: N(e.revision),
|
|
204
|
+
data: r(e.data, E),
|
|
205
|
+
updatedAt: h
|
|
206
|
+
});
|
|
207
|
+
}, Le = async (t, n, r, i = !1) => {
|
|
208
|
+
let a = z(r.worldId), o = a.zones.find((e) => e.id === r.zoneId);
|
|
209
|
+
o || j("World entity location requires a configured Room");
|
|
210
|
+
let c = await t.query({
|
|
211
|
+
table: s,
|
|
212
|
+
predicate: C(w("id", r.roomId), w("tenantId", n)),
|
|
213
|
+
order: [],
|
|
214
|
+
take: 2,
|
|
215
|
+
skip: void 0,
|
|
216
|
+
projection: [
|
|
217
|
+
"id",
|
|
218
|
+
"tenantId",
|
|
219
|
+
"name",
|
|
220
|
+
"hostId",
|
|
221
|
+
"epoch",
|
|
222
|
+
"state",
|
|
223
|
+
"maxClients",
|
|
224
|
+
"pool"
|
|
225
|
+
],
|
|
226
|
+
lock: "update"
|
|
227
|
+
}), l = c[0];
|
|
228
|
+
c.length === 1 && l && l.epoch === r.epoch && l.state === "live" && typeof l.hostId == "string" || j("World entity location lost current SQL Room authority"), await g(t, a, l, !0);
|
|
229
|
+
let u = a.instances.filter((e) => e.room === l.name);
|
|
230
|
+
if (u.length) {
|
|
231
|
+
a.zones.some((e) => e.room === l.name) && j("World entity Room cannot ambiguously name a zone and an instance");
|
|
232
|
+
let o = await t.query({
|
|
233
|
+
table: e,
|
|
234
|
+
predicate: C(w("tenantId", n), w("worldId", r.worldId), w("roomId", r.roomId)),
|
|
235
|
+
order: [],
|
|
236
|
+
take: 2,
|
|
237
|
+
skip: void 0,
|
|
238
|
+
projection: void 0,
|
|
239
|
+
lock: "update"
|
|
240
|
+
}), s = o[0];
|
|
241
|
+
if (o.length === 1 && s && u.some((e) => e.id === s.instance) && s.state === "live" && s.epoch === r.epoch && s.hostId === l.hostId || j("World entity location lost current SQL instance authority"), i) {
|
|
242
|
+
let e = s.expiresAt instanceof Date ? s.expiresAt.getTime() : typeof s.expiresAt == "string" ? Date.parse(s.expiresAt) : NaN;
|
|
243
|
+
(!Number.isSafeInteger(e) || B() >= e) && j("Expired World instances refuse new entity ownership");
|
|
244
|
+
}
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
(l.name !== o.room || o.layering && l.maxClients !== o.layering.maxPlayers) && j("World entity location differs from its configured zone Room");
|
|
248
|
+
let d = await t.query({
|
|
249
|
+
table: _,
|
|
250
|
+
predicate: C(w("tenantId", n), w("worldId", r.worldId), w("zoneId", r.zoneId), w("cellId", r.cellId), w("layer", r.layer)),
|
|
251
|
+
order: [],
|
|
252
|
+
take: 2,
|
|
253
|
+
skip: void 0,
|
|
254
|
+
projection: [
|
|
255
|
+
"roomId",
|
|
256
|
+
"hostId",
|
|
257
|
+
"epoch",
|
|
258
|
+
"state"
|
|
259
|
+
],
|
|
260
|
+
lock: "update"
|
|
261
|
+
}), f = d[0];
|
|
262
|
+
(d.length !== 1 || f?.roomId !== r.roomId || f.hostId !== l.hostId || f.epoch !== r.epoch || f.state !== "live") && j("World entity location lost current SQL cell authority");
|
|
263
|
+
}, U = async (e, t, n) => {
|
|
264
|
+
await h(e, n.map((e) => e.roomId), t);
|
|
265
|
+
for (let r of [...n].sort(Ve)) await Le(e, t, r);
|
|
266
|
+
}, W = (e, t) => e.worldId === t.worldId && e.zoneId === t.zoneId && e.cellId === t.cellId && e.layer === t.layer && e.roomId === t.roomId && e.epoch === t.epoch, G = (e, t, r) => D.suspend(() => {
|
|
267
|
+
let i;
|
|
268
|
+
try {
|
|
269
|
+
i = je(e, t);
|
|
270
|
+
} catch {
|
|
271
|
+
return D.fail(new n({ detail: "World entity authorization refused admission" }));
|
|
272
|
+
}
|
|
273
|
+
return D.isEffect(i) ? i.pipe(D.flatMap(r)) : D.fail(new n({ detail: "World entity authorization must return an Effect" }));
|
|
274
|
+
}), Re = async (e, t, n, i = t.worldId, a) => {
|
|
275
|
+
if (a === void 0 && !z(t.worldId).persistence.journal && !z(i).persistence.journal) return;
|
|
276
|
+
let o = r(t, xe);
|
|
277
|
+
await e.insert(k, {
|
|
278
|
+
id: pe({
|
|
279
|
+
kind: "typeid",
|
|
280
|
+
prefix: "wjour"
|
|
281
|
+
}, k),
|
|
282
|
+
tenantId: t.tenantId,
|
|
283
|
+
entityId: t.entityId,
|
|
284
|
+
revision: t.revision,
|
|
285
|
+
subjectId: t.subject?.id ?? null,
|
|
286
|
+
subjectKind: t.subject?.kind ?? null,
|
|
287
|
+
operation: n,
|
|
288
|
+
snapshot: o,
|
|
289
|
+
createdAt: new Date(t.updatedAt),
|
|
290
|
+
requestKey: a?.requestKey ?? null,
|
|
291
|
+
requestDigest: a?.requestDigest ?? null
|
|
292
|
+
});
|
|
293
|
+
}, ze = (e) => {
|
|
294
|
+
let i, a;
|
|
295
|
+
try {
|
|
296
|
+
P(e, [
|
|
297
|
+
"tenantId",
|
|
298
|
+
"entityId",
|
|
299
|
+
"subject",
|
|
300
|
+
"kind",
|
|
301
|
+
"location",
|
|
302
|
+
"data"
|
|
303
|
+
]), a = V(e.location), i = Object.freeze({
|
|
304
|
+
...De(e),
|
|
305
|
+
subject: Oe(e.subject),
|
|
306
|
+
kind: M(e.kind, 120),
|
|
307
|
+
location: a,
|
|
308
|
+
data: r(e.data, E)
|
|
309
|
+
});
|
|
310
|
+
} catch (e) {
|
|
311
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World entity creation" }));
|
|
312
|
+
}
|
|
313
|
+
return G("create", i, () => I(() => v.transactional(async (e) => {
|
|
314
|
+
await U(e, i.tenantId, [a]), await Le(e, i.tenantId, a, !0), (await F(e, i, !0)).length && j("World entity identity already exists");
|
|
315
|
+
let t = B(), n = {
|
|
316
|
+
id: pe({
|
|
317
|
+
kind: "typeid",
|
|
318
|
+
prefix: "went"
|
|
319
|
+
}, O),
|
|
320
|
+
...De(i),
|
|
321
|
+
subjectId: i.subject?.id ?? null,
|
|
322
|
+
subjectKind: i.subject?.kind ?? null,
|
|
323
|
+
kind: i.kind,
|
|
324
|
+
worldId: a.worldId,
|
|
325
|
+
zoneId: a.zoneId,
|
|
326
|
+
cellId: a.cellId,
|
|
327
|
+
layer: a.layer,
|
|
328
|
+
roomId: a.roomId,
|
|
329
|
+
epoch: a.epoch,
|
|
330
|
+
revision: 1,
|
|
331
|
+
data: i.data,
|
|
332
|
+
updatedAt: new Date(t),
|
|
333
|
+
returnAnchor: null,
|
|
334
|
+
activeTransitionId: null,
|
|
335
|
+
transitionedAt: null,
|
|
336
|
+
transitionRecordedAt: null
|
|
337
|
+
}, r = H(n);
|
|
338
|
+
return await e.insert(O, n), await Re(e, r, "create"), await Le(e, i.tenantId, a, !0), r;
|
|
339
|
+
})));
|
|
340
|
+
}, Be = (e) => {
|
|
341
|
+
let t;
|
|
342
|
+
try {
|
|
343
|
+
P(e, ["tenantId", "entityId"]), t = De(e);
|
|
344
|
+
} catch {
|
|
345
|
+
return D.fail(new n({ detail: "Invalid World entity lookup" }));
|
|
346
|
+
}
|
|
347
|
+
return G("observe", t, () => I(async () => {
|
|
348
|
+
let e = await F(v, t);
|
|
349
|
+
if (e.length > 1 && j("Ambiguous SQL World entity"), !e.length) return null;
|
|
350
|
+
let n = H(e[0]);
|
|
351
|
+
return (n.tenantId !== t.tenantId || n.entityId !== t.entityId) && j("World entity escaped its exact scope"), n;
|
|
352
|
+
}));
|
|
353
|
+
}, Ve = (e, t) => e.roomId < t.roomId ? -1 : e.roomId > t.roomId ? 1 : e.cellId < t.cellId ? -1 : +(e.cellId > t.cellId), K = (e, t) => {
|
|
354
|
+
P(t, e === "transfer" ? [
|
|
355
|
+
"tenantId",
|
|
356
|
+
"entityId",
|
|
357
|
+
"expectedRevision",
|
|
358
|
+
"source",
|
|
359
|
+
"target",
|
|
360
|
+
"data"
|
|
361
|
+
] : [
|
|
362
|
+
"tenantId",
|
|
363
|
+
"entityId",
|
|
364
|
+
"expectedRevision",
|
|
365
|
+
"source",
|
|
366
|
+
"data"
|
|
367
|
+
]);
|
|
368
|
+
let n = V(t.source), i = e === "transfer" ? V(t.target) : n, a = Object.freeze({
|
|
369
|
+
...De(t),
|
|
370
|
+
expectedRevision: N(t.expectedRevision),
|
|
371
|
+
source: n,
|
|
372
|
+
data: r(t.data, E),
|
|
373
|
+
...e === "transfer" ? { target: i } : {}
|
|
374
|
+
});
|
|
375
|
+
return Object.freeze({
|
|
376
|
+
captured: a,
|
|
377
|
+
source: n,
|
|
378
|
+
target: i
|
|
379
|
+
});
|
|
380
|
+
}, He = async (t, n, r, i, a) => {
|
|
381
|
+
let { captured: o, source: s, target: c } = r;
|
|
382
|
+
n === "transfer" && await Le(t, o.tenantId, c, !0);
|
|
383
|
+
let u = await F(t, o, !0);
|
|
384
|
+
u.length !== 1 && j("World entity write requires one durable entity");
|
|
385
|
+
let d = H(u[0]);
|
|
386
|
+
u[0].activeTransitionId !== null && u[0].activeTransitionId !== a && j("World entity is fenced by an active SQL transition"), d.tenantId === o.tenantId && d.entityId === o.entityId && d.revision === o.expectedRevision && W(d, s) && d.revision !== 2147483647 || j("World entity write lost its SQL owner or revision");
|
|
387
|
+
let f = d.returnAnchor ?? null;
|
|
388
|
+
if (n === "transfer") {
|
|
389
|
+
let n = z(c.worldId).instances.length ? await t.query({
|
|
390
|
+
table: e,
|
|
391
|
+
predicate: C(w("tenantId", o.tenantId), w("roomId", c.roomId), w("worldId", c.worldId)),
|
|
392
|
+
order: [],
|
|
393
|
+
take: 2,
|
|
394
|
+
skip: void 0,
|
|
395
|
+
projection: void 0
|
|
396
|
+
}) : [];
|
|
397
|
+
n.length > 1 && j("Ambiguous instance transfer owner");
|
|
398
|
+
let r = n[0];
|
|
399
|
+
if (!r && !f && a) {
|
|
400
|
+
let e = await t.query({
|
|
401
|
+
table: l,
|
|
402
|
+
predicate: C(w("tenantId", o.tenantId), w("id", a)),
|
|
403
|
+
order: [],
|
|
404
|
+
take: 2,
|
|
405
|
+
skip: void 0,
|
|
406
|
+
projection: void 0
|
|
407
|
+
});
|
|
408
|
+
e.length !== 1 && j("World transfer lost its transition receipt");
|
|
409
|
+
let n = Z(e[0]).intent.target;
|
|
410
|
+
(n.kind === "return" || n.kind === "instance") && j("Instance intention lacks its actual instance or return anchor");
|
|
411
|
+
}
|
|
412
|
+
if (r || f) {
|
|
413
|
+
a && L || j("Instance entry/return requires an actual fenced transition");
|
|
414
|
+
let e = await t.query({
|
|
415
|
+
table: l,
|
|
416
|
+
predicate: C(w("tenantId", o.tenantId), w("id", a)),
|
|
417
|
+
order: [],
|
|
418
|
+
take: 2,
|
|
419
|
+
skip: void 0,
|
|
420
|
+
projection: void 0
|
|
421
|
+
});
|
|
422
|
+
e.length !== 1 && j("Instance transition receipt is missing");
|
|
423
|
+
let n = Z(e[0]);
|
|
424
|
+
if ((n.mode !== "portal" || n.phase !== "switching" || n.entityId !== o.entityId || n.entityRevision !== d.revision || J(n.source) !== J(X(s)) || J(n.target) !== J(X(c))) && j("Instance anchor escaped its actual transfer"), r) {
|
|
425
|
+
let e = n.intent.target;
|
|
426
|
+
(f || e.kind !== "instance" || n.intent.options.returnTo !== "here" || r.instance !== e.instance || r.groupKey !== J([
|
|
427
|
+
"world-instance-group-v1",
|
|
428
|
+
o.tenantId,
|
|
429
|
+
c.worldId,
|
|
430
|
+
e.instance,
|
|
431
|
+
e.group
|
|
432
|
+
])) && j("Instance entry requires its original group and return intention"), f = Ie({
|
|
433
|
+
instanceId: M(r.id),
|
|
434
|
+
instance: e.instance,
|
|
435
|
+
instanceRoomId: c.roomId,
|
|
436
|
+
groupKey: r.groupKey,
|
|
437
|
+
entryTransitionId: n.id,
|
|
438
|
+
enteredRevision: d.revision + 1,
|
|
439
|
+
source: X(s)
|
|
440
|
+
});
|
|
441
|
+
} else {
|
|
442
|
+
let e = f;
|
|
443
|
+
(n.intent.target.kind !== "return" || c.worldId !== e.source.worldId || c.zoneId !== e.source.zoneId || c.layer !== e.source.layer || c.at[0] !== e.source.at[0] || c.at[1] !== e.source.at[1]) && j("World return must resolve the immutable per-entity anchor"), f = null;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
let p = B(), m = {
|
|
448
|
+
worldId: c.worldId,
|
|
449
|
+
zoneId: c.zoneId,
|
|
450
|
+
cellId: c.cellId,
|
|
451
|
+
layer: c.layer,
|
|
452
|
+
roomId: c.roomId,
|
|
453
|
+
epoch: c.epoch,
|
|
454
|
+
revision: d.revision + 1,
|
|
455
|
+
data: o.data,
|
|
456
|
+
returnAnchor: f,
|
|
457
|
+
updatedAt: new Date(p)
|
|
458
|
+
}, h = H({
|
|
459
|
+
...u[0],
|
|
460
|
+
...m
|
|
461
|
+
});
|
|
462
|
+
return await t.updateMany("_voltro_world_entities", m, { where: C(ke(o), w("revision", d.revision), w("roomId", d.roomId), w("epoch", d.epoch)) }) !== 1 && j("World entity commit lost its SQL revision"), await Re(t, h, n, d.worldId, i), n === "transfer" && await Le(t, o.tenantId, c, !0), h;
|
|
463
|
+
}, Ue = (e, r) => {
|
|
464
|
+
let i;
|
|
465
|
+
try {
|
|
466
|
+
i = K(e, r);
|
|
467
|
+
} catch (e) {
|
|
468
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World entity write" }));
|
|
469
|
+
}
|
|
470
|
+
return G(e, i.captured, () => I(() => v.transactional(async (t) => (await U(t, i.captured.tenantId, [i.source, i.target]), He(t, e, i)))));
|
|
471
|
+
}, We = (e) => {
|
|
472
|
+
if (Array.isArray(e) && Object.getPrototypeOf(e) === Array.prototype && Reflect.ownKeys(e).length === e.length + 1 || j("World entity batch requires own entries"), e.length > A) throw new t({
|
|
473
|
+
budget: "worldEntityBatchRows",
|
|
474
|
+
limit: A
|
|
475
|
+
});
|
|
476
|
+
let n = [], r = /* @__PURE__ */ new Set();
|
|
477
|
+
for (let t = 0; t < e.length; t++) {
|
|
478
|
+
let i = Object.getOwnPropertyDescriptor(e, String(t));
|
|
479
|
+
i?.enumerable && "value" in i || j("World entity batch requires own entries");
|
|
480
|
+
let a = K("persist", i.value), o = JSON.stringify([a.captured.tenantId, a.captured.entityId]);
|
|
481
|
+
(r.has(o) || n.length && n[0].captured.tenantId !== a.captured.tenantId) && j("World entity batch requires unique entities in one tenant"), r.add(o), n.push(a);
|
|
482
|
+
}
|
|
483
|
+
return n;
|
|
484
|
+
}, Ge = (e) => {
|
|
485
|
+
let r;
|
|
486
|
+
try {
|
|
487
|
+
r = We(e);
|
|
488
|
+
} catch (e) {
|
|
489
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World entity batch" }));
|
|
490
|
+
}
|
|
491
|
+
return r.length ? D.gen(function* () {
|
|
492
|
+
for (let e of r) yield* G("persist", e.captured, () => D.void);
|
|
493
|
+
return yield* I(() => v.transactional(async (e) => {
|
|
494
|
+
await U(e, r[0].captured.tenantId, r.map((e) => e.source));
|
|
495
|
+
let t = /* @__PURE__ */ new Map();
|
|
496
|
+
for (let n of [...r].sort((e, t) => e.captured.entityId < t.captured.entityId ? -1 : +(e.captured.entityId > t.captured.entityId))) t.set(n.captured.entityId, await He(e, "persist", n));
|
|
497
|
+
return Object.freeze(r.map((e) => t.get(e.captured.entityId)));
|
|
498
|
+
}));
|
|
499
|
+
}) : D.succeed(Object.freeze([]));
|
|
500
|
+
}, Ke = (e, r, i) => {
|
|
501
|
+
let a, o;
|
|
502
|
+
try {
|
|
503
|
+
P(i, [
|
|
504
|
+
"roomId",
|
|
505
|
+
"tenantId",
|
|
506
|
+
"requestId"
|
|
507
|
+
]), a = Object.freeze({
|
|
508
|
+
roomId: M(i.roomId),
|
|
509
|
+
tenantId: M(i.tenantId),
|
|
510
|
+
requestId: M(i.requestId, 384)
|
|
511
|
+
}), r.length || j("World entity command requires a nonempty batch"), r.some((e) => e.captured.tenantId !== a.tenantId || e.source.roomId !== a.roomId) && j("World entity command escaped its actual outbox origin");
|
|
512
|
+
let t = (e) => Ce("sha256").update(JSON.stringify(Ae(e)), "utf8").digest("hex");
|
|
513
|
+
o = Object.freeze({
|
|
514
|
+
requestKey: t([
|
|
515
|
+
"world-entity-command",
|
|
516
|
+
a.tenantId,
|
|
517
|
+
a.roomId,
|
|
518
|
+
a.requestId
|
|
519
|
+
]),
|
|
520
|
+
requestDigest: t([e, r.map((e) => e.captured)])
|
|
521
|
+
});
|
|
522
|
+
} catch (e) {
|
|
523
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World entity command" }));
|
|
524
|
+
}
|
|
525
|
+
let s = async (t, n) => {
|
|
526
|
+
let i = await t.query({
|
|
527
|
+
table: k,
|
|
528
|
+
predicate: w("requestKey", o.requestKey),
|
|
529
|
+
order: [{
|
|
530
|
+
column: "entityId",
|
|
531
|
+
direction: "asc"
|
|
532
|
+
}],
|
|
533
|
+
take: A + 1,
|
|
534
|
+
skip: void 0,
|
|
535
|
+
projection: void 0,
|
|
536
|
+
...n ? { lock: "update" } : {}
|
|
537
|
+
});
|
|
538
|
+
if (!i.length) return !1;
|
|
539
|
+
i.length !== r.length && j("World entity command has incomplete protected receipts");
|
|
540
|
+
let s = new Map(r.map((e) => [e.captured.entityId, e]));
|
|
541
|
+
for (let t of i) {
|
|
542
|
+
let n = M(t.entityId), r = s.get(n);
|
|
543
|
+
r && t.tenantId === a.tenantId && t.requestDigest === o.requestDigest && t.operation === e && t.revision === r.captured.expectedRevision + 1 || j("World entity command identity or payload conflicts with its receipt"), s.delete(n);
|
|
544
|
+
}
|
|
545
|
+
return s.size && j("World entity command receipts omit accepted entities"), !0;
|
|
546
|
+
};
|
|
547
|
+
return D.gen(function* () {
|
|
548
|
+
for (let t of r) yield* G(e, t.captured, () => D.void);
|
|
549
|
+
(yield* I(() => s(v, !1))) || (yield* I(() => v.transactional(async (t) => {
|
|
550
|
+
let n = r.flatMap((e) => [e.source, e.target]).sort(Ve);
|
|
551
|
+
if (await U(t, a.tenantId, n), !await s(t, !0)) for (let n of [...r].sort((e, t) => e.captured.entityId < t.captured.entityId ? -1 : +(e.captured.entityId > t.captured.entityId))) await He(t, e, n, o);
|
|
552
|
+
})));
|
|
553
|
+
});
|
|
554
|
+
}, qe = (e, r) => {
|
|
555
|
+
try {
|
|
556
|
+
return Ke("persist", We(e), r);
|
|
557
|
+
} catch (e) {
|
|
558
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World entity persistence command" }));
|
|
559
|
+
}
|
|
560
|
+
}, Je = (e, r) => {
|
|
561
|
+
try {
|
|
562
|
+
return Ke("transfer", [K("transfer", e)], r);
|
|
563
|
+
} catch (e) {
|
|
564
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World entity transfer command" }));
|
|
565
|
+
}
|
|
566
|
+
}, q = (e) => (P(e, [
|
|
567
|
+
"tenantId",
|
|
568
|
+
"roomId",
|
|
569
|
+
"requestId"
|
|
570
|
+
]), Object.freeze({
|
|
571
|
+
tenantId: M(e.tenantId),
|
|
572
|
+
roomId: M(e.roomId),
|
|
573
|
+
requestId: M(e.requestId, 384)
|
|
574
|
+
})), J = (e) => Ce("sha256").update(JSON.stringify(Ae(e)), "utf8").digest("hex"), Y = (e) => J([
|
|
575
|
+
"world-transition",
|
|
576
|
+
e.tenantId,
|
|
577
|
+
e.roomId,
|
|
578
|
+
e.requestId
|
|
579
|
+
]), X = (e) => Object.freeze({
|
|
580
|
+
worldId: e.worldId,
|
|
581
|
+
zoneId: e.zoneId,
|
|
582
|
+
at: e.at,
|
|
583
|
+
layer: e.layer,
|
|
584
|
+
roomId: e.roomId,
|
|
585
|
+
epoch: e.epoch
|
|
586
|
+
}), Ye = (e) => {
|
|
587
|
+
let t = e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : NaN;
|
|
588
|
+
return (!Number.isSafeInteger(t) || t < 0 || t > 864e13) && j("Invalid World transition SQL time"), t;
|
|
589
|
+
}, Z = (e) => {
|
|
590
|
+
let t = q({
|
|
591
|
+
tenantId: e.tenantId,
|
|
592
|
+
roomId: e.sourceRoomId,
|
|
593
|
+
requestId: e.requestId
|
|
594
|
+
}), n = V(e.source), i = V(e.target), s = e.mode, c = e.phase;
|
|
595
|
+
(s !== "portal" && s !== "seamless" || typeof c != "string" || !a.includes(c) || e.requestKey !== Y(t) || typeof e.requestDigest != "string" || !/^[a-f0-9]{64}$/.test(e.requestDigest) || n.roomId !== t.roomId || e.sourceWorldId !== n.worldId || e.targetWorldId !== i.worldId) && j("Contradictory World transition identity or phase");
|
|
596
|
+
let l = M(e.entityId), u = N(e.revision), d = N(e.entityRevision), f = N(e.requestedRevision), p = r(o(e.intent), 4096);
|
|
597
|
+
(p.entityId !== l || f > d || p.options.mode === "portal" && s !== "portal") && j("World transition intention contradicts its durable entity");
|
|
598
|
+
let h = e.subjectId === null && e.subjectKind === null ? null : Oe({
|
|
599
|
+
id: e.subjectId,
|
|
600
|
+
kind: e.subjectKind
|
|
601
|
+
}), g = Ye(e.createdAt), _ = Ye(e.updatedAt), ee = e.committedAt === null ? null : Ye(e.committedAt), v = e.failure === null ? null : M(e.failure, 120), y = e.groupReceipt == null ? void 0 : se(e.groupReceipt);
|
|
602
|
+
(e.groupKey == null != (y === void 0) || y && (e.groupKey !== y.key || u <= y.boundRevision)) && j("World transition group fence is contradictory");
|
|
603
|
+
let b = e.groupCommandReceipt == null ? void 0 : ne(e.groupCommandReceipt);
|
|
604
|
+
(e.groupCommandKey == null != (b === void 0) || b && (!y || e.groupCommandKey !== re(b) || y.requestId !== ie(b) || b.origin.tenantId !== t.tenantId || b.startedAt < g || b.startedAt > _ || J({
|
|
605
|
+
target: p.target,
|
|
606
|
+
options: p.options
|
|
607
|
+
}) !== J({
|
|
608
|
+
target: b.intent.target,
|
|
609
|
+
options: b.intent.options
|
|
610
|
+
}))) && j("World group command differs from its immutable member intention");
|
|
611
|
+
let te;
|
|
612
|
+
if (e.groupProceedReceipt != null) {
|
|
613
|
+
let t = e.groupProceedReceipt;
|
|
614
|
+
P(t, [
|
|
615
|
+
"at",
|
|
616
|
+
"revision",
|
|
617
|
+
"returnAnchor"
|
|
618
|
+
]);
|
|
619
|
+
let r = t.at, i = N(t.revision), a = X(V(t.returnAnchor));
|
|
620
|
+
(!b || b.intent.onTimeout !== "proceed" || !y?.requiresReadiness || typeof r != "number" || !Number.isSafeInteger(r) || r < b.waitUntil || r > _ || i <= y.boundRevision || i > u || J(a) !== J(X(n)) || ![
|
|
621
|
+
"switching",
|
|
622
|
+
"committed",
|
|
623
|
+
"settled",
|
|
624
|
+
"failed",
|
|
625
|
+
"rolledBack"
|
|
626
|
+
].includes(c)) && j("World proceed decision escaped its original command/member anchor"), te = Object.freeze({
|
|
627
|
+
at: r,
|
|
628
|
+
revision: i,
|
|
629
|
+
returnAnchor: a
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
let x = e.readySession == null ? void 0 : m(e.readySession), ae = e.readyAt == null ? void 0 : Ye(e.readyAt);
|
|
633
|
+
(x === void 0 != (ae === void 0) || x && (!y || x.tenantId !== t.tenantId || x.subjectId !== h?.id || x.roomId !== i.roomId || x.epoch !== i.epoch || ![
|
|
634
|
+
"switching",
|
|
635
|
+
"committed",
|
|
636
|
+
"settled",
|
|
637
|
+
"failed",
|
|
638
|
+
"rolledBack"
|
|
639
|
+
].includes(c) || ae < g || ae > _)) && j("World transition ready observation escaped its original target");
|
|
640
|
+
let oe = x === void 0 ? void 0 : Object.freeze({
|
|
641
|
+
sessionId: x.sessionId,
|
|
642
|
+
roomId: x.roomId,
|
|
643
|
+
epoch: x.epoch,
|
|
644
|
+
readyAt: ae
|
|
645
|
+
}), S = null;
|
|
646
|
+
if (e.result !== null) {
|
|
647
|
+
let n = r(e.result, xe);
|
|
648
|
+
P(n, [
|
|
649
|
+
"tenantId",
|
|
650
|
+
"entityId",
|
|
651
|
+
"subject",
|
|
652
|
+
"kind",
|
|
653
|
+
"worldId",
|
|
654
|
+
"zoneId",
|
|
655
|
+
"cellId",
|
|
656
|
+
"layer",
|
|
657
|
+
"roomId",
|
|
658
|
+
"epoch",
|
|
659
|
+
"revision",
|
|
660
|
+
"data",
|
|
661
|
+
"updatedAt",
|
|
662
|
+
"returnAnchor"
|
|
663
|
+
]);
|
|
664
|
+
let a = Oe(n.subject);
|
|
665
|
+
S = H({
|
|
666
|
+
...n,
|
|
667
|
+
subjectId: a?.id ?? null,
|
|
668
|
+
subjectKind: a?.kind ?? null,
|
|
669
|
+
updatedAt: new Date(n.updatedAt)
|
|
670
|
+
}), S.tenantId === t.tenantId && S.entityId === l && S.revision === d && W(S, i) && S.subject?.id === h?.id && S.subject?.kind === h?.kind || j("World transition commit receipt escaped its entity");
|
|
671
|
+
}
|
|
672
|
+
let ce = c === "committed" || c === "settled";
|
|
673
|
+
(_ < g || ce !== (ee !== null) || ce !== (S !== null) || (c === "failed" || c === "rolledBack") != (v !== null) || ee !== null && (ee < g || ee > _)) && j("Contradictory World transition commit boundary");
|
|
674
|
+
let le = e.actorSnapshot == null ? void 0 : fe(e.actorSnapshot, E), ue = e.actorSnapshotRevision == null ? void 0 : N(e.actorSnapshotRevision);
|
|
675
|
+
(le === void 0 != (ue === void 0) || ue !== void 0 && (ue > u || ue < 2 || c === "requested")) && j("World actor snapshot phase receipt is contradictory"), le && le.entity.id !== l && j("World actor snapshot escaped its entity");
|
|
676
|
+
let de = e.groupDriveAcknowledgedAt == null ? void 0 : Ye(e.groupDriveAcknowledgedAt);
|
|
677
|
+
de !== void 0 && (!b || !["settled", "rolledBack"].includes(c) || de < _) && j("World group driving acknowledgment contradicts its terminal command");
|
|
678
|
+
let C = e.actorDepartureRevision == null ? void 0 : N(e.actorDepartureRevision);
|
|
679
|
+
C !== void 0 && (s !== "portal" || !le || C <= ue || C > u || ![
|
|
680
|
+
"detaching",
|
|
681
|
+
"switching",
|
|
682
|
+
"committed",
|
|
683
|
+
"settled",
|
|
684
|
+
"failed",
|
|
685
|
+
"rolledBack"
|
|
686
|
+
].includes(c)) && j("World portal departure contradicts its captured source");
|
|
687
|
+
let w;
|
|
688
|
+
if (e.actorFinalSnapshot != null) {
|
|
689
|
+
let t = e.actorFinalSnapshot;
|
|
690
|
+
P(t, [
|
|
691
|
+
"snapshot",
|
|
692
|
+
"data",
|
|
693
|
+
"revision"
|
|
694
|
+
]), w = Object.freeze({
|
|
695
|
+
snapshot: fe(t.snapshot, E),
|
|
696
|
+
data: r(t.data, E),
|
|
697
|
+
revision: N(t.revision)
|
|
698
|
+
}), (!le || s !== "seamless" || n.worldId !== i.worldId || w.snapshot.entity.id !== l || w.snapshot.schemaHash !== le.schemaHash || w.revision <= ue || w.revision > u || ![
|
|
699
|
+
"switching",
|
|
700
|
+
"committed",
|
|
701
|
+
"settled",
|
|
702
|
+
"failed",
|
|
703
|
+
"rolledBack"
|
|
704
|
+
].includes(c)) && j("World final actor snapshot contradicts its handoff");
|
|
705
|
+
}
|
|
706
|
+
return Object.freeze({
|
|
707
|
+
...de === void 0 ? {} : { groupDriveAcknowledgedAt: de },
|
|
708
|
+
...C === void 0 ? {} : { actorDepartureRevision: C },
|
|
709
|
+
...te === void 0 ? {} : { groupProceed: te },
|
|
710
|
+
...b === void 0 ? {} : { groupCommand: b },
|
|
711
|
+
...w === void 0 ? {} : { actorFinalSnapshot: w },
|
|
712
|
+
...le === void 0 ? {} : {
|
|
713
|
+
actorSnapshot: le,
|
|
714
|
+
actorSnapshotRevision: ue
|
|
715
|
+
},
|
|
716
|
+
...y === void 0 ? {} : { group: y },
|
|
717
|
+
...oe === void 0 ? {} : { ready: oe },
|
|
718
|
+
id: M(e.id),
|
|
719
|
+
origin: t,
|
|
720
|
+
entityId: l,
|
|
721
|
+
subject: h,
|
|
722
|
+
mode: s,
|
|
723
|
+
phase: c,
|
|
724
|
+
revision: u,
|
|
725
|
+
entityRevision: d,
|
|
726
|
+
requestedRevision: f,
|
|
727
|
+
intent: p,
|
|
728
|
+
source: X(n),
|
|
729
|
+
target: X(i),
|
|
730
|
+
sourceData: r(e.sourceData, E),
|
|
731
|
+
data: r(e.data, E),
|
|
732
|
+
result: S,
|
|
733
|
+
failure: v,
|
|
734
|
+
createdAt: g,
|
|
735
|
+
updatedAt: _,
|
|
736
|
+
committedAt: ee
|
|
737
|
+
});
|
|
738
|
+
}, Q = (e, t, n = !1) => e.query({
|
|
739
|
+
table: l,
|
|
740
|
+
predicate: w("requestKey", Y(t)),
|
|
741
|
+
order: [],
|
|
742
|
+
take: 2,
|
|
743
|
+
skip: void 0,
|
|
744
|
+
projection: void 0,
|
|
745
|
+
...n ? { lock: "update" } : {}
|
|
746
|
+
}), Xe = async (e, n, r) => {
|
|
747
|
+
if (!n.subject || !r && !n.actorFinalSnapshot && n.actorDepartureRevision === void 0) return;
|
|
748
|
+
let i = C(w("tenantId", n.origin.tenantId), w("roomId", n.source.roomId), w("subjectId", n.subject.id), w("role", "player")), a = r ? C(i, w("epoch", n.source.epoch), he("state", [
|
|
749
|
+
"reserved",
|
|
750
|
+
"connected",
|
|
751
|
+
"grace"
|
|
752
|
+
])) : C(i, w("worldSourceTransitionId", n.id)), o = await e.query({
|
|
753
|
+
table: c,
|
|
754
|
+
predicate: a,
|
|
755
|
+
order: [{
|
|
756
|
+
column: "id",
|
|
757
|
+
direction: "asc"
|
|
758
|
+
}],
|
|
759
|
+
take: A + 1,
|
|
760
|
+
skip: void 0,
|
|
761
|
+
projection: ["id", "worldSourceTransitionId"],
|
|
762
|
+
lock: "update"
|
|
763
|
+
});
|
|
764
|
+
if (o.length > A) throw new t({
|
|
765
|
+
budget: "worldSourceSeats",
|
|
766
|
+
limit: A
|
|
767
|
+
});
|
|
768
|
+
for (let t of o) r && t.worldSourceTransitionId != null && t.worldSourceTransitionId !== n.id && j("World source Seat belongs to another departure"), await e.updateMany("_voltro_room_seats", { worldSourceTransitionId: r ? n.id : null }, { where: C(a, w("id", t.id)) }) !== 1 && j("World source Seat restriction lost its original row");
|
|
769
|
+
}, $ = (e, t, r) => D.suspend(() => {
|
|
770
|
+
if (Fe === void 0) return D.fail(new n({ detail: "World transition state is not configured" }));
|
|
771
|
+
let i;
|
|
772
|
+
try {
|
|
773
|
+
i = Fe(e, t);
|
|
774
|
+
} catch {
|
|
775
|
+
return D.fail(new n({ detail: "World transition authorization refused admission" }));
|
|
776
|
+
}
|
|
777
|
+
return D.isEffect(i) ? i.pipe(D.flatMap(r)) : D.fail(new n({ detail: "World transition authorization requires an Effect" }));
|
|
778
|
+
}), Ze = (e) => {
|
|
779
|
+
let t;
|
|
780
|
+
try {
|
|
781
|
+
t = q(e);
|
|
782
|
+
} catch {
|
|
783
|
+
return D.fail(new n({ detail: "Invalid World transition lookup" }));
|
|
784
|
+
}
|
|
785
|
+
return $("observe", t, () => I(async () => {
|
|
786
|
+
let e = await Q(v, t);
|
|
787
|
+
return e.length > 1 && j("Ambiguous SQL World transition"), e.length ? Z(e[0]) : null;
|
|
788
|
+
}));
|
|
789
|
+
}, Qe = (e, t) => D.suspend(() => {
|
|
790
|
+
if (!R || t.members.length > R.maxRows) return D.fail(new n({ detail: "World group authority is not configured for this complete set" }));
|
|
791
|
+
try {
|
|
792
|
+
let r = R.authorize(e, t);
|
|
793
|
+
return D.isEffect(r) ? r : D.fail(new n({ detail: "World group authority requires an Effect" }));
|
|
794
|
+
} catch {
|
|
795
|
+
return D.fail(new n({ detail: "World group authority refused admission" }));
|
|
796
|
+
}
|
|
797
|
+
}), $e = (e, t) => D.suspend(() => {
|
|
798
|
+
if (!R?.readiness) return D.fail(new n({ detail: "Actual World group session readiness is not configured" }));
|
|
799
|
+
try {
|
|
800
|
+
let r = R.readiness.confirm(e, t);
|
|
801
|
+
return D.isEffect(r) ? r : D.fail(new n({ detail: "World target readiness requires an actual Effect" }));
|
|
802
|
+
} catch {
|
|
803
|
+
return D.fail(new n({ detail: "Actual World target session readiness remains incomplete" }));
|
|
804
|
+
}
|
|
805
|
+
}), et = async (e, t) => {
|
|
806
|
+
let n = await D.runPromise(D.result($e(e, t)));
|
|
807
|
+
if (Se.isFailure(n)) throw n.failure;
|
|
808
|
+
}, tt = async (e, t, n, r = !1) => {
|
|
809
|
+
t.group && t.subject !== null && n.tenantId === t.origin.tenantId && n.subjectId === t.subject.id && n.roomId === t.target.roomId && n.epoch === t.target.epoch || j("World target session evidence escaped its group Subject/target");
|
|
810
|
+
let i = await e.query({
|
|
811
|
+
table: s,
|
|
812
|
+
predicate: C(w("id", n.roomId), w("tenantId", n.tenantId)),
|
|
813
|
+
order: [],
|
|
814
|
+
take: 2,
|
|
815
|
+
skip: void 0,
|
|
816
|
+
projection: [
|
|
817
|
+
"id",
|
|
818
|
+
"tenantId",
|
|
819
|
+
"epoch",
|
|
820
|
+
"state",
|
|
821
|
+
"erasure",
|
|
822
|
+
"snapshotErasure"
|
|
823
|
+
],
|
|
824
|
+
...r ? { lock: "update" } : {}
|
|
825
|
+
});
|
|
826
|
+
(i.length !== 1 || i[0].id !== n.roomId || i[0].tenantId !== n.tenantId || i[0].epoch !== n.epoch || i[0].state !== "live" || i[0].erasure != null || i[0].snapshotErasure != null) && j("World ready target Room is no longer current");
|
|
827
|
+
let a = await e.query({
|
|
828
|
+
table: c,
|
|
829
|
+
predicate: C(w("sessionId", n.sessionId), w("tenantId", n.tenantId)),
|
|
830
|
+
order: [],
|
|
831
|
+
take: 2,
|
|
832
|
+
skip: void 0,
|
|
833
|
+
projection: [
|
|
834
|
+
"sessionId",
|
|
835
|
+
"tenantId",
|
|
836
|
+
"subjectId",
|
|
837
|
+
"roomId",
|
|
838
|
+
"epoch",
|
|
839
|
+
"role",
|
|
840
|
+
"state",
|
|
841
|
+
"nonce",
|
|
842
|
+
"token"
|
|
843
|
+
],
|
|
844
|
+
...r ? { lock: "update" } : {}
|
|
845
|
+
}), o = a[0];
|
|
846
|
+
(a.length !== 1 || o.sessionId !== n.sessionId || o.tenantId !== n.tenantId || o.subjectId !== n.subjectId || o.roomId !== n.roomId || o.epoch !== n.epoch || o.role !== "player" || o.state !== "connected" || o.nonce !== n.nonce || o.token !== n.credentialDigest) && j("World target Seat is not the actual connected credential"), await et(t, n);
|
|
847
|
+
}, nt = async (e, t) => {
|
|
848
|
+
R && t.group || j("World ready member requires a durable complete group");
|
|
849
|
+
let n = await e.query({
|
|
850
|
+
table: l,
|
|
851
|
+
predicate: C(w("tenantId", t.origin.tenantId), w("groupKey", t.group.key)),
|
|
852
|
+
order: [],
|
|
853
|
+
take: R.maxRows + 1,
|
|
854
|
+
skip: void 0,
|
|
855
|
+
projection: [
|
|
856
|
+
"tenantId",
|
|
857
|
+
"sourceRoomId",
|
|
858
|
+
"requestId",
|
|
859
|
+
"subjectId",
|
|
860
|
+
"subjectKind",
|
|
861
|
+
"revision",
|
|
862
|
+
"groupKey",
|
|
863
|
+
"groupReceipt"
|
|
864
|
+
]
|
|
865
|
+
});
|
|
866
|
+
n.length > R.maxRows && j("World group readiness exceeds its complete set budget");
|
|
867
|
+
let r = n.map((e) => {
|
|
868
|
+
let n = se(e.groupReceipt);
|
|
869
|
+
return (e.tenantId !== t.origin.tenantId || e.groupKey !== t.group.key || n.key !== t.group.key) && j("World ready group inventory escaped its tenant/key"), {
|
|
870
|
+
origin: q({
|
|
871
|
+
tenantId: e.tenantId,
|
|
872
|
+
roomId: e.sourceRoomId,
|
|
873
|
+
requestId: e.requestId
|
|
874
|
+
}),
|
|
875
|
+
subject: Oe({
|
|
876
|
+
id: e.subjectId,
|
|
877
|
+
kind: e.subjectKind
|
|
878
|
+
}),
|
|
879
|
+
revision: N(e.revision),
|
|
880
|
+
group: n
|
|
881
|
+
};
|
|
882
|
+
});
|
|
883
|
+
return S(r) ?? j("World ready group has no complete receipt");
|
|
884
|
+
}, rt = (e) => {
|
|
885
|
+
let t;
|
|
886
|
+
try {
|
|
887
|
+
R?.readiness || j("Actual World group readiness is not configured"), P(e, [
|
|
888
|
+
"origin",
|
|
889
|
+
"expectedRevision",
|
|
890
|
+
"subject",
|
|
891
|
+
"evidence"
|
|
892
|
+
]);
|
|
893
|
+
let n = Oe(e.subject) ?? j("World ready player requires trusted Subject identity");
|
|
894
|
+
t = Object.freeze({
|
|
895
|
+
origin: q(e.origin),
|
|
896
|
+
expectedRevision: N(e.expectedRevision),
|
|
897
|
+
subject: n,
|
|
898
|
+
evidence: m(e.evidence)
|
|
899
|
+
});
|
|
900
|
+
} catch {
|
|
901
|
+
return D.fail(new n({ detail: "Invalid or unconfigured World group ready intention" }));
|
|
902
|
+
}
|
|
903
|
+
return $("observe", t.origin, () => I(async () => {
|
|
904
|
+
let e = await Q(v, t.origin);
|
|
905
|
+
e.length !== 1 && j("World ready player requires one original transition");
|
|
906
|
+
let n = Z(e[0]);
|
|
907
|
+
n.group && n.subject?.id === t.subject.id && n.subject.kind === t.subject.kind && n.phase === "switching" || j("World ready intention belongs to no matching switching player");
|
|
908
|
+
let r = await nt(v, n), i = await D.runPromise(D.result(Qe("ready", r)));
|
|
909
|
+
if (Se.isFailure(i)) throw i.failure;
|
|
910
|
+
return v.transactional(async (e) => {
|
|
911
|
+
await U(e, t.origin.tenantId, [V(n.source), V(n.target)]);
|
|
912
|
+
let r = await F(e, {
|
|
913
|
+
tenantId: t.origin.tenantId,
|
|
914
|
+
entityId: n.entityId
|
|
915
|
+
}, !0), i = await Q(e, t.origin, !0);
|
|
916
|
+
(r.length !== 1 || i.length !== 1) && j("World ready intention lost its locked source");
|
|
917
|
+
let a = Z(i[0]), o = H(r[0]);
|
|
918
|
+
a.id === n.id && a.phase === "switching" && a.subject?.id === t.subject.id && a.subject.kind === t.subject.kind && a.group?.key === n.group.key && a.group?.digest === n.group.digest && r[0].activeTransitionId === a.id && o.revision === a.entityRevision && W(o, V(a.source)) || j("World ready intention lost its current source/group fence"), await tt(e, a, t.evidence, !0);
|
|
919
|
+
let s = i[0].readySession == null ? void 0 : m(i[0].readySession);
|
|
920
|
+
if (s && J(s) === J(t.evidence) && a.revision === t.expectedRevision + 1) return a;
|
|
921
|
+
(a.revision !== t.expectedRevision || a.revision >= 2147483645) && j("World ready intention lost its phase revision");
|
|
922
|
+
let c = B();
|
|
923
|
+
c < a.updatedAt && j("World ready intention clock moved backwards");
|
|
924
|
+
let l = {
|
|
925
|
+
readySession: t.evidence,
|
|
926
|
+
readyAt: new Date(c),
|
|
927
|
+
revision: a.revision + 1,
|
|
928
|
+
updatedAt: new Date(c)
|
|
929
|
+
};
|
|
930
|
+
return await e.updateMany("_voltro_world_transitions", l, { where: C(w("id", a.id), w("tenantId", t.origin.tenantId), w("phase", "switching"), w("revision", a.revision), w("groupKey", a.group.key)) }) !== 1 && j("World ready intention lost its phase CAS"), Z({
|
|
931
|
+
...i[0],
|
|
932
|
+
...l
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
}));
|
|
936
|
+
}, it = (e) => {
|
|
937
|
+
let t;
|
|
938
|
+
try {
|
|
939
|
+
(!R?.readiness || !Array.isArray(e) || !e.length || e.length > R.maxRows || Reflect.ownKeys(e).length !== e.length + 1) && j("World group readiness requires its configured complete origin list");
|
|
940
|
+
let n = [];
|
|
941
|
+
for (let t = 0; t < e.length; t++) {
|
|
942
|
+
let r = Object.getOwnPropertyDescriptor(e, t);
|
|
943
|
+
r && "value" in r || j("World group readiness requires own origins"), n.push(q(r.value));
|
|
944
|
+
}
|
|
945
|
+
new Set(n.map(Y)).size !== n.length && j("World ready group origins must be unique"), t = Object.freeze(n);
|
|
946
|
+
} catch {
|
|
947
|
+
return D.fail(new n({ detail: "Invalid or unconfigured complete World group readiness" }));
|
|
948
|
+
}
|
|
949
|
+
return D.gen(function* () {
|
|
950
|
+
for (let e of t) yield* $("observe", e, () => D.void);
|
|
951
|
+
return yield* I(async () => {
|
|
952
|
+
let e = [];
|
|
953
|
+
for (let n of t) {
|
|
954
|
+
let t = await Q(v, n);
|
|
955
|
+
t.length !== 1 && j("World readiness requires every original transition");
|
|
956
|
+
let r = Z(t[0]);
|
|
957
|
+
(r.phase !== "switching" || t[0].readySession == null && !r.groupProceed) && j("World group has not received every ready intention or deferred decision"), e.push({
|
|
958
|
+
record: r,
|
|
959
|
+
evidence: t[0].readySession == null ? void 0 : m(t[0].readySession)
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
let n = S(e.map((e) => e.record)) ?? j("World readiness requires a complete durable group"), r = await D.runPromise(D.result(Qe("commit", n)));
|
|
963
|
+
if (Se.isFailure(r)) throw r.failure;
|
|
964
|
+
let i = mt(e.map((e) => e.record));
|
|
965
|
+
if (i) {
|
|
966
|
+
let e = await D.runPromise(D.result(ht(i)));
|
|
967
|
+
if (Se.isFailure(e)) throw e.failure;
|
|
968
|
+
await gt(v, i.records, B(), !1);
|
|
969
|
+
} else for (let t of e) t.evidence || j("World group member lacks actual readiness evidence"), await tt(v, t.record, t.evidence);
|
|
970
|
+
});
|
|
971
|
+
});
|
|
972
|
+
}, at = (e) => {
|
|
973
|
+
let t;
|
|
974
|
+
try {
|
|
975
|
+
R || j("World transition groups are not configured"), t = oe(e, R.maxRows);
|
|
976
|
+
} catch {
|
|
977
|
+
return D.fail(new n({ detail: "Invalid or unconfigured World transition group" }));
|
|
978
|
+
}
|
|
979
|
+
let r = ce(t, R?.readiness !== void 0);
|
|
980
|
+
return D.gen(function* () {
|
|
981
|
+
yield* Qe("bind", t);
|
|
982
|
+
for (let e of t.members) yield* $("observe", e.origin, () => D.void);
|
|
983
|
+
return yield* I(async () => {
|
|
984
|
+
let e = async (e, n = !1) => {
|
|
985
|
+
let r = [];
|
|
986
|
+
for (let i = 0; i < t.members.length; i++) {
|
|
987
|
+
let a = t.members[i], o = await Q(e, a.origin, n);
|
|
988
|
+
o.length !== 1 && j("World group requires every original durable request");
|
|
989
|
+
let s = Z(o[0]);
|
|
990
|
+
(s.subject?.id !== a.subject.id || s.subject.kind !== a.subject.kind) && j("World group request belongs to another Subject"), r.push({
|
|
991
|
+
member: a,
|
|
992
|
+
ordinal: i,
|
|
993
|
+
row: o[0],
|
|
994
|
+
record: s
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
return new Set(r.map((e) => e.record.entityId)).size !== r.length && j("World group entities must be distinct"), r;
|
|
998
|
+
}, n = (e) => {
|
|
999
|
+
let n = S(e.map((e) => e.record));
|
|
1000
|
+
return n !== void 0 && (J(n) !== J(t) && j("World group differs from its original membership receipt"), !0);
|
|
1001
|
+
}, i = await e(v);
|
|
1002
|
+
if (n(i)) return Object.freeze(i.map((e) => e.record));
|
|
1003
|
+
let a = i[0].record.target;
|
|
1004
|
+
return i.some((e) => e.record.phase !== "requested" || e.record.revision !== e.member.expectedRevision || e.record.target.worldId !== a.worldId || e.record.target.layer !== a.layer) && j("World group must bind original requested records in one target World/layer"), v.transactional(async (e) => {
|
|
1005
|
+
await U(e, t.tenantId, i.flatMap((e) => [V(e.record.source), V(e.record.target)]));
|
|
1006
|
+
let o = [...i].sort((e, t) => e.record.entityId < t.record.entityId ? -1 : 1), s = /* @__PURE__ */ new Map();
|
|
1007
|
+
for (let n of o) {
|
|
1008
|
+
let r = await F(e, {
|
|
1009
|
+
tenantId: t.tenantId,
|
|
1010
|
+
entityId: n.record.entityId
|
|
1011
|
+
}, !0);
|
|
1012
|
+
r.length !== 1 && j("World group lost its current entity"), s.set(n.record.entityId, r[0]);
|
|
1013
|
+
}
|
|
1014
|
+
let c = [];
|
|
1015
|
+
for (let t of o) {
|
|
1016
|
+
let n = await Q(e, t.member.origin, !0);
|
|
1017
|
+
n.length !== 1 && j("World group lost its requested transition");
|
|
1018
|
+
let r = Z(n[0]);
|
|
1019
|
+
r.id !== t.record.id && j("World group transition identity changed under locks"), c.push({
|
|
1020
|
+
...t,
|
|
1021
|
+
row: n[0],
|
|
1022
|
+
record: r
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
if (n(c)) {
|
|
1026
|
+
let e = new Map(c.map((e) => [Y(e.member.origin), e.record]));
|
|
1027
|
+
return Object.freeze(t.members.map((t) => e.get(Y(t.origin))));
|
|
1028
|
+
}
|
|
1029
|
+
let l = B();
|
|
1030
|
+
for (let e of c) {
|
|
1031
|
+
let n = s.get(e.record.entityId), r = H(n);
|
|
1032
|
+
(e.record.phase !== "requested" || e.record.revision !== e.member.expectedRevision || e.record.revision >= 2147483640 || e.record.subject?.id !== e.member.subject.id || e.record.subject.kind !== e.member.subject.kind || r.subject?.id !== e.member.subject.id || r.subject.kind !== e.member.subject.kind || r.tenantId !== t.tenantId || n.activeTransitionId !== e.record.id || r.revision !== e.record.entityRevision || !W(r, V(e.record.source)) || e.record.target.worldId !== a.worldId || e.record.target.layer !== a.layer || l < e.record.updatedAt) && j("World group lost an original owner/Subject/phase fence");
|
|
1033
|
+
}
|
|
1034
|
+
let u = /* @__PURE__ */ new Map();
|
|
1035
|
+
for (let n of c) {
|
|
1036
|
+
let i = r[n.ordinal], a = {
|
|
1037
|
+
groupKey: i.key,
|
|
1038
|
+
groupReceipt: i,
|
|
1039
|
+
revision: n.record.revision + 1,
|
|
1040
|
+
updatedAt: new Date(l)
|
|
1041
|
+
};
|
|
1042
|
+
await e.updateMany("_voltro_world_transitions", a, { where: C(w("id", n.record.id), w("tenantId", t.tenantId), w("revision", n.record.revision), w("phase", "requested"), w("groupKey", null)) }) !== 1 && j("World group binding lost its phase CAS"), u.set(Y(n.member.origin), Z({
|
|
1043
|
+
...n.row,
|
|
1044
|
+
...a
|
|
1045
|
+
}));
|
|
1046
|
+
}
|
|
1047
|
+
return Object.freeze(t.members.map((e) => u.get(Y(e.origin))));
|
|
1048
|
+
});
|
|
1049
|
+
});
|
|
1050
|
+
});
|
|
1051
|
+
}, ot = (e) => {
|
|
1052
|
+
let t;
|
|
1053
|
+
try {
|
|
1054
|
+
R || j("World transition groups are not configured"), P(e, [
|
|
1055
|
+
"members",
|
|
1056
|
+
"phase",
|
|
1057
|
+
"failure"
|
|
1058
|
+
]), (!["failed", "rolledBack"].includes(e.phase) || e.phase === "failed" != (e.failure !== void 0) || !Array.isArray(e.members) || e.members.length < 1 || e.members.length > R.maxRows || Reflect.ownKeys(e.members).length !== e.members.length + 1) && j("Invalid World group cancellation");
|
|
1059
|
+
let n = /* @__PURE__ */ new Set(), r = [];
|
|
1060
|
+
for (let t = 0; t < e.members.length; t++) {
|
|
1061
|
+
let i = Object.getOwnPropertyDescriptor(e.members, t);
|
|
1062
|
+
i && "value" in i || j("World group cancellation requires own member values");
|
|
1063
|
+
let a = i.value;
|
|
1064
|
+
P(a, ["origin", "expectedRevision"]);
|
|
1065
|
+
let o = q(a.origin), s = Y(o);
|
|
1066
|
+
(n.has(s) || r.length && o.tenantId !== r[0].origin.tenantId) && j("World group cancellation requires unique one-tenant members"), n.add(s), r.push(Object.freeze({
|
|
1067
|
+
origin: o,
|
|
1068
|
+
expectedRevision: N(a.expectedRevision)
|
|
1069
|
+
}));
|
|
1070
|
+
}
|
|
1071
|
+
t = Object.freeze({
|
|
1072
|
+
phase: e.phase,
|
|
1073
|
+
members: Object.freeze(r),
|
|
1074
|
+
...e.failure === void 0 ? {} : { failure: M(e.failure, 120) }
|
|
1075
|
+
});
|
|
1076
|
+
} catch {
|
|
1077
|
+
return D.fail(new n({ detail: "Invalid or unconfigured World group cancellation" }));
|
|
1078
|
+
}
|
|
1079
|
+
return D.gen(function* () {
|
|
1080
|
+
for (let e of t.members) yield* $("advance", {
|
|
1081
|
+
...e,
|
|
1082
|
+
phase: t.phase,
|
|
1083
|
+
...t.failure === void 0 ? {} : { failure: t.failure }
|
|
1084
|
+
}, () => D.void);
|
|
1085
|
+
return yield* I(async () => {
|
|
1086
|
+
let e = async (e, n = !1) => {
|
|
1087
|
+
let r = [];
|
|
1088
|
+
for (let i of t.members) {
|
|
1089
|
+
let t = await Q(e, i.origin, n);
|
|
1090
|
+
t.length !== 1 && j("World group cancellation requires every durable member"), r.push({
|
|
1091
|
+
member: i,
|
|
1092
|
+
row: t[0],
|
|
1093
|
+
record: Z(t[0])
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
return new Set(r.map((e) => e.record.entityId)).size !== r.length && j("World group cancellation entities must be distinct"), r;
|
|
1097
|
+
}, n = (e) => e.every(({ member: e, record: n }) => n.phase === t.phase && n.revision === e.expectedRevision + 1 && (t.phase !== "failed" || n.failure === t.failure) || t.phase === "failed" && n.phase === "rolledBack" && n.revision === e.expectedRevision + 2 && n.failure === t.failure), r = await e(v), i = S(r.map((e) => e.record));
|
|
1098
|
+
i === void 0 && j("World cancellation requires a durable complete group fence");
|
|
1099
|
+
let a = await D.runPromise(D.result(Qe(t.phase === "failed" ? "fail" : "rollback", i)));
|
|
1100
|
+
if (Se.isFailure(a)) throw a.failure;
|
|
1101
|
+
if (n(r)) return Object.freeze(r.map((e) => e.record));
|
|
1102
|
+
let o = [], s = await v.transactional(async (e) => {
|
|
1103
|
+
o = [];
|
|
1104
|
+
let a = [...r].sort((e, t) => e.record.entityId < t.record.entityId ? -1 : 1), s = /* @__PURE__ */ new Map();
|
|
1105
|
+
for (let t of a) {
|
|
1106
|
+
let n = await F(e, {
|
|
1107
|
+
tenantId: t.record.origin.tenantId,
|
|
1108
|
+
entityId: t.record.entityId
|
|
1109
|
+
}, !0);
|
|
1110
|
+
n.length !== 1 && j("World group cancellation lost an entity"), s.set(t.record.entityId, n[0]);
|
|
1111
|
+
}
|
|
1112
|
+
let c = [];
|
|
1113
|
+
for (let t of a) {
|
|
1114
|
+
let n = await Q(e, t.member.origin, !0);
|
|
1115
|
+
n.length !== 1 && j("World group cancellation lost a transition");
|
|
1116
|
+
let r = Z(n[0]);
|
|
1117
|
+
r.id !== t.record.id && j("World group cancellation identity changed"), c.push({
|
|
1118
|
+
member: t.member,
|
|
1119
|
+
row: n[0],
|
|
1120
|
+
record: r
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
let l = S(c.map((e) => e.record));
|
|
1124
|
+
if (J(l ?? null) !== J(i) && j("World group cancellation fence changed under locks"), n(c)) {
|
|
1125
|
+
let e = new Map(c.map((e) => [Y(e.member.origin), e.record]));
|
|
1126
|
+
return Object.freeze(t.members.map((t) => e.get(Y(t.origin))));
|
|
1127
|
+
}
|
|
1128
|
+
let u = B();
|
|
1129
|
+
for (let { member: e, record: n } of c) {
|
|
1130
|
+
let r = s.get(n.entityId), i = H(r);
|
|
1131
|
+
(n.revision !== e.expectedRevision || n.revision > 2147483647 - (t.phase === "failed" ? 2 : 1) || t.phase === "failed" && [
|
|
1132
|
+
"committed",
|
|
1133
|
+
"settled",
|
|
1134
|
+
"failed",
|
|
1135
|
+
"rolledBack"
|
|
1136
|
+
].includes(n.phase) || t.phase === "rolledBack" && n.phase !== "failed" || u < n.updatedAt || r.activeTransitionId !== n.id || i.revision !== n.entityRevision || !W(i, V(n.source)) || i.subject?.id !== n.subject?.id || i.subject?.kind !== n.subject?.kind) && j("World group cancellation lost its original source/phase fence");
|
|
1137
|
+
}
|
|
1138
|
+
let d = /* @__PURE__ */ new Map();
|
|
1139
|
+
for (let { record: n, row: r } of c) {
|
|
1140
|
+
let i = n.entityRevision, a = u;
|
|
1141
|
+
if (t.phase === "rolledBack" && n.actorFinalSnapshot) {
|
|
1142
|
+
let t = await He(e, "persist", K("persist", {
|
|
1143
|
+
tenantId: n.origin.tenantId,
|
|
1144
|
+
entityId: n.entityId,
|
|
1145
|
+
expectedRevision: i,
|
|
1146
|
+
source: n.source,
|
|
1147
|
+
data: n.actorFinalSnapshot.data
|
|
1148
|
+
}), void 0, n.id);
|
|
1149
|
+
i = t.revision, a = t.updatedAt, a < u && j("World group rollback clock moved backwards");
|
|
1150
|
+
}
|
|
1151
|
+
t.phase === "rolledBack" && await e.updateMany("_voltro_world_entities", { activeTransitionId: null }, { where: C(ke({
|
|
1152
|
+
tenantId: n.origin.tenantId,
|
|
1153
|
+
entityId: n.entityId
|
|
1154
|
+
}), w("activeTransitionId", n.id), w("revision", i)) }) !== 1 && j("World group rollback lost its active entity fence"), t.phase === "rolledBack" && await Xe(e, n, !1);
|
|
1155
|
+
let o = {
|
|
1156
|
+
phase: t.phase,
|
|
1157
|
+
revision: n.revision + 1,
|
|
1158
|
+
entityRevision: i,
|
|
1159
|
+
failure: t.phase === "failed" ? t.failure : n.failure,
|
|
1160
|
+
updatedAt: new Date(a)
|
|
1161
|
+
};
|
|
1162
|
+
await e.updateMany("_voltro_world_transitions", o, { where: C(w("id", n.id), w("tenantId", n.origin.tenantId), w("phase", n.phase), w("revision", n.revision)) }) !== 1 && j("World group cancellation lost its phase CAS"), d.set(Y(n.origin), Z({
|
|
1163
|
+
...r,
|
|
1164
|
+
...o
|
|
1165
|
+
}));
|
|
1166
|
+
}
|
|
1167
|
+
return o = Object.freeze(t.members.map((e) => d.get(Y(e.origin)))), o;
|
|
1168
|
+
});
|
|
1169
|
+
for (let e of o) ge.observe(e);
|
|
1170
|
+
return s;
|
|
1171
|
+
});
|
|
1172
|
+
});
|
|
1173
|
+
}, st = (e) => {
|
|
1174
|
+
let i, a, s, c;
|
|
1175
|
+
try {
|
|
1176
|
+
P(e, [
|
|
1177
|
+
"tenantId",
|
|
1178
|
+
"entityId",
|
|
1179
|
+
"expectedRevision",
|
|
1180
|
+
"source",
|
|
1181
|
+
"target",
|
|
1182
|
+
"data",
|
|
1183
|
+
"sourceData",
|
|
1184
|
+
"origin",
|
|
1185
|
+
"mode",
|
|
1186
|
+
"intent",
|
|
1187
|
+
"expectedSubject"
|
|
1188
|
+
]), e.mode !== "portal" && e.mode !== "seamless" && j("Invalid World transition mode"), a = K("transfer", {
|
|
1189
|
+
tenantId: e.tenantId,
|
|
1190
|
+
entityId: e.entityId,
|
|
1191
|
+
expectedRevision: e.expectedRevision,
|
|
1192
|
+
source: e.source,
|
|
1193
|
+
target: e.target,
|
|
1194
|
+
data: e.data
|
|
1195
|
+
});
|
|
1196
|
+
let t = q(e.origin);
|
|
1197
|
+
(t.tenantId !== a.captured.tenantId || t.roomId !== a.source.roomId) && j("World transition escaped actual source origin"), i = Object.freeze({
|
|
1198
|
+
...a.captured,
|
|
1199
|
+
target: X(a.target),
|
|
1200
|
+
source: X(a.source),
|
|
1201
|
+
sourceData: r(e.sourceData, E),
|
|
1202
|
+
origin: t,
|
|
1203
|
+
mode: e.mode,
|
|
1204
|
+
intent: r(o(e.intent), 4096)
|
|
1205
|
+
}), (i.intent.entityId !== i.entityId || i.intent.options.mode === "portal" && i.mode !== "portal") && j("World transition intention contradicts resolved work"), s = J(i), e.expectedSubject !== void 0 && (c = Oe(e.expectedSubject) ?? j("World ownership precondition requires an actual Subject"), i = Object.freeze({
|
|
1206
|
+
...i,
|
|
1207
|
+
expectedSubject: c
|
|
1208
|
+
}));
|
|
1209
|
+
} catch (e) {
|
|
1210
|
+
throw e instanceof t ? e : new n({ detail: "Invalid World transition creation" });
|
|
1211
|
+
}
|
|
1212
|
+
let u = async (e, t) => {
|
|
1213
|
+
let n = await Q(e, i.origin, t);
|
|
1214
|
+
if (!n.length) return null;
|
|
1215
|
+
(n.length !== 1 || n[0].requestDigest !== s) && j("World transition request conflicts with its retained receipt");
|
|
1216
|
+
let r = Z(n[0]);
|
|
1217
|
+
return c && (r.subject?.id !== c.id || r.subject?.kind !== c.kind) && j("World transition receipt belongs to another Subject"), r;
|
|
1218
|
+
};
|
|
1219
|
+
return Object.freeze({
|
|
1220
|
+
captured: i,
|
|
1221
|
+
work: a,
|
|
1222
|
+
replay: u,
|
|
1223
|
+
insert: async (e, t) => {
|
|
1224
|
+
let n = await u(e, !0);
|
|
1225
|
+
if (n !== null) return n;
|
|
1226
|
+
t.length !== 1 && j("World transition requires one durable source entity");
|
|
1227
|
+
let r = H(t[0]), o = B();
|
|
1228
|
+
c && (r.subject?.id !== c.id || r.subject?.kind !== c.kind) && j("World transition source belongs to another Subject"), (r.revision !== i.expectedRevision || !W(r, a.source) || t[0].activeTransitionId !== null || r.revision > 2147483647 - (i.mode === "portal" ? 2 : 1) || o < r.updatedAt) && j("World transition lost its source, revision budget or is already active");
|
|
1229
|
+
let d = t[0].transitionedAt === null ? null : Ye(t[0].transitionedAt);
|
|
1230
|
+
d !== null && (d > o || o - d < z(a.source.worldId).transitionCooldownMs) && j("World transition cooldown refused admission");
|
|
1231
|
+
let f = pe({
|
|
1232
|
+
kind: "typeid",
|
|
1233
|
+
prefix: "wtran"
|
|
1234
|
+
}, l), p = {
|
|
1235
|
+
id: f,
|
|
1236
|
+
tenantId: i.tenantId,
|
|
1237
|
+
entityId: i.entityId,
|
|
1238
|
+
subjectId: r.subject?.id ?? null,
|
|
1239
|
+
subjectKind: r.subject?.kind ?? null,
|
|
1240
|
+
sourceRoomId: i.origin.roomId,
|
|
1241
|
+
sourceWorldId: i.source.worldId,
|
|
1242
|
+
targetWorldId: i.target.worldId,
|
|
1243
|
+
requestId: i.origin.requestId,
|
|
1244
|
+
requestKey: Y(i.origin),
|
|
1245
|
+
requestDigest: s,
|
|
1246
|
+
groupKey: null,
|
|
1247
|
+
groupReceipt: null,
|
|
1248
|
+
groupCommandKey: null,
|
|
1249
|
+
groupCommandReceipt: null,
|
|
1250
|
+
groupProceedReceipt: null,
|
|
1251
|
+
readySession: null,
|
|
1252
|
+
readyAt: null,
|
|
1253
|
+
actorSnapshot: null,
|
|
1254
|
+
actorSnapshotRevision: null,
|
|
1255
|
+
actorFinalSnapshot: null,
|
|
1256
|
+
actorDepartureRevision: null,
|
|
1257
|
+
groupDriveAcknowledgedAt: null,
|
|
1258
|
+
mode: i.mode,
|
|
1259
|
+
phase: "requested",
|
|
1260
|
+
revision: 1,
|
|
1261
|
+
requestedRevision: r.revision,
|
|
1262
|
+
entityRevision: r.revision,
|
|
1263
|
+
intent: i.intent,
|
|
1264
|
+
source: i.source,
|
|
1265
|
+
target: i.target,
|
|
1266
|
+
sourceData: i.sourceData,
|
|
1267
|
+
data: i.data,
|
|
1268
|
+
result: null,
|
|
1269
|
+
failure: null,
|
|
1270
|
+
createdAt: new Date(o),
|
|
1271
|
+
updatedAt: new Date(o),
|
|
1272
|
+
committedAt: null
|
|
1273
|
+
}, m = Z(p);
|
|
1274
|
+
return await e.updateMany("_voltro_world_entities", {
|
|
1275
|
+
activeTransitionId: f,
|
|
1276
|
+
transitionRecordedAt: new Date(o)
|
|
1277
|
+
}, { where: C(ke(i), w("revision", r.revision), w("activeTransitionId", null)) }) !== 1 && j("World transition lost its active entity fence"), await e.insert(l, p), m;
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
}, ct = (e) => {
|
|
1281
|
+
let r;
|
|
1282
|
+
try {
|
|
1283
|
+
r = st(e);
|
|
1284
|
+
} catch (e) {
|
|
1285
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World transition creation" }));
|
|
1286
|
+
}
|
|
1287
|
+
return $("begin", r.captured, () => D.gen(function* () {
|
|
1288
|
+
let e = yield* I(() => r.replay(v, !1));
|
|
1289
|
+
return e === null ? yield* I(() => v.transactional(async (e) => (await U(e, r.captured.tenantId, [r.work.source]), r.insert(e, await F(e, r.captured, !0))))) : e;
|
|
1290
|
+
}));
|
|
1291
|
+
}, lt = async (e, t, n = !1) => {
|
|
1292
|
+
R || j("World group command observation requires a group budget");
|
|
1293
|
+
let r = re({ origin: t }), i = await e.query({
|
|
1294
|
+
table: l,
|
|
1295
|
+
predicate: C(w("tenantId", t.tenantId), w("groupCommandKey", r)),
|
|
1296
|
+
order: [{
|
|
1297
|
+
column: "id",
|
|
1298
|
+
direction: "asc"
|
|
1299
|
+
}],
|
|
1300
|
+
take: R.maxRows + 1,
|
|
1301
|
+
skip: void 0,
|
|
1302
|
+
projection: void 0,
|
|
1303
|
+
...n ? { lock: "update" } : {}
|
|
1304
|
+
});
|
|
1305
|
+
if (!i.length) return null;
|
|
1306
|
+
i.length > R.maxRows && j("World group command exceeds its complete inventory budget");
|
|
1307
|
+
let a = i.map(Z), o = S(a), s = a[0].groupCommand;
|
|
1308
|
+
return o && s && J(s.origin) === J(t) && !a.some((e) => !e.groupCommand || J(e.groupCommand) !== J(s)) || j("World group command receipt or membership is incomplete"), Object.freeze({
|
|
1309
|
+
command: s,
|
|
1310
|
+
records: Object.freeze([...a].sort((e, t) => e.group.ordinal - t.group.ordinal))
|
|
1311
|
+
});
|
|
1312
|
+
}, ut = (e) => {
|
|
1313
|
+
let t;
|
|
1314
|
+
try {
|
|
1315
|
+
t = q(e);
|
|
1316
|
+
} catch {
|
|
1317
|
+
return D.fail(new n({ detail: "Invalid World group command origin" }));
|
|
1318
|
+
}
|
|
1319
|
+
return $("observe", t, () => D.gen(function* () {
|
|
1320
|
+
let e = yield* I(() => lt(v, t));
|
|
1321
|
+
if (e) for (let t of e.records) yield* $("observe", t.origin, () => D.void);
|
|
1322
|
+
return e;
|
|
1323
|
+
}));
|
|
1324
|
+
}, dt = (e) => {
|
|
1325
|
+
let i;
|
|
1326
|
+
try {
|
|
1327
|
+
P(e, [
|
|
1328
|
+
"tenantId",
|
|
1329
|
+
"roomId",
|
|
1330
|
+
"hostId",
|
|
1331
|
+
"epoch",
|
|
1332
|
+
"worldId",
|
|
1333
|
+
"maxRows",
|
|
1334
|
+
"maxBytes"
|
|
1335
|
+
]), (!Number.isSafeInteger(e.maxRows) || e.maxRows < 1 || e.maxRows > 4095 || !Number.isSafeInteger(e.maxBytes) || e.maxBytes < 1 || e.maxBytes > 16777216) && j("World source inventory requires explicit row/byte bounds"), i = Object.freeze({
|
|
1336
|
+
tenantId: M(e.tenantId),
|
|
1337
|
+
roomId: M(e.roomId),
|
|
1338
|
+
hostId: M(e.hostId),
|
|
1339
|
+
epoch: N(e.epoch),
|
|
1340
|
+
worldId: M(e.worldId),
|
|
1341
|
+
maxRows: e.maxRows,
|
|
1342
|
+
maxBytes: e.maxBytes
|
|
1343
|
+
}), z(i.worldId);
|
|
1344
|
+
} catch {
|
|
1345
|
+
return D.fail(new n({ detail: "Invalid World source transition inventory" }));
|
|
1346
|
+
}
|
|
1347
|
+
return $("scanSourceTransitions", i, () => D.gen(function* () {
|
|
1348
|
+
let e = yield* I(() => v.transactional(async (e) => {
|
|
1349
|
+
let n = await e.query({
|
|
1350
|
+
table: s,
|
|
1351
|
+
predicate: C(w("id", i.roomId), w("tenantId", i.tenantId)),
|
|
1352
|
+
order: [],
|
|
1353
|
+
take: 2,
|
|
1354
|
+
skip: void 0,
|
|
1355
|
+
projection: [
|
|
1356
|
+
"hostId",
|
|
1357
|
+
"epoch",
|
|
1358
|
+
"state",
|
|
1359
|
+
"erasure",
|
|
1360
|
+
"snapshotErasure"
|
|
1361
|
+
],
|
|
1362
|
+
lock: "update"
|
|
1363
|
+
});
|
|
1364
|
+
(n.length !== 1 || n[0].hostId !== i.hostId || n[0].epoch !== i.epoch || n[0].state !== "live" || n[0].erasure != null || n[0].snapshotErasure != null) && j("World source inventory lost its live Room owner");
|
|
1365
|
+
let a = await e.query({
|
|
1366
|
+
table: l,
|
|
1367
|
+
predicate: C(w("tenantId", i.tenantId), w("sourceRoomId", i.roomId), w("sourceWorldId", i.worldId), ye("phase", "settled"), ye("phase", "rolledBack")),
|
|
1368
|
+
order: [{
|
|
1369
|
+
column: "id",
|
|
1370
|
+
direction: "asc"
|
|
1371
|
+
}],
|
|
1372
|
+
take: i.maxRows + 1,
|
|
1373
|
+
skip: void 0,
|
|
1374
|
+
projection: void 0
|
|
1375
|
+
});
|
|
1376
|
+
if (a.length > i.maxRows) throw new t({
|
|
1377
|
+
budget: "worldSourceTransitions",
|
|
1378
|
+
limit: i.maxRows
|
|
1379
|
+
});
|
|
1380
|
+
let o = a.map((e) => Z(e));
|
|
1381
|
+
return o.some((e) => e.source.epoch !== i.epoch || e.source.roomId !== i.roomId || e.source.worldId !== i.worldId) && j("World source inventory requires completed prior-epoch recovery"), r(o, i.maxBytes);
|
|
1382
|
+
}));
|
|
1383
|
+
for (let t of e) yield* $("observe", t.origin, () => D.void);
|
|
1384
|
+
return e;
|
|
1385
|
+
}));
|
|
1386
|
+
}, ft = (e) => {
|
|
1387
|
+
let t;
|
|
1388
|
+
try {
|
|
1389
|
+
P(e, [
|
|
1390
|
+
"tenantId",
|
|
1391
|
+
"after",
|
|
1392
|
+
"limit"
|
|
1393
|
+
]), (!R || !Number.isSafeInteger(e.limit) || e.limit < 1 || e.limit > A || e.after !== void 0 && !/^[a-f0-9]{64}$/.test(e.after)) && j("World command scan requires bounded tenant cursor"), t = Object.freeze({
|
|
1394
|
+
tenantId: M(e.tenantId),
|
|
1395
|
+
limit: e.limit,
|
|
1396
|
+
...e.after === void 0 ? {} : { after: e.after }
|
|
1397
|
+
});
|
|
1398
|
+
} catch {
|
|
1399
|
+
return D.fail(new n({ detail: "Invalid World group command scan" }));
|
|
1400
|
+
}
|
|
1401
|
+
return $("scanGroupCommands", t, () => D.gen(function* () {
|
|
1402
|
+
let e = yield* I(async () => {
|
|
1403
|
+
let e = await v.query({
|
|
1404
|
+
table: l,
|
|
1405
|
+
predicate: C(w("tenantId", t.tenantId), ye("groupCommandKey", null), w("groupDriveAcknowledgedAt", null), ...t.after === void 0 ? [] : [me("groupCommandKey", t.after)]),
|
|
1406
|
+
order: [{
|
|
1407
|
+
column: "groupCommandKey",
|
|
1408
|
+
direction: "asc"
|
|
1409
|
+
}, {
|
|
1410
|
+
column: "id",
|
|
1411
|
+
direction: "asc"
|
|
1412
|
+
}],
|
|
1413
|
+
take: t.limit + 1,
|
|
1414
|
+
skip: void 0,
|
|
1415
|
+
projection: void 0
|
|
1416
|
+
}), n = e.slice(0, t.limit), r = [], i = /* @__PURE__ */ new Set();
|
|
1417
|
+
for (let e of n) {
|
|
1418
|
+
let t = Z(e).groupCommand;
|
|
1419
|
+
t || j("World command scan found incomplete original metadata");
|
|
1420
|
+
let n = re(t);
|
|
1421
|
+
if (e.groupCommandKey !== n && j("World command scan lost its immutable key"), i.has(n)) continue;
|
|
1422
|
+
i.add(n);
|
|
1423
|
+
let a = await lt(v, t.origin);
|
|
1424
|
+
a || j("World command scan lost complete original membership"), !a.records.every((e) => e.groupDriveAcknowledgedAt !== void 0) && (a.records.some((e) => e.groupDriveAcknowledgedAt !== void 0) && j("World group completion receipt is partial"), r.push(a));
|
|
1425
|
+
}
|
|
1426
|
+
let a = n.at(-1);
|
|
1427
|
+
return Object.freeze({
|
|
1428
|
+
groups: Object.freeze(r),
|
|
1429
|
+
nextCursor: e.length > t.limit && a ? String(a.groupCommandKey) : null
|
|
1430
|
+
});
|
|
1431
|
+
});
|
|
1432
|
+
for (let t of e.groups) for (let e of t.records) yield* $("observe", e.origin, () => D.void);
|
|
1433
|
+
return e;
|
|
1434
|
+
}));
|
|
1435
|
+
}, pt = (e) => {
|
|
1436
|
+
let t;
|
|
1437
|
+
try {
|
|
1438
|
+
P(e, ["origin", "members"]), (!R || !Array.isArray(e.members) || !e.members.length || e.members.length > R.maxRows) && j("World group driving acknowledgment requires complete bounded membership"), t = Object.freeze({
|
|
1439
|
+
origin: q(e.origin),
|
|
1440
|
+
members: Object.freeze(e.members.map((e) => (P(e, ["origin", "expectedRevision"]), Object.freeze({
|
|
1441
|
+
origin: q(e.origin),
|
|
1442
|
+
expectedRevision: N(e.expectedRevision)
|
|
1443
|
+
}))))
|
|
1444
|
+
});
|
|
1445
|
+
} catch {
|
|
1446
|
+
return D.fail(new n({ detail: "Invalid World group driving acknowledgment" }));
|
|
1447
|
+
}
|
|
1448
|
+
return $("acknowledgeGroupCommand", t, () => D.gen(function* () {
|
|
1449
|
+
let e = yield* I(() => lt(v, t.origin));
|
|
1450
|
+
if (!e) return j("World group driving acknowledgment lost its original command");
|
|
1451
|
+
let n = yield* I(() => nt(v, e.records[0]));
|
|
1452
|
+
return yield* Qe("completeCommand", n), yield* I(() => v.transactional(async (e) => {
|
|
1453
|
+
let n = await lt(e, t.origin, !0);
|
|
1454
|
+
n && n.records.length === t.members.length && new Set(t.members.map((e) => Y(e.origin))).size === t.members.length && n.records.every((e) => t.members.some((t) => Y(t.origin) === Y(e.origin) && t.expectedRevision === e.revision)) && (n.records.every((e) => e.phase === "settled") || n.records.every((e) => e.phase === "rolledBack")) || j("World group driving acknowledgment requires the exact complete terminal group");
|
|
1455
|
+
let r = n.records[0].groupDriveAcknowledgedAt;
|
|
1456
|
+
if (r !== void 0) return n.records.every((e) => e.groupDriveAcknowledgedAt === r) || j("World group driving acknowledgment is partial"), n;
|
|
1457
|
+
n.records.some((e) => e.groupDriveAcknowledgedAt !== void 0) && j("World group driving acknowledgment is partial");
|
|
1458
|
+
let i = B();
|
|
1459
|
+
for (let r of n.records) i < r.updatedAt && j("World group driving acknowledgment clock regressed"), await e.updateMany("_voltro_world_transitions", { groupDriveAcknowledgedAt: new Date(i) }, { where: C(w("id", r.id), w("tenantId", t.origin.tenantId), w("revision", r.revision), w("phase", r.phase), w("groupDriveAcknowledgedAt", null)) }) !== 1 && j("World group driving acknowledgment lost its terminal CAS");
|
|
1460
|
+
return await lt(e, t.origin) ?? j("World group driving acknowledgment lost its command");
|
|
1461
|
+
}));
|
|
1462
|
+
}));
|
|
1463
|
+
}, mt = (e) => {
|
|
1464
|
+
if (!e.some((e) => e.groupProceed)) return;
|
|
1465
|
+
let t = S(e), n = e[0]?.groupCommand, r = e[0]?.groupProceed?.at;
|
|
1466
|
+
return t && n && r !== void 0 && !e.some((e) => e.groupProceed?.at !== r || !e.groupCommand || J(e.groupCommand) !== J(n)) || j("World deferred readiness requires the complete original decision"), Object.freeze({
|
|
1467
|
+
command: n,
|
|
1468
|
+
records: Object.freeze([...e])
|
|
1469
|
+
});
|
|
1470
|
+
}, ht = (e) => D.suspend(() => {
|
|
1471
|
+
if (!R?.proceed) return D.fail(new n({ detail: "World proceed policy is not explicitly configured" }));
|
|
1472
|
+
try {
|
|
1473
|
+
let t = R.proceed.authorize(e);
|
|
1474
|
+
return D.isEffect(t) ? t : D.fail(new n({ detail: "World proceed policy requires an Effect" }));
|
|
1475
|
+
} catch {
|
|
1476
|
+
return D.fail(new n({ detail: "World proceed policy refused admission" }));
|
|
1477
|
+
}
|
|
1478
|
+
}), gt = async (e, t, n, r) => {
|
|
1479
|
+
let i = le(t, !0);
|
|
1480
|
+
for (let r of t) {
|
|
1481
|
+
r.groupProceed && n < r.groupProceed.at && j("World proceed clock moved behind its durable decision");
|
|
1482
|
+
let t = await e.query({
|
|
1483
|
+
table: s,
|
|
1484
|
+
predicate: C(w("tenantId", i.tenantId), w("id", r.target.roomId)),
|
|
1485
|
+
order: [],
|
|
1486
|
+
take: 2,
|
|
1487
|
+
skip: void 0,
|
|
1488
|
+
projection: [
|
|
1489
|
+
"epoch",
|
|
1490
|
+
"state",
|
|
1491
|
+
"erasure",
|
|
1492
|
+
"snapshotErasure"
|
|
1493
|
+
]
|
|
1494
|
+
});
|
|
1495
|
+
(t.length !== 1 || t[0].epoch !== r.target.epoch || t[0].state !== "live" || t[0].erasure != null || t[0].snapshotErasure != null) && j("World proceed target Room is no longer current");
|
|
1496
|
+
}
|
|
1497
|
+
for (let a = 0; a < i.seats.length; a++) {
|
|
1498
|
+
let o = i.seats[a], s = t.find((e) => e.subject?.id === o.subjectId), l = ae(i.tenantId, i.requestId, a), u = await e.query({
|
|
1499
|
+
table: c,
|
|
1500
|
+
predicate: C(w("tenantId", i.tenantId), w("sessionId", l)),
|
|
1501
|
+
order: [],
|
|
1502
|
+
take: 2,
|
|
1503
|
+
skip: void 0,
|
|
1504
|
+
projection: void 0,
|
|
1505
|
+
...r ? { lock: "update" } : {}
|
|
1506
|
+
});
|
|
1507
|
+
u.length !== 1 && j("World proceed requires every actual capacity Seat");
|
|
1508
|
+
let d = u[0];
|
|
1509
|
+
x(d, i, a), (d.epoch !== s.target.epoch || d.worldSourceTransitionId != null || (d.state === "reserved" ? Ye(d.expiresAt) <= n : d.state === "grace" ? d.graceUntil == null || Ye(d.graceUntil) <= n : d.state !== "connected")) && j("World proceed lost actual current target capacity");
|
|
1510
|
+
}
|
|
1511
|
+
}, _t = (e) => {
|
|
1512
|
+
let t;
|
|
1513
|
+
try {
|
|
1514
|
+
t = q(e);
|
|
1515
|
+
} catch {
|
|
1516
|
+
return D.fail(new n({ detail: "Invalid World proceed command origin" }));
|
|
1517
|
+
}
|
|
1518
|
+
let r = (e) => {
|
|
1519
|
+
if (!e.records.some((e) => e.groupProceed)) return !1;
|
|
1520
|
+
let t = e.records[0].groupProceed?.at;
|
|
1521
|
+
return (t === void 0 || e.records.some((e) => e.groupProceed?.at !== t)) && j("World proceed decision is incomplete"), !0;
|
|
1522
|
+
};
|
|
1523
|
+
return $("observe", t, () => D.gen(function* () {
|
|
1524
|
+
let e = yield* I(() => lt(v, t));
|
|
1525
|
+
if (!e || e.command.intent.onTimeout !== "proceed" || e.records.some((e) => !e.group?.requiresReadiness)) return yield* D.fail(new n({ detail: "World command does not permit deferred group readiness" }));
|
|
1526
|
+
yield* ht(e);
|
|
1527
|
+
for (let t of e.records) yield* $("observe", t.origin, () => D.void);
|
|
1528
|
+
return r(e) ? e : yield* I(() => v.transactional(async (n) => {
|
|
1529
|
+
await U(n, t.tenantId, e.records.flatMap((e) => [V(e.source), V(e.target)]));
|
|
1530
|
+
let i = [...e.records].sort((e, t) => e.entityId < t.entityId ? -1 : 1), a = /* @__PURE__ */ new Map();
|
|
1531
|
+
for (let e of i) {
|
|
1532
|
+
let r = await F(n, {
|
|
1533
|
+
tenantId: t.tenantId,
|
|
1534
|
+
entityId: e.entityId
|
|
1535
|
+
}, !0);
|
|
1536
|
+
r.length !== 1 && j("World proceed lost a durable source entity"), a.set(e.entityId, r[0]);
|
|
1537
|
+
}
|
|
1538
|
+
let o = [];
|
|
1539
|
+
for (let e of i) {
|
|
1540
|
+
let t = await Q(n, e.origin, !0);
|
|
1541
|
+
t.length !== 1 && j("World proceed lost an original transition");
|
|
1542
|
+
let r = Z(t[0]);
|
|
1543
|
+
(r.id !== e.id || r.entityId !== e.entityId) && j("World proceed member identity changed"), o.push({
|
|
1544
|
+
row: t[0],
|
|
1545
|
+
record: r
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
let s = await lt(n, t);
|
|
1549
|
+
if (s && J(s.command) === J(e.command) && J(S(s.records)) === J(S(e.records)) || j("World proceed command/group changed under locks"), r(s)) return s;
|
|
1550
|
+
let c = B();
|
|
1551
|
+
c < s.command.waitUntil && j("World proceed cannot waive readiness before its original deadline");
|
|
1552
|
+
for (let { record: e } of o) {
|
|
1553
|
+
let t = a.get(e.entityId), n = H(t);
|
|
1554
|
+
(e.phase !== "switching" || e.revision >= 2147483645 || !e.actorSnapshot || c < e.updatedAt || t.activeTransitionId !== e.id || n.revision !== e.entityRevision || !W(n, V(e.source)) || n.subject?.id !== e.subject?.id || n.subject?.kind !== e.subject?.kind) && j("World proceed lost prepared source ownership");
|
|
1555
|
+
}
|
|
1556
|
+
await gt(n, o.map((e) => e.record), c, !0);
|
|
1557
|
+
for (let { record: e } of o) {
|
|
1558
|
+
let r = Object.freeze({
|
|
1559
|
+
at: c,
|
|
1560
|
+
revision: e.revision + 1,
|
|
1561
|
+
returnAnchor: e.source
|
|
1562
|
+
});
|
|
1563
|
+
await n.updateMany("_voltro_world_transitions", {
|
|
1564
|
+
groupProceedReceipt: r,
|
|
1565
|
+
revision: e.revision + 1,
|
|
1566
|
+
updatedAt: new Date(c)
|
|
1567
|
+
}, { where: C(w("id", e.id), w("tenantId", t.tenantId), w("phase", "switching"), w("revision", e.revision)) }) !== 1 && j("World proceed lost its decision CAS");
|
|
1568
|
+
}
|
|
1569
|
+
return await lt(n, t) ?? j("World proceed lost its complete durable decision");
|
|
1570
|
+
}));
|
|
1571
|
+
}));
|
|
1572
|
+
}, vt = (e) => {
|
|
1573
|
+
let r, i, a;
|
|
1574
|
+
try {
|
|
1575
|
+
P(e, [
|
|
1576
|
+
"tenantId",
|
|
1577
|
+
"requestId",
|
|
1578
|
+
"members",
|
|
1579
|
+
"command"
|
|
1580
|
+
]), a = e.command === void 0 ? void 0 : te(e.command), (!R || !Array.isArray(e.members) || !e.members.length || e.members.length > R.maxRows || Reflect.ownKeys(e.members).length !== e.members.length + 1) && j("World group begin requires bounded complete membership");
|
|
1581
|
+
let t = [];
|
|
1582
|
+
for (let n = 0; n < e.members.length; n++) {
|
|
1583
|
+
let r = Object.getOwnPropertyDescriptor(e.members, n);
|
|
1584
|
+
r && "value" in r || j("World group begin requires own member data");
|
|
1585
|
+
let i = st(r.value);
|
|
1586
|
+
i.captured.expectedSubject && i.captured.tenantId === e.tenantId || j("World group begin requires every expected Subject"), t.push(i);
|
|
1587
|
+
}
|
|
1588
|
+
new Set(t.map((e) => e.captured.entityId)).size !== t.length && j("World group begin entities must be distinct");
|
|
1589
|
+
let n = t[0].captured.target;
|
|
1590
|
+
t.some((e) => e.captured.target.worldId !== n.worldId || e.captured.target.layer !== n.layer) && j("World group begin requires one target World and layer"), i = oe({
|
|
1591
|
+
tenantId: e.tenantId,
|
|
1592
|
+
requestId: e.requestId,
|
|
1593
|
+
members: t.map((e) => ({
|
|
1594
|
+
origin: e.captured.origin,
|
|
1595
|
+
expectedRevision: 1,
|
|
1596
|
+
subject: e.captured.expectedSubject
|
|
1597
|
+
}))
|
|
1598
|
+
}, R.maxRows), a && (a.origin.tenantId !== i.tenantId || i.requestId !== ie(a) || !t.some((e) => e.captured.origin.roomId === a.origin.roomId) || t.some((e) => J({
|
|
1599
|
+
target: e.captured.intent.target,
|
|
1600
|
+
options: e.captured.intent.options
|
|
1601
|
+
}) !== J({
|
|
1602
|
+
target: a.intent.target,
|
|
1603
|
+
options: a.intent.options
|
|
1604
|
+
}))) && j("World group command escaped its original Room or member intentions"), r = Object.freeze(t.sort((e, t) => e.captured.entityId < t.captured.entityId ? -1 : 1));
|
|
1605
|
+
} catch (e) {
|
|
1606
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World group creation" }));
|
|
1607
|
+
}
|
|
1608
|
+
let o = (e) => {
|
|
1609
|
+
let t = S(e);
|
|
1610
|
+
if (t) return (J(t) !== J(i) || a && e.some((t) => J(t.groupCommand ?? null) !== J(e[0].groupCommand ?? null)) || e.some((e) => a ? !e.groupCommand || J(te({
|
|
1611
|
+
origin: e.groupCommand.origin,
|
|
1612
|
+
intent: e.groupCommand.intent
|
|
1613
|
+
})) !== J(a) : e.groupCommand !== void 0)) && j("World group begin conflicts with its original binding/command"), Object.freeze(i.members.map((t) => e.find((e) => Y(e.origin) === Y(t.origin))));
|
|
1614
|
+
};
|
|
1615
|
+
return D.gen(function* () {
|
|
1616
|
+
yield* Qe("bind", i);
|
|
1617
|
+
for (let e of r) yield* $("begin", e.captured, () => D.void);
|
|
1618
|
+
return yield* I(async () => {
|
|
1619
|
+
let e = [];
|
|
1620
|
+
for (let t of r) {
|
|
1621
|
+
let n = await t.replay(v, !1);
|
|
1622
|
+
n && e.push(n);
|
|
1623
|
+
}
|
|
1624
|
+
if (e.length) {
|
|
1625
|
+
e.length !== r.length && j("World group begin cannot adopt a partial preexisting request set");
|
|
1626
|
+
let t = o(e);
|
|
1627
|
+
if (t) return t;
|
|
1628
|
+
j("World group begin cannot adopt preexisting unbound requests");
|
|
1629
|
+
}
|
|
1630
|
+
return v.transactional(async (e) => {
|
|
1631
|
+
await U(e, i.tenantId, r.flatMap((e) => [e.work.source, e.work.target]));
|
|
1632
|
+
let t = /* @__PURE__ */ new Map();
|
|
1633
|
+
for (let n of r) t.set(n.captured.entityId, await F(e, n.captured, !0));
|
|
1634
|
+
if (a) {
|
|
1635
|
+
let t = await lt(e, a.origin);
|
|
1636
|
+
if (t) {
|
|
1637
|
+
let n = o(t.records);
|
|
1638
|
+
n || j("World group command has no complete retained binding");
|
|
1639
|
+
for (let t of r) await t.replay(e, !1) || j("World group command member receipt changed");
|
|
1640
|
+
return n;
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
let n = [];
|
|
1644
|
+
for (let i of r) n.push(await i.insert(e, t.get(i.captured.entityId)));
|
|
1645
|
+
let s = o(n);
|
|
1646
|
+
if (s) return s;
|
|
1647
|
+
let c = ce(i, R.readiness !== void 0), l = B(), u = a ? ne({
|
|
1648
|
+
...a,
|
|
1649
|
+
startedAt: l,
|
|
1650
|
+
waitUntil: l + a.intent.waitForAllMs
|
|
1651
|
+
}) : void 0, d = [];
|
|
1652
|
+
for (let t = 0; t < i.members.length; t++) {
|
|
1653
|
+
let r = i.members[t], a = n.find((e) => Y(e.origin) === Y(r.origin));
|
|
1654
|
+
(a.phase !== "requested" || a.revision !== 1 || a.subject?.id !== r.subject.id || a.subject.kind !== r.subject.kind || l < a.updatedAt) && j("World group begin lost its requested member fence");
|
|
1655
|
+
let o = c[t], s = {
|
|
1656
|
+
groupKey: o.key,
|
|
1657
|
+
groupReceipt: o,
|
|
1658
|
+
revision: 2,
|
|
1659
|
+
updatedAt: new Date(l),
|
|
1660
|
+
groupCommandKey: u ? re(u) : null,
|
|
1661
|
+
groupCommandReceipt: u ?? null
|
|
1662
|
+
};
|
|
1663
|
+
await e.updateMany("_voltro_world_transitions", s, { where: C(w("id", a.id), w("tenantId", i.tenantId), w("revision", 1), w("phase", "requested"), w("groupKey", null)) }) !== 1 && j("World group begin lost its binding CAS");
|
|
1664
|
+
let f = await Q(e, r.origin, !0);
|
|
1665
|
+
f.length !== 1 && j("World group begin lost its bound member"), d.push(Z(f[0]));
|
|
1666
|
+
}
|
|
1667
|
+
return Object.freeze(d);
|
|
1668
|
+
});
|
|
1669
|
+
});
|
|
1670
|
+
});
|
|
1671
|
+
}, yt = (t, r, i = !1, a) => {
|
|
1672
|
+
let o, c, l;
|
|
1673
|
+
try {
|
|
1674
|
+
P(t, i ? [
|
|
1675
|
+
"origin",
|
|
1676
|
+
"roomId",
|
|
1677
|
+
"hostId",
|
|
1678
|
+
"epoch",
|
|
1679
|
+
"priorEpoch",
|
|
1680
|
+
"worldRecoveryEpoch"
|
|
1681
|
+
] : r === "source" ? [
|
|
1682
|
+
"origin",
|
|
1683
|
+
"roomId",
|
|
1684
|
+
"hostId",
|
|
1685
|
+
"epoch",
|
|
1686
|
+
"operation"
|
|
1687
|
+
] : [
|
|
1688
|
+
"origin",
|
|
1689
|
+
"roomId",
|
|
1690
|
+
"hostId",
|
|
1691
|
+
"epoch"
|
|
1692
|
+
]);
|
|
1693
|
+
let e = i ? "rollback" : r === "source" ? t.operation : void 0;
|
|
1694
|
+
r === "source" && e !== "detach" && e !== "rollback" && j("Invalid World source actor operation"), i && (c = N(t.priorEpoch), (r !== "source" || t.epoch !== c + 1) && j("World source recovery requires the next claimed epoch"), l = N(t.worldRecoveryEpoch ?? c), l > c && j("World recovery baseline exceeds its prior owner")), o = Object.freeze({
|
|
1695
|
+
origin: q(t.origin),
|
|
1696
|
+
roomId: M(t.roomId),
|
|
1697
|
+
hostId: M(t.hostId),
|
|
1698
|
+
epoch: N(t.epoch),
|
|
1699
|
+
...e === void 0 ? {} : { operation: e }
|
|
1700
|
+
});
|
|
1701
|
+
} catch {
|
|
1702
|
+
return D.fail(new n({ detail: "Invalid World actor owner admission" }));
|
|
1703
|
+
}
|
|
1704
|
+
return $(i ? "actorSourceRecovery" : r === "source" ? "actorSource" : "actorTarget", i ? Object.freeze({
|
|
1705
|
+
origin: o.origin,
|
|
1706
|
+
roomId: o.roomId,
|
|
1707
|
+
hostId: o.hostId,
|
|
1708
|
+
epoch: o.epoch,
|
|
1709
|
+
priorEpoch: c,
|
|
1710
|
+
worldRecoveryEpoch: l
|
|
1711
|
+
}) : o, () => I(async () => {
|
|
1712
|
+
i && l < c && (a || j("Older World source epochs require active checkpoint adoption authority"), de(a, {
|
|
1713
|
+
tenantId: o.origin.tenantId,
|
|
1714
|
+
roomId: o.roomId,
|
|
1715
|
+
hostId: o.hostId,
|
|
1716
|
+
epoch: o.epoch,
|
|
1717
|
+
priorEpoch: c,
|
|
1718
|
+
worldRecoveryEpoch: l
|
|
1719
|
+
}));
|
|
1720
|
+
let t = await Q(v, o.origin);
|
|
1721
|
+
t.length !== 1 && j("World actor operation requires an actual transition");
|
|
1722
|
+
let n = Z(t[0]), u = n[r];
|
|
1723
|
+
return (u.roomId !== o.roomId || (i ? u.epoch < l || u.epoch > c : u.epoch !== o.epoch)) && j("World actor operation differs from its original owner epoch"), v.transactional(async (t) => {
|
|
1724
|
+
i ? await h(t, [o.roomId], o.origin.tenantId) : await U(t, o.origin.tenantId, [V(u)]);
|
|
1725
|
+
let a = await t.query({
|
|
1726
|
+
table: s,
|
|
1727
|
+
predicate: C(w("id", o.roomId), w("tenantId", o.origin.tenantId)),
|
|
1728
|
+
order: [],
|
|
1729
|
+
take: 2,
|
|
1730
|
+
skip: void 0,
|
|
1731
|
+
projection: void 0,
|
|
1732
|
+
lock: "update"
|
|
1733
|
+
});
|
|
1734
|
+
if ((a.length !== 1 || a[0].hostId !== o.hostId || a[0].epoch !== o.epoch || a[0].state !== (i ? "creating" : "live") || a[0].erasure != null || a[0].snapshotErasure != null) && j("World actor operation lost its actual admitted Host"), i) {
|
|
1735
|
+
let n = z(u.worldId), r = n.instances.some((e) => e.room === a[0].name);
|
|
1736
|
+
(r ? n.zones.some((e) => e.room === a[0].name) : n.zones.find((e) => e.id === u.zoneId)?.room !== a[0].name) && j("World source recovery Room differs from its declared placement"), (await t.query({
|
|
1737
|
+
table: "_voltro_room_hosts",
|
|
1738
|
+
predicate: w("id", o.hostId),
|
|
1739
|
+
order: [],
|
|
1740
|
+
take: 2,
|
|
1741
|
+
skip: void 0,
|
|
1742
|
+
projection: ["id"]
|
|
1743
|
+
})).length !== 1 && j("World source recovery requires its retained Host"), await g(t, n, a[0], !0);
|
|
1744
|
+
let i = await t.query({
|
|
1745
|
+
table: r ? e : _,
|
|
1746
|
+
predicate: C(w("tenantId", o.origin.tenantId), w("roomId", o.roomId)),
|
|
1747
|
+
order: [],
|
|
1748
|
+
take: 2,
|
|
1749
|
+
skip: void 0,
|
|
1750
|
+
projection: void 0,
|
|
1751
|
+
lock: "update"
|
|
1752
|
+
}), s = i[0];
|
|
1753
|
+
(i.length !== 1 || s.epoch !== u.epoch || s.worldId !== u.worldId || (r ? !n.instances.some((e) => e.id === s.instance && e.room === a[0].name) : s.zoneId !== u.zoneId || s.layer !== u.layer || s.cellId !== d(n, {
|
|
1754
|
+
zone: u.zoneId,
|
|
1755
|
+
at: u.at
|
|
1756
|
+
}).id)) && j("World source recovery differs from its durable cell epoch");
|
|
1757
|
+
}
|
|
1758
|
+
let c = await F(t, {
|
|
1759
|
+
tenantId: o.origin.tenantId,
|
|
1760
|
+
entityId: n.entityId
|
|
1761
|
+
}, !0), l = await Q(t, o.origin, !0);
|
|
1762
|
+
l.length !== 1 && j("World actor operation lost its transition");
|
|
1763
|
+
let f = Z(l[0]), p = r === "target" ? "committed" : o.operation === "rollback" ? "failed" : f.mode === "portal" ? "detaching" : "switching";
|
|
1764
|
+
(f.id !== n.id || f.phase !== p || !f.actorSnapshot && (r !== "source" || o.operation !== "rollback") || r === "target" && !f.result || c.length !== 1 || c[0].activeTransitionId !== (r === "source" ? f.id : null)) && j("World actor operation lost its phase, snapshot or active entity fence");
|
|
1765
|
+
let m = H(c[0]);
|
|
1766
|
+
return m.revision === f.entityRevision && W(m, V(f[r])) && m.subject?.id === f.subject?.id && m.subject?.kind === f.subject?.kind || j("World actor entity advanced beyond its transition receipt"), f;
|
|
1767
|
+
});
|
|
1768
|
+
}));
|
|
1769
|
+
}, bt = (e) => {
|
|
1770
|
+
let t;
|
|
1771
|
+
try {
|
|
1772
|
+
P(e, [
|
|
1773
|
+
"tenantId",
|
|
1774
|
+
"roomId",
|
|
1775
|
+
"transitionId"
|
|
1776
|
+
]), t = Object.freeze({
|
|
1777
|
+
tenantId: M(e.tenantId),
|
|
1778
|
+
roomId: M(e.roomId),
|
|
1779
|
+
transitionId: M(e.transitionId)
|
|
1780
|
+
});
|
|
1781
|
+
} catch {
|
|
1782
|
+
return D.fail(new n({ detail: "Invalid World actor receipt scope" }));
|
|
1783
|
+
}
|
|
1784
|
+
return $("actorReceipt", t, () => I(async () => {
|
|
1785
|
+
let e = await v.query({
|
|
1786
|
+
table: l,
|
|
1787
|
+
predicate: C(w("tenantId", t.tenantId), w("id", t.transitionId)),
|
|
1788
|
+
order: [],
|
|
1789
|
+
take: 2,
|
|
1790
|
+
skip: void 0,
|
|
1791
|
+
projection: void 0
|
|
1792
|
+
});
|
|
1793
|
+
if (!e.length) return null;
|
|
1794
|
+
e.length !== 1 && j("World actor receipt identity is ambiguous");
|
|
1795
|
+
let n = Z(e[0]);
|
|
1796
|
+
return n.source.roomId !== t.roomId && n.target.roomId !== t.roomId && j("World actor receipt Room is not a participant"), n;
|
|
1797
|
+
}));
|
|
1798
|
+
}, xt = (e) => {
|
|
1799
|
+
let t;
|
|
1800
|
+
try {
|
|
1801
|
+
P(e, [
|
|
1802
|
+
"origin",
|
|
1803
|
+
"roomId",
|
|
1804
|
+
"hostId",
|
|
1805
|
+
"epoch",
|
|
1806
|
+
"binding",
|
|
1807
|
+
"sessionId",
|
|
1808
|
+
"subjectId",
|
|
1809
|
+
"subjectKind",
|
|
1810
|
+
"credentialDigest"
|
|
1811
|
+
]), e.subjectKind !== void 0 && e.subjectKind !== "user" && e.subjectKind !== "guest" && j("World Seat requires an authenticated Subject kind"), t = Object.freeze({
|
|
1812
|
+
origin: q(e.origin),
|
|
1813
|
+
roomId: M(e.roomId),
|
|
1814
|
+
hostId: M(e.hostId),
|
|
1815
|
+
epoch: N(e.epoch),
|
|
1816
|
+
binding: f(e.binding),
|
|
1817
|
+
sessionId: M(e.sessionId),
|
|
1818
|
+
subjectId: M(e.subjectId),
|
|
1819
|
+
subjectKind: e.subjectKind ?? "user",
|
|
1820
|
+
credentialDigest: e.credentialDigest
|
|
1821
|
+
}), typeof t.credentialDigest == "string" && /^[a-f0-9]{64}$/.test(t.credentialDigest) && t.binding.sourceRoomId === t.origin.roomId && t.binding.requestId === t.origin.requestId || j("World Seat admission scope differs from its durable origin");
|
|
1822
|
+
} catch {
|
|
1823
|
+
return D.fail(new n({ detail: "Invalid World target Seat admission" }));
|
|
1824
|
+
}
|
|
1825
|
+
return $("actorSeat", t, () => I(async () => {
|
|
1826
|
+
let e = await Q(v, t.origin);
|
|
1827
|
+
e.length !== 1 && j("World Seat admission requires its actual transition");
|
|
1828
|
+
let n = Z(e[0]);
|
|
1829
|
+
return (n.id !== t.binding.transitionId || n.entityId !== t.binding.entityId || n.subject?.kind !== t.subjectKind || n.subject.id !== t.subjectId || n.target.roomId !== t.roomId || (n.phase === "settled" ? t.epoch < n.target.epoch : n.target.epoch !== t.epoch)) && j("World Seat admission differs from its player target"), v.transactional(async (e) => {
|
|
1830
|
+
await U(e, t.origin.tenantId, [V(n.phase === "settled" ? {
|
|
1831
|
+
...n.target,
|
|
1832
|
+
epoch: t.epoch
|
|
1833
|
+
} : n.target)]);
|
|
1834
|
+
let r = await e.query({
|
|
1835
|
+
table: s,
|
|
1836
|
+
predicate: C(w("id", t.roomId), w("tenantId", t.origin.tenantId)),
|
|
1837
|
+
order: [],
|
|
1838
|
+
take: 2,
|
|
1839
|
+
skip: void 0,
|
|
1840
|
+
projection: void 0,
|
|
1841
|
+
lock: "update"
|
|
1842
|
+
});
|
|
1843
|
+
(r.length !== 1 || r[0].hostId !== t.hostId || r[0].epoch !== t.epoch || r[0].state !== "live" || r[0].erasure != null || r[0].snapshotErasure != null) && j("World Seat admission lost its actual target Host");
|
|
1844
|
+
let i = await F(e, {
|
|
1845
|
+
tenantId: t.origin.tenantId,
|
|
1846
|
+
entityId: n.entityId
|
|
1847
|
+
}, !0), a = await Q(e, t.origin, !0);
|
|
1848
|
+
(a.length !== 1 || i.length !== 1) && j("World Seat admission lost its transition/entity");
|
|
1849
|
+
let o = Z(a[0]);
|
|
1850
|
+
(o.id !== n.id || o.entityId !== n.entityId || J(o.group ?? null) !== J(n.group ?? null) || !o.actorSnapshot || J(o.target) !== J(n.target) || J(o.source) !== J(n.source) || o.subject?.kind !== t.subjectKind || o.subject.id !== t.subjectId || [
|
|
1851
|
+
"requested",
|
|
1852
|
+
"reserving",
|
|
1853
|
+
"failed",
|
|
1854
|
+
"rolledBack"
|
|
1855
|
+
].includes(o.phase)) && j("World Seat admission has no prepared transition");
|
|
1856
|
+
let l = o.group ? await nt(e, o) : void 0, u = (l ? l.members.map((e) => e.subject.id).sort() : [t.subjectId]).indexOf(t.subjectId);
|
|
1857
|
+
(u < 0 || ae(t.origin.tenantId, ue(o), u) !== t.sessionId) && j("World Seat admission differs from its canonical batch Session");
|
|
1858
|
+
let d = o.phase === "committed" || o.phase === "settled", f = H(i[0]), m = o.phase === "settled" ? {
|
|
1859
|
+
...o.target,
|
|
1860
|
+
epoch: t.epoch
|
|
1861
|
+
} : o.target;
|
|
1862
|
+
((o.phase === "settled" ? f.revision < o.entityRevision : f.revision !== o.entityRevision) || !W(f, V(d ? m : o.source)) || f.subject?.kind !== t.subjectKind || f.subject.id !== t.subjectId || i[0].activeTransitionId !== (d ? null : o.id) || d && !o.result) && j("World Seat admission lost its authoritative entity fence");
|
|
1863
|
+
let h = await e.query({
|
|
1864
|
+
table: c,
|
|
1865
|
+
predicate: C(w("tenantId", t.origin.tenantId), w("roomId", t.roomId), w("sessionId", t.sessionId), w("subjectId", t.subjectId), w("epoch", t.epoch), w("role", "player"), w("state", "connected"), w("token", t.credentialDigest)),
|
|
1866
|
+
order: [],
|
|
1867
|
+
take: 2,
|
|
1868
|
+
skip: void 0,
|
|
1869
|
+
projection: ["reservationBatchReceipt"],
|
|
1870
|
+
lock: "update"
|
|
1871
|
+
});
|
|
1872
|
+
return (h.length !== 1 || JSON.stringify(p(h[0].reservationBatchReceipt)) !== JSON.stringify(t.binding)) && j("World Seat admission lacks its actual consumed credential and private binding"), o;
|
|
1873
|
+
});
|
|
1874
|
+
}));
|
|
1875
|
+
}, St = async (e, t, n) => {
|
|
1876
|
+
if (n.activeTransitionId == null) return;
|
|
1877
|
+
let r = await e.query({
|
|
1878
|
+
table: l,
|
|
1879
|
+
predicate: C(w("id", n.activeTransitionId), w("tenantId", t.tenantId)),
|
|
1880
|
+
order: [],
|
|
1881
|
+
take: 2,
|
|
1882
|
+
skip: void 0,
|
|
1883
|
+
projection: void 0,
|
|
1884
|
+
lock: "update"
|
|
1885
|
+
});
|
|
1886
|
+
r.length !== 1 && j("World projection transition fence has no receipt");
|
|
1887
|
+
let i = Z(r[0]);
|
|
1888
|
+
(i.entityId !== t.entityId || i.entityRevision !== t.revision || i.subject?.id !== t.subject?.id || i.subject?.kind !== t.subject?.kind || i.source.roomId !== t.roomId || i.source.epoch !== t.epoch || i.actorFinalSnapshot || i.actorDepartureRevision !== void 0 || ![
|
|
1889
|
+
"requested",
|
|
1890
|
+
"reserving",
|
|
1891
|
+
"prepared",
|
|
1892
|
+
"ghosting",
|
|
1893
|
+
"switching"
|
|
1894
|
+
].includes(i.phase) || i.mode === "portal" && i.phase === "switching") && j("World projection source departed or is compensating");
|
|
1895
|
+
}, Ct = (e) => {
|
|
1896
|
+
let t;
|
|
1897
|
+
try {
|
|
1898
|
+
P(e, [
|
|
1899
|
+
"tenantId",
|
|
1900
|
+
"entityId",
|
|
1901
|
+
"roomId",
|
|
1902
|
+
"hostId",
|
|
1903
|
+
"epoch"
|
|
1904
|
+
]), t = Object.freeze({
|
|
1905
|
+
tenantId: M(e.tenantId),
|
|
1906
|
+
entityId: M(e.entityId),
|
|
1907
|
+
roomId: M(e.roomId),
|
|
1908
|
+
hostId: M(e.hostId),
|
|
1909
|
+
epoch: N(e.epoch)
|
|
1910
|
+
});
|
|
1911
|
+
} catch {
|
|
1912
|
+
return D.fail(new n({ detail: "Invalid World actor projection admission" }));
|
|
1913
|
+
}
|
|
1914
|
+
return G("actorProjection", t, () => I(async () => {
|
|
1915
|
+
let e = await F(v, t);
|
|
1916
|
+
e.length !== 1 && j("World projection requires its actual persisted entity");
|
|
1917
|
+
let n = H(e[0]);
|
|
1918
|
+
return (n.roomId !== t.roomId || n.epoch !== t.epoch || n.returnAnchor) && j("World neighbor projection requires its actual non-instance source"), v.transactional(async (e) => {
|
|
1919
|
+
await U(e, t.tenantId, [n]);
|
|
1920
|
+
let r = await e.query({
|
|
1921
|
+
table: s,
|
|
1922
|
+
predicate: C(w("id", t.roomId), w("tenantId", t.tenantId)),
|
|
1923
|
+
order: [],
|
|
1924
|
+
take: 2,
|
|
1925
|
+
skip: void 0,
|
|
1926
|
+
projection: [
|
|
1927
|
+
"hostId",
|
|
1928
|
+
"state",
|
|
1929
|
+
"name",
|
|
1930
|
+
"epoch",
|
|
1931
|
+
"erasure",
|
|
1932
|
+
"snapshotErasure"
|
|
1933
|
+
],
|
|
1934
|
+
lock: "update"
|
|
1935
|
+
});
|
|
1936
|
+
(r.length !== 1 || r[0].hostId !== t.hostId || r[0].state !== "live" || r[0].epoch !== t.epoch || r[0].erasure != null || r[0].snapshotErasure != null || z(n.worldId).instances.some((e) => e.room === r[0].name)) && j("World projection lost its live non-instance Host");
|
|
1937
|
+
let i = await F(e, t, !0);
|
|
1938
|
+
i.length !== 1 && j("World projection lost its persisted entity");
|
|
1939
|
+
let a = H(i[0]);
|
|
1940
|
+
return a.revision === n.revision && W(a, n) || j("World projection changed ownership"), await St(e, a, i[0]), a;
|
|
1941
|
+
});
|
|
1942
|
+
}));
|
|
1943
|
+
}, wt = (e) => {
|
|
1944
|
+
let t, r, a;
|
|
1945
|
+
try {
|
|
1946
|
+
P(e, [
|
|
1947
|
+
"tenantId",
|
|
1948
|
+
"entityId",
|
|
1949
|
+
"roomId",
|
|
1950
|
+
"hostId",
|
|
1951
|
+
"epoch",
|
|
1952
|
+
"expectedRevision",
|
|
1953
|
+
"source",
|
|
1954
|
+
"target",
|
|
1955
|
+
"targetHostId"
|
|
1956
|
+
]), r = V(e.source), a = V(e.target), t = Object.freeze({
|
|
1957
|
+
tenantId: M(e.tenantId),
|
|
1958
|
+
entityId: M(e.entityId),
|
|
1959
|
+
roomId: M(e.roomId),
|
|
1960
|
+
hostId: M(e.hostId),
|
|
1961
|
+
epoch: N(e.epoch),
|
|
1962
|
+
expectedRevision: N(e.expectedRevision),
|
|
1963
|
+
source: Object.freeze({
|
|
1964
|
+
worldId: r.worldId,
|
|
1965
|
+
zoneId: r.zoneId,
|
|
1966
|
+
at: r.at,
|
|
1967
|
+
layer: r.layer,
|
|
1968
|
+
roomId: r.roomId,
|
|
1969
|
+
epoch: r.epoch
|
|
1970
|
+
}),
|
|
1971
|
+
target: Object.freeze({
|
|
1972
|
+
worldId: a.worldId,
|
|
1973
|
+
zoneId: a.zoneId,
|
|
1974
|
+
at: a.at,
|
|
1975
|
+
layer: a.layer,
|
|
1976
|
+
roomId: a.roomId,
|
|
1977
|
+
epoch: a.epoch
|
|
1978
|
+
}),
|
|
1979
|
+
targetHostId: M(e.targetHostId)
|
|
1980
|
+
}), (r.roomId !== t.roomId || r.epoch !== t.epoch || r.roomId === a.roomId || r.worldId !== a.worldId || r.layer !== a.layer) && j("Ghost neighbor crosses its source World or layer");
|
|
1981
|
+
let n = z(r.worldId), o = n.zones.find((e) => e.id === r.zoneId), s = d(n, {
|
|
1982
|
+
zone: r.zoneId,
|
|
1983
|
+
at: r.at
|
|
1984
|
+
}), c = d(n, {
|
|
1985
|
+
zone: a.zoneId,
|
|
1986
|
+
at: a.at
|
|
1987
|
+
});
|
|
1988
|
+
(r.zoneId !== a.zoneId && !o.neighbors.includes(a.zoneId) || !i(s.bounds, c.bounds)) && j("Ghost target is not an edge-adjacent declared neighbor");
|
|
1989
|
+
let l = Math.max(c.bounds[0][0] - r.at[0], 0, r.at[0] - c.bounds[1][0]), u = Math.max(c.bounds[0][1] - r.at[1], 0, r.at[1] - c.bounds[1][1]);
|
|
1990
|
+
Math.hypot(l, u) > n.handoff.ghostUnits && j("Ghost source lies outside its neighbor distance");
|
|
1991
|
+
} catch {
|
|
1992
|
+
return D.fail(new n({ detail: "Invalid World neighbor projection admission" }));
|
|
1993
|
+
}
|
|
1994
|
+
return G("actorNeighbor", t, () => I(() => v.transactional(async (e) => {
|
|
1995
|
+
await U(e, t.tenantId, [r, a]);
|
|
1996
|
+
let n = [];
|
|
1997
|
+
for (let i of [r, a]) {
|
|
1998
|
+
let r = await e.query({
|
|
1999
|
+
table: s,
|
|
2000
|
+
predicate: C(w("id", i.roomId), w("tenantId", t.tenantId)),
|
|
2001
|
+
order: [],
|
|
2002
|
+
take: 2,
|
|
2003
|
+
skip: void 0,
|
|
2004
|
+
projection: void 0,
|
|
2005
|
+
lock: "update"
|
|
2006
|
+
});
|
|
2007
|
+
(r.length !== 1 || r[0].state !== "live" || r[0].epoch !== i.epoch || r[0].erasure != null || r[0].snapshotErasure != null || z(i.worldId).instances.some((e) => e.room === r[0].name)) && j("Ghost neighbor lost a live non-instance owner"), n.push(r[0]);
|
|
2008
|
+
}
|
|
2009
|
+
(n[0].hostId !== t.hostId || n[1].hostId !== t.targetHostId || (n[0].pool ?? null) !== (n[1].pool ?? null)) && j("Ghost neighbor changed Host or pool");
|
|
2010
|
+
let i = await F(e, t, !0);
|
|
2011
|
+
i.length !== 1 && j("Ghost neighbor lost its actual source entity");
|
|
2012
|
+
let o = H(i[0]);
|
|
2013
|
+
return (o.revision !== t.expectedRevision || !W(o, r) || o.returnAnchor) && j("Ghost neighbor source revision or ownership changed"), await St(e, o, i[0]), o;
|
|
2014
|
+
})));
|
|
2015
|
+
}, Tt = (e) => {
|
|
2016
|
+
let t;
|
|
2017
|
+
try {
|
|
2018
|
+
P(e, [
|
|
2019
|
+
"tenantId",
|
|
2020
|
+
"entityId",
|
|
2021
|
+
"roomId",
|
|
2022
|
+
"hostId",
|
|
2023
|
+
"epoch",
|
|
2024
|
+
"subject"
|
|
2025
|
+
]), P(e.subject, ["id", "kind"]), ["user", "guest"].includes(e.subject.kind) || j("World player requires an authenticated Subject kind"), t = Object.freeze({
|
|
2026
|
+
tenantId: M(e.tenantId),
|
|
2027
|
+
entityId: M(e.entityId),
|
|
2028
|
+
roomId: M(e.roomId),
|
|
2029
|
+
hostId: M(e.hostId),
|
|
2030
|
+
epoch: N(e.epoch),
|
|
2031
|
+
subject: Object.freeze({
|
|
2032
|
+
id: M(e.subject.id),
|
|
2033
|
+
kind: e.subject.kind
|
|
2034
|
+
})
|
|
2035
|
+
});
|
|
2036
|
+
} catch {
|
|
2037
|
+
return D.fail(new n({ detail: "Invalid ordinary World player admission" }));
|
|
2038
|
+
}
|
|
2039
|
+
return G("actorPlayer", t, () => I(async () => {
|
|
2040
|
+
let e = await F(v, t);
|
|
2041
|
+
e.length !== 1 && j("World player requires its actual persisted entity");
|
|
2042
|
+
let n = H(e[0]);
|
|
2043
|
+
return (n.roomId !== t.roomId || n.epoch !== t.epoch) && j("World player entity belongs to another Room"), await v.transactional(async (e) => {
|
|
2044
|
+
await U(e, t.tenantId, [n]);
|
|
2045
|
+
let r = await e.query({
|
|
2046
|
+
table: s,
|
|
2047
|
+
predicate: C(w("id", t.roomId), w("tenantId", t.tenantId)),
|
|
2048
|
+
order: [],
|
|
2049
|
+
take: 2,
|
|
2050
|
+
skip: void 0,
|
|
2051
|
+
projection: [
|
|
2052
|
+
"hostId",
|
|
2053
|
+
"erasure",
|
|
2054
|
+
"snapshotErasure"
|
|
2055
|
+
],
|
|
2056
|
+
lock: "update"
|
|
2057
|
+
});
|
|
2058
|
+
(r.length !== 1 || r[0].hostId !== t.hostId || r[0].erasure != null || r[0].snapshotErasure != null) && j("World player lost its current published Host");
|
|
2059
|
+
let i = await F(e, t, !0);
|
|
2060
|
+
i.length !== 1 && j("World player lost its persisted entity");
|
|
2061
|
+
let a = H(i[0]);
|
|
2062
|
+
if (a.revision === n.revision && W(a, n) && a.subject?.id === t.subject.id && a.subject.kind === t.subject.kind || j("World player changed identity or ownership"), i[0].activeTransitionId != null) {
|
|
2063
|
+
let n = await e.query({
|
|
2064
|
+
table: l,
|
|
2065
|
+
predicate: C(w("id", i[0].activeTransitionId), w("tenantId", t.tenantId)),
|
|
2066
|
+
order: [],
|
|
2067
|
+
take: 2,
|
|
2068
|
+
skip: void 0,
|
|
2069
|
+
projection: void 0,
|
|
2070
|
+
lock: "update"
|
|
2071
|
+
});
|
|
2072
|
+
n.length !== 1 && j("World player transition fence has no complete receipt");
|
|
2073
|
+
let r = Z(n[0]);
|
|
2074
|
+
(r.entityId !== t.entityId || r.subject?.id !== t.subject.id || r.subject.kind !== t.subject.kind || r.source.roomId !== t.roomId || r.source.epoch !== t.epoch || r.actorFinalSnapshot || r.actorDepartureRevision !== void 0 || ![
|
|
2075
|
+
"requested",
|
|
2076
|
+
"reserving",
|
|
2077
|
+
"prepared",
|
|
2078
|
+
"ghosting",
|
|
2079
|
+
"switching"
|
|
2080
|
+
].includes(r.phase) || r.mode === "portal" && r.phase === "switching") && j("World player source has departed or is compensating");
|
|
2081
|
+
}
|
|
2082
|
+
return Object.freeze({
|
|
2083
|
+
entityId: a.entityId,
|
|
2084
|
+
worldId: a.worldId,
|
|
2085
|
+
zoneId: a.zoneId,
|
|
2086
|
+
cellId: a.cellId,
|
|
2087
|
+
layer: a.layer,
|
|
2088
|
+
revision: a.revision,
|
|
2089
|
+
data: a.data
|
|
2090
|
+
});
|
|
2091
|
+
});
|
|
2092
|
+
}));
|
|
2093
|
+
}, Et = (e, t) => {
|
|
2094
|
+
let r;
|
|
2095
|
+
try {
|
|
2096
|
+
P(e, [
|
|
2097
|
+
"origin",
|
|
2098
|
+
"roomId",
|
|
2099
|
+
"hostId",
|
|
2100
|
+
"epoch",
|
|
2101
|
+
"subjectId",
|
|
2102
|
+
"subjectKind"
|
|
2103
|
+
]), (typeof t != "function" || e.subjectKind !== "user" && e.subjectKind !== "guest") && j("World follower requires actual Subject/capacity scope"), r = Object.freeze({
|
|
2104
|
+
origin: q(e.origin),
|
|
2105
|
+
roomId: M(e.roomId),
|
|
2106
|
+
hostId: M(e.hostId),
|
|
2107
|
+
epoch: N(e.epoch),
|
|
2108
|
+
subjectId: M(e.subjectId),
|
|
2109
|
+
subjectKind: e.subjectKind
|
|
2110
|
+
});
|
|
2111
|
+
} catch {
|
|
2112
|
+
return D.fail(new n({ detail: "Invalid World follower admission" }));
|
|
2113
|
+
}
|
|
2114
|
+
return $("actorFollower", r, () => I(async () => {
|
|
2115
|
+
let e = await Q(v, r.origin);
|
|
2116
|
+
e.length !== 1 && j("World follower requires its original transition");
|
|
2117
|
+
let n = Z(e[0]);
|
|
2118
|
+
return (n.phase !== "settled" || !n.groupProceed || !n.groupCommand || !n.result || n.subject?.id !== r.subjectId || n.subject.kind !== r.subjectKind || n.target.roomId !== r.roomId || r.epoch < n.target.epoch) && j("World follower has no settled deferred target"), v.transactional(async (e) => {
|
|
2119
|
+
let i = V({
|
|
2120
|
+
...n.target,
|
|
2121
|
+
epoch: r.epoch
|
|
2122
|
+
});
|
|
2123
|
+
await U(e, r.origin.tenantId, [i]);
|
|
2124
|
+
let a = await e.query({
|
|
2125
|
+
table: s,
|
|
2126
|
+
predicate: C(w("id", r.roomId), w("tenantId", r.origin.tenantId)),
|
|
2127
|
+
order: [],
|
|
2128
|
+
take: 2,
|
|
2129
|
+
skip: void 0,
|
|
2130
|
+
projection: [
|
|
2131
|
+
"hostId",
|
|
2132
|
+
"epoch",
|
|
2133
|
+
"state",
|
|
2134
|
+
"erasure",
|
|
2135
|
+
"snapshotErasure"
|
|
2136
|
+
],
|
|
2137
|
+
lock: "update"
|
|
2138
|
+
});
|
|
2139
|
+
(a.length !== 1 || a[0].hostId !== r.hostId || a[0].epoch !== r.epoch || a[0].state !== "live" || a[0].erasure != null || a[0].snapshotErasure != null) && j("World follower lost its actual published target Host");
|
|
2140
|
+
let o = await F(e, {
|
|
2141
|
+
tenantId: r.origin.tenantId,
|
|
2142
|
+
entityId: n.entityId
|
|
2143
|
+
}, !0), c = await Q(e, r.origin, !0);
|
|
2144
|
+
(o.length !== 1 || c.length !== 1) && j("World follower lost original entity/transition");
|
|
2145
|
+
let l = Z(c[0]), u = H(o[0]);
|
|
2146
|
+
(l.id !== n.id || l.entityId !== n.entityId || l.phase !== "settled" || !l.groupProceed || !l.groupCommand || J(l.groupProceed) !== J(n.groupProceed) || J(l.groupCommand) !== J(n.groupCommand) || J(l.target) !== J(n.target) || l.subject?.id !== r.subjectId || l.subject.kind !== r.subjectKind || u.subject?.id !== r.subjectId || u.subject.kind !== r.subjectKind || u.revision < l.entityRevision || !W(u, i) || o[0].activeTransitionId != null) && j("World follower lost current settled entity ownership");
|
|
2147
|
+
let d = await lt(e, l.groupCommand.origin);
|
|
2148
|
+
d && mt(d.records) && d.records.some((e) => e.id === l.id) || j("World follower lost its complete original group decision");
|
|
2149
|
+
let f = await t(e, l), p = await F(e, {
|
|
2150
|
+
tenantId: r.origin.tenantId,
|
|
2151
|
+
entityId: l.entityId
|
|
2152
|
+
}, !0), m = await Q(e, r.origin, !0);
|
|
2153
|
+
return (p.length !== 1 || p[0].activeTransitionId != null || J(H(p[0])) !== J(u) || m.length !== 1 || J(Z(m[0])) !== J(l)) && j("World follower capacity work changed authoritative entity/transition data"), f;
|
|
2154
|
+
});
|
|
2155
|
+
}));
|
|
2156
|
+
}, Dt = (e) => {
|
|
2157
|
+
let t;
|
|
2158
|
+
try {
|
|
2159
|
+
P(e, [
|
|
2160
|
+
"origin",
|
|
2161
|
+
"roomId",
|
|
2162
|
+
"hostId",
|
|
2163
|
+
"epoch"
|
|
2164
|
+
]), t = Object.freeze({
|
|
2165
|
+
origin: q(e.origin),
|
|
2166
|
+
roomId: M(e.roomId),
|
|
2167
|
+
hostId: M(e.hostId),
|
|
2168
|
+
epoch: N(e.epoch)
|
|
2169
|
+
});
|
|
2170
|
+
} catch {
|
|
2171
|
+
return D.fail(new n({ detail: "Invalid World ghost admission" }));
|
|
2172
|
+
}
|
|
2173
|
+
return $("actorGhost", t, () => I(async () => {
|
|
2174
|
+
let e = await Q(v, t.origin);
|
|
2175
|
+
e.length !== 1 && j("World ghost requires an actual transition");
|
|
2176
|
+
let n = Z(e[0]);
|
|
2177
|
+
return n.mode === "seamless" && n.phase === "ghosting" && n.actorSnapshot && n.target.roomId === t.roomId && n.target.epoch === t.epoch || j("World ghost differs from its prepared seamless target"), v.transactional(async (e) => {
|
|
2178
|
+
await U(e, t.origin.tenantId, [V(n.source), V(n.target)]);
|
|
2179
|
+
let r = await e.query({
|
|
2180
|
+
table: s,
|
|
2181
|
+
predicate: C(w("id", t.roomId), w("tenantId", t.origin.tenantId)),
|
|
2182
|
+
order: [],
|
|
2183
|
+
take: 2,
|
|
2184
|
+
skip: void 0,
|
|
2185
|
+
projection: void 0,
|
|
2186
|
+
lock: "update"
|
|
2187
|
+
});
|
|
2188
|
+
(r.length !== 1 || r[0].hostId !== t.hostId || r[0].epoch !== t.epoch || r[0].state !== "live" || r[0].erasure != null || r[0].snapshotErasure != null) && j("World ghost lost its actual target owner");
|
|
2189
|
+
let i = await F(e, {
|
|
2190
|
+
tenantId: t.origin.tenantId,
|
|
2191
|
+
entityId: n.entityId
|
|
2192
|
+
}, !0), a = await Q(e, t.origin, !0);
|
|
2193
|
+
(a.length !== 1 || i.length !== 1) && j("World ghost lost its fenced source entity");
|
|
2194
|
+
let o = Z(a[0]), c = H(i[0]);
|
|
2195
|
+
return o.id === n.id && o.revision === n.revision && o.phase === "ghosting" && o.mode === "seamless" && o.actorSnapshot && !o.actorFinalSnapshot && i[0].activeTransitionId === o.id && c.revision === o.entityRevision && W(c, V(o.source)) && c.subject?.id === o.subject?.id && c.subject?.kind === o.subject?.kind || j("World ghost no longer belongs to its current source transition"), o;
|
|
2196
|
+
});
|
|
2197
|
+
}));
|
|
2198
|
+
}, Ot = (e) => yt(e, "target"), kt = (e, t) => yt(e, "source", !0, t), At = (e) => yt(e, "source"), jt = (e) => {
|
|
2199
|
+
let r;
|
|
2200
|
+
try {
|
|
2201
|
+
P(e, [
|
|
2202
|
+
"origin",
|
|
2203
|
+
"expectedRevision",
|
|
2204
|
+
"snapshot"
|
|
2205
|
+
]), r = Object.freeze({
|
|
2206
|
+
origin: q(e.origin),
|
|
2207
|
+
expectedRevision: N(e.expectedRevision),
|
|
2208
|
+
snapshot: fe(e.snapshot, E)
|
|
2209
|
+
});
|
|
2210
|
+
} catch (e) {
|
|
2211
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World actor transfer snapshot" }));
|
|
2212
|
+
}
|
|
2213
|
+
return $("snapshot", r, () => I(async () => {
|
|
2214
|
+
let e = await Q(v, r.origin);
|
|
2215
|
+
e.length !== 1 && j("World actor snapshot requires an existing transition");
|
|
2216
|
+
let t = Z(e[0]), n = (e) => e.actorSnapshot ? ((e.actorSnapshotRevision !== r.expectedRevision || J(e.actorSnapshot) !== J(r.snapshot)) && j("World actor snapshot conflicts with retained transfer bytes"), !0) : !1;
|
|
2217
|
+
return n(t) ? t : v.transactional(async (e) => {
|
|
2218
|
+
await U(e, r.origin.tenantId, [V(t.source)]);
|
|
2219
|
+
let i = await F(e, {
|
|
2220
|
+
tenantId: r.origin.tenantId,
|
|
2221
|
+
entityId: t.entityId
|
|
2222
|
+
}, !0), a = await Q(e, r.origin, !0);
|
|
2223
|
+
a.length !== 1 && j("World actor snapshot lost its transition");
|
|
2224
|
+
let o = Z(a[0]);
|
|
2225
|
+
return o.id !== t.id && j("World actor snapshot transition identity changed"), n(o) ? o : (o.phase === "reserving" && o.revision === r.expectedRevision && o.entityId === r.snapshot.entity.id && i.length === 1 && i[0].activeTransitionId === o.id && H(i[0]).revision === o.entityRevision && W(H(i[0]), V(o.source)) || j("World actor snapshot lost its reserving phase, source owner or entity fence"), await e.updateMany("_voltro_world_transitions", {
|
|
2226
|
+
actorSnapshot: r.snapshot,
|
|
2227
|
+
actorSnapshotRevision: r.expectedRevision
|
|
2228
|
+
}, { where: C(w("id", o.id), w("tenantId", r.origin.tenantId), w("revision", o.revision), w("phase", "reserving")) }) !== 1 && j("World actor snapshot CAS lost its transition"), Z({
|
|
2229
|
+
...a[0],
|
|
2230
|
+
actorSnapshot: r.snapshot,
|
|
2231
|
+
actorSnapshotRevision: r.expectedRevision
|
|
2232
|
+
}));
|
|
2233
|
+
});
|
|
2234
|
+
}));
|
|
2235
|
+
}, Mt = (e) => {
|
|
2236
|
+
let t;
|
|
2237
|
+
try {
|
|
2238
|
+
P(e, ["origin", "expectedRevision"]), t = Object.freeze({
|
|
2239
|
+
origin: q(e.origin),
|
|
2240
|
+
expectedRevision: N(e.expectedRevision)
|
|
2241
|
+
});
|
|
2242
|
+
} catch {
|
|
2243
|
+
return D.fail(new n({ detail: "Invalid World portal departure" }));
|
|
2244
|
+
}
|
|
2245
|
+
return $("departure", t, () => I(async () => {
|
|
2246
|
+
let e = await Q(v, t.origin);
|
|
2247
|
+
e.length !== 1 && j("World portal departure requires its actual transition");
|
|
2248
|
+
let n = Z(e[0]), r = (e) => e.actorDepartureRevision !== void 0 && (e.actorDepartureRevision !== t.expectedRevision && j("World portal departure conflicts with its retained phase"), !0);
|
|
2249
|
+
return r(n) ? n : v.transactional(async (e) => {
|
|
2250
|
+
await U(e, t.origin.tenantId, [V(n.source)]);
|
|
2251
|
+
let i = await F(e, {
|
|
2252
|
+
tenantId: t.origin.tenantId,
|
|
2253
|
+
entityId: n.entityId
|
|
2254
|
+
}, !0), a = await Q(e, t.origin, !0);
|
|
2255
|
+
a.length !== 1 && j("World portal departure lost its transition");
|
|
2256
|
+
let o = Z(a[0]);
|
|
2257
|
+
if (o.id !== n.id && j("World portal departure changed identity"), r(o)) return o;
|
|
2258
|
+
o.mode === "portal" && o.phase === "detaching" && o.revision === t.expectedRevision && o.actorSnapshot && i.length === 1 && i[0].activeTransitionId === o.id && H(i[0]).revision === o.entityRevision && W(H(i[0]), V(o.source)) || j("World portal departure lost its source owner, snapshot or entity fence"), await Xe(e, o, !0);
|
|
2259
|
+
let s = { actorDepartureRevision: t.expectedRevision };
|
|
2260
|
+
return await e.updateMany("_voltro_world_transitions", s, { where: C(w("id", o.id), w("tenantId", t.origin.tenantId), w("revision", o.revision), w("phase", "detaching")) }) !== 1 && j("World portal departure lost its phase CAS"), Z({
|
|
2261
|
+
...a[0],
|
|
2262
|
+
...s
|
|
2263
|
+
});
|
|
2264
|
+
});
|
|
2265
|
+
}));
|
|
2266
|
+
}, Nt = (e) => {
|
|
2267
|
+
let i;
|
|
2268
|
+
try {
|
|
2269
|
+
P(e, [
|
|
2270
|
+
"origin",
|
|
2271
|
+
"expectedRevision",
|
|
2272
|
+
"snapshot",
|
|
2273
|
+
"data"
|
|
2274
|
+
]), i = Object.freeze({
|
|
2275
|
+
origin: q(e.origin),
|
|
2276
|
+
expectedRevision: N(e.expectedRevision),
|
|
2277
|
+
snapshot: fe(e.snapshot, E),
|
|
2278
|
+
data: r(e.data, E)
|
|
2279
|
+
});
|
|
2280
|
+
} catch (e) {
|
|
2281
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World final actor snapshot" }));
|
|
2282
|
+
}
|
|
2283
|
+
return $("finalSnapshot", i, () => I(async () => {
|
|
2284
|
+
let e = await Q(v, i.origin);
|
|
2285
|
+
e.length !== 1 && j("World final snapshot requires an existing transition");
|
|
2286
|
+
let t = Z(e[0]), n = Object.freeze({
|
|
2287
|
+
snapshot: i.snapshot,
|
|
2288
|
+
data: i.data,
|
|
2289
|
+
revision: i.expectedRevision
|
|
2290
|
+
}), r = (e) => e.actorFinalSnapshot ? (J(e.actorFinalSnapshot) !== J(n) && j("World final snapshot conflicts with immutable handoff state"), !0) : !1;
|
|
2291
|
+
return r(t) ? t : v.transactional(async (e) => {
|
|
2292
|
+
await U(e, i.origin.tenantId, [V(t.source)]);
|
|
2293
|
+
let a = await F(e, {
|
|
2294
|
+
tenantId: i.origin.tenantId,
|
|
2295
|
+
entityId: t.entityId
|
|
2296
|
+
}, !0), o = await Q(e, i.origin, !0);
|
|
2297
|
+
o.length !== 1 && j("World final snapshot lost its transition");
|
|
2298
|
+
let s = Z(o[0]);
|
|
2299
|
+
return s.id !== t.id && j("World final snapshot transition identity changed"), r(s) ? s : (s.mode === "seamless" && s.phase === "switching" && s.revision === i.expectedRevision && s.actorSnapshot && s.source.worldId === s.target.worldId && s.actorSnapshot.schemaHash === i.snapshot.schemaHash && s.entityId === i.snapshot.entity.id && a.length === 1 && a[0].activeTransitionId === s.id && H(a[0]).revision === s.entityRevision && W(H(a[0]), V(s.source)) || j("World final snapshot lost its switching phase, schema, source owner or entity fence"), await Xe(e, s, !0), await e.updateMany("_voltro_world_transitions", { actorFinalSnapshot: n }, { where: C(w("id", s.id), w("tenantId", i.origin.tenantId), w("revision", s.revision), w("phase", "switching")) }) !== 1 && j("World final snapshot CAS lost its transition"), Z({
|
|
2300
|
+
...o[0],
|
|
2301
|
+
actorFinalSnapshot: n
|
|
2302
|
+
}));
|
|
2303
|
+
});
|
|
2304
|
+
}));
|
|
2305
|
+
}, Pt = (e) => (e.mode === "portal" && e.actorSnapshot && e.actorDepartureRevision === void 0 && j("World portal actor commit requires its durable source departure"), e.mode === "seamless" && e.actorSnapshot && !e.actorFinalSnapshot && j("World seamless actor commit requires a finalized handoff snapshot"), e.actorFinalSnapshot ? e.actorFinalSnapshot.data : e.data), Ft = (e) => {
|
|
2306
|
+
let t;
|
|
2307
|
+
try {
|
|
2308
|
+
P(e, [
|
|
2309
|
+
"origin",
|
|
2310
|
+
"expectedRevision",
|
|
2311
|
+
"phase",
|
|
2312
|
+
"failure"
|
|
2313
|
+
]), a.includes(e.phase) && e.phase === "failed" == (e.failure !== void 0) || j("Invalid World transition phase or failure reason"), t = Object.freeze({
|
|
2314
|
+
origin: q(e.origin),
|
|
2315
|
+
expectedRevision: N(e.expectedRevision),
|
|
2316
|
+
phase: e.phase,
|
|
2317
|
+
...e.failure === void 0 ? {} : { failure: M(e.failure, 120) }
|
|
2318
|
+
});
|
|
2319
|
+
} catch {
|
|
2320
|
+
return D.fail(new n({ detail: "Invalid World transition phase request" }));
|
|
2321
|
+
}
|
|
2322
|
+
return $("advance", t, () => I(async () => {
|
|
2323
|
+
let e = await Q(v, t.origin);
|
|
2324
|
+
e.length !== 1 && j("World transition phase requires one durable request");
|
|
2325
|
+
let n = Z(e[0]), r = V(n.source), i = V(n.target);
|
|
2326
|
+
if (n.group && [
|
|
2327
|
+
"committed",
|
|
2328
|
+
"failed",
|
|
2329
|
+
"rolledBack"
|
|
2330
|
+
].includes(t.phase) && j("Grouped World transition requires its complete coordinating operation"), n.revision === t.expectedRevision + 1 && n.phase === t.phase && (t.phase !== "failed" || n.failure === t.failure)) return n;
|
|
2331
|
+
let a, o = await v.transactional(async (e) => {
|
|
2332
|
+
a = void 0, (t.phase === "committed" || t.phase === "detaching") && await U(e, t.origin.tenantId, t.phase === "committed" ? [r, i] : [r]);
|
|
2333
|
+
let o = {
|
|
2334
|
+
tenantId: n.origin.tenantId,
|
|
2335
|
+
entityId: n.entityId
|
|
2336
|
+
}, s = await F(e, o, !0), c = await Q(e, t.origin, !0);
|
|
2337
|
+
c.length !== 1 && j("World transition disappeared during phase admission");
|
|
2338
|
+
let l = Z(c[0]);
|
|
2339
|
+
if (l.group && [
|
|
2340
|
+
"committed",
|
|
2341
|
+
"failed",
|
|
2342
|
+
"rolledBack"
|
|
2343
|
+
].includes(t.phase) && j("Grouped World transition forbids individual commit or cancellation"), l.id !== n.id && j("World transition identity changed during phase admission"), l.revision === t.expectedRevision + 1 && l.phase === t.phase && (t.phase !== "failed" || l.failure === t.failure)) return l;
|
|
2344
|
+
l.revision === t.expectedRevision && l.revision !== 2147483647 && ee(l.mode, l.phase, t.phase) || j("World transition lost its phase revision or legal edge");
|
|
2345
|
+
let u = B();
|
|
2346
|
+
u < l.updatedAt && j("World transition clock moved backwards"), l.phase === "committed" || s.length === 1 && s[0].activeTransitionId === l.id && H(s[0]).revision === l.entityRevision && W(H(s[0]), r) || j("World transition lost its durable source fence");
|
|
2347
|
+
let d = l.entityRevision, f = l.result, p = l.committedAt;
|
|
2348
|
+
if (t.phase === "detaching") {
|
|
2349
|
+
let t = await He(e, "persist", K("persist", {
|
|
2350
|
+
...o,
|
|
2351
|
+
expectedRevision: d,
|
|
2352
|
+
source: l.source,
|
|
2353
|
+
data: l.sourceData
|
|
2354
|
+
}), void 0, l.id);
|
|
2355
|
+
d = t.revision, u = t.updatedAt;
|
|
2356
|
+
}
|
|
2357
|
+
if (t.phase === "committed" && (f = await He(e, "transfer", K("transfer", {
|
|
2358
|
+
...o,
|
|
2359
|
+
expectedRevision: d,
|
|
2360
|
+
source: l.source,
|
|
2361
|
+
target: l.target,
|
|
2362
|
+
data: Pt(l)
|
|
2363
|
+
}), {
|
|
2364
|
+
requestKey: Y(l.origin),
|
|
2365
|
+
requestDigest: c[0].requestDigest
|
|
2366
|
+
}, l.id), d = f.revision, u = f.updatedAt, p = u, await e.updateMany("_voltro_world_entities", {
|
|
2367
|
+
activeTransitionId: null,
|
|
2368
|
+
transitionedAt: new Date(u)
|
|
2369
|
+
}, { where: C(ke(o), w("activeTransitionId", l.id), w("revision", d)) }) !== 1 && j("World transition commit lost its entity fence")), t.phase === "rolledBack" && l.actorFinalSnapshot) {
|
|
2370
|
+
let t = await He(e, "persist", K("persist", {
|
|
2371
|
+
...o,
|
|
2372
|
+
expectedRevision: d,
|
|
2373
|
+
source: l.source,
|
|
2374
|
+
data: l.actorFinalSnapshot.data
|
|
2375
|
+
}), void 0, l.id);
|
|
2376
|
+
d = t.revision, u = t.updatedAt;
|
|
2377
|
+
}
|
|
2378
|
+
t.phase === "rolledBack" && await e.updateMany("_voltro_world_entities", { activeTransitionId: null }, { where: C(ke(o), w("activeTransitionId", l.id), w("revision", d)) }) !== 1 && j("World transition rollback lost its source fence"), t.phase === "rolledBack" && await Xe(e, l, !1);
|
|
2379
|
+
let m = {
|
|
2380
|
+
phase: t.phase,
|
|
2381
|
+
revision: l.revision + 1,
|
|
2382
|
+
entityRevision: d,
|
|
2383
|
+
result: f,
|
|
2384
|
+
failure: t.phase === "failed" ? t.failure : l.failure,
|
|
2385
|
+
committedAt: p === null ? null : new Date(p),
|
|
2386
|
+
updatedAt: new Date(u)
|
|
2387
|
+
}, h = Z({
|
|
2388
|
+
...c[0],
|
|
2389
|
+
...m
|
|
2390
|
+
});
|
|
2391
|
+
return u < l.updatedAt && j("World transition clock moved backwards during commit"), await e.updateMany("_voltro_world_transitions", m, { where: C(w("id", l.id), w("tenantId", l.origin.tenantId), w("revision", l.revision), w("phase", l.phase)) }) !== 1 && j("World transition phase CAS lost its revision"), a = h, h;
|
|
2392
|
+
});
|
|
2393
|
+
return a && ge.observe(a), o;
|
|
2394
|
+
}));
|
|
2395
|
+
}, It = (e) => {
|
|
2396
|
+
let i, a, o;
|
|
2397
|
+
try {
|
|
2398
|
+
if (Array.isArray(e) && Object.getPrototypeOf(e) === Array.prototype && Reflect.ownKeys(e).length === e.length + 1 && e.length || j("World commit batch requires bounded own entries"), e.length > A) throw new t({
|
|
2399
|
+
budget: "worldTransitionBatchRows",
|
|
2400
|
+
limit: A
|
|
2401
|
+
});
|
|
2402
|
+
let n = [], r = /* @__PURE__ */ new Set();
|
|
2403
|
+
for (let t = 0; t < e.length; t++) {
|
|
2404
|
+
let i = Object.getOwnPropertyDescriptor(e, String(t));
|
|
2405
|
+
i?.enumerable && "value" in i || j("World commit batch refuses accessor entries");
|
|
2406
|
+
let a = i.value;
|
|
2407
|
+
P(a, ["origin", "expectedRevision"]);
|
|
2408
|
+
let o = q(a.origin), s = N(a.expectedRevision), c = Y(o);
|
|
2409
|
+
(r.has(c) || n.length && n[0].origin.tenantId !== o.tenantId) && j("World commit batch requires unique requests in one tenant"), r.add(c), n.push(Object.freeze({
|
|
2410
|
+
origin: o,
|
|
2411
|
+
expectedRevision: s
|
|
2412
|
+
}));
|
|
2413
|
+
}
|
|
2414
|
+
i = Object.freeze(n);
|
|
2415
|
+
let s = [...n].sort((e, t) => Y(e.origin) < Y(t.origin) ? -1 : 1);
|
|
2416
|
+
a = J(["world-transition-commit-batch", s.map((e) => e.origin)]), o = J(s);
|
|
2417
|
+
} catch (e) {
|
|
2418
|
+
return D.fail(e instanceof t ? e : new n({ detail: "Invalid World commit batch" }));
|
|
2419
|
+
}
|
|
2420
|
+
return D.gen(function* () {
|
|
2421
|
+
for (let e of i) yield* $("advance", {
|
|
2422
|
+
...e,
|
|
2423
|
+
phase: "committed"
|
|
2424
|
+
}, () => D.void);
|
|
2425
|
+
return yield* I(async () => {
|
|
2426
|
+
let e = async (e, t) => {
|
|
2427
|
+
let n = [];
|
|
2428
|
+
for (let r of i) {
|
|
2429
|
+
let i = await Q(e, r.origin, t);
|
|
2430
|
+
i.length !== 1 && j("World commit batch requires every durable request"), n.push({
|
|
2431
|
+
input: r,
|
|
2432
|
+
row: i[0],
|
|
2433
|
+
record: Z(i[0])
|
|
2434
|
+
});
|
|
2435
|
+
}
|
|
2436
|
+
return new Set(n.map((e) => e.record.entityId)).size !== n.length && j("World commit batch requires distinct entities"), n;
|
|
2437
|
+
}, t = async (e, t, n) => {
|
|
2438
|
+
let s = await e.query({
|
|
2439
|
+
table: k,
|
|
2440
|
+
predicate: C(w("tenantId", i[0].origin.tenantId), w("requestKey", a)),
|
|
2441
|
+
order: [],
|
|
2442
|
+
take: i.length + 1,
|
|
2443
|
+
skip: void 0,
|
|
2444
|
+
projection: void 0,
|
|
2445
|
+
...n ? { lock: "update" } : {}
|
|
2446
|
+
});
|
|
2447
|
+
if (!s.length) return !1;
|
|
2448
|
+
(s.length !== t.length || new Set(s.map((e) => e.entityId)).size !== t.length) && j("World batch receipt is incomplete or duplicated");
|
|
2449
|
+
for (let { record: e, input: n } of t) {
|
|
2450
|
+
let t = s.find((t) => t.entityId === e.entityId);
|
|
2451
|
+
(!t || t.tenantId !== n.origin.tenantId || t.requestKey !== a || t.requestDigest !== o || t.operation !== "transfer" || e.phase !== "committed" && e.phase !== "settled" || e.revision !== n.expectedRevision + (e.phase === "settled" ? 2 : 1) || e.result === null || t.revision !== e.entityRevision || t.subjectId !== (e.subject?.id ?? null) || t.subjectKind !== (e.subject?.kind ?? null) || Ye(t.createdAt) !== e.result.updatedAt || J(r(t.snapshot, xe)) !== J(e.result)) && j("World batch receipt conflicts with its original commit");
|
|
2452
|
+
}
|
|
2453
|
+
return !0;
|
|
2454
|
+
}, n = await e(v, !1), s = S(n.map((e) => e.record));
|
|
2455
|
+
if (s !== void 0) {
|
|
2456
|
+
let e = await D.runPromise(D.result(Qe("commit", s)));
|
|
2457
|
+
if (Se.isFailure(e)) throw e.failure;
|
|
2458
|
+
}
|
|
2459
|
+
if (await t(v, n, !1)) return Object.freeze(n.map((e) => e.record));
|
|
2460
|
+
n.some((e) => e.record.phase !== "switching" || e.record.revision !== e.input.expectedRevision) && j("World batch is not wholly ready for its original commit");
|
|
2461
|
+
let c = s !== void 0 && R?.readiness !== void 0 || n.some((e) => e.record.group?.requiresReadiness || e.record.ready !== void 0), l = mt(n.map((e) => e.record));
|
|
2462
|
+
if (c) {
|
|
2463
|
+
if (s && R?.readiness || j("World group readiness provider cannot be withdrawn before commit"), l) {
|
|
2464
|
+
let e = await D.runPromise(D.result(ht(l)));
|
|
2465
|
+
if (Se.isFailure(e)) throw e.failure;
|
|
2466
|
+
await gt(v, l.records, B(), !1);
|
|
2467
|
+
} else for (let e of n) e.row.readySession ?? j("World group has not received every target ready intention"), await tt(v, e.record, m(e.row.readySession));
|
|
2468
|
+
}
|
|
2469
|
+
return v.transactional(async (e) => {
|
|
2470
|
+
let r = n.flatMap((e) => [V(e.record.source), V(e.record.target)]).sort(Ve);
|
|
2471
|
+
await U(e, i[0].origin.tenantId, r);
|
|
2472
|
+
let u = [...n].sort((e, t) => e.record.entityId < t.record.entityId ? -1 : 1), d = /* @__PURE__ */ new Map();
|
|
2473
|
+
for (let t of u) {
|
|
2474
|
+
let n = await F(e, {
|
|
2475
|
+
tenantId: t.input.origin.tenantId,
|
|
2476
|
+
entityId: t.record.entityId
|
|
2477
|
+
}, !0);
|
|
2478
|
+
n.length !== 1 && j("World batch lost a durable entity"), d.set(t.record.entityId, n[0]);
|
|
2479
|
+
}
|
|
2480
|
+
let f = [];
|
|
2481
|
+
for (let t of u) {
|
|
2482
|
+
let n = await Q(e, t.input.origin, !0);
|
|
2483
|
+
n.length !== 1 && j("World batch lost a durable transition");
|
|
2484
|
+
let r = Z(n[0]);
|
|
2485
|
+
(r.id !== t.record.id || r.entityId !== t.record.entityId) && j("World batch identity changed under locks"), f.push({
|
|
2486
|
+
input: t.input,
|
|
2487
|
+
row: n[0],
|
|
2488
|
+
record: r
|
|
2489
|
+
});
|
|
2490
|
+
}
|
|
2491
|
+
let p = S(f.map((e) => e.record));
|
|
2492
|
+
if (J(p ?? null) !== J(s ?? null) && j("World commit group fence changed under locks"), await t(e, f, !0)) {
|
|
2493
|
+
let e = new Map(f.map((e) => [Y(e.input.origin), e.record]));
|
|
2494
|
+
return Object.freeze(i.map((t) => e.get(Y(t.origin))));
|
|
2495
|
+
}
|
|
2496
|
+
for (let e of f) {
|
|
2497
|
+
let t = d.get(e.record.entityId), n = H(t);
|
|
2498
|
+
e.record.phase === "switching" && e.record.revision === e.input.expectedRevision && e.record.revision !== 2147483647 && n.tenantId === e.input.origin.tenantId && n.entityId === e.record.entityId && t.activeTransitionId === e.record.id && n.revision === e.record.entityRevision && W(n, V(e.record.source)) || j("World batch lost an original source/phase fence");
|
|
2499
|
+
}
|
|
2500
|
+
if (c) {
|
|
2501
|
+
let t = mt(f.map((e) => e.record));
|
|
2502
|
+
if (J(t?.records.map((e) => e.groupProceed) ?? null) !== J(l ? [...l.records].sort((e, t) => e.entityId < t.entityId ? -1 : 1).map((e) => e.groupProceed) : null) && j("World deferred readiness decision changed under commit locks"), t) await gt(e, t.records, B(), !0);
|
|
2503
|
+
else for (let t of f) t.row.readySession ?? j("World group lost an original ready observation under locks"), await tt(e, t.record, m(t.row.readySession), !0);
|
|
2504
|
+
}
|
|
2505
|
+
let h = /* @__PURE__ */ new Map();
|
|
2506
|
+
for (let { input: t, row: n, record: r } of f) {
|
|
2507
|
+
let i = {
|
|
2508
|
+
tenantId: t.origin.tenantId,
|
|
2509
|
+
entityId: r.entityId
|
|
2510
|
+
}, s = await He(e, "transfer", K("transfer", {
|
|
2511
|
+
...i,
|
|
2512
|
+
expectedRevision: r.entityRevision,
|
|
2513
|
+
source: r.source,
|
|
2514
|
+
target: r.target,
|
|
2515
|
+
data: Pt(r)
|
|
2516
|
+
}), {
|
|
2517
|
+
requestKey: a,
|
|
2518
|
+
requestDigest: o
|
|
2519
|
+
}, r.id);
|
|
2520
|
+
s.updatedAt < r.updatedAt && j("World batch commit clock moved backwards"), await e.updateMany("_voltro_world_entities", {
|
|
2521
|
+
activeTransitionId: null,
|
|
2522
|
+
transitionedAt: new Date(s.updatedAt)
|
|
2523
|
+
}, { where: C(ke(i), w("activeTransitionId", r.id), w("revision", s.revision)) }) !== 1 && j("World batch lost its entity commit fence");
|
|
2524
|
+
let c = {
|
|
2525
|
+
phase: "committed",
|
|
2526
|
+
revision: r.revision + 1,
|
|
2527
|
+
entityRevision: s.revision,
|
|
2528
|
+
result: s,
|
|
2529
|
+
committedAt: new Date(s.updatedAt),
|
|
2530
|
+
updatedAt: new Date(s.updatedAt)
|
|
2531
|
+
}, l = Z({
|
|
2532
|
+
...n,
|
|
2533
|
+
...c
|
|
2534
|
+
});
|
|
2535
|
+
await e.updateMany("_voltro_world_transitions", c, { where: C(w("id", r.id), w("tenantId", t.origin.tenantId), w("revision", r.revision), w("phase", "switching")) }) !== 1 && j("World batch phase CAS lost its original revision"), h.set(Y(t.origin), l);
|
|
2536
|
+
}
|
|
2537
|
+
return Object.freeze(i.map((e) => h.get(Y(e.origin))));
|
|
2538
|
+
});
|
|
2539
|
+
});
|
|
2540
|
+
});
|
|
2541
|
+
}, Lt = (e, t) => (P(t, [
|
|
2542
|
+
"tenantId",
|
|
2543
|
+
"requestId",
|
|
2544
|
+
"kind",
|
|
2545
|
+
"completed"
|
|
2546
|
+
]), Object.freeze({
|
|
2547
|
+
tenantId: M(t.tenantId),
|
|
2548
|
+
subject: Oe({
|
|
2549
|
+
id: e,
|
|
2550
|
+
kind: t.kind
|
|
2551
|
+
}),
|
|
2552
|
+
requestId: M(t.requestId)
|
|
2553
|
+
})), Rt = (e) => C(w("tenantId", e.tenantId), w("subjectId", e.subject.id), w("subjectKind", e.subject.kind));
|
|
2554
|
+
return Object.freeze({
|
|
2555
|
+
handoffMetrics: () => L === void 0 ? void 0 : ge.snapshot(),
|
|
2556
|
+
worlds: _e,
|
|
2557
|
+
recoverRoom: (r, i) => {
|
|
2558
|
+
let a;
|
|
2559
|
+
try {
|
|
2560
|
+
P(r, [
|
|
2561
|
+
"tenantId",
|
|
2562
|
+
"roomId",
|
|
2563
|
+
"hostId",
|
|
2564
|
+
"priorEpoch",
|
|
2565
|
+
"epoch",
|
|
2566
|
+
"worldRecoveryEpoch"
|
|
2567
|
+
]), a = Object.freeze({
|
|
2568
|
+
tenantId: M(r.tenantId),
|
|
2569
|
+
roomId: M(r.roomId),
|
|
2570
|
+
hostId: M(r.hostId),
|
|
2571
|
+
priorEpoch: N(r.priorEpoch),
|
|
2572
|
+
epoch: N(r.epoch),
|
|
2573
|
+
...r.worldRecoveryEpoch === void 0 ? {} : { worldRecoveryEpoch: N(r.worldRecoveryEpoch) }
|
|
2574
|
+
}), a.epoch !== a.priorEpoch + 1 && j("World recovery requires the next claimed Room epoch");
|
|
2575
|
+
let e = a.worldRecoveryEpoch ?? a.priorEpoch;
|
|
2576
|
+
(e > a.priorEpoch || e < a.priorEpoch && !i) && j("Older World recovery requires active checkpoint adoption authority"), i && de(i, a);
|
|
2577
|
+
} catch {
|
|
2578
|
+
return D.fail(new n({ detail: "Invalid World Room recovery scope" }));
|
|
2579
|
+
}
|
|
2580
|
+
let o = C(w("id", a.roomId), w("tenantId", a.tenantId)), c = C(w("roomId", a.roomId), w("tenantId", a.tenantId)), u = async (e) => {
|
|
2581
|
+
await h(e, [a.roomId], a.tenantId);
|
|
2582
|
+
let t = await e.query({
|
|
2583
|
+
table: s,
|
|
2584
|
+
predicate: o,
|
|
2585
|
+
order: [],
|
|
2586
|
+
take: 2,
|
|
2587
|
+
skip: void 0,
|
|
2588
|
+
projection: void 0,
|
|
2589
|
+
lock: "update"
|
|
2590
|
+
}), n = t[0];
|
|
2591
|
+
return t.length === 1 && n.hostId === a.hostId && n.epoch === a.epoch && ["creating", "live"].includes(String(n.state)) && n.erasure == null && n.snapshotErasure == null || j("World recovery lost its claimed Room owner"), n;
|
|
2592
|
+
}, d = async (t, n) => {
|
|
2593
|
+
if ([...be.values()].filter((e) => e.instances.some((e) => e.room === n.name)).length) {
|
|
2594
|
+
[...be.values()].some((e) => e.zones.some((e) => e.room === n.name)) && j("World recovery Room has ambiguous zone and instance declarations");
|
|
2595
|
+
let r = await t.query({
|
|
2596
|
+
table: e,
|
|
2597
|
+
predicate: c,
|
|
2598
|
+
order: [],
|
|
2599
|
+
take: 2,
|
|
2600
|
+
skip: void 0,
|
|
2601
|
+
projection: void 0,
|
|
2602
|
+
lock: "update"
|
|
2603
|
+
}), i = r[0];
|
|
2604
|
+
r.length === 1 && i || j("World recovery requires one durable instance placement");
|
|
2605
|
+
let o = z(M(i.worldId, 120)), s = N(i.epoch);
|
|
2606
|
+
return (!o.instances.some((e) => e.id === i.instance && e.room === n.name) || ![
|
|
2607
|
+
"creating",
|
|
2608
|
+
"live",
|
|
2609
|
+
"hibernated"
|
|
2610
|
+
].includes(String(i.state)) || (s === a.epoch ? i.hostId !== a.hostId : s < (a.worldRecoveryEpoch ?? a.priorEpoch) || s > a.priorEpoch || n.state !== "creating")) && j("World recovery instance escaped its checkpoint baseline and claimed Room"), await g(t, o, n, !0), {
|
|
2611
|
+
cell: i,
|
|
2612
|
+
epoch: s,
|
|
2613
|
+
instance: !0,
|
|
2614
|
+
table: e
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
let r = await t.query({
|
|
2618
|
+
table: _,
|
|
2619
|
+
predicate: c,
|
|
2620
|
+
order: [],
|
|
2621
|
+
take: 2,
|
|
2622
|
+
skip: void 0,
|
|
2623
|
+
projection: void 0,
|
|
2624
|
+
lock: "update"
|
|
2625
|
+
});
|
|
2626
|
+
r.length !== 1 && j("World recovery requires one durable cell placement");
|
|
2627
|
+
let i = r[0], o = z(M(i.worldId, 120)), s = N(i.epoch);
|
|
2628
|
+
return (o.zones.find((e) => e.id === i.zoneId)?.room !== n.name || ![
|
|
2629
|
+
"creating",
|
|
2630
|
+
"live",
|
|
2631
|
+
"hibernated"
|
|
2632
|
+
].includes(String(i.state)) || (s === a.epoch ? i.hostId !== a.hostId : s < (a.worldRecoveryEpoch ?? a.priorEpoch) || s > a.priorEpoch || n.state !== "creating")) && j("World recovery cell escaped its checkpoint baseline and claimed Room"), await g(t, o, n, !0), {
|
|
2633
|
+
cell: i,
|
|
2634
|
+
epoch: s,
|
|
2635
|
+
instance: !1,
|
|
2636
|
+
table: _
|
|
2637
|
+
};
|
|
2638
|
+
}, f = async (e, n, r = !1) => {
|
|
2639
|
+
let i = await e.query({
|
|
2640
|
+
table: O,
|
|
2641
|
+
predicate: c,
|
|
2642
|
+
order: [{
|
|
2643
|
+
column: "entityId",
|
|
2644
|
+
direction: "asc"
|
|
2645
|
+
}],
|
|
2646
|
+
take: A + 1,
|
|
2647
|
+
skip: void 0,
|
|
2648
|
+
projection: void 0,
|
|
2649
|
+
...r ? { lock: "update" } : {}
|
|
2650
|
+
});
|
|
2651
|
+
if (i.length > A) throw new t({
|
|
2652
|
+
budget: "worldRecoveryRows",
|
|
2653
|
+
limit: A
|
|
2654
|
+
});
|
|
2655
|
+
for (let e of i) {
|
|
2656
|
+
let t = H(e);
|
|
2657
|
+
t.tenantId === a.tenantId && t.roomId === a.roomId && [n, a.epoch].includes(t.epoch) || j("World recovery entity escaped its claimed scope");
|
|
2658
|
+
}
|
|
2659
|
+
return i;
|
|
2660
|
+
};
|
|
2661
|
+
return G("recover", a, () => I(async () => {
|
|
2662
|
+
i && de(i, a);
|
|
2663
|
+
let e = await v.transactional(async (e) => {
|
|
2664
|
+
let t = await u(e), { epoch: n } = await d(e, t), r = await f(e, n);
|
|
2665
|
+
for (let n of new Set(r.map((e) => M(e.worldId, 120)))) await g(e, z(n), t, !0);
|
|
2666
|
+
return {
|
|
2667
|
+
rows: r,
|
|
2668
|
+
epoch: n
|
|
2669
|
+
};
|
|
2670
|
+
}), t = /* @__PURE__ */ new Set();
|
|
2671
|
+
for (let n of e.rows) {
|
|
2672
|
+
if (n.epoch === a.epoch || n.activeTransitionId === null) continue;
|
|
2673
|
+
L || j("World recovery needs configured transition authority");
|
|
2674
|
+
let r = await v.query({
|
|
2675
|
+
table: l,
|
|
2676
|
+
predicate: C(w("tenantId", a.tenantId), w("id", M(n.activeTransitionId))),
|
|
2677
|
+
order: [],
|
|
2678
|
+
take: 2,
|
|
2679
|
+
skip: void 0,
|
|
2680
|
+
projection: void 0
|
|
2681
|
+
});
|
|
2682
|
+
r.length !== 1 && j("World recovery transition receipt is missing");
|
|
2683
|
+
let o = Z(r[0]);
|
|
2684
|
+
if ((o.entityId !== n.entityId || o.source.roomId !== a.roomId || o.source.epoch !== e.epoch) && j("World recovery transition escaped its prior owner"), o.group) {
|
|
2685
|
+
if (t.has(o.group.key)) continue;
|
|
2686
|
+
R || j("World recovery requires complete group cancellation authority"), t.add(o.group.key);
|
|
2687
|
+
let e = await v.query({
|
|
2688
|
+
table: l,
|
|
2689
|
+
predicate: C(w("tenantId", a.tenantId), w("groupKey", o.group.key)),
|
|
2690
|
+
order: [{
|
|
2691
|
+
column: "id",
|
|
2692
|
+
direction: "asc"
|
|
2693
|
+
}],
|
|
2694
|
+
take: R.maxRows + 1,
|
|
2695
|
+
skip: void 0,
|
|
2696
|
+
projection: void 0
|
|
2697
|
+
});
|
|
2698
|
+
(e.length !== o.group.size || e.length > R.maxRows) && j("World recovery group membership is incomplete");
|
|
2699
|
+
let n = e.map(Z);
|
|
2700
|
+
Ne || j("World recovery requires actual group compensation");
|
|
2701
|
+
let r = Ne(Object.freeze(n), i);
|
|
2702
|
+
D.isEffect(r) || j("World recovery compensation must return an Effect"), await D.runPromise(r);
|
|
2703
|
+
} else {
|
|
2704
|
+
Ne || j("World recovery requires actual transition compensation");
|
|
2705
|
+
let e = Ne(Object.freeze([o]), i);
|
|
2706
|
+
D.isEffect(e) || j("World recovery compensation must return an Effect"), await D.runPromise(e);
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
await v.transactional(async (e) => {
|
|
2710
|
+
let t = await u(e), { cell: n, epoch: r, instance: i, table: o } = await d(e, t), s = await f(e, r, !0), c = B();
|
|
2711
|
+
for (let o of s) {
|
|
2712
|
+
let s = H(o);
|
|
2713
|
+
if (s.worldId === n.worldId && (i || s.zoneId === n.zoneId && s.cellId === n.cellId && s.layer === n.layer) || j("World recovery requires matching cells and reconciled transitions"), s.epoch === a.epoch) continue;
|
|
2714
|
+
(o.activeTransitionId !== null || s.epoch !== r || s.revision === 2147483647 || c < s.updatedAt || t.state !== "creating") && j("World entity recovery lost its prior revision or unpublished owner");
|
|
2715
|
+
let l = Object.freeze({
|
|
2716
|
+
...s,
|
|
2717
|
+
epoch: a.epoch,
|
|
2718
|
+
revision: s.revision + 1,
|
|
2719
|
+
updatedAt: c
|
|
2720
|
+
});
|
|
2721
|
+
await e.updateMany("_voltro_world_entities", {
|
|
2722
|
+
epoch: l.epoch,
|
|
2723
|
+
revision: l.revision,
|
|
2724
|
+
updatedAt: new Date(c)
|
|
2725
|
+
}, { where: C(ke(s), w("epoch", s.epoch), w("revision", s.revision), w("activeTransitionId", null)) }) !== 1 && j("World entity recovery lost its SQL CAS"), await Re(e, l, "recover");
|
|
2726
|
+
}
|
|
2727
|
+
let l = N(t.clients, 0);
|
|
2728
|
+
if (n.epoch !== a.epoch || n.state !== t.state || n.players !== l) {
|
|
2729
|
+
let r = N(n.revision);
|
|
2730
|
+
(r === 2147483647 || n.epoch !== a.epoch && t.state !== "creating") && j("World cell recovery cannot replace a published owner"), await e.updateMany(o, {
|
|
2731
|
+
hostId: a.hostId,
|
|
2732
|
+
epoch: a.epoch,
|
|
2733
|
+
revision: r + 1,
|
|
2734
|
+
players: l,
|
|
2735
|
+
state: t.state,
|
|
2736
|
+
updatedAt: new Date(c)
|
|
2737
|
+
}, { where: C(w("id", n.id), w("tenantId", a.tenantId), w("revision", r), w("epoch", n.epoch)) }) !== 1 && j("World cell recovery lost its SQL CAS");
|
|
2738
|
+
}
|
|
2739
|
+
});
|
|
2740
|
+
}));
|
|
2741
|
+
},
|
|
2742
|
+
admitActorNeighbor: wt,
|
|
2743
|
+
admitActorProjection: Ct,
|
|
2744
|
+
admitActorPlayer: Tt,
|
|
2745
|
+
create: ze,
|
|
2746
|
+
observe: Be,
|
|
2747
|
+
persist: (e) => Ue("persist", e),
|
|
2748
|
+
persistBatch: Ge,
|
|
2749
|
+
persistBatchFromCommand: qe,
|
|
2750
|
+
capturePersistence: (e) => {
|
|
2751
|
+
let t = K("persist", e);
|
|
2752
|
+
return Object.freeze({
|
|
2753
|
+
input: Object.freeze({
|
|
2754
|
+
...t.captured,
|
|
2755
|
+
source: X(t.source)
|
|
2756
|
+
}),
|
|
2757
|
+
cellId: t.source.cellId
|
|
2758
|
+
});
|
|
2759
|
+
},
|
|
2760
|
+
persistenceBatchRows: A,
|
|
2761
|
+
transfer: (e) => Ue("transfer", e),
|
|
2762
|
+
transferFromCommand: Je,
|
|
2763
|
+
onErase: (e, t) => {
|
|
2764
|
+
let r;
|
|
2765
|
+
try {
|
|
2766
|
+
r = Lt(e, t);
|
|
2767
|
+
} catch {
|
|
2768
|
+
return D.fail(new n({ detail: "Invalid World entity erasure scope" }));
|
|
2769
|
+
}
|
|
2770
|
+
return G("erase", r, () => D.suspend(() => {
|
|
2771
|
+
let e;
|
|
2772
|
+
try {
|
|
2773
|
+
e = Me(r);
|
|
2774
|
+
} catch {
|
|
2775
|
+
return D.fail(new n({ detail: "World entity quiescence refused admission" }));
|
|
2776
|
+
}
|
|
2777
|
+
return D.isEffect(e) ? e.pipe(D.flatMap(() => I(() => v.transactional(async (e) => {
|
|
2778
|
+
if (Pe === void 0) {
|
|
2779
|
+
let t = await e.query({
|
|
2780
|
+
table: O,
|
|
2781
|
+
predicate: Rt(r),
|
|
2782
|
+
order: [],
|
|
2783
|
+
take: we + 1,
|
|
2784
|
+
skip: void 0,
|
|
2785
|
+
projection: ["transitionRecordedAt"],
|
|
2786
|
+
lock: "update"
|
|
2787
|
+
});
|
|
2788
|
+
(t.length > we || t.some((e) => e.transitionRecordedAt !== null)) && j("World entity erasure requires its configured transition privacy source");
|
|
2789
|
+
}
|
|
2790
|
+
Pe !== void 0 && await e.deleteMany(l, { where: Rt(r) }), await e.deleteMany(k, { where: Rt(r) }), await e.deleteMany(O, { where: Rt(r) });
|
|
2791
|
+
})))) : D.fail(new n({ detail: "World entity erasure requires actual quiescence" }));
|
|
2792
|
+
}));
|
|
2793
|
+
},
|
|
2794
|
+
onExport: (e, i) => {
|
|
2795
|
+
let a;
|
|
2796
|
+
try {
|
|
2797
|
+
a = Lt(e, i);
|
|
2798
|
+
} catch {
|
|
2799
|
+
return D.fail(new n({ detail: "Invalid World entity export scope" }));
|
|
2800
|
+
}
|
|
2801
|
+
return G("export", a, () => I(() => v.transactional(async (e) => {
|
|
2802
|
+
let n = await e.query({
|
|
2803
|
+
table: O,
|
|
2804
|
+
predicate: Rt(a),
|
|
2805
|
+
order: [{
|
|
2806
|
+
column: "id",
|
|
2807
|
+
direction: "asc"
|
|
2808
|
+
}],
|
|
2809
|
+
take: we + 1,
|
|
2810
|
+
skip: void 0,
|
|
2811
|
+
projection: void 0
|
|
2812
|
+
}), i = await e.query({
|
|
2813
|
+
table: k,
|
|
2814
|
+
predicate: Rt(a),
|
|
2815
|
+
order: [{
|
|
2816
|
+
column: "id",
|
|
2817
|
+
direction: "asc"
|
|
2818
|
+
}],
|
|
2819
|
+
take: Te + 1,
|
|
2820
|
+
skip: void 0,
|
|
2821
|
+
projection: void 0
|
|
2822
|
+
}), o = Pe === void 0 ? [] : await e.query({
|
|
2823
|
+
table: l,
|
|
2824
|
+
predicate: Rt(a),
|
|
2825
|
+
order: [{
|
|
2826
|
+
column: "id",
|
|
2827
|
+
direction: "asc"
|
|
2828
|
+
}],
|
|
2829
|
+
take: Pe + 1,
|
|
2830
|
+
skip: void 0,
|
|
2831
|
+
projection: void 0
|
|
2832
|
+
});
|
|
2833
|
+
if (n.length > we || i.length > Te) throw new t({
|
|
2834
|
+
budget: "worldEntityPrivacyRows",
|
|
2835
|
+
limit: n.length > we ? we : Te
|
|
2836
|
+
});
|
|
2837
|
+
if (Pe === void 0 && n.some((e) => e.transitionRecordedAt !== null) && j("World entity export requires its configured transition privacy source"), Pe !== void 0 && o.length > Pe) throw new t({
|
|
2838
|
+
budget: "worldTransitionPrivacyRows",
|
|
2839
|
+
limit: Pe
|
|
2840
|
+
});
|
|
2841
|
+
let s = (e) => ((e.tenantId !== a.tenantId || e.subject?.id !== a.subject.id || e.subject.kind !== a.subject.kind) && j("World entity export escaped its Subject scope"), e);
|
|
2842
|
+
return Object.freeze([
|
|
2843
|
+
...n.map((e) => s(H(e))),
|
|
2844
|
+
...i.map((e) => {
|
|
2845
|
+
let t = r(e.snapshot, xe);
|
|
2846
|
+
P(t, [
|
|
2847
|
+
"tenantId",
|
|
2848
|
+
"entityId",
|
|
2849
|
+
"subject",
|
|
2850
|
+
"kind",
|
|
2851
|
+
"worldId",
|
|
2852
|
+
"zoneId",
|
|
2853
|
+
"cellId",
|
|
2854
|
+
"layer",
|
|
2855
|
+
"roomId",
|
|
2856
|
+
"epoch",
|
|
2857
|
+
"revision",
|
|
2858
|
+
"data",
|
|
2859
|
+
"updatedAt",
|
|
2860
|
+
"returnAnchor"
|
|
2861
|
+
]);
|
|
2862
|
+
let n = Oe(t.subject);
|
|
2863
|
+
(!Number.isSafeInteger(t.updatedAt) || t.updatedAt < 0 || t.updatedAt > 864e13) && j("Invalid World journal time");
|
|
2864
|
+
let i = s(H({
|
|
2865
|
+
...t,
|
|
2866
|
+
subjectId: n?.id ?? null,
|
|
2867
|
+
subjectKind: n?.kind ?? null,
|
|
2868
|
+
updatedAt: new Date(t.updatedAt)
|
|
2869
|
+
}));
|
|
2870
|
+
return e.tenantId === i.tenantId && e.entityId === i.entityId && e.revision === i.revision && e.subjectId === n?.id && e.subjectKind === n?.kind && [
|
|
2871
|
+
"create",
|
|
2872
|
+
"persist",
|
|
2873
|
+
"transfer",
|
|
2874
|
+
"recover"
|
|
2875
|
+
].includes(String(e.operation)) || j("Contradictory World journal scope"), Object.freeze({
|
|
2876
|
+
operation: e.operation,
|
|
2877
|
+
snapshot: i
|
|
2878
|
+
});
|
|
2879
|
+
}),
|
|
2880
|
+
...o.map((e) => {
|
|
2881
|
+
let t = Z(e);
|
|
2882
|
+
return (t.origin.tenantId !== a.tenantId || t.subject?.id !== a.subject.id || t.subject.kind !== a.subject.kind) && j("World transition export escaped its Subject scope"), Object.freeze({
|
|
2883
|
+
operation: "transition",
|
|
2884
|
+
transition: t
|
|
2885
|
+
});
|
|
2886
|
+
})
|
|
2887
|
+
]);
|
|
2888
|
+
})));
|
|
2889
|
+
},
|
|
2890
|
+
pruneJournal: (e, t) => {
|
|
2891
|
+
let r;
|
|
2892
|
+
try {
|
|
2893
|
+
P(e, ["tenantId", "entityId"]), r = De(e), (!Number.isSafeInteger(t) || t < 0 || t > B()) && j("Invalid World journal retention cutoff");
|
|
2894
|
+
} catch {
|
|
2895
|
+
return D.fail(new n({ detail: "Invalid World journal retention scope" }));
|
|
2896
|
+
}
|
|
2897
|
+
return G("pruneJournal", r, () => I(() => v.transactional(async (e) => {
|
|
2898
|
+
let n = C(ke(r), ve("createdAt", new Date(t)), w("requestKey", null)), i = await e.query({
|
|
2899
|
+
table: k,
|
|
2900
|
+
predicate: n,
|
|
2901
|
+
order: [{
|
|
2902
|
+
column: "revision",
|
|
2903
|
+
direction: "asc"
|
|
2904
|
+
}, {
|
|
2905
|
+
column: "id",
|
|
2906
|
+
direction: "asc"
|
|
2907
|
+
}],
|
|
2908
|
+
take: Te,
|
|
2909
|
+
skip: void 0,
|
|
2910
|
+
projection: [
|
|
2911
|
+
"id",
|
|
2912
|
+
"tenantId",
|
|
2913
|
+
"entityId"
|
|
2914
|
+
],
|
|
2915
|
+
lock: "update"
|
|
2916
|
+
});
|
|
2917
|
+
if (!i.length) return 0;
|
|
2918
|
+
let a = i.map((e) => ((e.tenantId !== r.tenantId || e.entityId !== r.entityId) && j("World journal retention escaped its entity scope"), M(e.id))), o = await e.deleteMany(k, { where: C(n, he("id", a)) });
|
|
2919
|
+
return o !== i.length && j("World journal retention lost its selected rows"), o;
|
|
2920
|
+
})));
|
|
2921
|
+
},
|
|
2922
|
+
transitionsEnabled: L !== void 0,
|
|
2923
|
+
transitions: L === void 0 ? void 0 : Object.freeze({
|
|
2924
|
+
begin: ct,
|
|
2925
|
+
advance: Ft,
|
|
2926
|
+
observe: Ze,
|
|
2927
|
+
scanSourceTransitions: dt,
|
|
2928
|
+
retainActorSnapshot: jt,
|
|
2929
|
+
retainActorDeparture: Mt,
|
|
2930
|
+
finalizeActorSnapshot: Nt,
|
|
2931
|
+
admitActorSeat: xt,
|
|
2932
|
+
withActorFollower: Et,
|
|
2933
|
+
admitActorGhost: Dt,
|
|
2934
|
+
admitActorTarget: Ot,
|
|
2935
|
+
admitActorSource: At,
|
|
2936
|
+
admitActorSourceRecovery: kt,
|
|
2937
|
+
observeActorReceipt: bt,
|
|
2938
|
+
batchCommitRows: A,
|
|
2939
|
+
beginGroup: vt,
|
|
2940
|
+
observeGroupCommand: ut,
|
|
2941
|
+
scanGroupCommands: ft,
|
|
2942
|
+
acknowledgeGroupCommand: pt,
|
|
2943
|
+
proceedGroup: _t,
|
|
2944
|
+
commitBatch: It,
|
|
2945
|
+
bindGroup: at,
|
|
2946
|
+
advanceGroup: ot,
|
|
2947
|
+
requiresGroupReadiness: R?.readiness !== void 0,
|
|
2948
|
+
readyMember: rt,
|
|
2949
|
+
confirmGroupReady: it
|
|
2950
|
+
})
|
|
2951
|
+
});
|
|
2952
|
+
}, Me = (e) => Object.freeze({
|
|
2953
|
+
extendSchema: Object.freeze({ tables: e.transitionsEnabled ? Ee : A }),
|
|
2954
|
+
subjectPrivacy: Object.freeze({
|
|
2955
|
+
tables: Object.freeze(e.transitionsEnabled ? [
|
|
2956
|
+
O,
|
|
2957
|
+
k,
|
|
2958
|
+
l
|
|
2959
|
+
] : [O, k]),
|
|
2960
|
+
kinds: Object.freeze(["user", "guest"])
|
|
2961
|
+
}),
|
|
2962
|
+
onErase: e.onErase.bind(e),
|
|
2963
|
+
onExport: e.onExport.bind(e)
|
|
2964
|
+
}), Ne = (e, t) => {
|
|
2965
|
+
t && typeof t.persistBatchFromCommand == "function" || j("World entity persistence command requires an actual source");
|
|
2966
|
+
let n = M(e), r = t.persistBatchFromCommand.bind(t);
|
|
2967
|
+
return Object.freeze({
|
|
2968
|
+
run: Object.freeze({ [n]: (e, t) => r(e, t) }),
|
|
2969
|
+
publish: Object.freeze({})
|
|
2970
|
+
});
|
|
2971
|
+
}, L = (e, t) => {
|
|
2972
|
+
t && typeof t.transferFromCommand == "function" || j("World entity transfer command requires an actual source");
|
|
2973
|
+
let n = M(e), r = t.transferFromCommand.bind(t);
|
|
2974
|
+
return Object.freeze({
|
|
2975
|
+
run: Object.freeze({ [n]: (e, t) => r(e, t) }),
|
|
2976
|
+
publish: Object.freeze({})
|
|
2977
|
+
});
|
|
2978
|
+
};
|
|
2979
|
+
export { O as WORLD_ENTITIES_TABLE, k as WORLD_JOURNAL_TABLE, je as dataStoreWorldEntities, Me as worldEntitiesContribution, we as worldEntitiesTable, Ne as worldEntityPersistenceCommandBindings, A as worldEntityTables, L as worldEntityTransferCommandBindings, Te as worldJournalTable, Ee as worldTransitionTables };
|