@graphrefly/ts 0.0.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/LICENSE +21 -0
- package/dist/adapters/index.cjs +9015 -0
- package/dist/adapters/index.cjs.map +1 -0
- package/dist/adapters/index.d.cts +678 -0
- package/dist/adapters/index.d.ts +678 -0
- package/dist/adapters/index.js +2894 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/observe-storage.cjs +260 -0
- package/dist/adapters/observe-storage.cjs.map +1 -0
- package/dist/adapters/observe-storage.d.cts +77 -0
- package/dist/adapters/observe-storage.d.ts +77 -0
- package/dist/adapters/observe-storage.js +161 -0
- package/dist/adapters/observe-storage.js.map +1 -0
- package/dist/append-log-DisvEReb.d.cts +189 -0
- package/dist/append-log-DzKMmjxx.d.ts +189 -0
- package/dist/chunk-2ILL7HQI.js +1189 -0
- package/dist/chunk-2ILL7HQI.js.map +1 -0
- package/dist/chunk-4VLAQHZI.js +330 -0
- package/dist/chunk-4VLAQHZI.js.map +1 -0
- package/dist/chunk-6PHB5CJS.js +229 -0
- package/dist/chunk-6PHB5CJS.js.map +1 -0
- package/dist/chunk-COHO25CZ.js +2449 -0
- package/dist/chunk-COHO25CZ.js.map +1 -0
- package/dist/chunk-D6BG7U6A.js +161 -0
- package/dist/chunk-D6BG7U6A.js.map +1 -0
- package/dist/chunk-DJC4CHLQ.js +818 -0
- package/dist/chunk-DJC4CHLQ.js.map +1 -0
- package/dist/chunk-DK554R7P.js +67 -0
- package/dist/chunk-DK554R7P.js.map +1 -0
- package/dist/chunk-DKP56CSW.js +322 -0
- package/dist/chunk-DKP56CSW.js.map +1 -0
- package/dist/chunk-G4M3NHRJ.js +688 -0
- package/dist/chunk-G4M3NHRJ.js.map +1 -0
- package/dist/chunk-GAJW5I5P.js +1 -0
- package/dist/chunk-GAJW5I5P.js.map +1 -0
- package/dist/chunk-GDL26N2T.js +282 -0
- package/dist/chunk-GDL26N2T.js.map +1 -0
- package/dist/chunk-GTPCOEOZ.js +741 -0
- package/dist/chunk-GTPCOEOZ.js.map +1 -0
- package/dist/chunk-H2HTHFVN.js +1 -0
- package/dist/chunk-H2HTHFVN.js.map +1 -0
- package/dist/chunk-HDRL4VQQ.js +218 -0
- package/dist/chunk-HDRL4VQQ.js.map +1 -0
- package/dist/chunk-I3IHOHCJ.js +2267 -0
- package/dist/chunk-I3IHOHCJ.js.map +1 -0
- package/dist/chunk-JIMUDQN3.js +965 -0
- package/dist/chunk-JIMUDQN3.js.map +1 -0
- package/dist/chunk-JR4IKCR2.js +462 -0
- package/dist/chunk-JR4IKCR2.js.map +1 -0
- package/dist/chunk-K3FXTC3I.js +165 -0
- package/dist/chunk-K3FXTC3I.js.map +1 -0
- package/dist/chunk-OOEN33FB.js +65 -0
- package/dist/chunk-OOEN33FB.js.map +1 -0
- package/dist/chunk-PKVBHGBM.js +554 -0
- package/dist/chunk-PKVBHGBM.js.map +1 -0
- package/dist/chunk-RIIOUTGM.js +1857 -0
- package/dist/chunk-RIIOUTGM.js.map +1 -0
- package/dist/chunk-SCRFRCGR.js +33 -0
- package/dist/chunk-SCRFRCGR.js.map +1 -0
- package/dist/chunk-SWTLEQL6.js +53 -0
- package/dist/chunk-SWTLEQL6.js.map +1 -0
- package/dist/chunk-SZAETNNA.js +1 -0
- package/dist/chunk-SZAETNNA.js.map +1 -0
- package/dist/chunk-TEW47IVR.js +49 -0
- package/dist/chunk-TEW47IVR.js.map +1 -0
- package/dist/chunk-Y3ZLRGHC.js +1482 -0
- package/dist/chunk-Y3ZLRGHC.js.map +1 -0
- package/dist/chunk-Z2ANQ6JW.js +149 -0
- package/dist/chunk-Z2ANQ6JW.js.map +1 -0
- package/dist/codec-BB7p8fJc.d.cts +38 -0
- package/dist/codec-BB7p8fJc.d.ts +38 -0
- package/dist/composition/index.cjs +2505 -0
- package/dist/composition/index.cjs.map +1 -0
- package/dist/composition/index.d.cts +95 -0
- package/dist/composition/index.d.ts +95 -0
- package/dist/composition/index.js +19 -0
- package/dist/composition/index.js.map +1 -0
- package/dist/core/index.cjs +2475 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +25 -0
- package/dist/core/index.d.ts +25 -0
- package/dist/core/index.js +74 -0
- package/dist/core/index.js.map +1 -0
- package/dist/cqrs/index.cjs +595 -0
- package/dist/cqrs/index.cjs.map +1 -0
- package/dist/cqrs/index.d.cts +200 -0
- package/dist/cqrs/index.d.ts +200 -0
- package/dist/cqrs/index.js +557 -0
- package/dist/cqrs/index.js.map +1 -0
- package/dist/data-structures/index.cjs +4277 -0
- package/dist/data-structures/index.cjs.map +1 -0
- package/dist/data-structures/index.d.cts +22 -0
- package/dist/data-structures/index.d.ts +22 -0
- package/dist/data-structures/index.js +31 -0
- package/dist/data-structures/index.js.map +1 -0
- package/dist/describe-BZb7AS2y.d.ts +57 -0
- package/dist/describe-Ciu8SUnN.d.cts +57 -0
- package/dist/graph/index.cjs +7832 -0
- package/dist/graph/index.cjs.map +1 -0
- package/dist/graph/index.d.cts +251 -0
- package/dist/graph/index.d.ts +251 -0
- package/dist/graph/index.js +131 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph-DfdF9zy4.d.ts +666 -0
- package/dist/graph-s23RbbFO.d.cts +666 -0
- package/dist/index-CAEmLCYF.d.cts +166 -0
- package/dist/index-SnzZu3x7.d.ts +166 -0
- package/dist/index.cjs +15409 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +582 -0
- package/dist/index.js.map +1 -0
- package/dist/messages-BZqrGGm1.d.cts +55 -0
- package/dist/messages-BZqrGGm1.d.ts +55 -0
- package/dist/messaging/index.cjs +818 -0
- package/dist/messaging/index.cjs.map +1 -0
- package/dist/messaging/index.d.cts +235 -0
- package/dist/messaging/index.d.ts +235 -0
- package/dist/messaging/index.js +767 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/observe-event-log-0SVsx7JG.d.cts +88 -0
- package/dist/observe-event-log-Dnm76owp.d.ts +88 -0
- package/dist/operators/index.cjs +3774 -0
- package/dist/operators/index.cjs.map +1 -0
- package/dist/operators/index.d.cts +308 -0
- package/dist/operators/index.d.ts +308 -0
- package/dist/operators/index.js +112 -0
- package/dist/operators/index.js.map +1 -0
- package/dist/orchestration/index.cjs +3541 -0
- package/dist/orchestration/index.cjs.map +1 -0
- package/dist/orchestration/index.d.cts +302 -0
- package/dist/orchestration/index.d.ts +302 -0
- package/dist/orchestration/index.js +1004 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/patterns/index.cjs +1045 -0
- package/dist/patterns/index.cjs.map +1 -0
- package/dist/patterns/index.d.cts +39 -0
- package/dist/patterns/index.d.ts +39 -0
- package/dist/patterns/index.js +33 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/reactive-collection-BxBqtIOE.d.cts +344 -0
- package/dist/reactive-collection-Cb1II1Fi.d.ts +344 -0
- package/dist/reactive-collection-storage-BNiEc-Gd.d.ts +217 -0
- package/dist/reactive-collection-storage-D-KmjE0J.d.cts +217 -0
- package/dist/reactive-map-BcB4KsQR.d.ts +256 -0
- package/dist/reactive-map-D-g3dv8I.d.cts +256 -0
- package/dist/read-through-B1CYPfq_.d.cts +82 -0
- package/dist/read-through-DwyJhGs1.d.ts +82 -0
- package/dist/render/index.cjs +250 -0
- package/dist/render/index.cjs.map +1 -0
- package/dist/render/index.d.cts +58 -0
- package/dist/render/index.d.ts +58 -0
- package/dist/render/index.js +20 -0
- package/dist/render/index.js.map +1 -0
- package/dist/resilience-Dig3Q7n0.d.cts +45 -0
- package/dist/resilience-Dig3Q7n0.d.ts +45 -0
- package/dist/semantic-memory-graph-BYoIlP35.d.cts +356 -0
- package/dist/semantic-memory-graph-CxyXLms3.d.ts +356 -0
- package/dist/solutions/index.cjs +3249 -0
- package/dist/solutions/index.cjs.map +1 -0
- package/dist/solutions/index.d.cts +520 -0
- package/dist/solutions/index.d.ts +520 -0
- package/dist/solutions/index.js +31 -0
- package/dist/solutions/index.js.map +1 -0
- package/dist/sources/browser.cjs +3095 -0
- package/dist/sources/browser.cjs.map +1 -0
- package/dist/sources/browser.d.cts +39 -0
- package/dist/sources/browser.d.ts +39 -0
- package/dist/sources/browser.js +137 -0
- package/dist/sources/browser.js.map +1 -0
- package/dist/sources/index.cjs +3021 -0
- package/dist/sources/index.cjs.map +1 -0
- package/dist/sources/index.d.cts +7 -0
- package/dist/sources/index.d.ts +7 -0
- package/dist/sources/index.js +63 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/node.cjs +675 -0
- package/dist/sources/node.cjs.map +1 -0
- package/dist/sources/node.d.cts +109 -0
- package/dist/sources/node.d.ts +109 -0
- package/dist/sources/node.js +639 -0
- package/dist/sources/node.js.map +1 -0
- package/dist/storage/browser.cjs +777 -0
- package/dist/storage/browser.cjs.map +1 -0
- package/dist/storage/browser.d.cts +40 -0
- package/dist/storage/browser.d.ts +40 -0
- package/dist/storage/browser.js +275 -0
- package/dist/storage/browser.js.map +1 -0
- package/dist/storage/index.cjs +1989 -0
- package/dist/storage/index.cjs.map +1 -0
- package/dist/storage/index.d.cts +92 -0
- package/dist/storage/index.d.ts +92 -0
- package/dist/storage/index.js +161 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/node.cjs +898 -0
- package/dist/storage/node.cjs.map +1 -0
- package/dist/storage/node.d.cts +66 -0
- package/dist/storage/node.d.ts +66 -0
- package/dist/storage/node.js +402 -0
- package/dist/storage/node.js.map +1 -0
- package/dist/testing/index.cjs +95 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +20 -0
- package/dist/testing/index.d.ts +20 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types-bNMSWKqF.d.cts +732 -0
- package/dist/types-h12mNYbq.d.ts +732 -0
- package/package.json +250 -0
|
@@ -0,0 +1,767 @@
|
|
|
1
|
+
import {
|
|
2
|
+
releaseGraphNodes
|
|
3
|
+
} from "../chunk-2ILL7HQI.js";
|
|
4
|
+
import "../chunk-PKVBHGBM.js";
|
|
5
|
+
import "../chunk-I3IHOHCJ.js";
|
|
6
|
+
import "../chunk-4VLAQHZI.js";
|
|
7
|
+
import {
|
|
8
|
+
depBatch
|
|
9
|
+
} from "../chunk-SWTLEQL6.js";
|
|
10
|
+
import "../chunk-DK554R7P.js";
|
|
11
|
+
|
|
12
|
+
// src/messaging/index.ts
|
|
13
|
+
var PROMPTS_TOPIC = "prompts";
|
|
14
|
+
var RESPONSES_TOPIC = "responses";
|
|
15
|
+
var INJECTIONS_TOPIC = "injections";
|
|
16
|
+
var DEFERRED_TOPIC = "deferred";
|
|
17
|
+
var SPAWNS_TOPIC = "spawns";
|
|
18
|
+
var CONTEXT_TOPIC = "context";
|
|
19
|
+
var TODOS_TOPIC = "todos";
|
|
20
|
+
var STANDARD_TOPICS = Object.freeze([
|
|
21
|
+
PROMPTS_TOPIC,
|
|
22
|
+
RESPONSES_TOPIC,
|
|
23
|
+
INJECTIONS_TOPIC,
|
|
24
|
+
DEFERRED_TOPIC,
|
|
25
|
+
SPAWNS_TOPIC,
|
|
26
|
+
CONTEXT_TOPIC,
|
|
27
|
+
TODOS_TOPIC
|
|
28
|
+
]);
|
|
29
|
+
var busStates = /* @__PURE__ */ new WeakMap();
|
|
30
|
+
var dynamicHubStates = /* @__PURE__ */ new WeakMap();
|
|
31
|
+
var DEFAULT_DYNAMIC_HUB_MAX_TOPICS = 1024;
|
|
32
|
+
var DEFAULT_DYNAMIC_HUB_MAX_TOPIC_LENGTH = 256;
|
|
33
|
+
function messageBus(graph, opts) {
|
|
34
|
+
const unique = [...new Set(opts.topics)];
|
|
35
|
+
if (unique.length !== opts.topics.length) throw new Error("messageBus: duplicate topic");
|
|
36
|
+
if (unique.length === 0) throw new Error("messageBus: at least one topic is required");
|
|
37
|
+
const name = opts.name ?? "messageBus";
|
|
38
|
+
const state = {
|
|
39
|
+
graph,
|
|
40
|
+
name,
|
|
41
|
+
now: opts.now ?? Date.now,
|
|
42
|
+
topics: Object.freeze([...unique]),
|
|
43
|
+
records: /* @__PURE__ */ new Map(),
|
|
44
|
+
seq: 0
|
|
45
|
+
};
|
|
46
|
+
for (const topic of unique) {
|
|
47
|
+
const producers = [];
|
|
48
|
+
const body = (ctx) => {
|
|
49
|
+
for (let i = 0; i < producers.length; i++) {
|
|
50
|
+
for (const produced of depBatch(ctx, i) ?? []) {
|
|
51
|
+
if (produced.kind === "publish") {
|
|
52
|
+
ctx.down([
|
|
53
|
+
[
|
|
54
|
+
"DATA",
|
|
55
|
+
produced.envelope
|
|
56
|
+
]
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const node = graph.node([], body, {
|
|
63
|
+
name: `${name}/${topic}`,
|
|
64
|
+
factory: "messageTopic",
|
|
65
|
+
meta: { topic },
|
|
66
|
+
completeWhenDepsComplete: false,
|
|
67
|
+
errorWhenDepsError: false
|
|
68
|
+
});
|
|
69
|
+
state.records.set(topic, { node, producers, body });
|
|
70
|
+
}
|
|
71
|
+
const bus = {
|
|
72
|
+
topics: state.topics,
|
|
73
|
+
topic(topic) {
|
|
74
|
+
return requireTopic(state, topic);
|
|
75
|
+
},
|
|
76
|
+
publish(topic, payload, publishOpts = {}) {
|
|
77
|
+
const node = requireTopic(state, topic);
|
|
78
|
+
const envelope = {
|
|
79
|
+
topic,
|
|
80
|
+
seq: ++state.seq,
|
|
81
|
+
payload,
|
|
82
|
+
timestampMs: state.now(),
|
|
83
|
+
...publishOpts.key === void 0 ? {} : { key: publishOpts.key }
|
|
84
|
+
};
|
|
85
|
+
node.down([["DATA", envelope]]);
|
|
86
|
+
return envelope;
|
|
87
|
+
},
|
|
88
|
+
has(topic) {
|
|
89
|
+
return state.records.has(topic);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
busStates.set(bus, state);
|
|
93
|
+
return bus;
|
|
94
|
+
}
|
|
95
|
+
function dynamicHub(graph, opts = {}) {
|
|
96
|
+
const name = opts.name ?? "dynamicHub";
|
|
97
|
+
const unknownTopic = normalizeUnknownTopicPolicy(opts.unknownTopic);
|
|
98
|
+
const maxTopics = normalizeHubLimit(
|
|
99
|
+
opts.maxTopics,
|
|
100
|
+
DEFAULT_DYNAMIC_HUB_MAX_TOPICS,
|
|
101
|
+
"dynamicHub: maxTopics"
|
|
102
|
+
);
|
|
103
|
+
const maxTopicLength = normalizeHubLimit(
|
|
104
|
+
opts.maxTopicLength,
|
|
105
|
+
DEFAULT_DYNAMIC_HUB_MAX_TOPIC_LENGTH,
|
|
106
|
+
"dynamicHub: maxTopicLength"
|
|
107
|
+
);
|
|
108
|
+
const now = opts.now ?? Date.now;
|
|
109
|
+
const initialTopics = uniqueTopics(opts.topics ?? [], maxTopicLength);
|
|
110
|
+
if (initialTopics.length > maxTopics) {
|
|
111
|
+
throw new Error("dynamicHub: topics exceed maxTopics");
|
|
112
|
+
}
|
|
113
|
+
const commandSources = [];
|
|
114
|
+
const commandBody = (ctx) => {
|
|
115
|
+
for (let i = 0; i < commandSources.length; i++) {
|
|
116
|
+
for (const command2 of depBatch(ctx, i) ?? []) ctx.down([["DATA", command2]]);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const command = graph.node([], commandBody, {
|
|
120
|
+
name: `${name}/command`,
|
|
121
|
+
factory: "dynamicHubCommand",
|
|
122
|
+
completeWhenDepsComplete: false,
|
|
123
|
+
errorWhenDepsError: false
|
|
124
|
+
});
|
|
125
|
+
const events = graph.node(
|
|
126
|
+
[command],
|
|
127
|
+
(ctx) => {
|
|
128
|
+
const runtime = ctx.state.get() ?? {
|
|
129
|
+
topics: [...initialTopics],
|
|
130
|
+
open: true,
|
|
131
|
+
seq: 0,
|
|
132
|
+
cursor: 0
|
|
133
|
+
};
|
|
134
|
+
ctx.state.persist(true);
|
|
135
|
+
for (const commandFact of depBatch(ctx, 0) ?? []) {
|
|
136
|
+
const parsed = parseDynamicHubCommand(commandFact);
|
|
137
|
+
if (typeof parsed === "string") {
|
|
138
|
+
ctx.down([["DATA", hubError(runtime, commandFact, parsed, timestampOrFallback(now))]]);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const reduced = reduceDynamicHubCommand(
|
|
142
|
+
runtime,
|
|
143
|
+
parsed,
|
|
144
|
+
unknownTopic,
|
|
145
|
+
maxTopics,
|
|
146
|
+
maxTopicLength,
|
|
147
|
+
now
|
|
148
|
+
);
|
|
149
|
+
for (const event of reduced) ctx.down([["DATA", event]]);
|
|
150
|
+
}
|
|
151
|
+
ctx.state.set(runtime);
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: `${name}/events`,
|
|
155
|
+
factory: "dynamicHubEvents",
|
|
156
|
+
meta: { unknownTopic },
|
|
157
|
+
completeWhenDepsComplete: false,
|
|
158
|
+
errorWhenDepsError: false
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
const status = graph.node(
|
|
162
|
+
[events],
|
|
163
|
+
(ctx) => {
|
|
164
|
+
for (const event of depBatch(ctx, 0) ?? []) {
|
|
165
|
+
const typed = event;
|
|
166
|
+
ctx.down([["DATA", typed.status]]);
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: `${name}/status`,
|
|
171
|
+
factory: "dynamicHubStatus",
|
|
172
|
+
completeWhenDepsComplete: false,
|
|
173
|
+
errorWhenDepsError: false
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
const errors = graph.node(
|
|
177
|
+
[events],
|
|
178
|
+
(ctx) => {
|
|
179
|
+
for (const event of depBatch(ctx, 0) ?? []) {
|
|
180
|
+
const typed = event;
|
|
181
|
+
if (typed.kind !== "error") continue;
|
|
182
|
+
ctx.down([
|
|
183
|
+
[
|
|
184
|
+
"DATA",
|
|
185
|
+
{
|
|
186
|
+
...typed.topic === void 0 ? {} : { topic: typed.topic },
|
|
187
|
+
error: typed.error,
|
|
188
|
+
command: typed.command,
|
|
189
|
+
meta: typed.meta
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
]);
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: `${name}/errors`,
|
|
197
|
+
factory: "dynamicHubErrors",
|
|
198
|
+
completeWhenDepsComplete: false,
|
|
199
|
+
errorWhenDepsError: false
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
const deadLetter = opts.deadLetter === true || unknownTopic === "dead-letter" ? graph.node(
|
|
203
|
+
[events],
|
|
204
|
+
(ctx) => {
|
|
205
|
+
for (const event of depBatch(ctx, 0) ?? []) {
|
|
206
|
+
const typed = event;
|
|
207
|
+
if (typed.kind !== "dead-letter") continue;
|
|
208
|
+
ctx.down([
|
|
209
|
+
[
|
|
210
|
+
"DATA",
|
|
211
|
+
{
|
|
212
|
+
...typed.topic === void 0 ? {} : { topic: typed.topic },
|
|
213
|
+
reason: typed.reason,
|
|
214
|
+
command: typed.command,
|
|
215
|
+
meta: typed.meta
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
]);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: `${name}/deadLetter`,
|
|
223
|
+
factory: "dynamicHubDeadLetter",
|
|
224
|
+
completeWhenDepsComplete: false,
|
|
225
|
+
errorWhenDepsError: false
|
|
226
|
+
}
|
|
227
|
+
) : void 0;
|
|
228
|
+
const releaseEventsRetain = graph.retain(events, { reason: `${name}.dynamicHub.events` });
|
|
229
|
+
const hub = {
|
|
230
|
+
command,
|
|
231
|
+
events,
|
|
232
|
+
status,
|
|
233
|
+
errors,
|
|
234
|
+
...deadLetter === void 0 ? {} : { deadLetter },
|
|
235
|
+
create(topic, commandOpts = {}) {
|
|
236
|
+
return publishHubCommand(command, {
|
|
237
|
+
kind: "create",
|
|
238
|
+
topic,
|
|
239
|
+
...commandOpts.key === void 0 ? {} : { key: commandOpts.key },
|
|
240
|
+
...commandOpts.payload === void 0 ? {} : { payload: commandOpts.payload }
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
delete(topic, commandOpts = {}) {
|
|
244
|
+
return publishHubCommand(command, {
|
|
245
|
+
kind: "delete",
|
|
246
|
+
topic,
|
|
247
|
+
...commandOpts.key === void 0 ? {} : { key: commandOpts.key },
|
|
248
|
+
...commandOpts.payload === void 0 ? {} : { payload: commandOpts.payload }
|
|
249
|
+
});
|
|
250
|
+
},
|
|
251
|
+
publish(topic, payload, commandOpts = {}) {
|
|
252
|
+
return publishHubCommand(command, {
|
|
253
|
+
kind: "publish",
|
|
254
|
+
topic,
|
|
255
|
+
payload,
|
|
256
|
+
...commandOpts.key === void 0 ? {} : { key: commandOpts.key }
|
|
257
|
+
});
|
|
258
|
+
},
|
|
259
|
+
subscribeTopic(topic, commandOpts = {}) {
|
|
260
|
+
return publishHubCommand(command, {
|
|
261
|
+
kind: "subscribe",
|
|
262
|
+
topic,
|
|
263
|
+
...commandOpts.key === void 0 ? {} : { key: commandOpts.key },
|
|
264
|
+
...commandOpts.payload === void 0 ? {} : { payload: commandOpts.payload }
|
|
265
|
+
});
|
|
266
|
+
},
|
|
267
|
+
close(commandOpts = {}) {
|
|
268
|
+
return publishHubCommand(command, {
|
|
269
|
+
kind: "close",
|
|
270
|
+
...commandOpts.key === void 0 ? {} : { key: commandOpts.key },
|
|
271
|
+
...commandOpts.payload === void 0 ? {} : { payload: commandOpts.payload }
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
dynamicHubStates.set(hub, {
|
|
276
|
+
graph,
|
|
277
|
+
name,
|
|
278
|
+
maxTopicLength,
|
|
279
|
+
commandSources,
|
|
280
|
+
commandBody,
|
|
281
|
+
releaseEventsRetain
|
|
282
|
+
});
|
|
283
|
+
return hub;
|
|
284
|
+
}
|
|
285
|
+
function fromHubTopic(hub, topic, opts = {}) {
|
|
286
|
+
const state = requireDynamicHubState(hub);
|
|
287
|
+
assertTopicKey(topic, "fromHubTopic", state.maxTopicLength);
|
|
288
|
+
return state.graph.node(
|
|
289
|
+
[hub.events],
|
|
290
|
+
(ctx) => {
|
|
291
|
+
for (const event of depBatch(ctx, 0) ?? []) {
|
|
292
|
+
const typed = event;
|
|
293
|
+
if (typed.kind !== "message" || typed.topic !== topic) continue;
|
|
294
|
+
ctx.down([
|
|
295
|
+
[
|
|
296
|
+
"DATA",
|
|
297
|
+
{
|
|
298
|
+
topic,
|
|
299
|
+
seq: typed.meta.seq,
|
|
300
|
+
payload: typed.payload,
|
|
301
|
+
timestampMs: typed.meta.timestampMs,
|
|
302
|
+
...typed.key === void 0 ? {} : { key: typed.key }
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
]);
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: opts.name ?? `${state.name}/${topic}/fromHubTopic`,
|
|
310
|
+
factory: "fromHubTopic",
|
|
311
|
+
meta: { topic },
|
|
312
|
+
completeWhenDepsComplete: false,
|
|
313
|
+
errorWhenDepsError: false
|
|
314
|
+
}
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
function toHubTopic(graph, source, hub, topic, opts = {}) {
|
|
318
|
+
const state = requireDynamicHubState(hub);
|
|
319
|
+
assertTopicKey(topic, "toHubTopic", state.maxTopicLength);
|
|
320
|
+
if (state.graph !== graph) throw new Error("toHubTopic: hub and source graph must match");
|
|
321
|
+
if (isReachableUpstream(source, hub.command)) {
|
|
322
|
+
throw new Error("toHubTopic: source already depends on hub command path");
|
|
323
|
+
}
|
|
324
|
+
const commands = graph.node(
|
|
325
|
+
[source],
|
|
326
|
+
(ctx) => {
|
|
327
|
+
for (const value of depBatch(ctx, 0) ?? []) {
|
|
328
|
+
try {
|
|
329
|
+
const key = opts.keyOf?.(value);
|
|
330
|
+
ctx.down([
|
|
331
|
+
[
|
|
332
|
+
"DATA",
|
|
333
|
+
{
|
|
334
|
+
kind: "publish",
|
|
335
|
+
topic,
|
|
336
|
+
payload: value,
|
|
337
|
+
...key === void 0 ? {} : { key }
|
|
338
|
+
}
|
|
339
|
+
]
|
|
340
|
+
]);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
ctx.down([
|
|
343
|
+
[
|
|
344
|
+
"DATA",
|
|
345
|
+
{
|
|
346
|
+
kind: "invalid",
|
|
347
|
+
topic,
|
|
348
|
+
error: error instanceof Error ? error.message : String(error)
|
|
349
|
+
}
|
|
350
|
+
]
|
|
351
|
+
]);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
name: opts.name ?? `${state.name}/${topic}/toHubTopic`,
|
|
357
|
+
factory: "toHubTopic",
|
|
358
|
+
meta: { topic },
|
|
359
|
+
completeWhenDepsComplete: false,
|
|
360
|
+
errorWhenDepsError: false
|
|
361
|
+
}
|
|
362
|
+
);
|
|
363
|
+
const commandSource = commands;
|
|
364
|
+
state.commandSources.push(commandSource);
|
|
365
|
+
try {
|
|
366
|
+
hub.command.replaceDeps([...state.commandSources], state.commandBody);
|
|
367
|
+
} catch (error) {
|
|
368
|
+
state.commandSources.splice(state.commandSources.indexOf(commandSource), 1);
|
|
369
|
+
releaseGraphNodes(graph, [commands], {
|
|
370
|
+
reason: "toHubTopic failed command wiring"
|
|
371
|
+
});
|
|
372
|
+
throw error;
|
|
373
|
+
}
|
|
374
|
+
return { commands };
|
|
375
|
+
}
|
|
376
|
+
function fromTopic(bus, topic) {
|
|
377
|
+
return bus.topic(topic);
|
|
378
|
+
}
|
|
379
|
+
function toTopic(graph, source, bus, topic, opts = {}) {
|
|
380
|
+
const state = busStates.get(bus);
|
|
381
|
+
if (state === void 0) throw new Error("toTopic: unknown message bus implementation");
|
|
382
|
+
if (state.graph !== graph) throw new Error("toTopic: bus and source graph must match");
|
|
383
|
+
const record = requireTopicRecord(state, topic);
|
|
384
|
+
const name = opts.name ?? `toTopic/${topic}`;
|
|
385
|
+
const producer = graph.node(
|
|
386
|
+
[source],
|
|
387
|
+
(ctx) => {
|
|
388
|
+
for (const value of depBatch(ctx, 0) ?? []) {
|
|
389
|
+
try {
|
|
390
|
+
const key = opts.keyOf?.(value);
|
|
391
|
+
const envelope = {
|
|
392
|
+
topic,
|
|
393
|
+
seq: ++state.seq,
|
|
394
|
+
payload: value,
|
|
395
|
+
timestampMs: state.now(),
|
|
396
|
+
...key === void 0 ? {} : { key }
|
|
397
|
+
};
|
|
398
|
+
ctx.down([
|
|
399
|
+
[
|
|
400
|
+
"DATA",
|
|
401
|
+
{
|
|
402
|
+
kind: "publish",
|
|
403
|
+
envelope
|
|
404
|
+
}
|
|
405
|
+
]
|
|
406
|
+
]);
|
|
407
|
+
} catch (error) {
|
|
408
|
+
ctx.down([["DATA", { kind: "error", topic, error }]]);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
name,
|
|
414
|
+
factory: "toTopic",
|
|
415
|
+
meta: { topic },
|
|
416
|
+
completeWhenDepsComplete: false,
|
|
417
|
+
errorWhenDepsError: false
|
|
418
|
+
}
|
|
419
|
+
);
|
|
420
|
+
record.producers.push(producer);
|
|
421
|
+
record.node.replaceDeps([...record.producers], record.body);
|
|
422
|
+
const events = graph.node(
|
|
423
|
+
[producer, source],
|
|
424
|
+
(ctx) => {
|
|
425
|
+
for (const produced of depBatch(ctx, 0) ?? []) {
|
|
426
|
+
const typed = produced;
|
|
427
|
+
if (typed.kind === "publish") {
|
|
428
|
+
ctx.down([
|
|
429
|
+
[
|
|
430
|
+
"DATA",
|
|
431
|
+
{
|
|
432
|
+
kind: "publish",
|
|
433
|
+
topic,
|
|
434
|
+
seq: typed.envelope.seq,
|
|
435
|
+
payload: typed.envelope.payload
|
|
436
|
+
}
|
|
437
|
+
]
|
|
438
|
+
]);
|
|
439
|
+
} else {
|
|
440
|
+
ctx.down([
|
|
441
|
+
["DATA", { kind: "error", topic, error: typed.error }]
|
|
442
|
+
]);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const terminal = ctx.terminal[0];
|
|
446
|
+
if (terminal !== false && terminal !== void 0 && terminal !== true) {
|
|
447
|
+
ctx.down([
|
|
448
|
+
["DATA", { kind: "error", topic, error: terminal }]
|
|
449
|
+
]);
|
|
450
|
+
}
|
|
451
|
+
const sourceTerminal = ctx.terminal[1];
|
|
452
|
+
if (sourceTerminal === true) {
|
|
453
|
+
ctx.down([["DATA", { kind: "complete", topic }]]);
|
|
454
|
+
} else if (sourceTerminal !== false && sourceTerminal !== void 0) {
|
|
455
|
+
ctx.down([
|
|
456
|
+
["DATA", { kind: "error", topic, error: sourceTerminal }]
|
|
457
|
+
]);
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
name: `${name}/events`,
|
|
462
|
+
factory: "toTopicEvents",
|
|
463
|
+
meta: { topic },
|
|
464
|
+
completeWhenDepsComplete: false,
|
|
465
|
+
errorWhenDepsError: false,
|
|
466
|
+
terminalAsRealInput: true
|
|
467
|
+
}
|
|
468
|
+
);
|
|
469
|
+
return { events };
|
|
470
|
+
}
|
|
471
|
+
function requireTopic(state, topic) {
|
|
472
|
+
return requireTopicRecord(state, topic).node;
|
|
473
|
+
}
|
|
474
|
+
function requireTopicRecord(state, topic) {
|
|
475
|
+
const record = state.records.get(topic);
|
|
476
|
+
if (record === void 0) throw new Error(`messageBus: unknown topic '${topic}'`);
|
|
477
|
+
return record;
|
|
478
|
+
}
|
|
479
|
+
function uniqueTopics(topics, maxTopicLength) {
|
|
480
|
+
const unique = [...new Set(topics)];
|
|
481
|
+
if (unique.length !== topics.length) throw new Error("dynamicHub: duplicate topic");
|
|
482
|
+
for (const topic of unique) assertTopicKey(topic, "dynamicHub", maxTopicLength);
|
|
483
|
+
return Object.freeze(unique.sort());
|
|
484
|
+
}
|
|
485
|
+
function normalizeUnknownTopicPolicy(policy) {
|
|
486
|
+
if (policy === void 0) return "error";
|
|
487
|
+
if (policy === "drop" || policy === "error" || policy === "dead-letter" || policy === "create-as-fact") {
|
|
488
|
+
return policy;
|
|
489
|
+
}
|
|
490
|
+
throw new Error("dynamicHub: unknownTopic policy is not recognized");
|
|
491
|
+
}
|
|
492
|
+
function normalizeHubLimit(value, fallback, owner) {
|
|
493
|
+
if (value === void 0) return fallback;
|
|
494
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
495
|
+
throw new Error(`${owner} must be a positive integer`);
|
|
496
|
+
}
|
|
497
|
+
return value;
|
|
498
|
+
}
|
|
499
|
+
function publishHubCommand(commandNode, command) {
|
|
500
|
+
commandNode.down([["DATA", command]]);
|
|
501
|
+
return command;
|
|
502
|
+
}
|
|
503
|
+
function parseDynamicHubCommand(value) {
|
|
504
|
+
if (!isObjectRecord(value)) return "dynamicHub: command fact must be an object";
|
|
505
|
+
const kind = value.kind;
|
|
506
|
+
if (kind !== "create" && kind !== "delete" && kind !== "publish" && kind !== "subscribe" && kind !== "close") {
|
|
507
|
+
return "dynamicHub: command kind is not recognized";
|
|
508
|
+
}
|
|
509
|
+
if (kind === "close") {
|
|
510
|
+
return {
|
|
511
|
+
kind,
|
|
512
|
+
...typeof value.key === "string" ? { key: value.key } : {},
|
|
513
|
+
...value.payload === void 0 ? {} : { payload: value.payload }
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
const topic = value.topic;
|
|
517
|
+
if (typeof topic !== "string" || topic.length === 0) {
|
|
518
|
+
return "dynamicHub: command topic must be a non-empty string";
|
|
519
|
+
}
|
|
520
|
+
if (kind === "publish") {
|
|
521
|
+
if (value.payload === void 0) return "dynamicHub: publish command payload is required";
|
|
522
|
+
return {
|
|
523
|
+
kind,
|
|
524
|
+
topic,
|
|
525
|
+
payload: value.payload,
|
|
526
|
+
...typeof value.key === "string" ? { key: value.key } : {}
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
return {
|
|
530
|
+
kind,
|
|
531
|
+
topic,
|
|
532
|
+
...typeof value.key === "string" ? { key: value.key } : {},
|
|
533
|
+
...value.payload === void 0 ? {} : { payload: value.payload }
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
function isObjectRecord(value) {
|
|
537
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
538
|
+
}
|
|
539
|
+
function readHubTimestamp(now) {
|
|
540
|
+
try {
|
|
541
|
+
const timestampMs = now();
|
|
542
|
+
return Number.isFinite(timestampMs) ? timestampMs : "dynamicHub: now() must return a finite number";
|
|
543
|
+
} catch (error) {
|
|
544
|
+
return `dynamicHub: now() threw: ${error instanceof Error ? error.message : String(error)}`;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function timestampOrFallback(now) {
|
|
548
|
+
const timestampMs = readHubTimestamp(now);
|
|
549
|
+
return typeof timestampMs === "number" ? timestampMs : Date.now();
|
|
550
|
+
}
|
|
551
|
+
function reduceDynamicHubCommand(runtime, command, unknownTopic, maxTopics, maxTopicLength, now) {
|
|
552
|
+
const topic = "topic" in command ? command.topic : void 0;
|
|
553
|
+
if (topic !== void 0) {
|
|
554
|
+
const topicError = validateTopicKey(topic, "dynamicHub", maxTopicLength);
|
|
555
|
+
if (topicError !== void 0) {
|
|
556
|
+
return [hubError(runtime, command, topicError, timestampOrFallback(now))];
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
if (!runtime.open && command.kind !== "close") {
|
|
560
|
+
return [hubError(runtime, command, "dynamicHub: hub is closed", timestampOrFallback(now))];
|
|
561
|
+
}
|
|
562
|
+
switch (command.kind) {
|
|
563
|
+
case "create": {
|
|
564
|
+
const capacityError = canAddHubTopic(runtime, command.topic, maxTopics);
|
|
565
|
+
if (capacityError !== void 0) {
|
|
566
|
+
return [hubError(runtime, command, capacityError, timestampOrFallback(now))];
|
|
567
|
+
}
|
|
568
|
+
const timestampMs = readHubTimestamp(now);
|
|
569
|
+
if (typeof timestampMs === "string")
|
|
570
|
+
return [hubError(runtime, command, timestampMs, Date.now())];
|
|
571
|
+
addHubTopic(runtime, command.topic);
|
|
572
|
+
return [hubEvent(runtime, timestampMs, command)];
|
|
573
|
+
}
|
|
574
|
+
case "delete": {
|
|
575
|
+
if (!hasHubTopic(runtime, command.topic)) {
|
|
576
|
+
return unknownHubTopic(runtime, command, unknownTopic, now);
|
|
577
|
+
}
|
|
578
|
+
const timestampMs = readHubTimestamp(now);
|
|
579
|
+
if (typeof timestampMs === "string")
|
|
580
|
+
return [hubError(runtime, command, timestampMs, Date.now())];
|
|
581
|
+
deleteHubTopic(runtime, command.topic);
|
|
582
|
+
return [hubEvent(runtime, timestampMs, command)];
|
|
583
|
+
}
|
|
584
|
+
case "publish": {
|
|
585
|
+
if (!hasHubTopic(runtime, command.topic)) {
|
|
586
|
+
if (unknownTopic === "create-as-fact") {
|
|
587
|
+
const capacityError = canAddHubTopic(runtime, command.topic, maxTopics);
|
|
588
|
+
if (capacityError !== void 0) {
|
|
589
|
+
return [hubError(runtime, command, capacityError, timestampOrFallback(now))];
|
|
590
|
+
}
|
|
591
|
+
const createTimestampMs = readHubTimestamp(now);
|
|
592
|
+
if (typeof createTimestampMs === "string") {
|
|
593
|
+
return [hubError(runtime, command, createTimestampMs, Date.now())];
|
|
594
|
+
}
|
|
595
|
+
const messageTimestampMs = readHubTimestamp(now);
|
|
596
|
+
if (typeof messageTimestampMs === "string") {
|
|
597
|
+
return [hubError(runtime, command, messageTimestampMs, Date.now())];
|
|
598
|
+
}
|
|
599
|
+
addHubTopic(runtime, command.topic);
|
|
600
|
+
return [
|
|
601
|
+
hubEvent(runtime, createTimestampMs, { kind: "create", topic: command.topic }),
|
|
602
|
+
hubEvent(runtime, messageTimestampMs, {
|
|
603
|
+
kind: "message",
|
|
604
|
+
topic: command.topic,
|
|
605
|
+
payload: command.payload,
|
|
606
|
+
...command.key === void 0 ? {} : { key: command.key }
|
|
607
|
+
})
|
|
608
|
+
];
|
|
609
|
+
}
|
|
610
|
+
return unknownHubTopic(runtime, command, unknownTopic, now);
|
|
611
|
+
}
|
|
612
|
+
const timestampMs = readHubTimestamp(now);
|
|
613
|
+
if (typeof timestampMs === "string")
|
|
614
|
+
return [hubError(runtime, command, timestampMs, Date.now())];
|
|
615
|
+
return [
|
|
616
|
+
hubEvent(runtime, timestampMs, {
|
|
617
|
+
kind: "message",
|
|
618
|
+
topic: command.topic,
|
|
619
|
+
payload: command.payload,
|
|
620
|
+
...command.key === void 0 ? {} : { key: command.key }
|
|
621
|
+
})
|
|
622
|
+
];
|
|
623
|
+
}
|
|
624
|
+
case "subscribe": {
|
|
625
|
+
if (!hasHubTopic(runtime, command.topic)) {
|
|
626
|
+
if (unknownTopic === "create-as-fact") {
|
|
627
|
+
const capacityError = canAddHubTopic(runtime, command.topic, maxTopics);
|
|
628
|
+
if (capacityError !== void 0) {
|
|
629
|
+
return [hubError(runtime, command, capacityError, timestampOrFallback(now))];
|
|
630
|
+
}
|
|
631
|
+
const createTimestampMs = readHubTimestamp(now);
|
|
632
|
+
if (typeof createTimestampMs === "string") {
|
|
633
|
+
return [hubError(runtime, command, createTimestampMs, Date.now())];
|
|
634
|
+
}
|
|
635
|
+
const subscribeTimestampMs = readHubTimestamp(now);
|
|
636
|
+
if (typeof subscribeTimestampMs === "string") {
|
|
637
|
+
return [hubError(runtime, command, subscribeTimestampMs, Date.now())];
|
|
638
|
+
}
|
|
639
|
+
addHubTopic(runtime, command.topic);
|
|
640
|
+
return [
|
|
641
|
+
hubEvent(runtime, createTimestampMs, { kind: "create", topic: command.topic }),
|
|
642
|
+
hubEvent(runtime, subscribeTimestampMs, command)
|
|
643
|
+
];
|
|
644
|
+
}
|
|
645
|
+
return unknownHubTopic(runtime, command, unknownTopic, now);
|
|
646
|
+
}
|
|
647
|
+
const timestampMs = readHubTimestamp(now);
|
|
648
|
+
if (typeof timestampMs === "string")
|
|
649
|
+
return [hubError(runtime, command, timestampMs, Date.now())];
|
|
650
|
+
return [hubEvent(runtime, timestampMs, command)];
|
|
651
|
+
}
|
|
652
|
+
case "close": {
|
|
653
|
+
const timestampMs = readHubTimestamp(now);
|
|
654
|
+
if (typeof timestampMs === "string")
|
|
655
|
+
return [hubError(runtime, command, timestampMs, Date.now())];
|
|
656
|
+
runtime.open = false;
|
|
657
|
+
return [hubEvent(runtime, timestampMs, command)];
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
function hubEvent(runtime, timestampMs, event) {
|
|
662
|
+
const meta = nextHubMetadata(runtime, timestampMs);
|
|
663
|
+
return {
|
|
664
|
+
...event,
|
|
665
|
+
meta,
|
|
666
|
+
status: snapshotHubStatus(runtime, meta, event.kind)
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
function hubError(runtime, command, error, timestampMs) {
|
|
670
|
+
return hubEvent(runtime, timestampMs, {
|
|
671
|
+
kind: "error",
|
|
672
|
+
...isObjectRecord(command) && typeof command.topic === "string" ? { topic: command.topic } : {},
|
|
673
|
+
error,
|
|
674
|
+
command
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
function unknownHubTopic(runtime, command, policy, now) {
|
|
678
|
+
const topic = "topic" in command ? command.topic : void 0;
|
|
679
|
+
const reason = `dynamicHub: unknown topic '${topic ?? ""}'`;
|
|
680
|
+
if (policy === "drop") return [];
|
|
681
|
+
if (policy === "dead-letter") {
|
|
682
|
+
return [
|
|
683
|
+
hubEvent(runtime, timestampOrFallback(now), {
|
|
684
|
+
kind: "dead-letter",
|
|
685
|
+
...topic === void 0 ? {} : { topic },
|
|
686
|
+
reason,
|
|
687
|
+
command
|
|
688
|
+
})
|
|
689
|
+
];
|
|
690
|
+
}
|
|
691
|
+
return [hubError(runtime, command, reason, timestampOrFallback(now))];
|
|
692
|
+
}
|
|
693
|
+
function nextHubMetadata(runtime, timestampMs) {
|
|
694
|
+
runtime.seq += 1;
|
|
695
|
+
runtime.cursor = runtime.seq;
|
|
696
|
+
return { seq: runtime.seq, cursor: runtime.cursor, timestampMs };
|
|
697
|
+
}
|
|
698
|
+
function snapshotHubStatus(runtime, meta, kind) {
|
|
699
|
+
return {
|
|
700
|
+
open: runtime.open,
|
|
701
|
+
topics: Object.freeze([...runtime.topics].sort()),
|
|
702
|
+
seq: meta.seq,
|
|
703
|
+
cursor: meta.cursor,
|
|
704
|
+
lastEventKind: kind
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
function assertTopicKey(topic, owner, maxTopicLength) {
|
|
708
|
+
const error = validateTopicKey(topic, owner, maxTopicLength);
|
|
709
|
+
if (error !== void 0) throw new Error(error);
|
|
710
|
+
}
|
|
711
|
+
function validateTopicKey(topic, owner, maxTopicLength) {
|
|
712
|
+
if (typeof topic !== "string" || topic.length === 0) {
|
|
713
|
+
return `${owner}: topic must be a non-empty string`;
|
|
714
|
+
}
|
|
715
|
+
if (topic.length > maxTopicLength) {
|
|
716
|
+
return `${owner}: topic exceeds maxTopicLength`;
|
|
717
|
+
}
|
|
718
|
+
return void 0;
|
|
719
|
+
}
|
|
720
|
+
function hasHubTopic(runtime, topic) {
|
|
721
|
+
return runtime.topics.includes(topic);
|
|
722
|
+
}
|
|
723
|
+
function addHubTopic(runtime, topic) {
|
|
724
|
+
if (!hasHubTopic(runtime, topic)) runtime.topics = [...runtime.topics, topic];
|
|
725
|
+
}
|
|
726
|
+
function deleteHubTopic(runtime, topic) {
|
|
727
|
+
runtime.topics = runtime.topics.filter((existing) => existing !== topic);
|
|
728
|
+
}
|
|
729
|
+
function canAddHubTopic(runtime, topic, maxTopics) {
|
|
730
|
+
if (hasHubTopic(runtime, topic)) return void 0;
|
|
731
|
+
return runtime.topics.length >= maxTopics ? "dynamicHub: topic count exceeds maxTopics" : void 0;
|
|
732
|
+
}
|
|
733
|
+
function isReachableUpstream(from, target) {
|
|
734
|
+
const seen = /* @__PURE__ */ new Set();
|
|
735
|
+
const stack = [from];
|
|
736
|
+
while (stack.length > 0) {
|
|
737
|
+
const node = stack.pop();
|
|
738
|
+
if (node === void 0) continue;
|
|
739
|
+
if (node === target) return true;
|
|
740
|
+
if (seen.has(node)) continue;
|
|
741
|
+
seen.add(node);
|
|
742
|
+
for (const dep of node.deps) stack.push(dep);
|
|
743
|
+
}
|
|
744
|
+
return false;
|
|
745
|
+
}
|
|
746
|
+
function requireDynamicHubState(hub) {
|
|
747
|
+
const state = dynamicHubStates.get(hub);
|
|
748
|
+
if (state === void 0) throw new Error("dynamicHub: unknown hub implementation");
|
|
749
|
+
return state;
|
|
750
|
+
}
|
|
751
|
+
export {
|
|
752
|
+
CONTEXT_TOPIC,
|
|
753
|
+
DEFERRED_TOPIC,
|
|
754
|
+
INJECTIONS_TOPIC,
|
|
755
|
+
PROMPTS_TOPIC,
|
|
756
|
+
RESPONSES_TOPIC,
|
|
757
|
+
SPAWNS_TOPIC,
|
|
758
|
+
STANDARD_TOPICS,
|
|
759
|
+
TODOS_TOPIC,
|
|
760
|
+
dynamicHub,
|
|
761
|
+
fromHubTopic,
|
|
762
|
+
fromTopic,
|
|
763
|
+
messageBus,
|
|
764
|
+
toHubTopic,
|
|
765
|
+
toTopic
|
|
766
|
+
};
|
|
767
|
+
//# sourceMappingURL=index.js.map
|