@laserdata/laser-sdk 0.5.3 → 0.6.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/README.md +105 -79
- package/dist/agent/agdx.d.ts +8 -3
- package/dist/agent/agdx.d.ts.map +1 -1
- package/dist/agent/agdx.js +39 -22
- package/dist/agent/agdx.js.map +1 -1
- package/dist/agent/builder.d.ts +25 -15
- package/dist/agent/builder.d.ts.map +1 -1
- package/dist/agent/builder.js +103 -59
- package/dist/agent/builder.js.map +1 -1
- package/dist/agent/context.d.ts +3 -6
- package/dist/agent/context.d.ts.map +1 -1
- package/dist/agent/context.js +17 -9
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/contract.d.ts +2 -2
- package/dist/agent/contract.d.ts.map +1 -1
- package/dist/agent/contract.js +10 -6
- package/dist/agent/contract.js.map +1 -1
- package/dist/agent/memory-handler.d.ts +25 -0
- package/dist/agent/memory-handler.d.ts.map +1 -0
- package/dist/agent/memory-handler.js +43 -0
- package/dist/agent/memory-handler.js.map +1 -0
- package/dist/agent/registry.d.ts +3 -10
- package/dist/agent/registry.d.ts.map +1 -1
- package/dist/agent/registry.js +22 -19
- package/dist/agent/registry.js.map +1 -1
- package/dist/agent/reliable-consumer.d.ts +19 -9
- package/dist/agent/reliable-consumer.d.ts.map +1 -1
- package/dist/agent/reliable-consumer.js +193 -54
- package/dist/agent/reliable-consumer.js.map +1 -1
- package/dist/agent/replies.d.ts +6 -0
- package/dist/agent/replies.d.ts.map +1 -1
- package/dist/agent/replies.js +55 -4
- package/dist/agent/replies.js.map +1 -1
- package/dist/agent/router.d.ts +1 -1
- package/dist/agent/router.d.ts.map +1 -1
- package/dist/agent/router.js +5 -19
- package/dist/agent/router.js.map +1 -1
- package/dist/agent/scope.d.ts +7 -3
- package/dist/agent/scope.d.ts.map +1 -1
- package/dist/agent/scope.js +11 -1
- package/dist/agent/scope.js.map +1 -1
- package/dist/agent/timer.d.ts +6 -0
- package/dist/agent/timer.d.ts.map +1 -0
- package/dist/agent/timer.js +21 -0
- package/dist/agent/timer.js.map +1 -0
- package/dist/agent/workflow.d.ts +16 -19
- package/dist/agent/workflow.d.ts.map +1 -1
- package/dist/agent/workflow.js +17 -6
- package/dist/agent/workflow.js.map +1 -1
- package/dist/blob.d.ts +2 -3
- package/dist/blob.d.ts.map +1 -1
- package/dist/blob.js.map +1 -1
- package/dist/bridges/a2a.d.ts +34 -23
- package/dist/bridges/a2a.d.ts.map +1 -1
- package/dist/bridges/a2a.js +29 -19
- package/dist/bridges/a2a.js.map +1 -1
- package/dist/bridges/hops.d.ts +1 -1
- package/dist/bridges/hops.d.ts.map +1 -1
- package/dist/bridges/hops.js +1 -1
- package/dist/bridges/hops.js.map +1 -1
- package/dist/bridges/mcp.d.ts +27 -7
- package/dist/bridges/mcp.d.ts.map +1 -1
- package/dist/bridges/mcp.js +24 -9
- package/dist/bridges/mcp.js.map +1 -1
- package/dist/client/bytes.d.ts +5 -0
- package/dist/client/bytes.d.ts.map +1 -1
- package/dist/client/bytes.js +15 -0
- package/dist/client/bytes.js.map +1 -1
- package/dist/client/capabilities.d.ts +25 -13
- package/dist/client/capabilities.d.ts.map +1 -1
- package/dist/client/capabilities.js +145 -123
- package/dist/client/capabilities.js.map +1 -1
- package/dist/client/error-classify.d.ts +57 -0
- package/dist/client/error-classify.d.ts.map +1 -0
- package/dist/client/error-classify.js +347 -0
- package/dist/client/error-classify.js.map +1 -0
- package/dist/client/errors.d.ts +113 -40
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +191 -53
- package/dist/client/errors.js.map +1 -1
- package/dist/client/internals.d.ts +1 -0
- package/dist/client/internals.d.ts.map +1 -1
- package/dist/client/internals.js +1 -0
- package/dist/client/internals.js.map +1 -1
- package/dist/client/laser.d.ts +62 -46
- package/dist/client/laser.d.ts.map +1 -1
- package/dist/client/laser.js +206 -120
- package/dist/client/laser.js.map +1 -1
- package/dist/client/managed.d.ts +3 -0
- package/dist/client/managed.d.ts.map +1 -1
- package/dist/client/managed.js +70 -3
- package/dist/client/managed.js.map +1 -1
- package/dist/context-scope.d.ts +25 -9
- package/dist/context-scope.d.ts.map +1 -1
- package/dist/context-scope.js +36 -9
- package/dist/context-scope.js.map +1 -1
- package/dist/context.d.ts +33 -16
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +174 -95
- package/dist/context.js.map +1 -1
- package/dist/conversation-state.d.ts +1 -1
- package/dist/conversation-state.d.ts.map +1 -1
- package/dist/conversation-state.js +35 -16
- package/dist/conversation-state.js.map +1 -1
- package/dist/govern.d.ts +24 -5
- package/dist/govern.d.ts.map +1 -1
- package/dist/govern.js +116 -28
- package/dist/govern.js.map +1 -1
- package/dist/iggy/apache-iggy.d.ts +59 -56
- package/dist/iggy/apache-iggy.d.ts.map +1 -1
- package/dist/iggy/apache-iggy.js +300 -137
- package/dist/iggy/apache-iggy.js.map +1 -1
- package/dist/index.d.ts +97 -65
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -30
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +16 -2
- package/dist/intent.d.ts.map +1 -1
- package/dist/intent.js +50 -18
- package/dist/intent.js.map +1 -1
- package/dist/managed/coordination.d.ts +82 -0
- package/dist/managed/coordination.d.ts.map +1 -0
- package/dist/managed/coordination.js +367 -0
- package/dist/managed/coordination.js.map +1 -0
- package/dist/managed/destinations.d.ts +4 -3
- package/dist/managed/destinations.d.ts.map +1 -1
- package/dist/managed/destinations.js +29 -13
- package/dist/managed/destinations.js.map +1 -1
- package/dist/managed/filters.d.ts +5 -5
- package/dist/managed/filters.d.ts.map +1 -1
- package/dist/managed/filters.js +39 -22
- package/dist/managed/filters.js.map +1 -1
- package/dist/managed/forks.d.ts +8 -11
- package/dist/managed/forks.d.ts.map +1 -1
- package/dist/managed/forks.js +33 -13
- package/dist/managed/forks.js.map +1 -1
- package/dist/managed/graph.d.ts +1 -4
- package/dist/managed/graph.d.ts.map +1 -1
- package/dist/managed/graph.js +5 -3
- package/dist/managed/graph.js.map +1 -1
- package/dist/managed/kv.d.ts +26 -14
- package/dist/managed/kv.d.ts.map +1 -1
- package/dist/managed/kv.js +88 -61
- package/dist/managed/kv.js.map +1 -1
- package/dist/managed/projections.d.ts +5 -8
- package/dist/managed/projections.d.ts.map +1 -1
- package/dist/managed/projections.js +22 -2
- package/dist/managed/projections.js.map +1 -1
- package/dist/managed/query.d.ts +20 -6
- package/dist/managed/query.d.ts.map +1 -1
- package/dist/managed/query.js +97 -24
- package/dist/managed/query.js.map +1 -1
- package/dist/managed/runs.d.ts +2 -4
- package/dist/managed/runs.d.ts.map +1 -1
- package/dist/managed/runs.js +9 -1
- package/dist/managed/runs.js.map +1 -1
- package/dist/managed/watch.d.ts +2 -4
- package/dist/managed/watch.d.ts.map +1 -1
- package/dist/managed/watch.js +9 -1
- package/dist/managed/watch.js.map +1 -1
- package/dist/memory/handle.d.ts +75 -22
- package/dist/memory/handle.d.ts.map +1 -1
- package/dist/memory/handle.js +232 -58
- package/dist/memory/handle.js.map +1 -1
- package/dist/memory/log-memory.d.ts +24 -12
- package/dist/memory/log-memory.d.ts.map +1 -1
- package/dist/memory/log-memory.js +214 -100
- package/dist/memory/log-memory.js.map +1 -1
- package/dist/memory/topic.d.ts +2 -2
- package/dist/memory/topic.d.ts.map +1 -1
- package/dist/memory/topic.js +7 -5
- package/dist/memory/topic.js.map +1 -1
- package/dist/memory/types.d.ts +41 -5
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +44 -18
- package/dist/memory/types.js.map +1 -1
- package/dist/memory/vector-memory.d.ts +8 -6
- package/dist/memory/vector-memory.d.ts.map +1 -1
- package/dist/memory/vector-memory.js +65 -34
- package/dist/memory/vector-memory.js.map +1 -1
- package/dist/memory.d.ts +6 -5
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +4 -4
- package/dist/memory.js.map +1 -1
- package/dist/provenance/agent-topic.d.ts +3 -1
- package/dist/provenance/agent-topic.d.ts.map +1 -1
- package/dist/provenance/agent-topic.js +3 -1
- package/dist/provenance/agent-topic.js.map +1 -1
- package/dist/provenance/provenance.d.ts +3 -3
- package/dist/provenance/provenance.d.ts.map +1 -1
- package/dist/provenance/provenance.js +30 -18
- package/dist/provenance/provenance.js.map +1 -1
- package/dist/runtime/clock.d.ts +3 -0
- package/dist/runtime/clock.d.ts.map +1 -1
- package/dist/runtime/clock.js +16 -3
- package/dist/runtime/clock.js.map +1 -1
- package/dist/schema-codecs.d.ts +7 -3
- package/dist/schema-codecs.d.ts.map +1 -1
- package/dist/schema-codecs.js +80 -12
- package/dist/schema-codecs.js.map +1 -1
- package/dist/session.d.ts +27 -18
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +95 -37
- package/dist/session.js.map +1 -1
- package/dist/signing.d.ts +11 -5
- package/dist/signing.d.ts.map +1 -1
- package/dist/signing.js +64 -21
- package/dist/signing.js.map +1 -1
- package/dist/snapshot.d.ts +10 -2
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/snapshot.js +62 -28
- package/dist/snapshot.js.map +1 -1
- package/dist/state-store.d.ts +1 -1
- package/dist/state-store.d.ts.map +1 -1
- package/dist/state-store.js.map +1 -1
- package/dist/stream/batching.d.ts +81 -0
- package/dist/stream/batching.d.ts.map +1 -0
- package/dist/stream/batching.js +210 -0
- package/dist/stream/batching.js.map +1 -0
- package/dist/stream/bson.d.ts +3 -0
- package/dist/stream/bson.d.ts.map +1 -0
- package/dist/stream/bson.js +245 -0
- package/dist/stream/bson.js.map +1 -0
- package/dist/stream/codecs.d.ts +58 -6
- package/dist/stream/codecs.d.ts.map +1 -1
- package/dist/stream/codecs.js +143 -59
- package/dist/stream/codecs.js.map +1 -1
- package/dist/stream/consumer-group.d.ts +13 -10
- package/dist/stream/consumer-group.d.ts.map +1 -1
- package/dist/stream/consumer-group.js +91 -31
- package/dist/stream/consumer-group.js.map +1 -1
- package/dist/stream/consumer-start.d.ts +17 -0
- package/dist/stream/consumer-start.d.ts.map +1 -0
- package/dist/stream/consumer-start.js +2 -0
- package/dist/stream/consumer-start.js.map +1 -0
- package/dist/stream/consumer.d.ts +166 -24
- package/dist/stream/consumer.d.ts.map +1 -1
- package/dist/stream/consumer.js +451 -68
- package/dist/stream/consumer.js.map +1 -1
- package/dist/stream/cursor.d.ts +5 -12
- package/dist/stream/cursor.d.ts.map +1 -1
- package/dist/stream/cursor.js +34 -8
- package/dist/stream/cursor.js.map +1 -1
- package/dist/stream/header-value.d.ts +61 -15
- package/dist/stream/header-value.d.ts.map +1 -1
- package/dist/stream/header-value.js.map +1 -1
- package/dist/stream/message.d.ts +17 -0
- package/dist/stream/message.d.ts.map +1 -0
- package/dist/stream/message.js +9 -0
- package/dist/stream/message.js.map +1 -0
- package/dist/stream/producer.d.ts +127 -11
- package/dist/stream/producer.d.ts.map +1 -1
- package/dist/stream/producer.js +401 -36
- package/dist/stream/producer.js.map +1 -1
- package/dist/stream/publish.d.ts +6 -15
- package/dist/stream/publish.d.ts.map +1 -1
- package/dist/stream/publish.js +18 -28
- package/dist/stream/publish.js.map +1 -1
- package/dist/stream/record.d.ts +4 -6
- package/dist/stream/record.d.ts.map +1 -1
- package/dist/stream/record.js +4 -3
- package/dist/stream/record.js.map +1 -1
- package/dist/stream/routing.d.ts +12 -0
- package/dist/stream/routing.d.ts.map +1 -1
- package/dist/stream/routing.js +6 -1
- package/dist/stream/routing.js.map +1 -1
- package/dist/stream/stream.d.ts +1 -4
- package/dist/stream/stream.d.ts.map +1 -1
- package/dist/stream/stream.js +5 -1
- package/dist/stream/stream.js.map +1 -1
- package/dist/stream/topic.d.ts +22 -23
- package/dist/stream/topic.d.ts.map +1 -1
- package/dist/stream/topic.js +90 -30
- package/dist/stream/topic.js.map +1 -1
- package/dist/stream/typed-topic.d.ts +9 -13
- package/dist/stream/typed-topic.d.ts.map +1 -1
- package/dist/stream/typed-topic.js +25 -10
- package/dist/stream/typed-topic.js.map +1 -1
- package/dist/swarm.d.ts +0 -1
- package/dist/swarm.d.ts.map +1 -1
- package/dist/swarm.js +1 -0
- package/dist/swarm.js.map +1 -1
- package/dist/testing.d.ts +3 -3
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +3 -3
- package/dist/testing.js.map +1 -1
- package/dist/types/ids.d.ts +17 -2
- package/dist/types/ids.d.ts.map +1 -1
- package/dist/types/ids.js +34 -14
- package/dist/types/ids.js.map +1 -1
- package/dist/wire/agent.d.ts +22 -0
- package/dist/wire/agent.d.ts.map +1 -1
- package/dist/wire/agent.js +80 -25
- package/dist/wire/agent.js.map +1 -1
- package/dist/wire/authz.d.ts +35 -1
- package/dist/wire/authz.d.ts.map +1 -1
- package/dist/wire/authz.js +45 -15
- package/dist/wire/authz.js.map +1 -1
- package/dist/wire/cbor.d.ts.map +1 -1
- package/dist/wire/cbor.js +13 -2
- package/dist/wire/cbor.js.map +1 -1
- package/dist/wire/checkpoint.d.ts +17 -12
- package/dist/wire/checkpoint.d.ts.map +1 -1
- package/dist/wire/checkpoint.js +28 -3
- package/dist/wire/checkpoint.js.map +1 -1
- package/dist/wire/control.d.ts +82 -0
- package/dist/wire/control.d.ts.map +1 -1
- package/dist/wire/control.js +219 -0
- package/dist/wire/control.js.map +1 -1
- package/dist/wire/filter-eval.d.ts +41 -7
- package/dist/wire/filter-eval.d.ts.map +1 -1
- package/dist/wire/filter-eval.js +26 -28
- package/dist/wire/filter-eval.js.map +1 -1
- package/dist/wire/filter.d.ts +51 -17
- package/dist/wire/filter.d.ts.map +1 -1
- package/dist/wire/filter.js +99 -10
- package/dist/wire/filter.js.map +1 -1
- package/dist/wire/fork.d.ts +14 -1
- package/dist/wire/fork.d.ts.map +1 -1
- package/dist/wire/fork.js +19 -8
- package/dist/wire/fork.js.map +1 -1
- package/dist/wire/graph.d.ts +3 -0
- package/dist/wire/graph.d.ts.map +1 -1
- package/dist/wire/graph.js +18 -4
- package/dist/wire/graph.js.map +1 -1
- package/dist/wire/hello.d.ts +4 -1
- package/dist/wire/hello.d.ts.map +1 -1
- package/dist/wire/hello.js +13 -3
- package/dist/wire/hello.js.map +1 -1
- package/dist/wire/index.d.ts +4 -1
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +4 -1
- package/dist/wire/index.js.map +1 -1
- package/dist/wire/kv.d.ts +37 -2
- package/dist/wire/kv.d.ts.map +1 -1
- package/dist/wire/kv.js +36 -18
- package/dist/wire/kv.js.map +1 -1
- package/dist/wire/query.d.ts +6 -0
- package/dist/wire/query.d.ts.map +1 -1
- package/dist/wire/query.js +38 -12
- package/dist/wire/query.js.map +1 -1
- package/dist/wire/schema.d.ts +29 -6
- package/dist/wire/schema.d.ts.map +1 -1
- package/dist/wire/schema.js +61 -26
- package/dist/wire/schema.js.map +1 -1
- package/dist/wire/snapshot.js +1 -1
- package/dist/wire/snapshot.js.map +1 -1
- package/dist/wire/value.d.ts +10 -2
- package/dist/wire/value.d.ts.map +1 -1
- package/dist/wire/value.js +29 -3
- package/dist/wire/value.js.map +1 -1
- package/package.json +2 -3
- package/dist/stream/polling-strategy.d.ts +0 -14
- package/dist/stream/polling-strategy.d.ts.map +0 -1
- package/dist/stream/polling-strategy.js +0 -2
- package/dist/stream/polling-strategy.js.map +0 -1
package/dist/client/laser.js
CHANGED
|
@@ -10,18 +10,19 @@ import { Workflow } from "../agent/workflow.js";
|
|
|
10
10
|
import { aguiEvents, publishStateDelta, publishStateSnapshot, reconstructState } from "../bridges/agui.js";
|
|
11
11
|
import { AgentScope } from "../agent/scope.js";
|
|
12
12
|
import { ChunkAssembler } from "../agent/assembler.js";
|
|
13
|
-
import { AgentRegistry, ClientMetadataRequest,
|
|
13
|
+
import { AgentRegistry, ClientMetadataRequest, encodePresence, newRegistryCache } from "../agent/registry.js";
|
|
14
14
|
import { AsyncOnce } from "../runtime/async-once.js";
|
|
15
15
|
import { Stream } from "../stream/stream.js";
|
|
16
16
|
import { ContextScope } from "../context-scope.js";
|
|
17
17
|
import { Sessions } from "../session.js";
|
|
18
|
-
import { ActionKind, GovernorState, encodePolicyEvidence,
|
|
18
|
+
import { ActionKind, GovernorState, encodePolicyEvidence, POLICY_DECISION_OPERATION } from "../govern.js";
|
|
19
19
|
import { MemoryBackend, MemoryHandle } from "../memory/handle.js";
|
|
20
20
|
import { MemoryTopicBuilder } from "../memory/topic.js";
|
|
21
21
|
import { NOOP_OBSERVER } from "../observe.js";
|
|
22
22
|
import { executeBatch } from "../managed/batch.js";
|
|
23
|
-
import {
|
|
23
|
+
import { ForkHandle } from "../managed/forks.js";
|
|
24
24
|
import { Kv } from "../managed/kv.js";
|
|
25
|
+
import { LeaseCoordinator } from "../managed/coordination.js";
|
|
25
26
|
import { Bindings, Projections, Schemas } from "../managed/projections.js";
|
|
26
27
|
import { QueryRequest } from "../managed/query.js";
|
|
27
28
|
import { Destinations } from "../managed/destinations.js";
|
|
@@ -30,7 +31,7 @@ import { GraphHandle } from "../managed/graph.js";
|
|
|
30
31
|
import { Runs } from "../managed/runs.js";
|
|
31
32
|
import { Watch } from "../managed/watch.js";
|
|
32
33
|
import { AGDX_HELLO_CODE, AGDX_SET_CLIENT_METADATA_CODE, CONTROL_OP_VERSION, QUERY_OP_VERSION } from "../wire/codes.js";
|
|
33
|
-
import { QueryCancelCommand, QueryCommand, QueryStatusCommand } from "../wire/commands.js";
|
|
34
|
+
import { QueryCancelCommand, QueryCommand, QueryPageCommand, QueryStatusCommand } from "../wire/commands.js";
|
|
34
35
|
import { encodeControlEnvelope } from "../wire/control.js";
|
|
35
36
|
import { decodeBackendAnnounce } from "../wire/hello.js";
|
|
36
37
|
import { AgentId, ConversationId } from "../types/ids.js";
|
|
@@ -43,27 +44,27 @@ import { AgentTopic } from "../provenance/agent-topic.js";
|
|
|
43
44
|
import { encodeProvenanceHeaders, provenancePartitionKey } from "../provenance/provenance.js";
|
|
44
45
|
import { CHANGES_TOPIC, CONTROL_TOPIC, DLQ_TOPIC, OPS_STREAM } from "../wire/topics.js";
|
|
45
46
|
import { encodeNamed } from "../wire/cbor.js";
|
|
46
|
-
import { ConfigError, NoStreamError, PresenceConflictError, QueryExecutionError, InvalidError, TimeoutError, UnsupportedError } from "./errors.js";
|
|
47
|
+
import { ConfigError, NoStreamError, PresenceConflictError, QueryExecutionError, ProtocolError, InvalidError, TimeoutError, UnsupportedError } from "./errors.js";
|
|
47
48
|
import { executeManaged } from "./managed.js";
|
|
48
49
|
import { INTERNAL_GOVERN, INTERNAL_REPLY_HUB, INTERNAL_TRANSPORT, INTERNAL_VERIFIER } from "./internals.js";
|
|
49
|
-
import { OPEN_CAPABILITIES, managedCapabilitiesFrom, mergeCapabilities, isReady, servesConsistency } from "./capabilities.js";
|
|
50
|
+
import { OPEN_CAPABILITIES, advertisedTopology, managedCapabilitiesFrom, mergeCapabilities, isReady, servesConsistency } from "./capabilities.js";
|
|
50
51
|
const LOCAL_CONNECTION_STRING = "iggy:iggy@127.0.0.1:8090";
|
|
51
52
|
// The Iggy error code a server answers an unknown command with.
|
|
52
53
|
const INVALID_COMMAND = 3;
|
|
53
54
|
const DEFAULT_TOPOLOGY = {
|
|
54
55
|
opsStream: OPS_STREAM,
|
|
55
56
|
controlTopic: CONTROL_TOPIC,
|
|
56
|
-
|
|
57
|
+
dlqTopic: DLQ_TOPIC,
|
|
57
58
|
changesTopic: CHANGES_TOPIC
|
|
58
59
|
};
|
|
59
60
|
const NO_TOPOLOGY_OVERRIDES = {
|
|
60
61
|
opsStream: false,
|
|
61
62
|
controlTopic: false,
|
|
62
|
-
|
|
63
|
+
dlqTopic: false,
|
|
63
64
|
changesTopic: false
|
|
64
65
|
};
|
|
65
66
|
export class LaserBuilder {
|
|
66
|
-
|
|
67
|
+
connectWith;
|
|
67
68
|
connectOptionsValue = {};
|
|
68
69
|
publishOptionsValue = {};
|
|
69
70
|
connectionStringValue;
|
|
@@ -78,8 +79,12 @@ export class LaserBuilder {
|
|
|
78
79
|
verifierValue;
|
|
79
80
|
topologyValue = DEFAULT_TOPOLOGY;
|
|
80
81
|
topologyOverridesValue = NO_TOPOLOGY_OVERRIDES;
|
|
81
|
-
constructor(
|
|
82
|
-
this.
|
|
82
|
+
constructor(connectWith) {
|
|
83
|
+
this.connectWith = connectWith;
|
|
84
|
+
}
|
|
85
|
+
/** @internal */
|
|
86
|
+
static create(connectWith) {
|
|
87
|
+
return new LaserBuilder(connectWith);
|
|
83
88
|
}
|
|
84
89
|
/**
|
|
85
90
|
* Budget for the initial connect: TCP dial, TLS handshake, login, and the managed capability probe. An expired budget rejects with `TimeoutError` naming the stage that stalled. Default: 30 seconds, or `LASER_CONNECT_TIMEOUT_MS`.
|
|
@@ -109,19 +114,15 @@ export class LaserBuilder {
|
|
|
109
114
|
return this;
|
|
110
115
|
}
|
|
111
116
|
credentials(username, password) {
|
|
112
|
-
this.credentialsValue = {
|
|
113
|
-
return this;
|
|
114
|
-
}
|
|
115
|
-
token(value) {
|
|
116
|
-
this.credentialsValue = { kind: "token", token: value };
|
|
117
|
+
this.credentialsValue = { username, password };
|
|
117
118
|
return this;
|
|
118
119
|
}
|
|
119
|
-
|
|
120
|
+
client(client, options = {}) {
|
|
120
121
|
this.clientValue = client;
|
|
121
122
|
this.ownershipValue = options.ownership ?? "borrowed";
|
|
122
123
|
return this;
|
|
123
124
|
}
|
|
124
|
-
|
|
125
|
+
stream(value) {
|
|
125
126
|
this.defaultStreamValue = value;
|
|
126
127
|
return this;
|
|
127
128
|
}
|
|
@@ -151,9 +152,9 @@ export class LaserBuilder {
|
|
|
151
152
|
this.topologyOverridesValue = { ...this.topologyOverridesValue, controlTopic: true };
|
|
152
153
|
return this;
|
|
153
154
|
}
|
|
154
|
-
|
|
155
|
-
this.topologyValue = { ...this.topologyValue,
|
|
156
|
-
this.topologyOverridesValue = { ...this.topologyOverridesValue,
|
|
155
|
+
dlqTopic(value) {
|
|
156
|
+
this.topologyValue = { ...this.topologyValue, dlqTopic: value };
|
|
157
|
+
this.topologyOverridesValue = { ...this.topologyOverridesValue, dlqTopic: true };
|
|
157
158
|
return this;
|
|
158
159
|
}
|
|
159
160
|
changesTopic(value) {
|
|
@@ -161,15 +162,17 @@ export class LaserBuilder {
|
|
|
161
162
|
this.topologyOverridesValue = { ...this.topologyOverridesValue, changesTopic: true };
|
|
162
163
|
return this;
|
|
163
164
|
}
|
|
164
|
-
|
|
165
|
+
/** Connects with the configured settings. A configuration conflict
|
|
166
|
+
* rejects before any I/O, like every other failure of the connect. */
|
|
167
|
+
async connect() {
|
|
165
168
|
const modes = Number(this.connectionStringValue !== undefined) +
|
|
166
169
|
Number(this.addressValue !== undefined) +
|
|
167
170
|
Number(this.clientValue !== undefined);
|
|
168
171
|
if (modes > 1) {
|
|
169
|
-
throw new ConfigError("connectionString(), address(), and
|
|
172
|
+
throw new ConfigError("connectionString(), address(), and client() are mutually exclusive");
|
|
170
173
|
}
|
|
171
174
|
if (this.credentialsValue !== undefined && this.addressValue === undefined) {
|
|
172
|
-
throw new ConfigError("credentials()
|
|
175
|
+
throw new ConfigError("credentials() requires address()");
|
|
173
176
|
}
|
|
174
177
|
if (this.addressValue !== undefined) {
|
|
175
178
|
const { host, port } = this.addressValue;
|
|
@@ -180,14 +183,14 @@ export class LaserBuilder {
|
|
|
180
183
|
const topologyEntries = [
|
|
181
184
|
["opsStream", this.topologyValue.opsStream],
|
|
182
185
|
["controlTopic", this.topologyValue.controlTopic],
|
|
183
|
-
["
|
|
186
|
+
["dlqTopic", this.topologyValue.dlqTopic],
|
|
184
187
|
["changesTopic", this.topologyValue.changesTopic]
|
|
185
188
|
];
|
|
186
189
|
for (const [name, value] of topologyEntries) {
|
|
187
190
|
if (value.length === 0)
|
|
188
191
|
throw new ConfigError(`${name} must not be empty`);
|
|
189
192
|
}
|
|
190
|
-
return this.
|
|
193
|
+
return this.connectWith({
|
|
191
194
|
connectOptions: connectOptions(this.connectOptionsValue),
|
|
192
195
|
publishOptions: publishOptions(this.publishOptionsValue),
|
|
193
196
|
...(this.connectionStringValue !== undefined
|
|
@@ -208,10 +211,13 @@ export class LaserBuilder {
|
|
|
208
211
|
}
|
|
209
212
|
}
|
|
210
213
|
export { INTERNAL_GOVERN, INTERNAL_REPLY_HUB, INTERNAL_TRANSPORT, INTERNAL_VERIFIER } from "./internals.js";
|
|
211
|
-
|
|
214
|
+
// `connectionString` is the string the client dialed, absent for an injected
|
|
215
|
+
// client, which has nothing to dial a coordination connection with.
|
|
216
|
+
function newSharedState(connectionString) {
|
|
212
217
|
return {
|
|
213
218
|
registryCaches: new Map(),
|
|
214
219
|
replyHubs: new Map(),
|
|
220
|
+
leases: LeaseCoordinator.forConnection(connectionString),
|
|
215
221
|
announcedTopology: DEFAULT_TOPOLOGY
|
|
216
222
|
};
|
|
217
223
|
}
|
|
@@ -244,7 +250,7 @@ function actionKind(kind) {
|
|
|
244
250
|
}
|
|
245
251
|
function metadataString(envelope, key) {
|
|
246
252
|
const value = envelope.metadata?.get(key);
|
|
247
|
-
return value?.kind === "
|
|
253
|
+
return value?.kind === "str" ? value.value : undefined;
|
|
248
254
|
}
|
|
249
255
|
function metadataActionFields(envelope) {
|
|
250
256
|
const onBehalfOf = metadataString(envelope, METADATA_DELEGATED_BY);
|
|
@@ -319,10 +325,10 @@ export class Laser {
|
|
|
319
325
|
? this.configuredTopology.controlTopic
|
|
320
326
|
: this.shared.announcedTopology.controlTopic;
|
|
321
327
|
}
|
|
322
|
-
get
|
|
323
|
-
return this.topologyOverrides.
|
|
324
|
-
? this.configuredTopology.
|
|
325
|
-
: this.shared.announcedTopology.
|
|
328
|
+
get dlqTopic() {
|
|
329
|
+
return this.topologyOverrides.dlqTopic
|
|
330
|
+
? this.configuredTopology.dlqTopic
|
|
331
|
+
: this.shared.announcedTopology.dlqTopic;
|
|
326
332
|
}
|
|
327
333
|
get changesTopic() {
|
|
328
334
|
return this.topologyOverrides.changesTopic
|
|
@@ -330,32 +336,29 @@ export class Laser {
|
|
|
330
336
|
: this.shared.announcedTopology.changesTopic;
|
|
331
337
|
}
|
|
332
338
|
static builder() {
|
|
333
|
-
return
|
|
339
|
+
return LaserBuilder.create(async (options) => {
|
|
334
340
|
const deadline = Date.now() + options.connectOptions.timeoutMs;
|
|
335
341
|
let transport;
|
|
342
|
+
let dialed;
|
|
336
343
|
if (options.client !== undefined) {
|
|
337
344
|
transport = await ApacheIggyTransport.fromClient(options.client, options.ownership, options.publishOptions, deadline);
|
|
338
345
|
}
|
|
339
346
|
else if (options.address !== undefined) {
|
|
340
|
-
const credentials = options.credentials ?? {
|
|
341
|
-
|
|
342
|
-
username: "iggy",
|
|
343
|
-
password: "iggy"
|
|
344
|
-
};
|
|
345
|
-
const userInfo = credentials.kind === "token"
|
|
346
|
-
? encodeURIComponent(credentials.token)
|
|
347
|
-
: `${encodeURIComponent(credentials.username)}:${encodeURIComponent(credentials.password)}`;
|
|
347
|
+
const credentials = options.credentials ?? { username: "iggy", password: "iggy" };
|
|
348
|
+
const userInfo = `${encodeURIComponent(credentials.username)}:${encodeURIComponent(credentials.password)}`;
|
|
348
349
|
const authorityHost = options.address.host.includes(":")
|
|
349
350
|
? `[${options.address.host.replace(/^\[|\]$/g, "")}]`
|
|
350
351
|
: options.address.host;
|
|
351
|
-
|
|
352
|
+
dialed = `iggy://${userInfo}@${authorityHost}:${String(options.address.port)}`;
|
|
353
|
+
transport = await ApacheIggyTransport.connect(dialed, options.publishOptions, deadline);
|
|
352
354
|
}
|
|
353
355
|
else {
|
|
354
|
-
|
|
356
|
+
dialed = options.connectionString ?? LOCAL_CONNECTION_STRING;
|
|
357
|
+
transport = await ApacheIggyTransport.connect(dialed, options.publishOptions, deadline);
|
|
355
358
|
}
|
|
356
359
|
const laser = new Laser(transport, options.defaultStream, options.capabilities === undefined
|
|
357
360
|
? new AsyncOnce()
|
|
358
|
-
: AsyncOnce.resolved(options.capabilities), newSharedState(), options.observer, options.governor === undefined
|
|
361
|
+
: AsyncOnce.resolved(options.capabilities), newSharedState(dialed), options.observer, options.governor === undefined
|
|
359
362
|
? undefined
|
|
360
363
|
: new GovernorState(options.governor.policy, options.governor.mode, undefined, options.governor.retention), options.verifier, options.topology, options.topologyOverrides, options.capabilities ?? OPEN_CAPABILITIES);
|
|
361
364
|
if (options.capabilities === undefined)
|
|
@@ -363,15 +366,14 @@ export class Laser {
|
|
|
363
366
|
return laser;
|
|
364
367
|
});
|
|
365
368
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
return builder.connect();
|
|
369
|
+
/**
|
|
370
|
+
* Wrap a connected, logged-in Apache Iggy client with no default stream.
|
|
371
|
+
* Chain `withDefaultStream`, `withCapabilities`, or `withObserver` to
|
|
372
|
+
* configure the handle. A `borrowed` client (the default) stays open when
|
|
373
|
+
* the handle closes, an `owned` one closes with it.
|
|
374
|
+
*/
|
|
375
|
+
static fromClient(client, options = {}) {
|
|
376
|
+
return Laser.builder().client(client, options).capabilities(OPEN_CAPABILITIES).connect();
|
|
375
377
|
}
|
|
376
378
|
/**
|
|
377
379
|
* Connect using an Iggy connection string. Connecting gives up after 30 seconds, or `LASER_CONNECT_TIMEOUT_MS`, with a `TimeoutError` that says whether the server never accepted the connection or never answered the login. Use `Laser.builder().connectTimeout()` for another budget.
|
|
@@ -379,14 +381,14 @@ export class Laser {
|
|
|
379
381
|
static async connect(connectionString) {
|
|
380
382
|
const deadline = Date.now() + connectOptions().timeoutMs;
|
|
381
383
|
const transport = await ApacheIggyTransport.connect(connectionString, undefined, deadline);
|
|
382
|
-
const laser = new Laser(transport, undefined, new AsyncOnce(), newSharedState());
|
|
384
|
+
const laser = new Laser(transport, undefined, new AsyncOnce(), newSharedState(connectionString));
|
|
383
385
|
await laser.probeCapabilitiesBefore(deadline);
|
|
384
386
|
return laser;
|
|
385
387
|
}
|
|
386
388
|
static async connectWithStream(connectionString, stream) {
|
|
387
389
|
const deadline = Date.now() + connectOptions().timeoutMs;
|
|
388
390
|
const transport = await ApacheIggyTransport.connect(connectionString, undefined, deadline);
|
|
389
|
-
const laser = new Laser(transport, stream, new AsyncOnce(), newSharedState());
|
|
391
|
+
const laser = new Laser(transport, stream, new AsyncOnce(), newSharedState(connectionString));
|
|
390
392
|
await laser.probeCapabilitiesBefore(deadline);
|
|
391
393
|
return laser;
|
|
392
394
|
}
|
|
@@ -406,15 +408,48 @@ export class Laser {
|
|
|
406
408
|
withDefaultStream(stream) {
|
|
407
409
|
return new Laser(this.transport, stream, this.capabilitiesOnce, this.shared, this.observer, this.governor, this.verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, this.capabilityOverride, false);
|
|
408
410
|
}
|
|
411
|
+
/** A clone whose managed operations use `opsStream` instead of the ops
|
|
412
|
+
* stream the deployment announced. The connection is shared. */
|
|
413
|
+
withOpsStream(opsStream) {
|
|
414
|
+
return this.withTopology({ opsStream });
|
|
415
|
+
}
|
|
416
|
+
/** A clone whose control commands publish to `controlTopic` on the ops
|
|
417
|
+
* stream. The connection is shared. */
|
|
418
|
+
withControlTopic(controlTopic) {
|
|
419
|
+
return this.withTopology({ controlTopic });
|
|
420
|
+
}
|
|
421
|
+
/** A clone whose dead-letter capsules publish to `dlqTopic` on the ops
|
|
422
|
+
* stream. The connection is shared. */
|
|
423
|
+
withDlqTopic(dlqTopic) {
|
|
424
|
+
return this.withTopology({ dlqTopic });
|
|
425
|
+
}
|
|
426
|
+
/** A clone whose change-feed records are read from `changesTopic` on the ops
|
|
427
|
+
* stream. The connection is shared. */
|
|
428
|
+
withChangesTopic(changesTopic) {
|
|
429
|
+
return this.withTopology({ changesTopic });
|
|
430
|
+
}
|
|
431
|
+
withTopology(override) {
|
|
432
|
+
const topology = {
|
|
433
|
+
opsStream: this.opsStream,
|
|
434
|
+
controlTopic: this.controlTopic,
|
|
435
|
+
dlqTopic: this.dlqTopic,
|
|
436
|
+
changesTopic: this.changesTopic,
|
|
437
|
+
...override
|
|
438
|
+
};
|
|
439
|
+
const overrides = {
|
|
440
|
+
opsStream: this.topologyOverrides.opsStream || override.opsStream !== undefined,
|
|
441
|
+
controlTopic: this.topologyOverrides.controlTopic || override.controlTopic !== undefined,
|
|
442
|
+
dlqTopic: this.topologyOverrides.dlqTopic || override.dlqTopic !== undefined,
|
|
443
|
+
changesTopic: this.topologyOverrides.changesTopic || override.changesTopic !== undefined
|
|
444
|
+
};
|
|
445
|
+
return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, this.observer, this.governor, this.verifier, topology, overrides, this.configuredCapabilities, this.capabilityOverride, false);
|
|
446
|
+
}
|
|
409
447
|
withCapabilities(capabilities) {
|
|
410
448
|
return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, this.observer, this.governor, this.verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, capabilities, false);
|
|
411
449
|
}
|
|
412
450
|
withGovernor(governor, mode, retention = {}) {
|
|
413
451
|
return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, this.observer, new GovernorState(governor, mode, undefined, retention), this.verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, this.capabilityOverride, false);
|
|
414
452
|
}
|
|
415
|
-
withVerifier(verifier) {
|
|
416
|
-
return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, this.observer, this.governor, verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, this.capabilityOverride, false);
|
|
417
|
-
}
|
|
418
453
|
withObserver(observer) {
|
|
419
454
|
return new Laser(this.transport, this.defaultStream, this.capabilitiesOnce, this.shared, observer, this.governor, this.verifier, this.configuredTopology, this.topologyOverrides, this.configuredCapabilities, this.capabilityOverride, false);
|
|
420
455
|
}
|
|
@@ -481,7 +516,9 @@ export class Laser {
|
|
|
481
516
|
if (isReady(capabilities))
|
|
482
517
|
return capabilities;
|
|
483
518
|
if (capabilities.backends.length === 0) {
|
|
484
|
-
throw new UnsupportedError("server has no managed backend descriptors"
|
|
519
|
+
throw new UnsupportedError("server has no managed backend descriptors", {
|
|
520
|
+
surface: "readiness"
|
|
521
|
+
});
|
|
485
522
|
}
|
|
486
523
|
if (Date.now() >= deadline) {
|
|
487
524
|
throw new TimeoutError("timed out waiting for managed backend readiness", {
|
|
@@ -492,41 +529,45 @@ export class Laser {
|
|
|
492
529
|
}
|
|
493
530
|
}
|
|
494
531
|
applyAdvertisedTopology(capabilities) {
|
|
495
|
-
const topology = capabilities
|
|
532
|
+
const topology = advertisedTopology(capabilities);
|
|
496
533
|
if (topology === undefined)
|
|
497
534
|
return;
|
|
498
535
|
this.shared.announcedTopology = {
|
|
499
536
|
opsStream: topology.opsStream,
|
|
500
537
|
controlTopic: topology.controlTopic,
|
|
501
|
-
|
|
538
|
+
dlqTopic: topology.dlqTopic,
|
|
502
539
|
changesTopic: topology.changesTopic
|
|
503
540
|
};
|
|
504
541
|
}
|
|
542
|
+
/** @internal */
|
|
505
543
|
[INTERNAL_TRANSPORT]() {
|
|
506
544
|
return this.transport;
|
|
507
545
|
}
|
|
546
|
+
/** @internal */
|
|
508
547
|
[INTERNAL_VERIFIER]() {
|
|
509
548
|
return this.verifier;
|
|
510
549
|
}
|
|
550
|
+
/** @internal */
|
|
511
551
|
[INTERNAL_REPLY_HUB](topic) {
|
|
512
552
|
return this.replyHub(topic);
|
|
513
553
|
}
|
|
554
|
+
/** @internal */
|
|
514
555
|
[INTERNAL_GOVERN](action) {
|
|
515
556
|
if (this.governor === undefined)
|
|
516
557
|
return Promise.resolve(action.payload.slice());
|
|
517
558
|
return this.governor.govern(action, (evidence) => this.emitPolicyEvidence(action.stream, evidence));
|
|
518
559
|
}
|
|
519
|
-
get
|
|
560
|
+
get client() {
|
|
520
561
|
return this.transport.iggyClient;
|
|
521
562
|
}
|
|
522
563
|
stream(name) {
|
|
523
|
-
return
|
|
564
|
+
return Stream.create(this.transport, name, (stream, topic, payload, provenance) => this[INTERNAL_GOVERN]({
|
|
524
565
|
kind: ActionKind.Publish,
|
|
525
566
|
stream,
|
|
526
567
|
topic,
|
|
527
|
-
...(provenance?.agent !== undefined ? { source: provenance.agent.
|
|
568
|
+
...(provenance?.agent !== undefined ? { source: provenance.agent.asStr() } : {}),
|
|
528
569
|
...(provenance?.targetAgentId !== undefined
|
|
529
|
-
? { target: provenance.targetAgentId.
|
|
570
|
+
? { target: provenance.targetAgentId.asStr() }
|
|
530
571
|
: {}),
|
|
531
572
|
...(provenance !== undefined ? { conversation: provenance.conversationId } : {}),
|
|
532
573
|
...(provenance?.correlationId !== undefined
|
|
@@ -575,13 +616,13 @@ export class Laser {
|
|
|
575
616
|
}), this.verifier);
|
|
576
617
|
}
|
|
577
618
|
agent(id) {
|
|
578
|
-
return
|
|
619
|
+
return AgentScope.create(this, id);
|
|
579
620
|
}
|
|
580
621
|
contract(router) {
|
|
581
|
-
return
|
|
622
|
+
return ContractBuilder.create(this, router);
|
|
582
623
|
}
|
|
583
624
|
workflow(name) {
|
|
584
|
-
return
|
|
625
|
+
return Workflow.create(this, name);
|
|
585
626
|
}
|
|
586
627
|
publishStateSnapshot(topic, source, conversation, state) {
|
|
587
628
|
return publishStateSnapshot(this, topic, source, conversation, state);
|
|
@@ -602,13 +643,13 @@ export class Laser {
|
|
|
602
643
|
return scatterReport(this, source, selector, payload, inboxRoute, deadlineMs);
|
|
603
644
|
}
|
|
604
645
|
context(conversation) {
|
|
605
|
-
return
|
|
646
|
+
return ContextScope.create(this, conversation);
|
|
606
647
|
}
|
|
607
648
|
/** The session accessor: one conversation seen as typed turns, a model-ready
|
|
608
649
|
* context, scoped memory, and checkpointed replay. Built on `context`, so a
|
|
609
650
|
* session is never a second store. */
|
|
610
|
-
sessions(
|
|
611
|
-
return
|
|
651
|
+
sessions(config) {
|
|
652
|
+
return Sessions.create(this, config);
|
|
612
653
|
}
|
|
613
654
|
memory(namespace) {
|
|
614
655
|
return this.memoryWith(namespace, MemoryBackend.Auto);
|
|
@@ -619,7 +660,7 @@ export class Laser {
|
|
|
619
660
|
}
|
|
620
661
|
/** Configures a durable memory topic before opening it. */
|
|
621
662
|
memoryTopic(topic) {
|
|
622
|
-
return
|
|
663
|
+
return MemoryTopicBuilder.create(this, topic);
|
|
623
664
|
}
|
|
624
665
|
memoryWith(namespace, backend, embedder) {
|
|
625
666
|
return backend === MemoryBackend.Vector
|
|
@@ -646,15 +687,15 @@ export class Laser {
|
|
|
646
687
|
...(provenance.correlationId !== undefined
|
|
647
688
|
? { correlation: provenance.correlationId }
|
|
648
689
|
: {}),
|
|
649
|
-
...(provenance.agent !== undefined ? { agent: provenance.agent.
|
|
690
|
+
...(provenance.agent !== undefined ? { agent: provenance.agent.asStr() } : {})
|
|
650
691
|
}, async () => {
|
|
651
692
|
const governedPayload = await this[INTERNAL_GOVERN]({
|
|
652
693
|
kind: ActionKind.Send,
|
|
653
694
|
stream,
|
|
654
695
|
topic,
|
|
655
|
-
...(provenance.agent !== undefined ? { source: provenance.agent.
|
|
696
|
+
...(provenance.agent !== undefined ? { source: provenance.agent.asStr() } : {}),
|
|
656
697
|
...(provenance.targetAgentId !== undefined
|
|
657
|
-
? { target: provenance.targetAgentId.
|
|
698
|
+
? { target: provenance.targetAgentId.asStr() }
|
|
658
699
|
: {}),
|
|
659
700
|
conversation: provenance.conversationId,
|
|
660
701
|
...(provenance.correlationId !== undefined
|
|
@@ -673,19 +714,6 @@ export class Laser {
|
|
|
673
714
|
await this.transport.sendMessageWithHeaders(stream, topic, governedPayload, headers, provenancePartitionKey(provenance));
|
|
674
715
|
});
|
|
675
716
|
}
|
|
676
|
-
async policyEvidence(conversation) {
|
|
677
|
-
const messages = await this.context(conversation).fetch([AgentTopic.Audit], Number.MAX_SAFE_INTEGER);
|
|
678
|
-
return messages.flatMap((message) => {
|
|
679
|
-
if (message.envelope?.operation !== POLICY_DECISION_OPERATION)
|
|
680
|
-
return [];
|
|
681
|
-
try {
|
|
682
|
-
return [decodePolicyEvidence(message.envelope.body)];
|
|
683
|
-
}
|
|
684
|
-
catch {
|
|
685
|
-
return [];
|
|
686
|
-
}
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
717
|
async emitPolicyEvidence(stream, evidence) {
|
|
690
718
|
const conversation = evidence.conversation === undefined
|
|
691
719
|
? ConversationId.parse("00000000000000000000000000")
|
|
@@ -706,10 +734,10 @@ export class Laser {
|
|
|
706
734
|
};
|
|
707
735
|
}
|
|
708
736
|
async reassembleChannel(conversation, topic, channel) {
|
|
709
|
-
const cursor = await this.topic(topic).replay(
|
|
737
|
+
const cursor = (await this.topic(topic).replay()).batch(1_000);
|
|
710
738
|
const envelopes = [];
|
|
711
739
|
for (;;) {
|
|
712
|
-
const records = await cursor.
|
|
740
|
+
const records = await cursor.pollRecords();
|
|
713
741
|
if (records.length === 0)
|
|
714
742
|
break;
|
|
715
743
|
for (const record of records) {
|
|
@@ -735,7 +763,9 @@ export class Laser {
|
|
|
735
763
|
async consumed(target, at) {
|
|
736
764
|
if (this.transport.resolveStreamTopicNames === undefined ||
|
|
737
765
|
this.transport.getConsumerOffset === undefined) {
|
|
738
|
-
throw new UnsupportedError("the active Iggy transport cannot resolve consumer offsets"
|
|
766
|
+
throw new UnsupportedError("the active Iggy transport cannot resolve consumer offsets", {
|
|
767
|
+
surface: "stream"
|
|
768
|
+
});
|
|
739
769
|
}
|
|
740
770
|
const names = await this.transport.resolveStreamTopicNames(at.streamId, at.topicId);
|
|
741
771
|
if (names === undefined) {
|
|
@@ -744,7 +774,7 @@ export class Laser {
|
|
|
744
774
|
const consumer = target.kind === "group"
|
|
745
775
|
? {
|
|
746
776
|
kind: "group",
|
|
747
|
-
name: typeof target.name === "string" ? target.name : target.name.
|
|
777
|
+
name: typeof target.name === "string" ? target.name : target.name.asStr()
|
|
748
778
|
}
|
|
749
779
|
: { kind: "consumer", name: target.name };
|
|
750
780
|
const offset = await this.transport.getConsumerOffset(names.stream, names.topic, consumer, at.partitionId);
|
|
@@ -756,7 +786,9 @@ export class Laser {
|
|
|
756
786
|
}
|
|
757
787
|
async redriveDeadLetter(capsule) {
|
|
758
788
|
if (this.transport.resolveStreamTopicNames === undefined) {
|
|
759
|
-
throw new UnsupportedError("the active Iggy transport cannot resolve dead-letter sources"
|
|
789
|
+
throw new UnsupportedError("the active Iggy transport cannot resolve dead-letter sources", {
|
|
790
|
+
surface: "stream"
|
|
791
|
+
});
|
|
760
792
|
}
|
|
761
793
|
const source = capsule.source;
|
|
762
794
|
const names = await this.transport.resolveStreamTopicNames(source.streamId, source.topicId);
|
|
@@ -787,7 +819,7 @@ export class Laser {
|
|
|
787
819
|
const correlationId = provenance.correlationId ?? ConversationId.new().toString();
|
|
788
820
|
const correlated = { ...provenance, correlationId };
|
|
789
821
|
const hub = await this.replyHub(replyTopic);
|
|
790
|
-
const ticket = hub.subscribe(correlationId, correlated.targetAgentId?.
|
|
822
|
+
const ticket = hub.subscribe(correlationId, correlated.targetAgentId?.asStr());
|
|
791
823
|
try {
|
|
792
824
|
await this.sendAgent(requestTopic, payload, correlated);
|
|
793
825
|
}
|
|
@@ -798,16 +830,16 @@ export class Laser {
|
|
|
798
830
|
return ticket.wait(timeoutMs, signal);
|
|
799
831
|
}
|
|
800
832
|
clientMetadata() {
|
|
801
|
-
return
|
|
833
|
+
return ClientMetadataRequest.create(this.transport);
|
|
802
834
|
}
|
|
803
835
|
async advertisePresence(presence) {
|
|
804
|
-
const requested = presence.agent.
|
|
836
|
+
const requested = AgentId.new(presence.agent).asStr();
|
|
805
837
|
const advertised = this.shared.advertisedAgent;
|
|
806
838
|
if (advertised !== undefined && advertised !== requested) {
|
|
807
839
|
throw new PresenceConflictError(advertised, requested);
|
|
808
840
|
}
|
|
809
841
|
this.shared.advertisedAgent = requested;
|
|
810
|
-
await this.managedTransport().sendManaged(AGDX_SET_CLIENT_METADATA_CODE,
|
|
842
|
+
await this.managedTransport().sendManaged(AGDX_SET_CLIENT_METADATA_CODE, encodePresence(presence));
|
|
811
843
|
}
|
|
812
844
|
async clearPresence() {
|
|
813
845
|
await this.managedTransport().sendManaged(AGDX_SET_CLIENT_METADATA_CODE, new Uint8Array());
|
|
@@ -822,7 +854,7 @@ export class Laser {
|
|
|
822
854
|
this.shared.registryCaches.set(stream, cache);
|
|
823
855
|
}
|
|
824
856
|
const cursor = await this.topic(AgentTopic.Registry).replay();
|
|
825
|
-
return
|
|
857
|
+
return AgentRegistry.create(cursor, cache, () => this.clientMetadata(), undefined, this.verifier);
|
|
826
858
|
}
|
|
827
859
|
async publishCard(source, card) {
|
|
828
860
|
validateAgentCard(card);
|
|
@@ -850,7 +882,7 @@ export class Laser {
|
|
|
850
882
|
await this.topic(AgentTopic.Registry).ensure(1);
|
|
851
883
|
let fact = this.agdx(AgentTopic.Registry, operator, ConversationId.new())
|
|
852
884
|
.status(operation)
|
|
853
|
-
.body(new TextEncoder().encode(agent.
|
|
885
|
+
.body(new TextEncoder().encode(agent.asStr()));
|
|
854
886
|
if (key !== undefined)
|
|
855
887
|
fact = fact.signedBy(key);
|
|
856
888
|
await fact.send();
|
|
@@ -879,13 +911,18 @@ export class Laser {
|
|
|
879
911
|
return this.queryTarget({ kind: "operational", index });
|
|
880
912
|
}
|
|
881
913
|
queryTarget(target) {
|
|
882
|
-
return
|
|
914
|
+
return QueryRequest.create(target, (query) => this.executeQuery(query), (executionId) => this.queryStatus(executionId), (executionId) => this.cancelQuery(executionId));
|
|
883
915
|
}
|
|
884
916
|
queryLakehouse(destinationId, destinationGeneration) {
|
|
885
917
|
return this.queryTarget({ kind: "lakehouse", destinationId, destinationGeneration });
|
|
886
918
|
}
|
|
887
919
|
destinations() {
|
|
888
|
-
return
|
|
920
|
+
return Destinations.create(this.managedTransport(), () => this.capabilities());
|
|
921
|
+
}
|
|
922
|
+
/** Sends one checkpoint request envelope, the deep form behind every
|
|
923
|
+
* `destinations()` mutation. */
|
|
924
|
+
executeCheckpoint(request) {
|
|
925
|
+
return this.destinations().executeCheckpoint(request);
|
|
889
926
|
}
|
|
890
927
|
// What a consumer group needs to reach its filter policy and read through
|
|
891
928
|
// the partition primaries.
|
|
@@ -910,11 +947,12 @@ export class Laser {
|
|
|
910
947
|
: {}),
|
|
911
948
|
...(transport.connectsNodes !== undefined ? { connectsNodes: transport.connectsNodes } : {})
|
|
912
949
|
},
|
|
913
|
-
capabilities: () => this.capabilities()
|
|
950
|
+
capabilities: () => this.capabilities(),
|
|
951
|
+
refreshCapabilities: () => this.refreshCapabilities()
|
|
914
952
|
};
|
|
915
953
|
}
|
|
916
954
|
kv(namespace) {
|
|
917
|
-
return
|
|
955
|
+
return Kv.create(this.managedTransport(), () => this.capabilities(), namespace, this.shared.leases);
|
|
918
956
|
}
|
|
919
957
|
async kvNamespaces() {
|
|
920
958
|
return Kv.namespaces(this.managedTransport(), () => this.capabilities());
|
|
@@ -924,28 +962,28 @@ export class Laser {
|
|
|
924
962
|
return executeBatch(this.managedTransport(), capabilities, ops);
|
|
925
963
|
}
|
|
926
964
|
fork(forkId) {
|
|
927
|
-
return
|
|
965
|
+
return ForkHandle.create(this.managedTransport(), () => this.capabilities(), forkId);
|
|
928
966
|
}
|
|
929
967
|
async forks() {
|
|
930
|
-
return
|
|
968
|
+
return ForkHandle.forks(this.managedTransport(), () => this.capabilities());
|
|
931
969
|
}
|
|
932
970
|
projections() {
|
|
933
|
-
return
|
|
971
|
+
return Projections.create(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
|
|
934
972
|
}
|
|
935
973
|
bindings() {
|
|
936
|
-
return
|
|
974
|
+
return Bindings.create((command) => this.publishControl(command));
|
|
937
975
|
}
|
|
938
976
|
schemas() {
|
|
939
|
-
return
|
|
977
|
+
return Schemas.create(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
|
|
940
978
|
}
|
|
941
979
|
runs() {
|
|
942
|
-
return
|
|
980
|
+
return Runs.create(this.managedTransport(), () => this.capabilities(), (command) => this.publishControl(command));
|
|
943
981
|
}
|
|
944
982
|
watch() {
|
|
945
|
-
return
|
|
983
|
+
return Watch.create(() => this.capabilities(), () => this.stream(this.opsStream).topic(this.changesTopic).replay());
|
|
946
984
|
}
|
|
947
985
|
graph(name) {
|
|
948
|
-
return
|
|
986
|
+
return GraphHandle.create(this.managedTransport(), () => this.capabilities(), name);
|
|
949
987
|
}
|
|
950
988
|
async whoami() {
|
|
951
989
|
return whoami(this.managedTransport(), await this.capabilities());
|
|
@@ -982,49 +1020,96 @@ export class Laser {
|
|
|
982
1020
|
.topic(this.controlTopic)
|
|
983
1021
|
.send(payload, { key: new TextEncoder().encode("control") });
|
|
984
1022
|
}
|
|
1023
|
+
/** Executes a pre-built `Query` and returns the raw paged result. Most
|
|
1024
|
+
* callers want `query(index)...fetch()` instead. Needs `laser-plane` in Laser
|
|
1025
|
+
* Stack or LaserData Cloud, otherwise it fails with `UnsupportedError`. */
|
|
985
1026
|
async executeQuery(query) {
|
|
986
1027
|
const capabilities = await this.capabilities();
|
|
987
1028
|
if (query.text !== undefined && !capabilities.query.keyword) {
|
|
988
|
-
throw new UnsupportedError("keyword query is not served by this deployment"
|
|
1029
|
+
throw new UnsupportedError("keyword query is not served by this deployment", {
|
|
1030
|
+
surface: "query",
|
|
1031
|
+
feature: "keyword"
|
|
1032
|
+
});
|
|
989
1033
|
}
|
|
990
1034
|
if (!servesConsistency(capabilities, query.consistency)) {
|
|
991
|
-
throw new UnsupportedError(`${query.consistency} query consistency is not served by this deployment
|
|
1035
|
+
throw new UnsupportedError(`${query.consistency} query consistency is not served by this deployment`, { surface: "query", feature: "consistency" });
|
|
992
1036
|
}
|
|
993
1037
|
const reply = await executeManaged(this.managedTransport(), capabilities, QueryCommand, {
|
|
994
1038
|
v: QUERY_OP_VERSION,
|
|
995
1039
|
query
|
|
996
1040
|
});
|
|
997
|
-
if (reply.kind === "ok")
|
|
1041
|
+
if (reply.kind === "ok") {
|
|
1042
|
+
if (reply.result.context.executionId.asU128() !== query.executionId.asU128()) {
|
|
1043
|
+
throw new ProtocolError("query reply execution id does not match the request");
|
|
1044
|
+
}
|
|
998
1045
|
return reply.result;
|
|
999
|
-
if (reply.error.kind === "unsupported") {
|
|
1000
|
-
throw new UnsupportedError(reply.error.message);
|
|
1001
1046
|
}
|
|
1002
1047
|
throw new QueryExecutionError(`query failed: ${reply.error.kind}`, reply.error);
|
|
1003
1048
|
}
|
|
1049
|
+
/** Retrieves the next cursor page of an executing query. Needs the
|
|
1050
|
+
* `cursorPaging` capability. */
|
|
1051
|
+
async queryPage(executionId, cursor, deadlineMicros) {
|
|
1052
|
+
const capabilities = await this.capabilities();
|
|
1053
|
+
if (!capabilities.query.cursorPaging) {
|
|
1054
|
+
throw new UnsupportedError("query cursor paging is not advertised by this deployment", {
|
|
1055
|
+
surface: "query",
|
|
1056
|
+
feature: "cursor_paging"
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
const reply = await executeManaged(this.managedTransport(), capabilities, QueryPageCommand, {
|
|
1060
|
+
v: QUERY_OP_VERSION,
|
|
1061
|
+
executionId,
|
|
1062
|
+
cursor,
|
|
1063
|
+
deadlineMicros
|
|
1064
|
+
});
|
|
1065
|
+
if (reply.kind === "ok") {
|
|
1066
|
+
if (reply.result.context.executionId.asU128() !== executionId.asU128()) {
|
|
1067
|
+
throw new ProtocolError("query reply execution id does not match the request");
|
|
1068
|
+
}
|
|
1069
|
+
return reply.result;
|
|
1070
|
+
}
|
|
1071
|
+
throw new QueryExecutionError(`query page failed: ${reply.error.kind}`, reply.error);
|
|
1072
|
+
}
|
|
1073
|
+
/** Reads the current state of an executing or recently completed query. */
|
|
1004
1074
|
async queryStatus(executionId) {
|
|
1005
1075
|
const capabilities = await this.capabilities();
|
|
1006
1076
|
if (!capabilities.query.executionStatus) {
|
|
1007
|
-
throw new UnsupportedError("query execution status is not served by this deployment"
|
|
1077
|
+
throw new UnsupportedError("query execution status is not served by this deployment", {
|
|
1078
|
+
surface: "query",
|
|
1079
|
+
feature: "execution_status"
|
|
1080
|
+
});
|
|
1008
1081
|
}
|
|
1009
1082
|
const reply = await executeManaged(this.managedTransport(), capabilities, QueryStatusCommand, {
|
|
1010
1083
|
v: QUERY_OP_VERSION,
|
|
1011
1084
|
executionId
|
|
1012
1085
|
});
|
|
1013
|
-
if (reply.kind === "ok")
|
|
1086
|
+
if (reply.kind === "ok") {
|
|
1087
|
+
if (reply.status.executionId.asU128() !== executionId.asU128()) {
|
|
1088
|
+
throw new ProtocolError("query status execution id does not match the request");
|
|
1089
|
+
}
|
|
1014
1090
|
return reply.status;
|
|
1091
|
+
}
|
|
1015
1092
|
throw new QueryExecutionError(`query status failed: ${reply.error.kind}`, reply.error);
|
|
1016
1093
|
}
|
|
1094
|
+
/** Cancels an executing query by its unguessable identity. */
|
|
1017
1095
|
async cancelQuery(executionId) {
|
|
1018
1096
|
const capabilities = await this.capabilities();
|
|
1019
1097
|
if (!capabilities.query.cancellation) {
|
|
1020
|
-
throw new UnsupportedError("query cancellation is not served by this deployment"
|
|
1098
|
+
throw new UnsupportedError("query cancellation is not served by this deployment", {
|
|
1099
|
+
surface: "query",
|
|
1100
|
+
feature: "cancellation"
|
|
1101
|
+
});
|
|
1021
1102
|
}
|
|
1022
1103
|
const reply = await executeManaged(this.managedTransport(), capabilities, QueryCancelCommand, {
|
|
1023
1104
|
v: QUERY_OP_VERSION,
|
|
1024
1105
|
executionId
|
|
1025
1106
|
});
|
|
1026
|
-
if (reply.kind === "ok")
|
|
1107
|
+
if (reply.kind === "ok") {
|
|
1108
|
+
if (reply.status.executionId.asU128() !== executionId.asU128()) {
|
|
1109
|
+
throw new ProtocolError("query status execution id does not match the request");
|
|
1110
|
+
}
|
|
1027
1111
|
return reply.status;
|
|
1112
|
+
}
|
|
1028
1113
|
throw new QueryExecutionError(`query cancellation failed: ${reply.error.kind}`, reply.error);
|
|
1029
1114
|
}
|
|
1030
1115
|
/** Closes owned transport resources. Safe to call more than once. */
|
|
@@ -1036,6 +1121,7 @@ export class Laser {
|
|
|
1036
1121
|
}, () => undefined);
|
|
1037
1122
|
}
|
|
1038
1123
|
this.shared.replyHubs.clear();
|
|
1124
|
+
await this.shared.leases.close();
|
|
1039
1125
|
await closeProducerStatistics(this.transport);
|
|
1040
1126
|
await this.observe("laser.close", { operation: "close" }, () => this.transport.close());
|
|
1041
1127
|
})();
|