@plurnk/plurnk-service 4.1.0 → 4.3.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 +3 -0
- package/INSTALL.md +7 -2
- package/README.md +3 -1
- package/SPEC.md +1996 -1370
- package/dist/build-info.d.ts.map +1 -1
- package/dist/build-info.js +25 -3
- package/dist/build-info.js.map +1 -1
- package/dist/build-info.json +1 -1
- package/dist/completions/_plurnk-service +2 -2
- package/dist/completions/plurnk-service.bash +2 -2
- package/dist/completions/plurnk-service.fish +2 -0
- package/dist/content/body-preview.js.map +1 -1
- package/dist/content/byte-view.d.ts.map +1 -1
- package/dist/content/byte-view.js +3 -2
- package/dist/content/byte-view.js.map +1 -1
- package/dist/content/edit-collision.d.ts +2 -1
- package/dist/content/edit-collision.d.ts.map +1 -1
- package/dist/content/edit-collision.js.map +1 -1
- package/dist/content/edit-receipt.d.ts.map +1 -1
- package/dist/content/edit-receipt.js +28 -23
- package/dist/content/edit-receipt.js.map +1 -1
- package/dist/content/edited-span.js +1 -1
- package/dist/content/edited-span.js.map +1 -1
- package/dist/content/line-anchors.d.ts +3 -2
- package/dist/content/line-anchors.d.ts.map +1 -1
- package/dist/content/line-anchors.js +33 -19
- package/dist/content/line-anchors.js.map +1 -1
- package/dist/content/line-selection.js.map +1 -1
- package/dist/content/pattern-edits.js +1 -1
- package/dist/content/pattern-edits.js.map +1 -1
- package/dist/content/read-projector.d.ts +1 -1
- package/dist/content/read-projector.d.ts.map +1 -1
- package/dist/content/read-projector.js +10 -8
- package/dist/content/read-projector.js.map +1 -1
- package/dist/content/read-resolve.d.ts.map +1 -1
- package/dist/content/read-resolve.js +6 -5
- package/dist/content/read-resolve.js.map +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts +4 -4
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
- package/dist/core/AdmittedTurnExecutor.js +20 -18
- package/dist/core/AdmittedTurnExecutor.js.map +1 -1
- package/dist/core/AmbientMembers.d.ts +18 -0
- package/dist/core/AmbientMembers.d.ts.map +1 -0
- package/dist/core/AmbientMembers.js +84 -0
- package/dist/core/AmbientMembers.js.map +1 -0
- package/dist/core/BareBatchRunner.d.ts +1 -1
- package/dist/core/BareBatchRunner.d.ts.map +1 -1
- package/dist/core/BareBatchRunner.js +2 -2
- package/dist/core/BareBatchRunner.js.map +1 -1
- package/dist/core/CapabilityPolicies.js.map +1 -1
- package/dist/core/CapabilityResolver.d.ts +1 -2
- package/dist/core/CapabilityResolver.d.ts.map +1 -1
- package/dist/core/CapabilityResolver.js +11 -7
- package/dist/core/CapabilityResolver.js.map +1 -1
- package/dist/core/ChannelWrite.d.ts +2 -2
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +27 -0
- package/dist/core/ClientInteractions.js.map +1 -1
- package/dist/core/ContextFit.js +1 -1
- package/dist/core/ContextFit.js.map +1 -1
- package/dist/core/CoreSchemeServices.d.ts.map +1 -1
- package/dist/core/CoreSchemeServices.js +6 -4
- package/dist/core/CoreSchemeServices.js.map +1 -1
- package/dist/core/DataStatementRunner.d.ts.map +1 -1
- package/dist/core/DataStatementRunner.js +24 -15
- package/dist/core/DataStatementRunner.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +29 -5
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +242 -132
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/EditMutations.d.ts.map +1 -1
- package/dist/core/EditMutations.js +12 -6
- package/dist/core/EditMutations.js.map +1 -1
- package/dist/core/EditSequence.js.map +1 -1
- package/dist/core/Engine.d.ts +12 -6
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +29 -7
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/ExecutionOutputs.js.map +1 -1
- package/dist/core/ExecutorRegistry.d.ts +1 -2
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +2 -2
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/FileAddress.d.ts +1 -0
- package/dist/core/FileAddress.d.ts.map +1 -1
- package/dist/core/FileAddress.js +8 -1
- package/dist/core/FileAddress.js.map +1 -1
- package/dist/core/FilePublication.d.ts.map +1 -1
- package/dist/core/FilePublication.js +6 -3
- package/dist/core/FilePublication.js.map +1 -1
- package/dist/core/FileSnapshot.d.ts.map +1 -1
- package/dist/core/FileSnapshot.js +8 -5
- package/dist/core/FileSnapshot.js.map +1 -1
- package/dist/core/KillHandler.d.ts.map +1 -1
- package/dist/core/KillHandler.js +7 -0
- package/dist/core/KillHandler.js.map +1 -1
- package/dist/core/LiveSubscription.d.ts +1 -0
- package/dist/core/LiveSubscription.d.ts.map +1 -1
- package/dist/core/LiveSubscription.js +3 -2
- package/dist/core/LiveSubscription.js.map +1 -1
- package/dist/core/LiveSubscriptions.d.ts +4 -1
- package/dist/core/LiveSubscriptions.d.ts.map +1 -1
- package/dist/core/LiveSubscriptions.js +42 -1
- package/dist/core/LiveSubscriptions.js.map +1 -1
- package/dist/core/LogBody.d.ts.map +1 -1
- package/dist/core/LogBody.js +22 -19
- package/dist/core/LogBody.js.map +1 -1
- package/dist/core/LogVisibility.d.ts +1 -1
- package/dist/core/LogVisibility.d.ts.map +1 -1
- package/dist/core/LogVisibility.js +4 -6
- package/dist/core/LogVisibility.js.map +1 -1
- package/dist/core/LogWriter.d.ts.map +1 -1
- package/dist/core/LogWriter.js +6 -9
- package/dist/core/LogWriter.js.map +1 -1
- package/dist/core/LoopDriver.d.ts +4 -4
- package/dist/core/LoopDriver.d.ts.map +1 -1
- package/dist/core/LoopDriver.js +4 -5
- package/dist/core/LoopDriver.js.map +1 -1
- package/dist/core/LoopLifecycle.d.ts +2 -0
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/LoopLifecycle.js +13 -3
- package/dist/core/LoopLifecycle.js.map +1 -1
- package/dist/core/LoopLifecycle.sql +4 -4
- package/dist/core/LoopOutcome.d.ts.map +1 -1
- package/dist/core/LoopOutcome.js +2 -2
- package/dist/core/LoopOutcome.js.map +1 -1
- package/dist/core/MembershipMaterialization.d.ts.map +1 -1
- package/dist/core/MembershipMaterialization.js +29 -29
- package/dist/core/MembershipMaterialization.js.map +1 -1
- package/dist/core/MessageResources.d.ts +5 -1
- package/dist/core/MessageResources.d.ts.map +1 -1
- package/dist/core/MessageResources.js +12 -0
- package/dist/core/MessageResources.js.map +1 -1
- package/dist/core/MessageResources.sql +8 -0
- package/dist/core/MutationEffects.d.ts +1 -0
- package/dist/core/MutationEffects.d.ts.map +1 -1
- package/dist/core/MutationEffects.js +14 -10
- package/dist/core/MutationEffects.js.map +1 -1
- package/dist/core/OperationHistory.d.ts.map +1 -1
- package/dist/core/OperationHistory.js +4 -3
- package/dist/core/OperationHistory.js.map +1 -1
- package/dist/core/OperatorConfig.d.ts.map +1 -1
- package/dist/core/OperatorConfig.js +3 -2
- package/dist/core/OperatorConfig.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts +1 -1
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +7 -5
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/ProblemLog.d.ts +2 -5
- package/dist/core/ProblemLog.d.ts.map +1 -1
- package/dist/core/ProblemLog.js +2 -3
- package/dist/core/ProblemLog.js.map +1 -1
- package/dist/core/ProposalLifecycle.d.ts +12 -11
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +92 -84
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ReasoningEvent.d.ts +2 -0
- package/dist/core/ReasoningEvent.d.ts.map +1 -1
- package/dist/core/ReplyMetadata.d.ts.map +1 -1
- package/dist/core/ReplyMetadata.js +4 -3
- package/dist/core/ReplyMetadata.js.map +1 -1
- package/dist/core/ResourceBindings.d.ts +2 -2
- package/dist/core/ResourceBindings.d.ts.map +1 -1
- package/dist/core/ResourceBindings.js.map +1 -1
- package/dist/core/ResourceMutations.d.ts +1 -1
- package/dist/core/ResourceMutations.d.ts.map +1 -1
- package/dist/core/ResourceMutations.js +1 -2
- package/dist/core/ResourceMutations.js.map +1 -1
- package/dist/core/ResourceSelector.js +2 -2
- package/dist/core/ResourceSelector.js.map +1 -1
- package/dist/core/ResourceTransfers.d.ts.map +1 -1
- package/dist/core/ResourceTransfers.js +162 -120
- package/dist/core/ResourceTransfers.js.map +1 -1
- package/dist/core/SchemeRegistry.d.ts +6 -5
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +32 -26
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/ServiceHelp.d.ts.map +1 -1
- package/dist/core/ServiceHelp.js +2 -1
- package/dist/core/ServiceHelp.js.map +1 -1
- package/dist/core/StoredPacket.d.ts.map +1 -1
- package/dist/core/StoredPacket.js +26 -19
- package/dist/core/StoredPacket.js.map +1 -1
- package/dist/core/StrikeRail.d.ts +1 -2
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +4 -4
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/TerminalResult.d.ts +0 -2
- package/dist/core/TerminalResult.d.ts.map +1 -1
- package/dist/core/TerminalResult.js +0 -18
- package/dist/core/TerminalResult.js.map +1 -1
- package/dist/core/ToolInputSchema.d.ts.map +1 -1
- package/dist/core/ToolInputSchema.js +2 -2
- package/dist/core/ToolInputSchema.js.map +1 -1
- package/dist/core/ToolResources.d.ts +1 -0
- package/dist/core/ToolResources.d.ts.map +1 -1
- package/dist/core/ToolResources.js +7 -6
- package/dist/core/ToolResources.js.map +1 -1
- package/dist/core/TurnDispositionHandler.d.ts +1 -1
- package/dist/core/TurnDispositionHandler.d.ts.map +1 -1
- package/dist/core/TurnDispositionHandler.js +0 -1
- package/dist/core/TurnDispositionHandler.js.map +1 -1
- package/dist/core/TurnMaterialization.d.ts.map +1 -1
- package/dist/core/TurnMaterialization.js +3 -2
- package/dist/core/TurnMaterialization.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +13 -12
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +197 -173
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/TurnRunner.sql +3 -3
- package/dist/core/WorkerOwners.js.map +1 -1
- package/dist/core/caps/DbEntryCaps.js.map +1 -1
- package/dist/core/caps/DbMessageCaps.d.ts +3 -3
- package/dist/core/caps/DbMessageCaps.d.ts.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.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.js +1 -0
- package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts +1 -0
- package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.js +10 -1
- package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
- package/dist/core/env-catalog.js.map +1 -1
- package/dist/core/env-defaults.d.ts.map +1 -1
- package/dist/core/env-defaults.js +5 -3
- package/dist/core/env-defaults.js.map +1 -1
- package/dist/core/file-creation-policy.d.ts.map +1 -1
- package/dist/core/file-creation-policy.js +2 -1
- package/dist/core/file-creation-policy.js.map +1 -1
- package/dist/core/file-materialization.d.ts.map +1 -1
- package/dist/core/file-materialization.js +9 -11
- package/dist/core/file-materialization.js.map +1 -1
- 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 +34 -3
- package/dist/core/git-env.js.map +1 -1
- package/dist/core/git-membership.d.ts +8 -0
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +107 -21
- 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 +1 -0
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/notifications.d.ts +5 -0
- package/dist/core/notifications.d.ts.map +1 -1
- package/dist/core/packet-wire.d.ts +26 -21
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +150 -112
- 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 +6 -5
- package/dist/core/plurnk-uri.js.map +1 -1
- package/dist/core/results.d.ts +9 -4
- package/dist/core/results.d.ts.map +1 -1
- package/dist/core/results.js +14 -1
- package/dist/core/results.js.map +1 -1
- package/dist/core/runtime-floor.d.ts +8 -0
- package/dist/core/runtime-floor.d.ts.map +1 -0
- package/dist/core/runtime-floor.js +40 -0
- package/dist/core/runtime-floor.js.map +1 -0
- package/dist/core/runtime-guard.d.ts +2 -0
- package/dist/core/runtime-guard.d.ts.map +1 -0
- package/dist/core/runtime-guard.js +5 -0
- package/dist/core/runtime-guard.js.map +1 -0
- package/dist/core/scheme-types.d.ts +20 -0
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/sqlite-synchronous.d.ts +1 -1
- package/dist/core/sqlite-synchronous.d.ts.map +1 -1
- package/dist/core/sqlite-synchronous.js.map +1 -1
- package/dist/core/statement-primary.d.ts +2 -2
- package/dist/core/statement-primary.d.ts.map +1 -1
- package/dist/core/statement-primary.js.map +1 -1
- package/dist/core/workspace-settings.js +1 -1
- package/dist/core/workspace-settings.js.map +1 -1
- package/dist/evidence/EvidenceReader.d.ts.map +1 -1
- package/dist/evidence/EvidenceReader.js +20 -6
- package/dist/evidence/EvidenceReader.js.map +1 -1
- package/dist/launch/Launch.d.ts +1 -0
- package/dist/launch/Launch.d.ts.map +1 -1
- package/dist/launch/Launch.js +28 -12
- package/dist/launch/Launch.js.map +1 -1
- package/dist/man/plurnk-service.1 +12 -2
- package/dist/schemes/EffectPolicy.js +1 -1
- package/dist/schemes/EffectPolicy.js.map +1 -1
- package/dist/schemes/Env.d.ts +1 -1
- package/dist/schemes/Env.d.ts.map +1 -1
- package/dist/schemes/Env.js +7 -1
- package/dist/schemes/Env.js.map +1 -1
- package/dist/schemes/Exec.d.ts +10 -12
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +337 -437
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +4 -6
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +17 -17
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/ExecScheduler.d.ts.map +1 -1
- package/dist/schemes/ExecScheduler.js +1 -2
- package/dist/schemes/ExecScheduler.js.map +1 -1
- package/dist/schemes/ExecutionInput.js +3 -3
- package/dist/schemes/ExecutionInput.js.map +1 -1
- package/dist/schemes/File.d.ts +3 -18
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +148 -84
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +193 -161
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/QuestionTool.d.ts.map +1 -1
- package/dist/schemes/QuestionTool.js +6 -8
- package/dist/schemes/QuestionTool.js.map +1 -1
- package/dist/schemes/ResourceTreeScheme.d.ts.map +1 -1
- package/dist/schemes/ResourceTreeScheme.js +2 -2
- package/dist/schemes/ResourceTreeScheme.js.map +1 -1
- package/dist/schemes/TurnSource.js +3 -3
- package/dist/schemes/TurnSource.js.map +1 -1
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +4 -2
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-find.d.ts +2 -1
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +241 -130
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-manifest.js +1 -1
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_search-index.js.map +1 -1
- package/dist/schemes/exec-entry-sink.d.ts +30 -0
- package/dist/schemes/exec-entry-sink.d.ts.map +1 -0
- package/dist/schemes/exec-entry-sink.js +238 -0
- package/dist/schemes/exec-entry-sink.js.map +1 -0
- package/dist/schemes/exec-lifetime.d.ts.map +1 -1
- package/dist/schemes/exec-lifetime.js +5 -2
- package/dist/schemes/exec-lifetime.js.map +1 -1
- package/dist/server/ClientOperations.d.ts +45 -0
- package/dist/server/ClientOperations.d.ts.map +1 -0
- package/dist/server/ClientOperations.js +192 -0
- package/dist/server/ClientOperations.js.map +1 -0
- package/dist/server/ClientReads.d.ts +13 -5
- package/dist/server/ClientReads.d.ts.map +1 -1
- package/dist/server/ClientReads.js +108 -21
- package/dist/server/ClientReads.js.map +1 -1
- package/dist/server/Credentials.js +2 -2
- package/dist/server/Credentials.js.map +1 -1
- package/dist/server/Daemon.d.ts +40 -28
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +263 -839
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonLock.d.ts +2 -0
- package/dist/server/DaemonLock.d.ts.map +1 -1
- package/dist/server/DaemonLock.js +10 -1
- package/dist/server/DaemonLock.js.map +1 -1
- package/dist/server/DaemonModules.d.ts +39 -0
- package/dist/server/DaemonModules.d.ts.map +1 -0
- package/dist/server/DaemonModules.js +219 -0
- package/dist/server/DaemonModules.js.map +1 -0
- package/dist/server/DrainSupervisor.d.ts +4 -2
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +318 -290
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/EnvFunctionality.d.ts +10 -7
- package/dist/server/EnvFunctionality.d.ts.map +1 -1
- package/dist/server/EnvFunctionality.js +7 -5
- package/dist/server/EnvFunctionality.js.map +1 -1
- package/dist/server/Functionality.d.ts +4 -5
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js +24 -15
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/HttpListener.d.ts.map +1 -1
- package/dist/server/HttpListener.js +28 -8
- package/dist/server/HttpListener.js.map +1 -1
- package/dist/server/MembersFunctionality.d.ts +19 -7
- package/dist/server/MembersFunctionality.d.ts.map +1 -1
- package/dist/server/MembersFunctionality.js +37 -17
- package/dist/server/MembersFunctionality.js.map +1 -1
- package/dist/server/MessageDelivery.d.ts +43 -0
- package/dist/server/MessageDelivery.d.ts.map +1 -0
- package/dist/server/MessageDelivery.js +186 -0
- package/dist/server/MessageDelivery.js.map +1 -0
- package/dist/server/ModuleHost.d.ts +3 -3
- package/dist/server/ModuleHost.d.ts.map +1 -1
- package/dist/server/Places.d.ts +19 -0
- package/dist/server/Places.d.ts.map +1 -0
- package/dist/server/Places.js +76 -0
- package/dist/server/Places.js.map +1 -0
- package/dist/server/PluginSources.d.ts.map +1 -1
- package/dist/server/PluginSources.js +2 -1
- package/dist/server/PluginSources.js.map +1 -1
- package/dist/server/PlurnkSkill.d.ts.map +1 -1
- package/dist/server/PlurnkSkill.js +5 -4
- package/dist/server/PlurnkSkill.js.map +1 -1
- package/dist/server/Rollback.d.ts.map +1 -1
- package/dist/server/Rollback.js +2 -1
- package/dist/server/Rollback.js.map +1 -1
- package/dist/server/WorkerModels.d.ts +83 -0
- package/dist/server/WorkerModels.d.ts.map +1 -0
- package/dist/server/WorkerModels.js +500 -0
- package/dist/server/WorkerModels.js.map +1 -0
- package/dist/server/WorkerOverview.d.ts +22 -0
- package/dist/server/WorkerOverview.d.ts.map +1 -0
- package/dist/server/WorkerOverview.js +42 -0
- package/dist/server/WorkerOverview.js.map +1 -0
- package/dist/server/WorkspacePlugins.d.ts +1 -1
- package/dist/server/WorkspacePlugins.d.ts.map +1 -1
- package/dist/server/WorkspacePlugins.js +0 -1
- package/dist/server/WorkspacePlugins.js.map +1 -1
- package/dist/server/WorkspaceResidency.d.ts +3 -3
- package/dist/server/WorkspaceResidency.d.ts.map +1 -1
- package/dist/server/WorkspaceResidency.js.map +1 -1
- package/dist/server/client-input.d.ts +2 -2
- package/dist/server/client-input.d.ts.map +1 -1
- package/dist/server/client-input.js +19 -12
- package/dist/server/client-input.js.map +1 -1
- package/dist/server/envelope.d.ts +4 -1
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +7 -3
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +10 -6
- package/dist/server/logEntry.d.ts +38 -1
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +9 -9
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +4 -2
- package/dist/server/loopDocs.d.ts.map +1 -1
- package/dist/server/loopDocs.js +11 -2
- package/dist/server/loopDocs.js.map +1 -1
- package/dist/server/module-discovery.d.ts +2 -3
- package/dist/server/module-discovery.d.ts.map +1 -1
- package/dist/server/module-discovery.js +6 -6
- package/dist/server/module-discovery.js.map +1 -1
- package/dist/server/places.sql +83 -0
- package/dist/server/seam-loop.sql +8 -0
- package/dist/server/worker-overview.sql +50 -0
- package/dist/service.d.ts +1 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +35 -9
- package/dist/service.js.map +1 -1
- package/docs/members.md +31 -33
- package/migrations/033_hidden_places.sql +10 -0
- package/package.json +48 -57
- package/dist/observe/init.d.ts +0 -8
- package/dist/observe/init.d.ts.map +0 -1
- package/dist/observe/init.js +0 -163
- package/dist/observe/init.js.map +0 -1
- package/dist/server/WorkerModelResolver.d.ts +0 -20
- package/dist/server/WorkerModelResolver.d.ts.map +0 -1
- package/dist/server/WorkerModelResolver.js +0 -200
- package/dist/server/WorkerModelResolver.js.map +0 -1
|
@@ -55,6 +55,7 @@ const uniqueMatchLocations = (locations) => {
|
|
|
55
55
|
// label describes the same visible-body cost shown in the packet, a region reads in the one scope
|
|
56
56
|
// notation ({§packet-extent-metadata}), and a location names its channel only off the default.
|
|
57
57
|
const scoped = (key, value) => key === "region" || key === "enclosingRegion"
|
|
58
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- an item's region fields hold the TextRegions this module built; an entries walk does not carry which key holds which type
|
|
58
59
|
? ScopeFormat.region(value)
|
|
59
60
|
: value;
|
|
60
61
|
const renderFindContent = (items, defaultChannel) => renderJsonResult(items.map((item) => Array.isArray(item)
|
|
@@ -130,7 +131,7 @@ export const projectFindResult = (statement, scope, resources, scopes = [], defa
|
|
|
130
131
|
if (page.status !== 200) {
|
|
131
132
|
if (page.problem === undefined)
|
|
132
133
|
throw new Error("FIND pagination failed without Problem Details");
|
|
133
|
-
return Results.assert({ status: page.status, problem: page.problem, ...fields, range: page.range });
|
|
134
|
+
return Results.assert({ status: page.status, problem: page.problem, ...fields, ...(page.range === undefined ? {} : { range: page.range }) });
|
|
134
135
|
}
|
|
135
136
|
if (statement.matcher !== null && matchingPathCount === 0) {
|
|
136
137
|
return {
|
|
@@ -142,7 +143,7 @@ export const projectFindResult = (statement, scope, resources, scopes = [], defa
|
|
|
142
143
|
const results = page.items ?? [];
|
|
143
144
|
const returnedItemsWeightTotal = locationMode
|
|
144
145
|
? itemsWeightTotal
|
|
145
|
-
: results.reduce((sum, item) => sum + findItemWeight(item), 0);
|
|
146
|
+
: results.reduce((sum, item) => sum + (Array.isArray(item) ? findItemWeight(item) : 0), 0);
|
|
146
147
|
return {
|
|
147
148
|
status: 200,
|
|
148
149
|
content: renderFindContent(results, defaultChannel), // {§find-result-projection} {§json-result-rendering}
|
|
@@ -155,6 +156,18 @@ export const projectFindResult = (statement, scope, resources, scopes = [], defa
|
|
|
155
156
|
...(page.range === undefined ? {} : { range: page.range }),
|
|
156
157
|
};
|
|
157
158
|
};
|
|
159
|
+
// {§relation-indexed-dialects} An indexed dialect over candidates the index does not yet cover.
|
|
160
|
+
const incompleteIndex = (search, what) => ({
|
|
161
|
+
status: 503,
|
|
162
|
+
matches: [],
|
|
163
|
+
error: `The persistent search index covers ${search.indexed} of ${search.total} ${what}.`,
|
|
164
|
+
extensions: {
|
|
165
|
+
search,
|
|
166
|
+
stage: "search-index",
|
|
167
|
+
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
168
|
+
retryable: true,
|
|
169
|
+
},
|
|
170
|
+
});
|
|
158
171
|
export default class EntryFind {
|
|
159
172
|
static #targetPath(scheme, authority, pathname, fragment, projectRoot) {
|
|
160
173
|
const path = EntryManifest.toPath(scheme, authority, pathname, projectRoot);
|
|
@@ -173,6 +186,10 @@ export default class EntryFind {
|
|
|
173
186
|
// framework) and INCLUDES/EXCLUDES the entry - 200 keeps it, 204/203 drop it, and a
|
|
174
187
|
// 4xx matcher failure ends the whole operation. Path-scoping stays in the (target). Match
|
|
175
188
|
// locations remain grouped by resource internally until the target-shaped public projection.
|
|
189
|
+
//
|
|
190
|
+
// The steps run in the order their refusals are owed — the channel, the scope and its exact
|
|
191
|
+
// miss, the candidates, the universe beyond membership, the scope filter, the matcher — and each
|
|
192
|
+
// returns either the refusal or what the next step needs.
|
|
176
193
|
static async #matchPathnames(statement, ctx, manifest, address) {
|
|
177
194
|
if (statement.target === null) {
|
|
178
195
|
return {
|
|
@@ -186,12 +203,57 @@ export default class EntryFind {
|
|
|
186
203
|
};
|
|
187
204
|
}
|
|
188
205
|
const fragment = statement.target.fragment ?? null;
|
|
189
|
-
const
|
|
206
|
+
const unaddressed = EntryFind.#checkChannel(fragment, manifest);
|
|
207
|
+
if (unaddressed !== null)
|
|
208
|
+
return unaddressed;
|
|
209
|
+
const found = await EntryFind.#resolveScope(statement, ctx, manifest, address, fragment);
|
|
210
|
+
if ("status" in found)
|
|
211
|
+
return found;
|
|
212
|
+
const { scheme, authority, multipleAuthorities, scopePathname, scope } = found;
|
|
213
|
+
const superset = await EntryFind.#selectCandidates(statement, ctx, address, fragment, found);
|
|
214
|
+
if ("status" in superset)
|
|
215
|
+
return superset;
|
|
216
|
+
const coordinateByKey = new Map(superset.map((candidate) => [
|
|
217
|
+
multipleAuthorities ? EntryManifest.toPath(scheme, candidate.authority, candidate.pathname) : candidate.pathname,
|
|
218
|
+
{ authority: candidate.authority, pathname: candidate.pathname },
|
|
219
|
+
]));
|
|
220
|
+
const ambientKeys = await EntryFind.#ambientKeys(statement, address, found, superset);
|
|
221
|
+
const folders = EntryFind.#folderSummaries(statement, address, found, coordinateByKey, ambientKeys);
|
|
222
|
+
const inScope = EntryFind.#scopeCandidates(superset, found, address, fragment, ambientKeys);
|
|
223
|
+
if ("status" in inScope)
|
|
224
|
+
return inScope;
|
|
225
|
+
const candidates = multipleAuthorities
|
|
226
|
+
? inScope.map((candidate) => ({ ...candidate, pathname: EntryManifest.toPath(scheme, candidate.authority, candidate.pathname) }))
|
|
227
|
+
: inScope;
|
|
228
|
+
const channels = new Map(candidates.map((candidate) => [candidate.pathname, candidate.channel]));
|
|
229
|
+
const channelOf = (key) => {
|
|
230
|
+
const selected = channels.get(key);
|
|
231
|
+
if (selected === undefined)
|
|
232
|
+
throw new Error(`FIND candidate lost its selected channel: ${key}`);
|
|
233
|
+
return selected;
|
|
234
|
+
};
|
|
235
|
+
const effectiveBytes = address.bytes === undefined ? undefined : (key) => {
|
|
236
|
+
const coordinate = coordinateByKey.get(key);
|
|
237
|
+
if (coordinate === undefined)
|
|
238
|
+
throw new Error(`FIND byte source lost coordinate ${key}`);
|
|
239
|
+
return address.bytes(coordinate.pathname, coordinate.authority);
|
|
240
|
+
};
|
|
241
|
+
const matches = await EntryFind.#selectMatches(statement, ctx, address, { candidates, ambientKeys, channelOf, effectiveBytes });
|
|
242
|
+
if ("status" in matches)
|
|
243
|
+
return matches;
|
|
244
|
+
const projectedScope = multipleAuthorities && scopePathname !== null
|
|
245
|
+
? pathScope(EntryManifest.toPath(scheme, authority, scopePathname), manifest.folderScopes === true)
|
|
246
|
+
: scope;
|
|
247
|
+
return { status: 200, matches, channel: fragment ?? candidates[0]?.channel, ...(projectedScope === null ? {} : { scope: projectedScope }), folders,
|
|
248
|
+
...(ambientKeys.length === 0 ? {} : { ambient: new Set(ambientKeys) }) };
|
|
249
|
+
}
|
|
250
|
+
// The channel the FIND addresses, refused when the scheme has no default or does not declare it.
|
|
251
|
+
static #checkChannel(fragment, manifest) {
|
|
190
252
|
const availableChannels = [...new Set([
|
|
191
253
|
manifest.defaultChannel,
|
|
192
254
|
...Object.keys(manifest.channels),
|
|
193
255
|
])].filter((candidate) => candidate.length > 0);
|
|
194
|
-
if (manifest.defaultChannel.length === 0 && Object.keys(manifest.channels).length > 0 &&
|
|
256
|
+
if (manifest.defaultChannel.length === 0 && Object.keys(manifest.channels).length > 0 && fragment === null) {
|
|
195
257
|
return {
|
|
196
258
|
status: 400,
|
|
197
259
|
matches: [],
|
|
@@ -227,6 +289,11 @@ export default class EntryFind {
|
|
|
227
289
|
},
|
|
228
290
|
};
|
|
229
291
|
}
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
// The scheme, authority and path scope the target names; an exact path that names nothing is the
|
|
295
|
+
// scheme's miss ({§fs-errno}) unless the universe beyond membership holds it ({§membership-auto-add}).
|
|
296
|
+
static async #resolveScope(statement, ctx, manifest, address, fragment) {
|
|
230
297
|
// Scope by the manifest's persisted entries.scheme (storedScheme; absent →
|
|
231
298
|
// name). File persists under the reserved 'file' scheme ({§entry-identity-no-null}).
|
|
232
299
|
const scheme = EntryCrud.identityScheme(manifest);
|
|
@@ -248,7 +315,10 @@ export default class EntryFind {
|
|
|
248
315
|
workspace_id: ctx.workspaceId,
|
|
249
316
|
scheme, authority, pathname: scope.pathname,
|
|
250
317
|
});
|
|
251
|
-
|
|
318
|
+
// {§membership-auto-add} — an exact miss on a candidate is a listing or a match, not a 404.
|
|
319
|
+
const ambientExact = exact === undefined && address.ambient !== undefined && scheme === "file"
|
|
320
|
+
&& !scope.pathname.startsWith("../") && (await address.ambient.candidates(scope.pathname)).includes(scope.pathname);
|
|
321
|
+
if (exact === undefined && !ambientExact) {
|
|
252
322
|
const target = EntryFind.#targetPath(scheme, authority, scope.pathname, fragment, projectRoot);
|
|
253
323
|
return {
|
|
254
324
|
status: 404,
|
|
@@ -259,6 +329,13 @@ export default class EntryFind {
|
|
|
259
329
|
};
|
|
260
330
|
}
|
|
261
331
|
}
|
|
332
|
+
return { scheme, projectRoot, authority, multipleAuthorities, authorityScope, scopePathname, scope };
|
|
333
|
+
}
|
|
334
|
+
// {§find-scope-prefix-filter} {§find-scoped-isolation} The candidate rows: SQL's safe superset on the
|
|
335
|
+
// literal prefix, the authority glob applied, the asker's visibility applied, and derivation
|
|
336
|
+
// settled before an indexed dialect reads it.
|
|
337
|
+
static async #selectCandidates(statement, ctx, address, fragment, found) {
|
|
338
|
+
const { scheme, authority, multipleAuthorities, authorityScope, scope } = found;
|
|
262
339
|
// SQL receives only the literal prefix and returns a safe superset. The
|
|
263
340
|
// path matcher owns the shell-glob truth below: unlike SQLite GLOB, `*`
|
|
264
341
|
// cannot cross `/`, while `**` can. A declared folder scope remains a
|
|
@@ -269,7 +346,7 @@ export default class EntryFind {
|
|
|
269
346
|
workspace_id: workspaceId,
|
|
270
347
|
scheme,
|
|
271
348
|
authority: multipleAuthorities ? null : authority,
|
|
272
|
-
channel,
|
|
349
|
+
channel: fragment,
|
|
273
350
|
scope_prefix: address.pathBase !== undefined && scope?.candidatePrefix?.startsWith("../")
|
|
274
351
|
? null : scope?.candidatePrefix ?? null,
|
|
275
352
|
});
|
|
@@ -283,21 +360,48 @@ export default class EntryFind {
|
|
|
283
360
|
if (ctx.settleDerivations !== undefined && candidates.some((candidate) => candidate.deep_hash === null)) {
|
|
284
361
|
return { status: 503, matches: [], error: "Resource metadata is still being derived.", extensions: { stage: "search-index" } };
|
|
285
362
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
363
|
+
return candidates;
|
|
364
|
+
}
|
|
365
|
+
// {§membership-auto-add} The universe beyond membership that joins the listing and the text match.
|
|
366
|
+
static async #ambientKeys(statement, address, found, candidates) {
|
|
367
|
+
const { scheme, multipleAuthorities, scope } = found;
|
|
368
|
+
// {§membership-auto-add} — the universe beyond membership joins the listing and the text match;
|
|
369
|
+
// the indexed dialects (`~`, `&`) see members only, since nothing unadmitted is indexed.
|
|
370
|
+
let ambientKeys = [];
|
|
371
|
+
if (address.ambient !== undefined && scheme === "file" && !multipleAuthorities
|
|
372
|
+
&& !(statement.matcher !== null && (statement.matcher.dialect === "fts" || statement.matcher.dialect === "graph"))
|
|
373
|
+
&& !(scope?.candidatePrefix?.startsWith("../") ?? false)) {
|
|
374
|
+
const known = new Set(candidates.map((candidate) => candidate.pathname));
|
|
375
|
+
try {
|
|
376
|
+
ambientKeys = (await address.ambient.candidates(scope?.candidatePrefix ?? null))
|
|
377
|
+
.filter((key) => !known.has(key) && (scope === null || pathScopeMatches(scope, key, address.pathBase)));
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
ambientKeys = []; // a malformed glob is reported below, by the members' own filter
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return ambientKeys;
|
|
384
|
+
}
|
|
385
|
+
// A listing's folder rows, grouped by authority when the target spans several.
|
|
386
|
+
static #folderSummaries(statement, address, found, coordinateByKey, ambientKeys) {
|
|
387
|
+
const { scheme, authority, multipleAuthorities, scope } = found;
|
|
388
|
+
return statement.matcher === null && scope !== null
|
|
389
|
+
? [...Map.groupBy([...coordinateByKey.entries(), ...ambientKeys.map((key) => [key, { authority, pathname: key }])], ([, coordinate]) => coordinate.authority)]
|
|
390
|
+
.flatMap(([groupAuthority, entries]) => pathFolderSummaries(scope, entries.map(([, coordinate]) => coordinate.pathname), address.pathBase)
|
|
293
391
|
.map((folder) => ({
|
|
294
|
-
selector: multipleAuthorities ? EntryManifest.toPath(scheme,
|
|
295
|
-
pathnames: folder.pathnames.map((pathname) => multipleAuthorities ? EntryManifest.toPath(scheme,
|
|
392
|
+
selector: multipleAuthorities ? EntryManifest.toPath(scheme, groupAuthority, folder.selector) : folder.selector,
|
|
393
|
+
pathnames: folder.pathnames.map((pathname) => multipleAuthorities ? EntryManifest.toPath(scheme, groupAuthority, pathname) : pathname),
|
|
296
394
|
})))
|
|
297
395
|
: [];
|
|
396
|
+
}
|
|
397
|
+
// The shell-glob truth over the candidates ({§find-scope-prefix-filter}): a malformed glob is refused by
|
|
398
|
+
// name, and an exact path left with nothing is the scheme's miss.
|
|
399
|
+
static #scopeCandidates(candidates, found, address, fragment, ambientKeys) {
|
|
400
|
+
const { scheme, projectRoot, authority, multipleAuthorities, scopePathname, scope } = found;
|
|
401
|
+
let inScope = candidates;
|
|
298
402
|
if (scope !== null) {
|
|
299
403
|
try {
|
|
300
|
-
|
|
404
|
+
inScope = candidates.filter((c) => pathScopeMatches(scope, c.pathname, address.pathBase));
|
|
301
405
|
}
|
|
302
406
|
catch {
|
|
303
407
|
return {
|
|
@@ -312,7 +416,7 @@ export default class EntryFind {
|
|
|
312
416
|
};
|
|
313
417
|
}
|
|
314
418
|
}
|
|
315
|
-
if (!multipleAuthorities && scope?.kind === "exact" &&
|
|
419
|
+
if (!multipleAuthorities && scope?.kind === "exact" && inScope.length === 0 && ambientKeys.length === 0) {
|
|
316
420
|
const target = EntryFind.#targetPath(scheme, authority, scope.pathname, fragment, projectRoot);
|
|
317
421
|
return {
|
|
318
422
|
status: 404,
|
|
@@ -322,49 +426,26 @@ export default class EntryFind {
|
|
|
322
426
|
extensions: missExtensions(scheme, target),
|
|
323
427
|
};
|
|
324
428
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (selected === undefined)
|
|
334
|
-
throw new Error(`FIND candidate lost its selected channel: ${key}`);
|
|
335
|
-
return selected;
|
|
336
|
-
};
|
|
337
|
-
const effectiveBytes = address.bytes === undefined ? undefined : (key) => {
|
|
338
|
-
const coordinate = coordinateByKey.get(key);
|
|
339
|
-
if (coordinate === undefined)
|
|
340
|
-
throw new Error(`FIND byte source lost coordinate ${key}`);
|
|
341
|
-
return address.bytes(coordinate.pathname, coordinate.authority);
|
|
342
|
-
};
|
|
343
|
-
// Every dialect resolves to one selection per resource. Content
|
|
344
|
-
// dialects already carry honest match evidence; relation dialects map
|
|
345
|
-
// their indexed source spans into readable TextRegions below.
|
|
429
|
+
return inScope;
|
|
430
|
+
}
|
|
431
|
+
// Every dialect resolves to one selection per resource: rank for ~full-text, the relation index for
|
|
432
|
+
// &graph, every candidate for a bare listing, and the content matcher otherwise. Content dialects
|
|
433
|
+
// already carry honest match evidence; relation dialects map their indexed source spans into readable
|
|
434
|
+
// TextRegions.
|
|
435
|
+
static async #selectMatches(statement, ctx, address, selection) {
|
|
436
|
+
const { candidates, ambientKeys, channelOf } = selection;
|
|
346
437
|
let matches;
|
|
347
438
|
if (statement.matcher !== null && statement.matcher.dialect === "fts") {
|
|
348
439
|
const candidateSet = resolveSearchCandidates(candidates.map(({ pathname, deep_hash }) => ({ key: pathname, deepHash: deep_hash })));
|
|
349
440
|
if (candidateSet.state === "incomplete")
|
|
350
|
-
return
|
|
351
|
-
status: 503,
|
|
352
|
-
matches: [],
|
|
353
|
-
error: `The persistent search index covers ${candidateSet.indexed} of ${candidateSet.total} selected entries.`,
|
|
354
|
-
extensions: {
|
|
355
|
-
search: candidateSet,
|
|
356
|
-
stage: "search-index",
|
|
357
|
-
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
358
|
-
retryable: true,
|
|
359
|
-
},
|
|
360
|
-
};
|
|
441
|
+
return incompleteIndex(candidateSet, "selected entries");
|
|
361
442
|
const ranked = await EntryFts.rankCandidates(ctx.db, candidateSet.candidates, statement.matcher.raw.slice(1), ctx.signal);
|
|
362
443
|
if (ranked.status !== 200)
|
|
363
444
|
return { status: ranked.status, matches: [], problem: ranked.problem };
|
|
364
445
|
matches = ranked.matches.map(({ key, matches: locations }) => ({ pathname: key, matches: locations }));
|
|
365
446
|
}
|
|
366
447
|
else if (statement.matcher === null) {
|
|
367
|
-
matches = candidates.map((c) => ({ pathname: c.pathname, matches: [] }));
|
|
448
|
+
matches = [...candidates.map((c) => ({ pathname: c.pathname, matches: [] })), ...ambientKeys.map((pathname) => ({ pathname, matches: [] }))];
|
|
368
449
|
}
|
|
369
450
|
else if (statement.matcher.dialect === "graph") {
|
|
370
451
|
// {§relation-indexed-dialects} Parser admission owns graph syntax;
|
|
@@ -385,33 +466,13 @@ export default class EntryFind {
|
|
|
385
466
|
// in-scope candidates from the target glob for the final set.
|
|
386
467
|
const scopedCandidates = resolveSearchCandidates(candidates.map(({ pathname, deep_hash }) => ({ key: pathname, deepHash: deep_hash })));
|
|
387
468
|
if (scopedCandidates.state === "incomplete")
|
|
388
|
-
return
|
|
389
|
-
status: 503,
|
|
390
|
-
matches: [],
|
|
391
|
-
error: `The persistent search index covers ${scopedCandidates.indexed} of ${scopedCandidates.total} selected entries.`,
|
|
392
|
-
extensions: {
|
|
393
|
-
search: scopedCandidates,
|
|
394
|
-
stage: "search-index",
|
|
395
|
-
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
396
|
-
retryable: true,
|
|
397
|
-
},
|
|
398
|
-
};
|
|
469
|
+
return incompleteIndex(scopedCandidates, "selected entries");
|
|
399
470
|
const universeRows = await ctx.db.find_workspace_derivation_candidates.all({
|
|
400
471
|
workspace_id: ctx.workspaceId,
|
|
401
472
|
});
|
|
402
473
|
const universe = resolveSearchCandidates(universeRows.map(({ key, deep_hash }) => ({ key, deepHash: deep_hash })));
|
|
403
474
|
if (universe.state === "incomplete")
|
|
404
|
-
return
|
|
405
|
-
status: 503,
|
|
406
|
-
matches: [],
|
|
407
|
-
error: `The persistent search index covers ${universe.indexed} of ${universe.total} entries in the relationship universe.`,
|
|
408
|
-
extensions: {
|
|
409
|
-
search: universe,
|
|
410
|
-
stage: "search-index",
|
|
411
|
-
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
412
|
-
retryable: true,
|
|
413
|
-
},
|
|
414
|
-
};
|
|
475
|
+
return incompleteIndex(universe, "entries in the relationship universe");
|
|
415
476
|
const graph = await EntryGraph.matchCandidates(ctx.db, universe.candidates, scopedCandidates.candidates, statement.matcher.raw);
|
|
416
477
|
if (graph.status !== 200) {
|
|
417
478
|
return {
|
|
@@ -430,63 +491,99 @@ export default class EntryFind {
|
|
|
430
491
|
}));
|
|
431
492
|
}
|
|
432
493
|
else {
|
|
433
|
-
const
|
|
434
|
-
if (
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
494
|
+
const content = await EntryFind.#matchContent(statement.matcher, ctx, address, selection);
|
|
495
|
+
if ("status" in content)
|
|
496
|
+
return content;
|
|
497
|
+
matches = content;
|
|
498
|
+
}
|
|
499
|
+
return matches;
|
|
500
|
+
}
|
|
501
|
+
// {§find-source-agnostic} The content matcher over the candidates' text and bytes, and over the universe
|
|
502
|
+
// beyond membership: a hit there proposes admission instead of showing content ({§membership-auto-add}).
|
|
503
|
+
static async #matchContent(matcher, ctx, address, selection) {
|
|
504
|
+
const { candidates, ambientKeys, channelOf, effectiveBytes } = selection;
|
|
505
|
+
const { mimetypes } = ctx;
|
|
506
|
+
if (mimetypes === undefined)
|
|
507
|
+
throw new Error("EntryFind.#matchContent: body matcher requires the mimetypes capability in ctx");
|
|
508
|
+
// {§find-source-agnostic} — the shared content-matcher primitive (Log.find runs the same
|
|
509
|
+
// one over log rows). Candidates key by pathname; each hit becomes a Match.
|
|
510
|
+
const textCandidates = [];
|
|
511
|
+
const byteCandidates = [];
|
|
512
|
+
// {§find-bytes}/{§binary-parity} — a binary channel is searched as bytes, never as its stored
|
|
513
|
+
// text form: from the scheme's byte supplier (a File member's disk) or, absent one, from the
|
|
514
|
+
// bytes a DB entry keeps base64 in its content. It is never handed to the text matcher, so its
|
|
515
|
+
// bytes cannot poison a text search; a binary channel with neither source has nothing to search.
|
|
516
|
+
const contentBytes = new Map();
|
|
517
|
+
for (const c of candidates) {
|
|
518
|
+
if (c.content === undefined || c.mimetype === undefined)
|
|
519
|
+
throw new Error("EntryFind.#matchContent: content candidate is incomplete");
|
|
520
|
+
if (await MimetypeBinary.isBinaryMimetype(c.mimetype, mimetypes)) {
|
|
521
|
+
if (effectiveBytes !== undefined)
|
|
522
|
+
byteCandidates.push(c.pathname);
|
|
523
|
+
else if (c.content !== "") {
|
|
524
|
+
byteCandidates.push(c.pathname);
|
|
525
|
+
contentBytes.set(c.pathname, EntryCrud.contentByteSource(c.content));
|
|
455
526
|
}
|
|
456
|
-
else
|
|
457
|
-
textCandidates.push({ key: c.pathname, content: c.content, mimetype: c.mimetype });
|
|
458
527
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
? { status: 200, matches: [] }
|
|
462
|
-
: await Matcher.matchCandidates(statement.matcher, textCandidates, mimetypes);
|
|
463
|
-
if (r.status !== 200)
|
|
464
|
-
return {
|
|
465
|
-
status: r.status,
|
|
466
|
-
matches: [],
|
|
467
|
-
problem: r.problem,
|
|
468
|
-
};
|
|
469
|
-
const bytesMatched = byteCandidates.length === 0
|
|
470
|
-
? { status: 200, matches: [] }
|
|
471
|
-
: await EntryFind.#matchBytes(statement.matcher, byteCandidates, byteSupplier, mimetypes, channelOf);
|
|
472
|
-
if (bytesMatched.status !== 200)
|
|
473
|
-
return {
|
|
474
|
-
status: bytesMatched.status,
|
|
475
|
-
matches: [],
|
|
476
|
-
problem: bytesMatched.problem,
|
|
477
|
-
};
|
|
478
|
-
matches = [
|
|
479
|
-
...r.matches.map((match) => ({
|
|
480
|
-
pathname: match.key,
|
|
481
|
-
matches: match.matches.map((evidence) => ({ channel: channelOf(match.key), ...evidence })),
|
|
482
|
-
})),
|
|
483
|
-
...bytesMatched.matches,
|
|
484
|
-
];
|
|
528
|
+
else
|
|
529
|
+
textCandidates.push({ key: c.pathname, content: c.content, mimetype: c.mimetype });
|
|
485
530
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
531
|
+
// {§membership-auto-add} — a candidate's text is matched from disk; a match admits it, and the
|
|
532
|
+
// selection runs again over members, so an unadmitted candidate never shows its content.
|
|
533
|
+
const ambientSet = new Set(ambientKeys);
|
|
534
|
+
for (const key of ambientKeys) {
|
|
535
|
+
const text = await address.ambient.text(key);
|
|
536
|
+
if (text?.content != null)
|
|
537
|
+
textCandidates.push({ key, content: text.content, mimetype: text.mimetype });
|
|
538
|
+
}
|
|
539
|
+
const byteSupplier = effectiveBytes ?? ((pathname) => contentBytes.get(pathname));
|
|
540
|
+
const r = textCandidates.length === 0
|
|
541
|
+
? { status: 200, matches: [] }
|
|
542
|
+
: await Matcher.matchCandidates(matcher, textCandidates, mimetypes);
|
|
543
|
+
if (r.status !== 200)
|
|
544
|
+
return {
|
|
545
|
+
status: r.status,
|
|
546
|
+
matches: [],
|
|
547
|
+
problem: r.problem,
|
|
548
|
+
};
|
|
549
|
+
const ambientMatched = r.matches.filter((match) => ambientSet.has(match.key)).map((match) => match.key);
|
|
550
|
+
if (ambientMatched.length > 0) {
|
|
551
|
+
const proposal = await address.ambient.propose(ambientMatched);
|
|
552
|
+
if (proposal !== null)
|
|
553
|
+
return { status: 202, matches: [], proposal };
|
|
554
|
+
}
|
|
555
|
+
r.matches = r.matches.filter((match) => !ambientSet.has(match.key));
|
|
556
|
+
const bytesMatched = byteCandidates.length === 0
|
|
557
|
+
? { status: 200, matches: [] }
|
|
558
|
+
: await EntryFind.#matchBytes(matcher, byteCandidates, byteSupplier, mimetypes, channelOf);
|
|
559
|
+
if (bytesMatched.status !== 200)
|
|
560
|
+
return {
|
|
561
|
+
status: bytesMatched.status,
|
|
562
|
+
matches: [],
|
|
563
|
+
problem: bytesMatched.problem,
|
|
564
|
+
};
|
|
565
|
+
return [
|
|
566
|
+
...r.matches.map((match) => ({
|
|
567
|
+
pathname: match.key,
|
|
568
|
+
matches: match.matches.map((evidence) => ({ channel: channelOf(match.key), ...evidence })),
|
|
569
|
+
})),
|
|
570
|
+
...bytesMatched.matches,
|
|
571
|
+
];
|
|
572
|
+
}
|
|
573
|
+
// {§membership-auto-add} — a candidate's listing row: its type, weight and extent from disk, marked
|
|
574
|
+
// untracked; a binary or oversized candidate lists with no weight until a READ admits it.
|
|
575
|
+
static async #ambientItem(ambient, key, path, weigh) {
|
|
576
|
+
const text = await ambient.text(key);
|
|
577
|
+
if (text === null)
|
|
578
|
+
return null;
|
|
579
|
+
const content = text.content;
|
|
580
|
+
return [{
|
|
581
|
+
path,
|
|
582
|
+
mimetype: text.mimetype,
|
|
583
|
+
weight: content === null || weigh === undefined ? 0 : weigh(content),
|
|
584
|
+
lines: content === null ? 0 : content.split("\n").length,
|
|
585
|
+
aside: "untracked",
|
|
586
|
+
}];
|
|
490
587
|
}
|
|
491
588
|
// {§find-bytes} — the matcher runs over the bytes as one character each, so a text pattern
|
|
492
589
|
// finds strings and `\xNN` escapes find byte sequences; every hit is re-expressed in byte
|
|
@@ -523,6 +620,9 @@ export default class EntryFind {
|
|
|
523
620
|
match = await EntryFind.#matchPathnames(statement, ctx, manifest, address);
|
|
524
621
|
}
|
|
525
622
|
const empty = emptyFindFields();
|
|
623
|
+
// {§membership-auto-add} — the FIND proposes the admission of the candidates its pattern matched.
|
|
624
|
+
if (match.status === 202 && match.proposal !== undefined)
|
|
625
|
+
return { ...empty, ...match.proposal };
|
|
526
626
|
if (match.status !== 200) {
|
|
527
627
|
if (match.problem !== undefined) {
|
|
528
628
|
return Results.assert({
|
|
@@ -552,9 +652,16 @@ export default class EntryFind {
|
|
|
552
652
|
const resources = [];
|
|
553
653
|
for (const m of match.matches) {
|
|
554
654
|
const row = byPath.get(addressOf(m.pathname));
|
|
555
|
-
if (row
|
|
655
|
+
if (row !== undefined) {
|
|
656
|
+
resources.push({ item: row, match: m });
|
|
556
657
|
continue;
|
|
557
|
-
|
|
658
|
+
}
|
|
659
|
+
// {§membership-auto-add} — a listed candidate has no catalog row; its row is read from disk.
|
|
660
|
+
if (match.ambient?.has(m.pathname) && address.ambient !== undefined) {
|
|
661
|
+
const item = await EntryFind.#ambientItem(address.ambient, m.pathname, addressOf(m.pathname), ctx.weigh);
|
|
662
|
+
if (item !== null)
|
|
663
|
+
resources.push({ item, match: m });
|
|
664
|
+
}
|
|
558
665
|
}
|
|
559
666
|
// A terminal single-star catalog is a one-level map. Keep real entries
|
|
560
667
|
// at that level and collapse deeper descendants into exact, actionable
|
|
@@ -567,8 +674,11 @@ export default class EntryFind {
|
|
|
567
674
|
let items = 0;
|
|
568
675
|
for (const pathname of folder.pathnames) {
|
|
569
676
|
const row = byPath.get(addressOf(pathname));
|
|
570
|
-
if (row === undefined)
|
|
677
|
+
if (row === undefined) {
|
|
678
|
+
if (match.ambient?.has(pathname))
|
|
679
|
+
items++;
|
|
571
680
|
continue;
|
|
681
|
+
}
|
|
572
682
|
items++;
|
|
573
683
|
weight += row.reduce((sum, channel) => sum + channel.weight, 0);
|
|
574
684
|
}
|
|
@@ -580,7 +690,8 @@ export default class EntryFind {
|
|
|
580
690
|
if (match.scope === undefined)
|
|
581
691
|
throw new Error("FIND selection succeeded without a path scope");
|
|
582
692
|
const projected = projectFindResult(statement, match.scope, resources, scopes, manifest.defaultChannel);
|
|
583
|
-
|
|
693
|
+
// {§membership-auto-add} — a listed candidate has no stored representation to consume.
|
|
694
|
+
if (address.pathname === undefined || match.ambient?.has(address.pathname))
|
|
584
695
|
return projected;
|
|
585
696
|
// Exact FIND consumes the same selected canonical producer as exact
|
|
586
697
|
// READ. Query projection remains core-owned, while the durable selected-
|