@plurnk/plurnk-service 1.16.5 → 1.18.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/.env.defaults +140 -246
- package/INSTALL.md +84 -138
- package/README.md +10 -6
- package/SPEC.md +2468 -1694
- package/dist/Paths.d.ts +2 -0
- package/dist/Paths.d.ts.map +1 -1
- package/dist/Paths.js +2 -0
- package/dist/Paths.js.map +1 -1
- package/dist/build-info.d.ts.map +1 -1
- package/dist/build-info.js +7 -1
- package/dist/build-info.js.map +1 -1
- package/dist/build-info.json +1 -1
- package/dist/content/body-preview.d.ts +8 -0
- package/dist/content/body-preview.d.ts.map +1 -0
- package/dist/content/body-preview.js +39 -0
- package/dist/content/body-preview.js.map +1 -0
- package/dist/content/byte-view.d.ts +1 -4
- package/dist/content/byte-view.d.ts.map +1 -1
- package/dist/content/byte-view.js.map +1 -1
- package/dist/content/edit-collision.d.ts.map +1 -1
- package/dist/content/edit-collision.js +3 -4
- package/dist/content/edit-collision.js.map +1 -1
- package/dist/content/line-anchors.d.ts +2 -2
- package/dist/content/line-anchors.d.ts.map +1 -1
- package/dist/content/line-anchors.js +4 -3
- package/dist/content/line-anchors.js.map +1 -1
- package/dist/content/line-selection.d.ts +9 -0
- package/dist/content/line-selection.d.ts.map +1 -0
- package/dist/content/line-selection.js +29 -0
- package/dist/content/line-selection.js.map +1 -0
- package/dist/content/matcher.d.ts +0 -1
- package/dist/content/matcher.d.ts.map +1 -1
- package/dist/content/matcher.js +2 -3
- package/dist/content/matcher.js.map +1 -1
- package/dist/content/pattern-edits.d.ts +39 -0
- package/dist/content/pattern-edits.d.ts.map +1 -0
- package/dist/content/pattern-edits.js +121 -0
- package/dist/content/pattern-edits.js.map +1 -0
- package/dist/content/read-projector.d.ts +18 -9
- package/dist/content/read-projector.d.ts.map +1 -1
- package/dist/content/read-projector.js +132 -35
- package/dist/content/read-projector.js.map +1 -1
- package/dist/content/read-resolve.d.ts +4 -1
- package/dist/content/read-resolve.d.ts.map +1 -1
- package/dist/content/read-resolve.js +42 -7
- package/dist/content/read-resolve.js.map +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts +2 -5
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
- package/dist/core/AdmittedTurnExecutor.js +96 -88
- package/dist/core/AdmittedTurnExecutor.js.map +1 -1
- package/dist/core/BareBatchRunner.d.ts +6 -1
- package/dist/core/BareBatchRunner.d.ts.map +1 -1
- package/dist/core/BareBatchRunner.js +20 -5
- package/dist/core/BareBatchRunner.js.map +1 -1
- package/dist/core/BudgetReadout.d.ts +2 -3
- package/dist/core/BudgetReadout.d.ts.map +1 -1
- package/dist/core/BudgetReadout.js +23 -32
- package/dist/core/BudgetReadout.js.map +1 -1
- package/dist/core/CapabilityPolicies.d.ts +3 -8
- package/dist/core/CapabilityPolicies.d.ts.map +1 -1
- package/dist/core/CapabilityPolicies.js +2 -28
- package/dist/core/CapabilityPolicies.js.map +1 -1
- package/dist/core/CapabilityResolver.d.ts +10 -10
- package/dist/core/CapabilityResolver.d.ts.map +1 -1
- package/dist/core/CapabilityResolver.js +122 -93
- package/dist/core/CapabilityResolver.js.map +1 -1
- package/dist/core/ChannelWrite.d.ts +15 -11
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js +12 -13
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +99 -9
- package/dist/core/ClientInteractions.d.ts.map +1 -1
- package/dist/core/ClientInteractions.js +7 -0
- package/dist/core/ClientInteractions.js.map +1 -1
- package/dist/core/CoreSchemeServices.d.ts +13 -10
- package/dist/core/CoreSchemeServices.d.ts.map +1 -1
- package/dist/core/CoreSchemeServices.js +13 -5
- package/dist/core/CoreSchemeServices.js.map +1 -1
- package/dist/core/DataStatementRunner.d.ts +2 -2
- package/dist/core/DataStatementRunner.d.ts.map +1 -1
- package/dist/core/DataStatementRunner.js +208 -161
- package/dist/core/DataStatementRunner.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +24 -26
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +381 -232
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/Dispatcher.sql +66 -0
- package/dist/core/DurableStatement.d.ts.map +1 -1
- package/dist/core/DurableStatement.js +2 -1
- package/dist/core/DurableStatement.js.map +1 -1
- package/dist/core/EditMutations.d.ts +14 -18
- package/dist/core/EditMutations.d.ts.map +1 -1
- package/dist/core/EditMutations.js +211 -280
- package/dist/core/EditMutations.js.map +1 -1
- package/dist/core/EditMutations.sql +15 -0
- package/dist/core/EditSequence.d.ts +13 -0
- package/dist/core/EditSequence.d.ts.map +1 -0
- package/dist/core/EditSequence.js +73 -0
- package/dist/core/EditSequence.js.map +1 -0
- package/dist/core/Engine.d.ts +17 -23
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +74 -164
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +0 -724
- package/dist/core/EntryAddressBinding.d.ts +7 -17
- package/dist/core/EntryAddressBinding.d.ts.map +1 -1
- package/dist/core/EntryAddressBinding.js +12 -72
- package/dist/core/EntryAddressBinding.js.map +1 -1
- package/dist/core/ExecutionOutputs.d.ts +9 -0
- package/dist/core/ExecutionOutputs.d.ts.map +1 -0
- package/dist/core/ExecutionOutputs.js +36 -0
- package/dist/core/ExecutionOutputs.js.map +1 -0
- package/dist/core/ExecutionOutputs.sql +21 -0
- package/dist/core/ExecutorRegistry.d.ts +11 -5
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +37 -32
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/HostPaths.d.ts +1 -0
- package/dist/core/HostPaths.d.ts.map +1 -1
- package/dist/core/HostPaths.js +4 -0
- package/dist/core/HostPaths.js.map +1 -1
- package/dist/core/InferenceCall.d.ts.map +1 -1
- package/dist/core/InferenceCall.js +1 -2
- package/dist/core/InferenceCall.js.map +1 -1
- package/dist/core/InferenceCall.sql +29 -0
- package/dist/core/KillHandler.d.ts +1 -0
- package/dist/core/KillHandler.d.ts.map +1 -1
- package/dist/core/KillHandler.js +24 -21
- package/dist/core/KillHandler.js.map +1 -1
- package/dist/core/LogBody.d.ts +8 -1
- package/dist/core/LogBody.d.ts.map +1 -1
- package/dist/core/LogBody.js +44 -12
- package/dist/core/LogBody.js.map +1 -1
- package/dist/core/LogEntryProjection.d.ts +1 -0
- package/dist/core/LogEntryProjection.d.ts.map +1 -1
- package/dist/core/LogEntryProjection.js +12 -10
- package/dist/core/LogEntryProjection.js.map +1 -1
- package/dist/core/LogVisibility.d.ts +1 -0
- package/dist/core/LogVisibility.d.ts.map +1 -1
- package/dist/core/LogVisibility.js +3 -0
- package/dist/core/LogVisibility.js.map +1 -1
- package/dist/core/LogWriter.d.ts +2 -3
- package/dist/core/LogWriter.d.ts.map +1 -1
- package/dist/core/LogWriter.js +31 -36
- package/dist/core/LogWriter.js.map +1 -1
- package/dist/core/LogWriter.sql +23 -0
- package/dist/core/LoopDriver.d.ts +11 -8
- package/dist/core/LoopDriver.d.ts.map +1 -1
- package/dist/core/LoopDriver.js +161 -189
- package/dist/core/LoopDriver.js.map +1 -1
- package/dist/core/LoopDriver.sql +11 -0
- package/dist/core/LoopLifecycle.d.ts +32 -2
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/LoopLifecycle.js +88 -4
- package/dist/core/LoopLifecycle.js.map +1 -1
- package/dist/core/LoopLifecycle.sql +145 -28
- package/dist/core/LoopPolicyReader.sql +6 -0
- package/dist/core/MembershipMaterialization.d.ts.map +1 -1
- package/dist/core/MembershipMaterialization.js +6 -28
- package/dist/core/MembershipMaterialization.js.map +1 -1
- package/dist/core/ModelCall.d.ts.map +1 -1
- package/dist/core/ModelCall.js +2 -6
- package/dist/core/ModelCall.js.map +1 -1
- package/dist/core/ModelCall.sql +41 -0
- package/dist/core/MutationEffects.d.ts +5 -3
- package/dist/core/MutationEffects.d.ts.map +1 -1
- package/dist/core/MutationEffects.js +10 -28
- package/dist/core/MutationEffects.js.map +1 -1
- package/dist/core/NativeContent.d.ts +6 -0
- package/dist/core/NativeContent.d.ts.map +1 -0
- package/dist/core/NativeContent.js +16 -0
- package/dist/core/NativeContent.js.map +1 -0
- package/dist/core/NativeContent.sql +6 -0
- package/dist/core/NoticeChannel.js +1 -1
- package/dist/core/NoticeChannel.js.map +1 -1
- package/dist/core/OperatorConfig.js +5 -5
- package/dist/core/OperatorConfig.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts +8 -5
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +117 -81
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/PacketBuilder.sql +146 -0
- package/dist/core/PatternSelection.d.ts +28 -0
- package/dist/core/PatternSelection.d.ts.map +1 -0
- package/dist/core/PatternSelection.js +42 -0
- package/dist/core/PatternSelection.js.map +1 -0
- package/dist/core/ProblemLog.d.ts.map +1 -1
- package/dist/core/ProblemLog.js +0 -1
- package/dist/core/ProblemLog.js.map +1 -1
- package/dist/core/PromptFrames.d.ts +12 -0
- package/dist/core/PromptFrames.d.ts.map +1 -0
- package/dist/core/PromptFrames.js +28 -0
- package/dist/core/PromptFrames.js.map +1 -0
- package/dist/core/ProposalLifecycle.d.ts +0 -1
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +26 -23
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ProposalLifecycle.sql +33 -0
- package/dist/core/ProviderInstantiate.d.ts +1 -1
- package/dist/core/ProviderInstantiate.d.ts.map +1 -1
- package/dist/core/ProviderInstantiate.js +7 -14
- package/dist/core/ProviderInstantiate.js.map +1 -1
- package/dist/core/ReasoningView.d.ts +9 -0
- package/dist/core/ReasoningView.d.ts.map +1 -0
- package/dist/core/ReasoningView.js +47 -0
- package/dist/core/ReasoningView.js.map +1 -0
- package/dist/core/ResourceBindings.d.ts +16 -0
- package/dist/core/ResourceBindings.d.ts.map +1 -0
- package/dist/core/ResourceBindings.js +45 -0
- package/dist/core/ResourceBindings.js.map +1 -0
- package/dist/core/ResourceMutations.d.ts +5 -8
- package/dist/core/ResourceMutations.d.ts.map +1 -1
- package/dist/core/ResourceMutations.js +6 -7
- package/dist/core/ResourceMutations.js.map +1 -1
- package/dist/core/ResourceSelector.d.ts +2 -2
- package/dist/core/ResourceSelector.d.ts.map +1 -1
- package/dist/core/ResourceSelector.js +122 -62
- package/dist/core/ResourceSelector.js.map +1 -1
- package/dist/core/ResourceTransfers.d.ts +4 -2
- package/dist/core/ResourceTransfers.d.ts.map +1 -1
- package/dist/core/ResourceTransfers.js +95 -26
- package/dist/core/ResourceTransfers.js.map +1 -1
- package/dist/core/RuntimeWorker.d.ts +5 -0
- package/dist/core/RuntimeWorker.d.ts.map +1 -0
- package/dist/core/RuntimeWorker.js +15 -0
- package/dist/core/RuntimeWorker.js.map +1 -0
- package/dist/core/RuntimeWorker.sql +11 -0
- package/dist/core/SchemeRegistry.d.ts +12 -16
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +59 -85
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/StoredPacket.d.ts +6 -1
- package/dist/core/StoredPacket.d.ts.map +1 -1
- package/dist/core/StoredPacket.js +30 -10
- package/dist/core/StoredPacket.js.map +1 -1
- package/dist/core/StrikeRail.d.ts +11 -8
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +63 -114
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/StrikeRail.sql +12 -0
- package/dist/core/TerminalResult.d.ts +1 -1
- package/dist/core/TerminalResult.d.ts.map +1 -1
- package/dist/core/TerminalResult.js +2 -2
- package/dist/core/TerminalResult.js.map +1 -1
- package/dist/core/TokenCalibration.d.ts +1 -6
- package/dist/core/TokenCalibration.d.ts.map +1 -1
- package/dist/core/TokenCalibration.js +13 -9
- package/dist/core/TokenCalibration.js.map +1 -1
- package/dist/core/TokenCalibration.sql +15 -0
- package/dist/core/ToolInputSchema.d.ts +6 -0
- package/dist/core/ToolInputSchema.d.ts.map +1 -0
- package/dist/core/ToolInputSchema.js +43 -0
- package/dist/core/ToolInputSchema.js.map +1 -0
- package/dist/core/ToolResources.d.ts.map +1 -1
- package/dist/core/ToolResources.js +77 -51
- package/dist/core/ToolResources.js.map +1 -1
- package/dist/core/Turn.d.ts +5 -2
- package/dist/core/Turn.d.ts.map +1 -1
- package/dist/core/Turn.js +13 -11
- package/dist/core/Turn.js.map +1 -1
- package/dist/core/Turn.sql +25 -39
- package/dist/core/{SendBroadcastHandler.d.ts → TurnDispositionHandler.d.ts} +24 -18
- package/dist/core/TurnDispositionHandler.d.ts.map +1 -0
- package/dist/core/TurnDispositionHandler.js +206 -0
- package/dist/core/TurnDispositionHandler.js.map +1 -0
- package/dist/core/TurnMaterialization.d.ts +2 -3
- package/dist/core/TurnMaterialization.d.ts.map +1 -1
- package/dist/core/TurnMaterialization.js +47 -24
- package/dist/core/TurnMaterialization.js.map +1 -1
- package/dist/core/TurnMaterialization.sql +44 -0
- package/dist/core/TurnOps.d.ts.map +1 -1
- package/dist/core/TurnOps.js +8 -64
- package/dist/core/TurnOps.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +8 -15
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +1175 -1317
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/TurnRunner.sql +74 -0
- package/dist/core/TurnSources.sql +39 -0
- package/dist/core/WorkerControlAddress.d.ts +1 -0
- package/dist/core/WorkerControlAddress.d.ts.map +1 -1
- package/dist/core/WorkerControlAddress.js +5 -0
- package/dist/core/WorkerControlAddress.js.map +1 -1
- package/dist/core/WorkerControlHandler.d.ts +1 -3
- package/dist/core/WorkerControlHandler.d.ts.map +1 -1
- package/dist/core/WorkerControlHandler.js +64 -48
- package/dist/core/WorkerControlHandler.js.map +1 -1
- package/dist/core/WorkerName.d.ts +11 -12
- package/dist/core/WorkerName.d.ts.map +1 -1
- package/dist/core/WorkerName.js +40 -47
- package/dist/core/WorkerName.js.map +1 -1
- package/dist/core/WorkerName.sql +7 -10
- package/dist/core/WorkspaceGate.d.ts +1 -1
- package/dist/core/WorkspaceGate.d.ts.map +1 -1
- package/dist/core/WorkspaceGate.js +33 -10
- package/dist/core/WorkspaceGate.js.map +1 -1
- package/dist/core/ambient.sql +236 -0
- package/dist/core/attachments.d.ts +2 -1
- package/dist/core/attachments.d.ts.map +1 -1
- package/dist/core/attachments.js +5 -4
- package/dist/core/attachments.js.map +1 -1
- package/dist/core/caps/CapsResolve.d.ts +2 -3
- package/dist/core/caps/CapsResolve.d.ts.map +1 -1
- package/dist/core/caps/CapsResolve.js +5 -5
- package/dist/core/caps/CapsResolve.js.map +1 -1
- package/dist/core/caps/DbChannelCaps.d.ts +1 -1
- package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
- package/dist/core/caps/DbChannelCaps.js +4 -6
- package/dist/core/caps/DbChannelCaps.js.map +1 -1
- package/dist/core/caps/DbEntryCaps.d.ts +2 -1
- package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
- package/dist/core/caps/DbEntryCaps.js +11 -17
- package/dist/core/caps/DbEntryCaps.js.map +1 -1
- package/dist/core/caps/DbNotifyCaps.d.ts +1 -1
- package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -1
- package/dist/core/caps/DbNotifyCaps.js +3 -5
- package/dist/core/caps/DbNotifyCaps.js.map +1 -1
- package/dist/core/caps/DbProjectionCaps.js +1 -1
- package/dist/core/caps/DbProjectionCaps.js.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.js +5 -7
- package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts +0 -2
- package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.js +4 -20
- package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
- package/dist/core/env-catalog.d.ts +28 -0
- package/dist/core/env-catalog.d.ts.map +1 -0
- package/dist/core/env-catalog.js +99 -0
- package/dist/core/env-catalog.js.map +1 -0
- package/dist/core/env-defaults.d.ts.map +1 -1
- package/dist/core/env-defaults.js +4 -2
- package/dist/core/env-defaults.js.map +1 -1
- package/dist/core/file-materialization.d.ts +4 -1
- package/dist/core/file-materialization.d.ts.map +1 -1
- package/dist/core/file-materialization.js +15 -1
- package/dist/core/file-materialization.js.map +1 -1
- package/dist/core/fork.d.ts +1 -6
- package/dist/core/fork.d.ts.map +1 -1
- package/dist/core/fork.js +9 -153
- package/dist/core/fork.js.map +1 -1
- package/dist/core/fork.sql +162 -185
- package/dist/core/git-env.d.ts +1 -0
- package/dist/core/git-env.d.ts.map +1 -1
- package/dist/core/git-env.js +39 -2
- package/dist/core/git-env.js.map +1 -1
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +64 -48
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/git-state.d.ts.map +1 -1
- package/dist/core/git-state.js +26 -20
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/glob_match.d.ts +4 -0
- package/dist/core/glob_match.d.ts.map +1 -0
- package/dist/core/glob_match.js +7 -0
- package/dist/core/glob_match.js.map +1 -0
- package/dist/core/maintenance.sql +6 -0
- package/dist/core/mutation-types.d.ts +7 -28
- package/dist/core/mutation-types.d.ts.map +1 -1
- package/dist/core/operation-target-groups.d.ts.map +1 -1
- package/dist/core/operation-target-groups.js +2 -1
- package/dist/core/operation-target-groups.js.map +1 -1
- package/dist/core/packet-inject.d.ts.map +1 -1
- package/dist/core/packet-inject.js +2 -3
- package/dist/core/packet-inject.js.map +1 -1
- package/dist/core/packet-wire.d.ts +8 -6
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +381 -388
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/plurnk-uri.d.ts +1 -1
- package/dist/core/plurnk-uri.d.ts.map +1 -1
- package/dist/core/plurnk-uri.js +5 -12
- package/dist/core/plurnk-uri.js.map +1 -1
- package/dist/core/scheme-types.d.ts +3 -3
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/scheme-types.js.map +1 -1
- package/dist/core/sha256.d.ts +4 -0
- package/dist/core/sha256.d.ts.map +1 -0
- package/dist/core/sha256.js +6 -0
- package/dist/core/sha256.js.map +1 -0
- package/dist/core/teaching.js +1 -1
- package/dist/core/teaching.js.map +1 -1
- package/dist/core/turn-scheduler.d.ts.map +1 -1
- package/dist/core/turn-scheduler.js +5 -18
- package/dist/core/turn-scheduler.js.map +1 -1
- package/dist/core/turn-signals.d.ts +0 -6
- package/dist/core/turn-signals.d.ts.map +1 -1
- package/dist/core/turn-signals.js +1 -7
- package/dist/core/turn-signals.js.map +1 -1
- package/dist/core/worker-ops.sql +15 -22
- package/dist/core/workspace-settings.d.ts.map +1 -1
- package/dist/core/workspace-settings.js +18 -2
- package/dist/core/workspace-settings.js.map +1 -1
- package/dist/core/workspace-settings.sql +6 -0
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +30 -91
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/DigestRender.d.ts +1 -0
- package/dist/digest/DigestRender.d.ts.map +1 -1
- package/dist/digest/DigestRender.js +58 -62
- package/dist/digest/DigestRender.js.map +1 -1
- package/dist/digest/digest-rows.d.ts +16 -32
- package/dist/digest/digest-rows.d.ts.map +1 -1
- package/dist/digest/digest.sql +54 -20
- package/dist/schemes/Exec.d.ts +6 -12
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +318 -215
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +8 -6
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +33 -61
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/ExecScheduler.js +2 -2
- package/dist/schemes/ExecScheduler.js.map +1 -1
- package/dist/schemes/ExecutionInput.d.ts +12 -0
- package/dist/schemes/ExecutionInput.d.ts.map +1 -0
- package/dist/schemes/ExecutionInput.js +94 -0
- package/dist/schemes/ExecutionInput.js.map +1 -0
- package/dist/schemes/File.d.ts +5 -2
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +62 -91
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +84 -79
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Log.sql +183 -15
- package/dist/schemes/Prompt.d.ts.map +1 -1
- package/dist/schemes/Prompt.js +3 -12
- package/dist/schemes/Prompt.js.map +1 -1
- package/dist/schemes/QuestionTool.d.ts +5 -0
- package/dist/schemes/QuestionTool.d.ts.map +1 -1
- package/dist/schemes/QuestionTool.js +7 -15
- package/dist/schemes/QuestionTool.js.map +1 -1
- package/dist/schemes/Skill.d.ts +12 -7
- package/dist/schemes/Skill.d.ts.map +1 -1
- package/dist/schemes/Skill.js +149 -21
- package/dist/schemes/Skill.js.map +1 -1
- package/dist/schemes/TurnSource.d.ts +12 -0
- package/dist/schemes/TurnSource.d.ts.map +1 -0
- package/dist/schemes/TurnSource.js +117 -0
- package/dist/schemes/TurnSource.js.map +1 -0
- package/dist/schemes/Worker.d.ts +3 -3
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +61 -208
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts +12 -15
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +63 -63
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-crud.sql +159 -45
- package/dist/schemes/_entry-find.d.ts +1 -3
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +111 -112
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-find.sql +22 -14
- package/dist/schemes/_entry-fts.d.ts +14 -0
- package/dist/schemes/_entry-fts.d.ts.map +1 -0
- package/dist/schemes/_entry-fts.js +82 -0
- package/dist/schemes/_entry-fts.js.map +1 -0
- package/dist/schemes/_entry-fts.sql +31 -0
- package/dist/schemes/_entry-graph.d.ts.map +1 -1
- package/dist/schemes/_entry-graph.js +6 -14
- package/dist/schemes/_entry-graph.js.map +1 -1
- package/dist/schemes/_entry-graph.sql +29 -44
- package/dist/schemes/_entry-manifest.d.ts +2 -1
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +20 -26
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-manifest.sql +26 -0
- package/dist/schemes/_entry-ops.d.ts +3 -5
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +30 -43
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-ops.sql +5 -6
- package/dist/schemes/_entry-readable.d.ts +8 -0
- package/dist/schemes/_entry-readable.d.ts.map +1 -0
- package/dist/schemes/_entry-readable.js +38 -0
- package/dist/schemes/_entry-readable.js.map +1 -0
- package/dist/schemes/_entry-send.d.ts +1 -1
- package/dist/schemes/_entry-send.d.ts.map +1 -1
- package/dist/schemes/_entry-send.js +3 -3
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/schemes/_search-index.d.ts +5 -3
- package/dist/schemes/_search-index.d.ts.map +1 -1
- package/dist/schemes/_search-index.js +169 -160
- package/dist/schemes/_search-index.js.map +1 -1
- package/dist/schemes/_search-index.sql +47 -0
- package/dist/schemes/exec-abort.js +1 -1
- package/dist/schemes/exec-abort.js.map +1 -1
- package/dist/schemes/exec-env.d.ts +3 -0
- package/dist/schemes/exec-env.d.ts.map +1 -1
- package/dist/schemes/exec-env.js +66 -15
- package/dist/schemes/exec-env.js.map +1 -1
- package/dist/schemes/exec-runtime.d.ts +1 -1
- package/dist/schemes/exec-runtime.d.ts.map +1 -1
- package/dist/schemes/exec-runtime.js +1 -1
- package/dist/schemes/exec-runtime.js.map +1 -1
- package/dist/server/ClientReads.d.ts +2 -2
- package/dist/server/ClientReads.d.ts.map +1 -1
- package/dist/server/ClientReads.js +7 -9
- package/dist/server/ClientReads.js.map +1 -1
- package/dist/server/Daemon.d.ts +15 -21
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +165 -168
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonModule.d.ts +29 -22
- package/dist/server/DaemonModule.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.d.ts +8 -21
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +278 -306
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/EnvFunctionality.d.ts +43 -0
- package/dist/server/EnvFunctionality.d.ts.map +1 -0
- package/dist/server/EnvFunctionality.js +194 -0
- package/dist/server/EnvFunctionality.js.map +1 -0
- package/dist/server/Functionality.d.ts +12 -11
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js +279 -142
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/FunctionalityManager.d.ts +5 -5
- package/dist/server/FunctionalityManager.d.ts.map +1 -1
- package/dist/server/FunctionalityManager.js +29 -57
- package/dist/server/FunctionalityManager.js.map +1 -1
- package/dist/server/MembersFunctionality.d.ts +5 -4
- package/dist/server/MembersFunctionality.d.ts.map +1 -1
- package/dist/server/MembersFunctionality.js +24 -38
- package/dist/server/MembersFunctionality.js.map +1 -1
- package/dist/server/PlurnkSkill.d.ts +11 -0
- package/dist/server/PlurnkSkill.d.ts.map +1 -0
- package/dist/server/PlurnkSkill.js +41 -0
- package/dist/server/PlurnkSkill.js.map +1 -0
- package/dist/server/Retention.d.ts +25 -0
- package/dist/server/Retention.d.ts.map +1 -0
- package/dist/server/Retention.js +57 -0
- package/dist/server/Retention.js.map +1 -0
- package/dist/server/Retention.sql +59 -0
- package/dist/server/ServiceModules.d.ts +5 -0
- package/dist/server/ServiceModules.d.ts.map +1 -0
- package/dist/server/ServiceModules.js +10 -0
- package/dist/server/ServiceModules.js.map +1 -0
- package/dist/server/SkillsFunctionality.d.ts +14 -19
- package/dist/server/SkillsFunctionality.d.ts.map +1 -1
- package/dist/server/SkillsFunctionality.js +102 -106
- package/dist/server/SkillsFunctionality.js.map +1 -1
- package/dist/server/WorkerModelResolver.d.ts +4 -0
- package/dist/server/WorkerModelResolver.d.ts.map +1 -1
- package/dist/server/WorkerModelResolver.js +72 -39
- package/dist/server/WorkerModelResolver.js.map +1 -1
- package/dist/server/WorkspaceCapabilities.d.ts +21 -0
- package/dist/server/WorkspaceCapabilities.d.ts.map +1 -0
- package/dist/server/{WorkerCapabilities.js → WorkspaceCapabilities.js} +40 -40
- package/dist/server/WorkspaceCapabilities.js.map +1 -0
- package/dist/server/WorkspaceResidency.d.ts +38 -0
- package/dist/server/WorkspaceResidency.d.ts.map +1 -0
- package/dist/server/WorkspaceResidency.js +226 -0
- package/dist/server/WorkspaceResidency.js.map +1 -0
- package/dist/server/client-input.d.ts +1 -4
- package/dist/server/client-input.d.ts.map +1 -1
- package/dist/server/client-input.js +5 -46
- package/dist/server/client-input.js.map +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +4 -22
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/drain.sql +66 -43
- package/dist/server/envelope.d.ts +8 -1
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +9 -19
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +49 -13
- package/dist/server/lifecycle-recovery.sql +18 -20
- package/dist/server/logEntry.d.ts +1 -1
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +4 -1
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +25 -1
- package/dist/server/loopDocs.d.ts +2 -2
- package/dist/server/loopDocs.d.ts.map +1 -1
- package/dist/server/loopDocs.js +38 -31
- package/dist/server/loopDocs.js.map +1 -1
- package/dist/server/loopDocs.sql +1 -3
- package/dist/server/model-catalog.d.ts.map +1 -1
- package/dist/server/model-catalog.js +2 -1
- package/dist/server/model-catalog.js.map +1 -1
- package/dist/server/model-route.d.ts +1 -1
- package/dist/server/model-route.d.ts.map +1 -1
- package/dist/server/model-route.js +4 -2
- package/dist/server/model-route.js.map +1 -1
- package/dist/server/seam-entry-read.sql +3 -4
- package/dist/server/seam-loop.sql +2 -9
- package/dist/server/workspace-capabilities.sql +64 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +21 -18
- package/dist/service.js.map +1 -1
- package/docs/env.md +55 -0
- package/docs/members.md +83 -0
- package/docs/skills.md +50 -0
- package/migrations/001_workspaces.sql +53 -0
- package/migrations/002_workers.sql +198 -0
- package/migrations/003_loops.sql +326 -0
- package/migrations/004_inference.sql +401 -0
- package/migrations/005_entries.sql +215 -0
- package/migrations/006_log.sql +581 -0
- package/migrations/007_subscriptions.sql +175 -0
- package/migrations/008_interactions.sql +29 -0
- package/package.json +44 -41
- package/digest-sql/channel-dispositions/dispositions.sql +0 -15
- package/digest-sql/channel-state/state.sql +0 -6
- package/digest-sql/curation/curation.sql +0 -6
- package/digest-sql/derivations/derivations.sql +0 -4
- package/digest-sql/embeddings/embeddings.sql +0 -4
- package/digest-sql/entry-dispositions/dispositions.sql +0 -15
- package/digest-sql/entry-state/state.sql +0 -6
- package/digest-sql/token-counts/token-counts.sql +0 -2
- package/dist/core/EmbeddingCall.d.ts +0 -23
- package/dist/core/EmbeddingCall.d.ts.map +0 -1
- package/dist/core/EmbeddingCall.js +0 -149
- package/dist/core/EmbeddingCall.js.map +0 -1
- package/dist/core/OverflowTurn.d.ts +0 -11
- package/dist/core/OverflowTurn.d.ts.map +0 -1
- package/dist/core/OverflowTurn.js +0 -80
- package/dist/core/OverflowTurn.js.map +0 -1
- package/dist/core/Owner.d.ts +0 -8
- package/dist/core/Owner.d.ts.map +0 -1
- package/dist/core/Owner.js +0 -46
- package/dist/core/Owner.js.map +0 -1
- package/dist/core/SendBroadcastHandler.d.ts.map +0 -1
- package/dist/core/SendBroadcastHandler.js +0 -159
- package/dist/core/SendBroadcastHandler.js.map +0 -1
- package/dist/core/VectorPump.d.ts +0 -28
- package/dist/core/VectorPump.d.ts.map +0 -1
- package/dist/core/VectorPump.js +0 -130
- package/dist/core/VectorPump.js.map +0 -1
- package/dist/core/owner.sql +0 -11
- package/dist/core/worker-settings.d.ts +0 -10
- package/dist/core/worker-settings.d.ts.map +0 -1
- package/dist/core/worker-settings.js +0 -53
- package/dist/core/worker-settings.js.map +0 -1
- package/dist/schemes/_entry-chunk.d.ts +0 -14
- package/dist/schemes/_entry-chunk.d.ts.map +0 -1
- package/dist/schemes/_entry-chunk.js +0 -165
- package/dist/schemes/_entry-chunk.js.map +0 -1
- package/dist/schemes/_entry-semantic.d.ts +0 -63
- package/dist/schemes/_entry-semantic.d.ts.map +0 -1
- package/dist/schemes/_entry-semantic.js +0 -299
- package/dist/schemes/_entry-semantic.js.map +0 -1
- package/dist/schemes/_entry-semantic.sql +0 -99
- package/dist/schemes/cosine.d.ts +0 -4
- package/dist/schemes/cosine.d.ts.map +0 -1
- package/dist/schemes/cosine.js +0 -9
- package/dist/schemes/cosine.js.map +0 -1
- package/dist/server/WorkerCapabilities.d.ts +0 -21
- package/dist/server/WorkerCapabilities.d.ts.map +0 -1
- package/dist/server/WorkerCapabilities.js.map +0 -1
- package/dist/server/WorkerResidency.d.ts +0 -40
- package/dist/server/WorkerResidency.d.ts.map +0 -1
- package/dist/server/WorkerResidency.js +0 -283
- package/dist/server/WorkerResidency.js.map +0 -1
- package/dist/server/seam-log-read.sql +0 -21
- package/dist/server/worker-capabilities.sql +0 -28
- package/migrations/001_schema.sql +0 -2207
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
var _a;
|
|
2
|
-
// {§functionality-coordinator} — the one owner of the
|
|
2
|
+
// {§functionality-coordinator} — the one owner of the workspace Functionality
|
|
3
3
|
// lifecycle above the family adapters (Agent Skills, MCP, outbound A2A). It owns
|
|
4
|
-
// durable
|
|
5
|
-
// publication, and both projections:
|
|
6
|
-
//
|
|
4
|
+
// durable workspace state, lifecycle ordering, serialization, atomic
|
|
5
|
+
// publication, and both projections: workspace-scoped client actions and a
|
|
6
|
+
// generated executor family whose host verbs propose. An explicit
|
|
7
7
|
// client mutation and an accepted model proposal converge on `invoke`.
|
|
8
8
|
import { Validator } from "@plurnk/plurnk-contracts";
|
|
9
|
+
import { isDeepStrictEqual } from "node:util";
|
|
10
|
+
import { DocFile } from "@plurnk/plurnk-execs";
|
|
9
11
|
import FunctionalityManager, { FUNCTIONALITY_VERBS, functionalityRuntimeDecl, } from "./FunctionalityManager.js";
|
|
10
12
|
import Results, { OperationFailureError } from "../core/results.js";
|
|
11
13
|
import { generatedPathname } from "../core/plurnk-uri.js";
|
|
12
14
|
const STATE_VERSION = 1;
|
|
13
15
|
const FAMILY = /^[a-z][a-z0-9]*$/u;
|
|
14
16
|
const ALIAS = /^[a-z][a-z0-9-]*$/u;
|
|
17
|
+
// A family may declare its own alias grammar ({§functionality-adapter}); the coordinator enforces it
|
|
18
|
+
// wherever an alias enters: admission, the service projection, and persisted state.
|
|
19
|
+
const aliasPattern = (adapter) => adapter.aliasPattern ?? ALIAS;
|
|
15
20
|
const EMPTY_STATE = Object.freeze({ version: STATE_VERSION, definitions: Object.freeze({}) });
|
|
16
21
|
const SCHEMA = (name) => ({ $ref: `https://schemas.plurnk.xyz/v0/${name}.json` });
|
|
17
22
|
const ALIAS_INPUT = Object.freeze({
|
|
@@ -34,7 +39,7 @@ class Functionality {
|
|
|
34
39
|
this.#host = host;
|
|
35
40
|
}
|
|
36
41
|
// {§functionality-adapter} — registration publishes the family's client
|
|
37
|
-
// actions and its
|
|
42
|
+
// actions and its workspace capability provider at once.
|
|
38
43
|
register(adapter) {
|
|
39
44
|
const { family, namespaceOwner } = adapter;
|
|
40
45
|
if (!FAMILY.test(family))
|
|
@@ -63,17 +68,28 @@ class Functionality {
|
|
|
63
68
|
disable: ALIAS_INPUT,
|
|
64
69
|
remove: ALIAS_INPUT,
|
|
65
70
|
});
|
|
71
|
+
// {§functionality-model-projection} — the taught `add` example must satisfy the schema it teaches.
|
|
72
|
+
if (adapter.example !== undefined) {
|
|
73
|
+
const example = Validator.validateJsonSchemaInstance(schemas.add, adapter.example);
|
|
74
|
+
if (!example.valid) {
|
|
75
|
+
throw new Error(`Functionality family '${family}' teaches an add example that violates its own definition schema: ${JSON.stringify(example.errors)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
66
78
|
this.#adapters.set(family, adapter);
|
|
67
79
|
this.#owners.add(namespaceOwner);
|
|
68
80
|
this.#schemas.set(family, schemas);
|
|
69
|
-
this.#host.
|
|
81
|
+
this.#host.registerWorkspaceCapabilityProvider(namespaceOwner, {
|
|
70
82
|
activate: (context) => this.#activate(adapter, context),
|
|
71
83
|
deactivate: (identity) => this.#deactivate(adapter, identity),
|
|
72
84
|
});
|
|
85
|
+
// {§functionality-scope} — a worker-scoped family projects `worker.<family>.<verb>`, whose
|
|
86
|
+
// context names the Worker the verb acts for; every other family projects
|
|
87
|
+
// `workspace.<family>.<verb>`. One implementation sits beneath both.
|
|
88
|
+
const scope = adapter.scope ?? "workspace";
|
|
73
89
|
for (const verb of FUNCTIONALITY_VERBS) {
|
|
74
90
|
this.#host.registerModuleAction({
|
|
75
|
-
name:
|
|
76
|
-
scope
|
|
91
|
+
name: `${scope}.${family}.${verb}`,
|
|
92
|
+
scope,
|
|
77
93
|
inputSchema: schemas[verb],
|
|
78
94
|
outputSchema: SCHEMA(verb === "list"
|
|
79
95
|
? "FunctionalityListResult"
|
|
@@ -81,10 +97,12 @@ class Functionality {
|
|
|
81
97
|
? "FunctionalityDiscoverResult"
|
|
82
98
|
: "FunctionalityMutationResult"),
|
|
83
99
|
handler: async (params, context) => {
|
|
84
|
-
if (context.scope
|
|
85
|
-
throw new Error(
|
|
86
|
-
const
|
|
87
|
-
|
|
100
|
+
if (context.scope === "worldless" || context.scope !== scope)
|
|
101
|
+
throw new Error(`${scope}.${family}.${verb} requires a ${scope}-scoped context.`);
|
|
102
|
+
const identity = context.scope === "worker"
|
|
103
|
+
? { workspaceId: context.workspaceId, workerId: context.workerId }
|
|
104
|
+
: { workspaceId: context.workspaceId };
|
|
105
|
+
return (await this.invoke(family, verb, params, identity, "action")).body;
|
|
88
106
|
},
|
|
89
107
|
});
|
|
90
108
|
}
|
|
@@ -93,20 +111,20 @@ class Functionality {
|
|
|
93
111
|
refresh: (identity, options) => this.refresh(family, identity, options),
|
|
94
112
|
};
|
|
95
113
|
}
|
|
96
|
-
// Republish a family's unchanged state for one
|
|
114
|
+
// Republish a family's unchanged state for one workspace — a live catalog
|
|
97
115
|
// change, not a lifecycle mutation. Serialized like every publication.
|
|
98
116
|
// `gate: "none"` publishes inside the caller's own held turn (turn admission
|
|
99
117
|
// refreshing a family before packet assembly) instead of contending for
|
|
100
118
|
// workspace exclusivity it could never win.
|
|
101
119
|
async refresh(family, identity, options = {}) {
|
|
102
120
|
const adapter = this.#adapter(family);
|
|
103
|
-
await this.#serialize(identity.
|
|
104
|
-
const current = this.#families.get(this.#key(identity.
|
|
121
|
+
await this.#serialize(this.#key(identity.workspaceId, family), async () => {
|
|
122
|
+
const current = this.#families.get(this.#key(identity.workspaceId, family));
|
|
105
123
|
if (current === undefined)
|
|
106
124
|
return;
|
|
107
125
|
await this.#publish(adapter, identity, current.state, {
|
|
108
126
|
failure: "publish-unavailable",
|
|
109
|
-
retain: () => this.#host.
|
|
127
|
+
retain: () => this.#host.retainWorkspace(identity.workspaceId),
|
|
110
128
|
gate: options.gate ?? "wait",
|
|
111
129
|
});
|
|
112
130
|
});
|
|
@@ -114,20 +132,33 @@ class Functionality {
|
|
|
114
132
|
families() {
|
|
115
133
|
return [...this.#adapters.keys()].toSorted();
|
|
116
134
|
}
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
async settle(
|
|
135
|
+
// Join outstanding invocations before inspecting or closing durable state.
|
|
136
|
+
// Rejections have already been delivered to their action or execution stream.
|
|
137
|
+
async settle(workspaceId) {
|
|
120
138
|
const pending = [...this.#queues]
|
|
121
|
-
.filter(([key]) =>
|
|
139
|
+
.filter(([key]) => workspaceId === undefined || key.startsWith(`${workspaceId}:`))
|
|
122
140
|
.map(([, queue]) => queue.catch(() => undefined));
|
|
123
141
|
await Promise.all(pending);
|
|
124
142
|
}
|
|
125
143
|
// {§functionality-documents} — the family-generated documents of every
|
|
126
|
-
// published family for one
|
|
127
|
-
|
|
144
|
+
// published family for one workspace, projected under each reader's generated subtree.
|
|
145
|
+
// {§functionality-document-body} — read once per family from the adapter's package, the same
|
|
146
|
+
// `docs/<tag>.md` rule runtimes use. A family that ships no file has a header-only document.
|
|
147
|
+
#documentBodies = new Map();
|
|
148
|
+
#documentBody(adapter) {
|
|
149
|
+
let body = this.#documentBodies.get(adapter.family);
|
|
150
|
+
if (body === undefined) {
|
|
151
|
+
body = adapter.docsDir === undefined
|
|
152
|
+
? Promise.resolve("")
|
|
153
|
+
: DocFile.read(adapter.docsDir, adapter.family).then((text) => text ?? "");
|
|
154
|
+
this.#documentBodies.set(adapter.family, body);
|
|
155
|
+
}
|
|
156
|
+
return body;
|
|
157
|
+
}
|
|
158
|
+
documents(workspaceId) {
|
|
128
159
|
const out = [];
|
|
129
160
|
for (const [key, family] of this.#families) {
|
|
130
|
-
if (!key.startsWith(`${
|
|
161
|
+
if (!key.startsWith(`${workspaceId}:`) || family.prepared === null)
|
|
131
162
|
continue;
|
|
132
163
|
for (const document of family.prepared.documents) {
|
|
133
164
|
out.push({ pathname: generatedPathname(document.pathname), content: document.content });
|
|
@@ -148,11 +179,31 @@ class Functionality {
|
|
|
148
179
|
});
|
|
149
180
|
}
|
|
150
181
|
const input = params;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
182
|
+
if (verb === "discover")
|
|
183
|
+
return { status: 200, body: await this.#discover(adapter, input, identity) };
|
|
184
|
+
// {§functionality-scope} — a worker-scoped family's list and mutations act for the invoking
|
|
185
|
+
// Worker. The state is that Worker's and nothing resident changes, so they serialize on the
|
|
186
|
+
// Worker's own lane and take no workspace exclusivity: a Worker shapes its environment while
|
|
187
|
+
// its siblings run.
|
|
188
|
+
if (adapter.scope === "worker") {
|
|
189
|
+
const workerId = _a.#workerOf(adapter, identity);
|
|
190
|
+
return this.#serialize(`${this.#key(identity.workspaceId, family)}:${workerId}`, () => this.#invokeForWorker(adapter, verb, input, identity, workerId, caller));
|
|
155
191
|
}
|
|
192
|
+
if (verb === "list")
|
|
193
|
+
return { status: 200, body: await this.#list(adapter, identity) };
|
|
194
|
+
return this.#host.mutateWorkspace(identity.workspaceId, adapter.namespaceOwner, caller, () => this.#serialize(this.#key(identity.workspaceId, family), () => this.#mutate(adapter, verb, input, identity, caller)));
|
|
195
|
+
}
|
|
196
|
+
// A worker-scoped verb that names no Worker is a defect at the projection, never a client
|
|
197
|
+
// failure: both projections name the Worker ({§functionality-model-projection}).
|
|
198
|
+
static #workerOf(adapter, identity) {
|
|
199
|
+
if (identity.workerId === undefined)
|
|
200
|
+
throw new Error(`${adapter.family} is worker-scoped; the invocation names no Worker.`);
|
|
201
|
+
return identity.workerId;
|
|
202
|
+
}
|
|
203
|
+
// The origin a definition carries when this family owns it locally. Service definitions
|
|
204
|
+
// always come from the adapter's own `available()`; everything else is the family's own.
|
|
205
|
+
static #localOrigin(adapter) {
|
|
206
|
+
return adapter.scope === "worker" ? "worker" : "workspace";
|
|
156
207
|
}
|
|
157
208
|
#adapter(family) {
|
|
158
209
|
const adapter = this.#adapters.get(family);
|
|
@@ -160,26 +211,25 @@ class Functionality {
|
|
|
160
211
|
throw failure(family, "family-unknown", 404, `No Functionality family '${family}' is registered.`, { retryable: false });
|
|
161
212
|
return adapter;
|
|
162
213
|
}
|
|
163
|
-
#key(
|
|
164
|
-
return `${
|
|
214
|
+
#key(workspaceId, family) {
|
|
215
|
+
return `${workspaceId}:${family}`;
|
|
165
216
|
}
|
|
166
|
-
#serialize(
|
|
167
|
-
const key = this.#key(workerId, family);
|
|
217
|
+
#serialize(key, work) {
|
|
168
218
|
const previous = this.#queues.get(key) ?? Promise.resolve();
|
|
169
219
|
const next = previous.catch(() => undefined).then(work);
|
|
170
220
|
this.#queues.set(key, next);
|
|
171
221
|
return next;
|
|
172
222
|
}
|
|
173
223
|
async #activate(adapter, context) {
|
|
174
|
-
const identity = { workspaceId: context.workspaceId
|
|
175
|
-
await this.#serialize(identity.
|
|
176
|
-
const state = await this.#loadState(adapter, identity.
|
|
224
|
+
const identity = { workspaceId: context.workspaceId };
|
|
225
|
+
await this.#serialize(this.#key(identity.workspaceId, adapter.family), async () => {
|
|
226
|
+
const state = await this.#loadState(adapter, identity.workspaceId);
|
|
177
227
|
await this.#publish(adapter, identity, state, { failure: "publish-unavailable", retain: context.retain, gate: "none" });
|
|
178
228
|
});
|
|
179
229
|
}
|
|
180
230
|
async #deactivate(adapter, identity) {
|
|
181
|
-
await this.#serialize(identity.
|
|
182
|
-
const key = this.#key(identity.
|
|
231
|
+
await this.#serialize(this.#key(identity.workspaceId, adapter.family), async () => {
|
|
232
|
+
const key = this.#key(identity.workspaceId, adapter.family);
|
|
183
233
|
const family = this.#families.get(key);
|
|
184
234
|
this.#families.delete(key);
|
|
185
235
|
if (family?.prepared !== null && family?.prepared !== undefined) {
|
|
@@ -187,31 +237,40 @@ class Functionality {
|
|
|
187
237
|
}
|
|
188
238
|
});
|
|
189
239
|
}
|
|
190
|
-
async #loadState(adapter,
|
|
191
|
-
|
|
240
|
+
async #loadState(adapter, workspaceId) {
|
|
241
|
+
return _a.#parseState(adapter, await this.#host.readWorkspaceModuleState(workspaceId, adapter.namespaceOwner), `workspace ${workspaceId}`);
|
|
242
|
+
}
|
|
243
|
+
async #loadWorkerState(adapter, workerId) {
|
|
244
|
+
return _a.#parseState(adapter, await this.#host.readWorkerModuleState(workerId, adapter.namespaceOwner), `worker ${workerId}`);
|
|
245
|
+
}
|
|
246
|
+
static #parseState(adapter, raw, where) {
|
|
192
247
|
if (raw === null)
|
|
193
248
|
return EMPTY_STATE;
|
|
194
249
|
if (!isRecord(raw) || raw.version !== STATE_VERSION || !isRecord(raw.definitions)) {
|
|
195
|
-
throw new Error(`Functionality state for ${adapter.family}
|
|
250
|
+
throw new Error(`Functionality state for ${adapter.family} in ${where} is not a version ${STATE_VERSION} record.`);
|
|
196
251
|
}
|
|
197
252
|
const definitions = {};
|
|
198
253
|
for (const [alias, value] of Object.entries(raw.definitions)) {
|
|
199
|
-
if (!
|
|
254
|
+
if (!aliasPattern(adapter).test(alias) || !isRecord(value))
|
|
200
255
|
throw new Error(`Functionality state for ${adapter.family} has an invalid alias '${alias}'.`);
|
|
201
|
-
const { origin, enabled, definition } = value;
|
|
202
|
-
if ((origin !== "service" && origin !== "worker") || typeof enabled !== "boolean") {
|
|
256
|
+
const { origin, enabled, definition, inherited } = value;
|
|
257
|
+
if ((origin !== "service" && origin !== "workspace" && origin !== "worker") || typeof enabled !== "boolean") {
|
|
203
258
|
throw new Error(`Functionality state for ${adapter.family} alias '${alias}' is malformed.`);
|
|
204
259
|
}
|
|
205
|
-
if (
|
|
260
|
+
if (inherited !== undefined && (typeof inherited !== "string" || inherited.length === 0 || adapter.scope !== "worker")) {
|
|
261
|
+
throw new Error(`Functionality state for ${adapter.family} alias '${alias}' carries an invalid inheritance.`);
|
|
262
|
+
}
|
|
263
|
+
const provenance = inherited === undefined ? {} : { inherited };
|
|
264
|
+
if (origin === _a.#localOrigin(adapter)) {
|
|
206
265
|
const result = Validator.validateJsonSchemaInstance(adapter.definitionSchema, definition);
|
|
207
266
|
if (!result.valid)
|
|
208
267
|
throw new Error(`Functionality state for ${adapter.family} alias '${alias}' holds an invalid definition.`);
|
|
209
|
-
definitions[alias] = { origin, enabled, definition: definition };
|
|
268
|
+
definitions[alias] = { origin, enabled, definition: definition, ...provenance };
|
|
210
269
|
}
|
|
211
270
|
else {
|
|
212
271
|
if (definition !== undefined)
|
|
213
272
|
throw new Error(`Functionality state for ${adapter.family} alias '${alias}' persists a service definition.`);
|
|
214
|
-
definitions[alias] = { origin, enabled };
|
|
273
|
+
definitions[alias] = { origin, enabled, ...provenance };
|
|
215
274
|
}
|
|
216
275
|
}
|
|
217
276
|
return { version: STATE_VERSION, definitions };
|
|
@@ -222,38 +281,41 @@ class Functionality {
|
|
|
222
281
|
async #effective(adapter, identity, state) {
|
|
223
282
|
const effective = new Map();
|
|
224
283
|
for (const service of await adapter.available(identity)) {
|
|
225
|
-
if (!
|
|
226
|
-
throw new Error(`${adapter.family} service alias '${service.alias}' must match ${
|
|
284
|
+
if (!aliasPattern(adapter).test(service.alias))
|
|
285
|
+
throw new Error(`${adapter.family} service alias '${service.alias}' must match ${aliasPattern(adapter)}.`);
|
|
227
286
|
const record = state.definitions[service.alias];
|
|
228
287
|
const enabled = record?.origin === "service" ? record.enabled : service.enabled;
|
|
229
|
-
|
|
288
|
+
const inherited = record?.origin === "service" && record.inherited !== undefined ? { inherited: record.inherited } : {};
|
|
289
|
+
effective.set(service.alias, { alias: service.alias, origin: "service", definition: service.definition, enabled, ...inherited });
|
|
230
290
|
}
|
|
231
291
|
for (const [alias, record] of Object.entries(state.definitions)) {
|
|
232
|
-
|
|
292
|
+
const local = _a.#localOrigin(adapter);
|
|
293
|
+
if (record.origin !== local)
|
|
233
294
|
continue;
|
|
234
|
-
|
|
295
|
+
const inherited = record.inherited === undefined ? {} : { inherited: record.inherited };
|
|
296
|
+
effective.set(alias, { alias, origin: local, definition: record.definition, enabled: record.enabled, ...inherited });
|
|
235
297
|
}
|
|
236
298
|
return new Map([...effective].toSorted(([left], [right]) => left.localeCompare(right)));
|
|
237
299
|
}
|
|
238
300
|
#projection(definition, outcome) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
301
|
+
const base = {
|
|
302
|
+
alias: definition.alias, origin: definition.origin, definition: definition.definition,
|
|
303
|
+
...(definition.inherited === undefined ? {} : { inherited: definition.inherited }),
|
|
304
|
+
};
|
|
305
|
+
if (!definition.enabled)
|
|
306
|
+
return { ...base, state: "disabled" };
|
|
242
307
|
if (outcome === undefined)
|
|
243
308
|
throw new Error(`enabled ${definition.alias} has no preparation outcome`);
|
|
244
309
|
switch (outcome.state) {
|
|
245
|
-
case "active": return {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
};
|
|
249
|
-
case "unavailable": return { alias: definition.alias, origin: definition.origin, state: "unavailable", definition: definition.definition, problem: outcome.problem };
|
|
250
|
-
case "authorization-required": return { alias: definition.alias, origin: definition.origin, state: "authorization-required", definition: definition.definition, authorization: outcome.authorization };
|
|
310
|
+
case "active": return { ...base, state: "active", ...(outcome.detail === undefined ? {} : { detail: outcome.detail }) };
|
|
311
|
+
case "unavailable": return { ...base, state: "unavailable", problem: outcome.problem };
|
|
312
|
+
case "authorization-required": return { ...base, state: "authorization-required", authorization: outcome.authorization };
|
|
251
313
|
}
|
|
252
314
|
}
|
|
253
315
|
async #list(adapter, identity) {
|
|
254
|
-
const family = this.#families.get(this.#key(identity.
|
|
316
|
+
const family = this.#families.get(this.#key(identity.workspaceId, adapter.family));
|
|
255
317
|
if (family === undefined)
|
|
256
|
-
throw failure(adapter.family, "
|
|
318
|
+
throw failure(adapter.family, "workspace-not-resident", 409, `Workspace ${identity.workspaceId} has no resident ${adapter.family} Functionality.`, { recovery: "Retry through a workspace operation, then retry.", retryable: false });
|
|
257
319
|
const effective = await this.#effective(adapter, identity, family.state);
|
|
258
320
|
const outcomes = family.prepared?.outcomes ?? new Map();
|
|
259
321
|
return Validator.assertFunctionalityListResult({
|
|
@@ -265,13 +327,12 @@ class Functionality {
|
|
|
265
327
|
const candidates = await adapter.discover(query, identity);
|
|
266
328
|
return Validator.assertFunctionalityDiscoverResult({ family: adapter.family, candidates: [...candidates] });
|
|
267
329
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const
|
|
274
|
-
const definitions = { ...family.state.definitions };
|
|
330
|
+
// The verb semantics, one implementation for every family ({§functionality-scope}): the next
|
|
331
|
+
// state, the alias it concerns, and how the mutation reports. Only publication differs by scope.
|
|
332
|
+
async #transition(adapter, verb, input, identity, caller, state, effective) {
|
|
333
|
+
const local = _a.#localOrigin(adapter);
|
|
334
|
+
const here = adapter.scope === "worker" ? "this worker" : "this workspace";
|
|
335
|
+
const definitions = { ...state.definitions };
|
|
275
336
|
let alias;
|
|
276
337
|
let status = 200;
|
|
277
338
|
let removed = false;
|
|
@@ -279,14 +340,16 @@ class Functionality {
|
|
|
279
340
|
case "add": {
|
|
280
341
|
const admitted = await adapter.admit(input, identity, caller);
|
|
281
342
|
alias = admitted.alias;
|
|
282
|
-
if (!
|
|
283
|
-
throw failure(adapter.family, "alias-invalid", 400, `Alias '${alias}' must match ${
|
|
284
|
-
// A
|
|
343
|
+
if (!aliasPattern(adapter).test(alias))
|
|
344
|
+
throw failure(adapter.family, "alias-invalid", 400, `Alias '${alias}' must match ${aliasPattern(adapter)}.`, { alias, retryable: false });
|
|
345
|
+
// A local definition may shadow a service definition of the same
|
|
285
346
|
// alias; removing it reveals the service baseline again, disabled.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
347
|
+
const current = effective.get(alias);
|
|
348
|
+
if (current?.origin === local && !isDeepStrictEqual(current.definition, admitted.definition)) {
|
|
349
|
+
throw failure(adapter.family, "alias-exists", 409, `'${alias}' already has a different ${local} definition.`, { alias, recovery: "Use the existing definition, or remove it before adding its replacement.", retryable: false });
|
|
350
|
+
}
|
|
351
|
+
definitions[alias] = { origin: local, definition: admitted.definition, enabled: true };
|
|
352
|
+
status = current?.origin === local ? 200 : 201;
|
|
290
353
|
break;
|
|
291
354
|
}
|
|
292
355
|
case "enable":
|
|
@@ -294,9 +357,9 @@ class Functionality {
|
|
|
294
357
|
alias = input.alias;
|
|
295
358
|
const current = effective.get(alias);
|
|
296
359
|
if (current === undefined)
|
|
297
|
-
throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to
|
|
298
|
-
definitions[alias] = current.origin ===
|
|
299
|
-
? { origin:
|
|
360
|
+
throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to ${here}.`, { alias, retryable: false });
|
|
361
|
+
definitions[alias] = current.origin === local
|
|
362
|
+
? { origin: local, definition: current.definition, enabled: verb === "enable" }
|
|
300
363
|
: { origin: "service", enabled: verb === "enable" };
|
|
301
364
|
break;
|
|
302
365
|
}
|
|
@@ -304,7 +367,7 @@ class Functionality {
|
|
|
304
367
|
alias = input.alias;
|
|
305
368
|
const current = effective.get(alias);
|
|
306
369
|
if (current === undefined)
|
|
307
|
-
throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to
|
|
370
|
+
throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to ${here}.`, { alias, retryable: false });
|
|
308
371
|
if (current.origin === "service")
|
|
309
372
|
throw failure(adapter.family, "alias-service-owned", 409, `'${alias}' is a service definition and cannot be removed here.`, { alias, recovery: `Disable it, or change the service configuration that contributes it.`, retryable: false });
|
|
310
373
|
await adapter.forget?.({ alias, definition: current.definition }, identity);
|
|
@@ -317,19 +380,11 @@ class Functionality {
|
|
|
317
380
|
}
|
|
318
381
|
default: throw new Error(`unreachable verb ${verb}`);
|
|
319
382
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
const retry = verb === "enable" && family.prepared?.outcomes.get(alias)?.state !== "active";
|
|
324
|
-
const publication = await this.#publish(adapter, identity, nextState, {
|
|
325
|
-
failure: caller === "action" ? "reject" : "publish-unavailable",
|
|
326
|
-
retain: () => this.#host.retainWorker(identity.workerId),
|
|
327
|
-
gate: caller === "operation" ? "wait" : "try",
|
|
328
|
-
forceAlias: retry ? alias : null,
|
|
329
|
-
});
|
|
330
|
-
const effectiveAfter = await this.#effective(adapter, identity, nextState);
|
|
383
|
+
return { definitions, alias, status, removed };
|
|
384
|
+
}
|
|
385
|
+
#mutationResult(adapter, { alias, status, removed }, effectiveAfter, outcomes) {
|
|
331
386
|
const definition = effectiveAfter.get(alias);
|
|
332
|
-
const projection = definition === undefined ? undefined : this.#projection(definition,
|
|
387
|
+
const projection = definition === undefined ? undefined : this.#projection(definition, outcomes.get(alias));
|
|
333
388
|
const body = Validator.assertFunctionalityMutationResult({
|
|
334
389
|
status: projection?.state === "authorization-required" ? 202 : status,
|
|
335
390
|
family: adapter.family,
|
|
@@ -339,86 +394,168 @@ class Functionality {
|
|
|
339
394
|
});
|
|
340
395
|
return { status: body.status, body };
|
|
341
396
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
const
|
|
348
|
-
const
|
|
349
|
-
const
|
|
397
|
+
async #mutate(adapter, verb, input, identity, caller) {
|
|
398
|
+
const key = this.#key(identity.workspaceId, adapter.family);
|
|
399
|
+
const family = this.#families.get(key);
|
|
400
|
+
if (family === undefined)
|
|
401
|
+
throw failure(adapter.family, "workspace-not-resident", 409, `Workspace ${identity.workspaceId} has no resident ${adapter.family} Functionality.`, { recovery: "Retry through a workspace operation, then retry.", retryable: false });
|
|
402
|
+
const effective = await this.#effective(adapter, identity, family.state);
|
|
403
|
+
const transition = await this.#transition(adapter, verb, input, identity, caller, family.state, effective);
|
|
404
|
+
const nextState = { version: STATE_VERSION, definitions: transition.definitions };
|
|
405
|
+
// Re-enabling an alias that is not active retries its preparation; an
|
|
406
|
+
// already-active alias keeps its live attachment.
|
|
407
|
+
const retry = verb === "enable" && family.prepared?.outcomes.get(transition.alias)?.state !== "active";
|
|
408
|
+
const publication = await this.#publish(adapter, identity, nextState, {
|
|
409
|
+
failure: caller === "action" ? "reject" : "publish-unavailable",
|
|
410
|
+
retain: () => this.#host.retainWorkspace(identity.workspaceId),
|
|
411
|
+
gate: "none",
|
|
412
|
+
forceAlias: retry ? transition.alias : null,
|
|
413
|
+
});
|
|
414
|
+
const effectiveAfter = await this.#effective(adapter, identity, nextState);
|
|
415
|
+
return this.#mutationResult(adapter, transition, effectiveAfter, publication.outcomes);
|
|
416
|
+
}
|
|
417
|
+
// {§functionality-scope} — the Worker's own lane. State is read at each verb rather than held: the
|
|
418
|
+
// spawn reads the same row, and a Worker's row is written at its creation, so nothing in memory
|
|
419
|
+
// could be more current than the table.
|
|
420
|
+
async #invokeForWorker(adapter, verb, input, identity, workerId, caller) {
|
|
421
|
+
if (!this.#families.has(this.#key(identity.workspaceId, adapter.family)))
|
|
422
|
+
throw failure(adapter.family, "workspace-not-resident", 409, `Workspace ${identity.workspaceId} has no resident ${adapter.family} Functionality.`, { recovery: "Retry through a workspace operation, then retry.", retryable: false });
|
|
423
|
+
const state = await this.#loadWorkerState(adapter, workerId);
|
|
424
|
+
const effective = await this.#effective(adapter, identity, state);
|
|
425
|
+
if (verb === "list") {
|
|
426
|
+
const prepared = await this.#prepareForWorker(adapter, identity, effective, "publish-unavailable");
|
|
427
|
+
await prepared.commit();
|
|
428
|
+
return { status: 200, body: Validator.assertFunctionalityListResult({
|
|
429
|
+
family: adapter.family,
|
|
430
|
+
definitions: [...effective.values()].map((definition) => this.#projection(definition, prepared.outcomes.get(definition.alias))),
|
|
431
|
+
}) };
|
|
432
|
+
}
|
|
433
|
+
const transition = await this.#transition(adapter, verb, input, identity, caller, state, effective);
|
|
434
|
+
const nextState = { version: STATE_VERSION, definitions: transition.definitions };
|
|
435
|
+
const effectiveAfter = await this.#effective(adapter, identity, nextState);
|
|
436
|
+
const prepared = await this.#prepareForWorker(adapter, identity, effectiveAfter, caller === "action" ? "reject" : "publish-unavailable");
|
|
437
|
+
try {
|
|
438
|
+
await this.#host.replaceWorkerModuleState(workerId, adapter.namespaceOwner, _a.#persisted(nextState));
|
|
439
|
+
}
|
|
440
|
+
catch (cause) {
|
|
441
|
+
return _a.#abort(prepared, cause);
|
|
442
|
+
}
|
|
443
|
+
await prepared.commit();
|
|
444
|
+
return this.#mutationResult(adapter, transition, effectiveAfter, prepared.outcomes);
|
|
445
|
+
}
|
|
446
|
+
// A worker-scoped family's preparation yields outcomes only. It holds no residency — no runtimes,
|
|
447
|
+
// documents or snapshot ({§module-workspace-residency}) — because its definitions are read at the
|
|
448
|
+
// spawn that uses them rather than leased and cooled; the coordinator enforces that here.
|
|
449
|
+
async #prepareForWorker(adapter, identity, effective, failureMode) {
|
|
450
|
+
const enabled = _a.#enabled(effective);
|
|
451
|
+
const prepared = await adapter.prepare({
|
|
452
|
+
workspaceId: identity.workspaceId, enabled, previous: null, failure: failureMode,
|
|
453
|
+
retain: () => this.#host.retainWorkspace(identity.workspaceId),
|
|
454
|
+
});
|
|
455
|
+
try {
|
|
456
|
+
_a.#checkOutcomes(adapter, enabled, prepared);
|
|
457
|
+
if ((prepared.runtimes?.length ?? 0) > 0 || prepared.documents.length > 0 || prepared.snapshot !== null) {
|
|
458
|
+
throw new Error(`${adapter.family} is worker-scoped and holds no residency, yet its preparation published runtimes, documents or a snapshot.`);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
catch (cause) {
|
|
462
|
+
return _a.#abort(prepared, cause);
|
|
463
|
+
}
|
|
464
|
+
return prepared;
|
|
465
|
+
}
|
|
466
|
+
static #enabled(effective) {
|
|
350
467
|
const enabled = new Map();
|
|
351
468
|
for (const definition of effective.values()) {
|
|
352
469
|
if (definition.enabled)
|
|
353
470
|
enabled.set(definition.alias, definition.definition);
|
|
354
471
|
}
|
|
472
|
+
return enabled;
|
|
473
|
+
}
|
|
474
|
+
static #checkOutcomes(adapter, enabled, prepared) {
|
|
475
|
+
for (const alias of enabled.keys()) {
|
|
476
|
+
if (!prepared.outcomes.has(alias))
|
|
477
|
+
throw new Error(`${adapter.family} preparation reported no outcome for enabled alias '${alias}'.`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
// {§functionality-publication} — prepare, publish runtimes and state in one
|
|
481
|
+
// host replacement, then commit; on any failure abort and keep the previous
|
|
482
|
+
// snapshot authoritative. An execution stream stays pending until its
|
|
483
|
+
// workspace publication completes; it never acknowledges a future commit.
|
|
484
|
+
async #publish(adapter, identity, nextState, options) {
|
|
485
|
+
const key = this.#key(identity.workspaceId, adapter.family);
|
|
486
|
+
const previous = this.#families.get(key)?.prepared ?? null;
|
|
487
|
+
// A worker-scoped family's workspace publication carries only its manager: what is enabled
|
|
488
|
+
// is decided per Worker, at each verb and each spawn ({§functionality-scope}).
|
|
489
|
+
const effective = adapter.scope === "worker" ? new Map() : await this.#effective(adapter, identity, nextState);
|
|
490
|
+
const enabled = _a.#enabled(effective);
|
|
355
491
|
const prepared = await adapter.prepare({
|
|
356
492
|
workspaceId: identity.workspaceId,
|
|
357
|
-
workerId: identity.workerId,
|
|
358
493
|
enabled,
|
|
359
494
|
previous: previous?.snapshot ?? null,
|
|
360
495
|
failure: options.failure,
|
|
361
496
|
retain: options.retain,
|
|
362
497
|
...(options.forceAlias ? { force: options.forceAlias } : {}),
|
|
363
498
|
});
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
executor: new FunctionalityManager({
|
|
372
|
-
family: adapter.family, workspaceId: identity.workspaceId, workerId: identity.workerId, coordinator: this,
|
|
373
|
-
definitionSchema: adapter.definitionSchema, example: adapter.example, discovery: adapter.discovery,
|
|
374
|
-
}),
|
|
375
|
-
availability: { available: true, detail: "Worker Functionality manager" },
|
|
376
|
-
};
|
|
377
|
-
const runtimes = [manager, ...prepared.runtimes];
|
|
378
|
-
for (const runtime of prepared.runtimes) {
|
|
379
|
-
if (runtime.namespaceOwner !== adapter.namespaceOwner) {
|
|
380
|
-
await prepared.abort();
|
|
381
|
-
throw new Error(`${adapter.family} prepared a runtime owned by '${runtime.namespaceOwner}' instead of '${adapter.namespaceOwner}'.`);
|
|
499
|
+
let runtimes;
|
|
500
|
+
try {
|
|
501
|
+
_a.#checkOutcomes(adapter, enabled, prepared);
|
|
502
|
+
for (const runtime of prepared.runtimes ?? []) {
|
|
503
|
+
if (runtime.namespaceOwner !== adapter.namespaceOwner) {
|
|
504
|
+
throw new Error(`${adapter.family} prepared a runtime owned by '${runtime.namespaceOwner}' instead of '${adapter.namespaceOwner}'.`);
|
|
505
|
+
}
|
|
382
506
|
}
|
|
507
|
+
const manager = {
|
|
508
|
+
namespaceOwner: adapter.namespaceOwner,
|
|
509
|
+
decl: functionalityRuntimeDecl(adapter.family, adapter.summary, await this.#documentBody(adapter)),
|
|
510
|
+
executor: new FunctionalityManager({
|
|
511
|
+
family: adapter.family, workspaceId: identity.workspaceId, coordinator: this,
|
|
512
|
+
inputSchemas: this.#schemas.get(adapter.family), example: adapter.example, discovery: adapter.discovery,
|
|
513
|
+
}),
|
|
514
|
+
availability: { available: true, detail: "workspace Functionality manager" },
|
|
515
|
+
};
|
|
516
|
+
runtimes = [manager, ...(prepared.runtimes ?? [])];
|
|
517
|
+
}
|
|
518
|
+
catch (cause) {
|
|
519
|
+
return _a.#abort(prepared, cause);
|
|
383
520
|
}
|
|
384
521
|
const commit = async () => {
|
|
385
|
-
// The host reconciles the Worker's documents inside the replacement,
|
|
386
|
-
// so the snapshot it reads must already be the next one; a failed
|
|
387
|
-
// replacement restores the previous snapshot before aborting.
|
|
388
522
|
const before = this.#families.get(key);
|
|
389
|
-
this.#families.set(key, { state: nextState, prepared });
|
|
390
523
|
try {
|
|
391
|
-
await this.#host.
|
|
524
|
+
await this.#host.replaceWorkspaceCapabilities({
|
|
392
525
|
workspaceId: identity.workspaceId,
|
|
393
|
-
workerId: identity.workerId,
|
|
394
526
|
namespaceOwner: adapter.namespaceOwner,
|
|
395
527
|
state: _a.#persisted(nextState),
|
|
396
528
|
runtimes,
|
|
397
|
-
}, {
|
|
529
|
+
}, {
|
|
530
|
+
gate: options.gate,
|
|
531
|
+
publish: () => {
|
|
532
|
+
this.#families.set(key, { state: nextState, prepared });
|
|
533
|
+
return () => {
|
|
534
|
+
if (before === undefined)
|
|
535
|
+
this.#families.delete(key);
|
|
536
|
+
else
|
|
537
|
+
this.#families.set(key, before);
|
|
538
|
+
};
|
|
539
|
+
},
|
|
540
|
+
});
|
|
398
541
|
}
|
|
399
542
|
catch (cause) {
|
|
400
|
-
|
|
401
|
-
this.#families.delete(key);
|
|
402
|
-
else
|
|
403
|
-
this.#families.set(key, before);
|
|
404
|
-
await prepared.abort();
|
|
405
|
-
throw cause;
|
|
543
|
+
return _a.#abort(prepared, cause);
|
|
406
544
|
}
|
|
407
545
|
await prepared.commit();
|
|
408
546
|
};
|
|
409
|
-
|
|
410
|
-
await commit();
|
|
411
|
-
return { outcomes: prepared.outcomes };
|
|
412
|
-
}
|
|
413
|
-
// Inside the caller's own turn the workspace is held by that turn:
|
|
414
|
-
// publication queues behind it in this family's lane and settles
|
|
415
|
-
// before the next packet. The caller learns the preparation outcome now.
|
|
416
|
-
const pending = (this.#queues.get(key) ?? Promise.resolve()).catch(() => undefined).then(commit);
|
|
417
|
-
this.#queues.set(key, pending.catch((cause) => {
|
|
418
|
-
console.error(`[plurnk] ${adapter.family} publication for worker ${identity.workerId} failed at its turn boundary:`, cause);
|
|
419
|
-
}));
|
|
547
|
+
await commit();
|
|
420
548
|
return { outcomes: prepared.outcomes };
|
|
421
549
|
}
|
|
550
|
+
static async #abort(prepared, cause) {
|
|
551
|
+
try {
|
|
552
|
+
await prepared.abort();
|
|
553
|
+
}
|
|
554
|
+
catch (abortCause) {
|
|
555
|
+
throw new AggregateError([cause, abortCause], "Functionality publication and candidate cleanup failed");
|
|
556
|
+
}
|
|
557
|
+
throw cause;
|
|
558
|
+
}
|
|
422
559
|
}
|
|
423
560
|
_a = Functionality;
|
|
424
561
|
export default Functionality;
|