@swirls/looms 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/dist/actor/cell.d.ts +21 -2
- package/dist/actor/cell.js +15 -3
- package/dist/actor/host.d.ts +10 -2
- package/dist/actor/host.js +27 -4
- package/dist/actor/index.d.ts +2 -1
- package/dist/actor/index.js +1 -1
- package/dist/actor/routing.d.ts +3 -0
- package/dist/actor/routing.js +13 -2
- package/dist/agent/definitions-store.d.ts +1 -1
- package/dist/agent/definitions-store.js +1 -1
- package/dist/agent/definitions.d.ts +48 -0
- package/dist/agent/definitions.js +44 -0
- package/dist/agent/effects.d.ts +184 -0
- package/dist/agent/effects.js +172 -40
- package/dist/agent/events.d.ts +89 -0
- package/dist/agent/events.js +25 -0
- package/dist/agent/module.d.ts +412 -0
- package/dist/agent/module.js +5 -1
- package/dist/agent/scope.d.ts +88 -0
- package/dist/agent/threads.js +39 -3
- package/dist/agent/types.d.ts +4 -0
- package/dist/approval/effects.d.ts +40 -0
- package/dist/approval/module.d.ts +80 -0
- package/dist/client/client.d.ts +468 -119
- package/dist/client/client.js +214 -21
- package/dist/client/index.d.ts +1 -1
- package/dist/client/sse.d.ts +1 -1
- package/dist/client/sse.js +2 -2
- package/dist/cloudflare/durable-object.d.ts +66 -2
- package/dist/cloudflare/durable-object.js +96 -1
- package/dist/cloudflare/event-store.d.ts +7 -3
- package/dist/cloudflare/event-store.js +16 -3
- package/dist/cloudflare/index.d.ts +7 -1
- package/dist/cloudflare/index.js +7 -1
- package/dist/cloudflare/memory-queue.d.ts +18 -0
- package/dist/cloudflare/memory-queue.js +53 -0
- package/dist/cloudflare/queue-consumer.d.ts +52 -0
- package/dist/cloudflare/queue-consumer.js +102 -0
- package/dist/cloudflare/queue-message.d.ts +31 -0
- package/dist/cloudflare/queue-message.js +33 -0
- package/dist/cloudflare/queue-pull.d.ts +62 -0
- package/dist/cloudflare/queue-pull.js +130 -0
- package/dist/cloudflare/queue-worker.d.ts +39 -0
- package/dist/cloudflare/queue-worker.js +62 -0
- package/dist/cloudflare/queues.d.ts +10 -0
- package/dist/cloudflare/queues.js +10 -0
- package/dist/cloudflare/r2-blob-store.d.ts +33 -0
- package/dist/cloudflare/r2-blob-store.js +60 -0
- package/dist/cloudflare/router.d.ts +4 -1
- package/dist/cloudflare/router.js +8 -3
- package/dist/cloudflare/websocket.d.ts +27 -0
- package/dist/cloudflare/websocket.js +215 -0
- package/dist/core/blob-offload.d.ts +21 -0
- package/dist/core/blob-offload.js +143 -0
- package/dist/core/blob-store.d.ts +45 -0
- package/dist/core/blob-store.js +164 -0
- package/dist/core/blobs.d.ts +37 -0
- package/dist/core/blobs.js +160 -0
- package/dist/core/definition-resolver.d.ts +40 -0
- package/dist/core/definition-resolver.js +129 -0
- package/dist/core/definition-store.d.ts +6 -0
- package/dist/core/definition-store.js +37 -1
- package/dist/core/effects.d.ts +86 -3
- package/dist/core/effects.js +99 -3
- package/dist/core/envelope.d.ts +9 -0
- package/dist/core/envelope.js +4 -0
- package/dist/core/event-codec.js +3 -0
- package/dist/core/fold.js +83 -1
- package/dist/core/ids.d.ts +2 -0
- package/dist/core/ids.js +4 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +8 -0
- package/dist/core/launcher.d.ts +97 -0
- package/dist/core/launcher.js +67 -0
- package/dist/core/module-scope.d.ts +7 -3
- package/dist/core/module-scope.js +3 -0
- package/dist/core/module.d.ts +10 -0
- package/dist/core/projection.js +4 -0
- package/dist/core/protocol.d.ts +36 -1
- package/dist/core/protocol.js +35 -0
- package/dist/core/published.d.ts +2 -0
- package/dist/core/published.js +4 -1
- package/dist/core/replay.d.ts +96 -0
- package/dist/core/run-context.d.ts +33 -0
- package/dist/core/run-context.js +23 -0
- package/dist/core/sqlite-store.js +57 -5
- package/dist/core/state.d.ts +60 -0
- package/dist/core/state.js +19 -0
- package/dist/core/store.d.ts +6 -0
- package/dist/core/store.js +7 -0
- package/dist/core/subscription.d.ts +97 -0
- package/dist/core/subscription.js +224 -0
- package/dist/core/thread.d.ts +7 -0
- package/dist/core/thread.js +1 -0
- package/dist/core/trace.d.ts +21 -0
- package/dist/core/trace.js +45 -0
- package/dist/core/worker-callback.d.ts +25 -1
- package/dist/debugger/app/assets/{index-CgDzWJg7.css → index-B7GdT1UA.css} +1 -1
- package/dist/debugger/app/assets/index-C31SnCuN.js +22 -0
- package/dist/debugger/app/assets/routes-DPA3O5AF.js +47 -0
- package/dist/debugger/app/index.html +2 -2
- package/dist/debugger/components/event-inspector.d.ts +3 -1
- package/dist/debugger/components/event-inspector.js +25 -4
- package/dist/debugger/components/event-stream.d.ts +4 -1
- package/dist/debugger/components/event-stream.js +2 -2
- package/dist/debugger/components/run-tree.d.ts +5 -2
- package/dist/debugger/components/run-tree.js +10 -4
- package/dist/debugger/context.d.ts +8 -1
- package/dist/debugger/context.js +15 -3
- package/dist/debugger/events/protocol-summarize.js +18 -3
- package/dist/debugger/index.d.ts +1 -1
- package/dist/debugger/index.js +1 -1
- package/dist/debugger/shell/debugger-shell.js +1 -1
- package/dist/debugger/shell/events-pane.js +4 -3
- package/dist/debugger/styles.css +1 -0
- package/dist/evaluator/definitions-store.d.ts +3 -4
- package/dist/evaluator/definitions-store.js +3 -3
- package/dist/evaluator/definitions.d.ts +4 -1
- package/dist/evaluator/definitions.js +5 -2
- package/dist/evaluator/effects.d.ts +41 -0
- package/dist/evaluator/effects.js +6 -2
- package/dist/evaluator/module.d.ts +84 -0
- package/dist/evaluator/module.js +7 -3
- package/dist/evaluator/threads.d.ts +2 -0
- package/dist/evaluator/threads.js +4 -0
- package/dist/projectors/event-log.d.ts +87 -0
- package/dist/projectors/event-log.js +396 -0
- package/dist/projectors/index-model.d.ts +12 -0
- package/dist/projectors/index-model.js +12 -3
- package/dist/projectors/memory.js +7 -0
- package/dist/projectors/postgres.d.ts +1 -0
- package/dist/projectors/postgres.js +32 -15
- package/dist/projectors/schema.d.ts +5 -0
- package/dist/projectors/schema.js +26 -1
- package/dist/projectors/sqlite.js +47 -19
- package/dist/projectors/with-projectors.d.ts +7 -1
- package/dist/projectors/with-projectors.js +13 -3
- package/dist/react/materialize.js +5 -1
- package/dist/react/react.d.ts +10 -2
- package/dist/react/react.js +43 -19
- package/dist/react/store.d.ts +11 -2
- package/dist/react/store.js +104 -12
- package/dist/react/tables.d.ts +4 -1
- package/dist/runtime/cancellation.d.ts +2 -1
- package/dist/runtime/cancellation.js +35 -2
- package/dist/runtime/child-run.d.ts +10 -0
- package/dist/runtime/child-run.js +58 -0
- package/dist/runtime/deadline-transition-planner.js +11 -2
- package/dist/runtime/dispatch-effect.d.ts +2 -2
- package/dist/runtime/dispatch-effect.js +43 -19
- package/dist/runtime/errors.d.ts +14 -1
- package/dist/runtime/errors.js +10 -0
- package/dist/runtime/filesystem-blob-store.d.ts +6 -0
- package/dist/runtime/filesystem-blob-store.js +59 -0
- package/dist/runtime/helpers.d.ts +15 -6
- package/dist/runtime/helpers.js +46 -6
- package/dist/runtime/index.d.ts +4 -2
- package/dist/runtime/index.js +3 -1
- package/dist/runtime/local-effect-executor.d.ts +11 -2
- package/dist/runtime/local-effect-executor.js +80 -4
- package/dist/runtime/looms.d.ts +38 -4
- package/dist/runtime/looms.js +17 -3
- package/dist/runtime/repository.d.ts +5 -4
- package/dist/runtime/repository.js +5 -2
- package/dist/runtime/retry-policy.d.ts +5 -0
- package/dist/runtime/retry-policy.js +10 -2
- package/dist/runtime/run-start.d.ts +1 -1
- package/dist/runtime/run-start.js +10 -0
- package/dist/runtime/runtime.d.ts +2 -2
- package/dist/runtime/runtime.js +191 -68
- package/dist/runtime/server/auth.d.ts +3 -0
- package/dist/runtime/server/fetch-handler.d.ts +2 -2
- package/dist/runtime/server/fetch-handler.js +35 -4
- package/dist/runtime/server/grant.d.ts +49 -0
- package/dist/runtime/server/grant.js +177 -0
- package/dist/runtime/server/routes/effects.js +47 -5
- package/dist/runtime/server/routes/runs.js +6 -1
- package/dist/runtime/server/run-route.d.ts +18 -0
- package/dist/runtime/server/run-route.js +26 -0
- package/dist/runtime/server.d.ts +3 -1
- package/dist/runtime/server.js +3 -1
- package/dist/runtime/sse.js +26 -4
- package/dist/runtime/subscription.d.ts +8 -0
- package/dist/runtime/subscription.js +23 -0
- package/dist/runtime/types.d.ts +87 -8
- package/dist/runtime/wake-engine.d.ts +4 -2
- package/dist/runtime/wake-engine.js +57 -6
- package/dist/runtime/worker-callbacks.d.ts +12 -2
- package/dist/runtime/worker-callbacks.js +102 -72
- package/dist/runtime/worker-effect-dispatch.d.ts +14 -5
- package/dist/runtime/worker-effect-dispatch.js +84 -18
- package/dist/schedule/debugger/index.d.ts +4 -0
- package/dist/schedule/debugger/index.js +11 -0
- package/dist/schedule/debugger/schedule-view.d.ts +3 -0
- package/dist/schedule/debugger/schedule-view.js +68 -0
- package/dist/schedule/debugger/summarize.d.ts +2 -0
- package/dist/schedule/debugger/summarize.js +43 -0
- package/dist/schedule/definitions-store.d.ts +10 -0
- package/dist/schedule/definitions-store.js +8 -0
- package/dist/schedule/definitions.d.ts +57 -0
- package/dist/schedule/definitions.js +30 -0
- package/dist/schedule/effects.d.ts +756 -0
- package/dist/schedule/effects.js +244 -0
- package/dist/schedule/ensure.d.ts +55 -0
- package/dist/schedule/ensure.js +109 -0
- package/dist/schedule/events.d.ts +116 -0
- package/dist/schedule/events.js +49 -0
- package/dist/schedule/index.d.ts +11 -0
- package/dist/schedule/index.js +11 -0
- package/dist/schedule/module.d.ts +1474 -0
- package/dist/schedule/module.js +22 -0
- package/dist/schedule/projections.d.ts +55 -0
- package/dist/schedule/projections.js +88 -0
- package/dist/schedule/scope.d.ts +121 -0
- package/dist/schedule/scope.js +7 -0
- package/dist/schedule/signals.d.ts +25 -0
- package/dist/schedule/signals.js +33 -0
- package/dist/schedule/specs.d.ts +59 -0
- package/dist/schedule/specs.js +231 -0
- package/dist/schedule/threads.d.ts +25 -0
- package/dist/schedule/threads.js +259 -0
- package/dist/testing/corpus-module.d.ts +34 -0
- package/dist/testing/corpus-module.js +87 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +5 -6
- package/dist/testing/replay-corpus.d.ts +22 -0
- package/dist/testing/replay-corpus.js +50 -0
- package/dist/workflow/definitions-store.d.ts +1 -1
- package/dist/workflow/definitions-store.js +1 -1
- package/dist/workflow/definitions.d.ts +14 -0
- package/dist/workflow/effects.d.ts +122 -0
- package/dist/workflow/effects.js +16 -6
- package/dist/workflow/events.d.ts +42 -0
- package/dist/workflow/events.js +4 -0
- package/dist/workflow/module.d.ts +313 -0
- package/dist/workflow/module.js +7 -3
- package/dist/workflow/scope.d.ts +42 -0
- package/dist/workflow/threads.d.ts +72 -0
- package/dist/workflow/threads.js +106 -38
- package/package.json +14 -1
- package/dist/debugger/app/assets/index-D--9esm9.js +0 -22
- package/dist/debugger/app/assets/routes-Dakrdusf.js +0 -47
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Schema, type Effect } from 'effect';
|
|
2
|
+
import type { JsonValue } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Immutable labels for a run, such as tenant, project, or org.
|
|
5
|
+
* They are safe for every reader of the run: events, snapshots, summaries, and authorization.
|
|
6
|
+
*/
|
|
7
|
+
export type RunAttributes = {
|
|
8
|
+
readonly [key: string]: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Bearer material for a run, such as an attenuated macaroon.
|
|
12
|
+
* It is stored beside the log and is never written to an event, snapshot, or HTTP response.
|
|
13
|
+
*/
|
|
14
|
+
export type SecretContext = {
|
|
15
|
+
readonly [key: string]: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const RunAttributesSchema: Schema.$Record<Schema.String, Schema.String>;
|
|
18
|
+
export declare const SecretContextSchema: Schema.$Record<Schema.String, Schema.String>;
|
|
19
|
+
export interface RunSecretStore {
|
|
20
|
+
readonly get: (runId: string) => Effect.Effect<SecretContext, Error>;
|
|
21
|
+
readonly put: (runId: string, secrets: SecretContext) => Effect.Effect<void, Error>;
|
|
22
|
+
}
|
|
23
|
+
export declare function hasEntries(record: {
|
|
24
|
+
readonly [key: string]: string;
|
|
25
|
+
}): boolean;
|
|
26
|
+
export declare function sameStringRecord(left: {
|
|
27
|
+
readonly [key: string]: string;
|
|
28
|
+
}, right: {
|
|
29
|
+
readonly [key: string]: string;
|
|
30
|
+
}): boolean;
|
|
31
|
+
/** Reads a string map from an event payload. Anything else becomes an empty map. */
|
|
32
|
+
export declare function readAttributes(value: JsonValue | undefined): RunAttributes;
|
|
33
|
+
export declare function readSecretContext(value: JsonValue): SecretContext;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Option, Schema } from 'effect';
|
|
2
|
+
export const RunAttributesSchema = Schema.Record(Schema.String, Schema.String);
|
|
3
|
+
export const SecretContextSchema = Schema.Record(Schema.String, Schema.String);
|
|
4
|
+
const decodeAttributes = Schema.decodeUnknownOption(RunAttributesSchema);
|
|
5
|
+
const decodeSecretContext = Schema.decodeUnknownOption(SecretContextSchema);
|
|
6
|
+
export function hasEntries(record) {
|
|
7
|
+
return Object.keys(record).length > 0;
|
|
8
|
+
}
|
|
9
|
+
export function sameStringRecord(left, right) {
|
|
10
|
+
const leftKeys = Object.keys(left).toSorted();
|
|
11
|
+
const rightKeys = Object.keys(right).toSorted();
|
|
12
|
+
if (leftKeys.length !== rightKeys.length) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return leftKeys.every((key, index) => key === rightKeys[index] && left[key] === right[key]);
|
|
16
|
+
}
|
|
17
|
+
/** Reads a string map from an event payload. Anything else becomes an empty map. */
|
|
18
|
+
export function readAttributes(value) {
|
|
19
|
+
return value === undefined ? {} : Option.getOrElse(decodeAttributes(value), () => ({}));
|
|
20
|
+
}
|
|
21
|
+
export function readSecretContext(value) {
|
|
22
|
+
return Option.getOrElse(decodeSecretContext(value), () => ({}));
|
|
23
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Effect, Option, Queue, Schema, Stream } from 'effect';
|
|
2
2
|
import { EventEnvelopeSchema, fromWireEvent, withAssignedSeq } from './envelope.js';
|
|
3
3
|
import { assertEventByteLimits, assertSnapshotByteLimit, EventPayloadTooLargeError, SnapshotPayloadTooLargeError, } from './limits.js';
|
|
4
|
+
import { RunAttributesSchema } from './run-context.js';
|
|
4
5
|
import { SnapshotStoreError, withSnapshotStore, } from './snapshot-store.js';
|
|
5
6
|
import { RunStateSchema } from './state.js';
|
|
6
7
|
import { EventStoreConflictError, EventStoreError, EventStoreFencedError, } from './store.js';
|
|
@@ -40,7 +41,13 @@ CREATE TABLE IF NOT EXISTS looms_run_headers (
|
|
|
40
41
|
run_id TEXT PRIMARY KEY,
|
|
41
42
|
status TEXT NOT NULL,
|
|
42
43
|
kind TEXT,
|
|
43
|
-
definition_name TEXT
|
|
44
|
+
definition_name TEXT,
|
|
45
|
+
attributes TEXT NOT NULL DEFAULT '{}'
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
CREATE TABLE IF NOT EXISTS looms_run_secrets (
|
|
49
|
+
run_id TEXT PRIMARY KEY,
|
|
50
|
+
body TEXT NOT NULL
|
|
44
51
|
);
|
|
45
52
|
`.trim();
|
|
46
53
|
const StreamRowSchema = Schema.Struct({
|
|
@@ -117,6 +124,13 @@ function initSchema(exec) {
|
|
|
117
124
|
exec.run(sql);
|
|
118
125
|
}
|
|
119
126
|
}
|
|
127
|
+
// Databases created before attributes were indexed already have the headers table.
|
|
128
|
+
try {
|
|
129
|
+
exec.run(`ALTER TABLE looms_run_headers ADD COLUMN attributes TEXT NOT NULL DEFAULT '{}'`);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// The column is already present.
|
|
133
|
+
}
|
|
120
134
|
}
|
|
121
135
|
function parseEvent(body) {
|
|
122
136
|
return fromWireEvent(decodeEventBody(body));
|
|
@@ -136,14 +150,20 @@ const HeaderRowSchema = Schema.Struct({
|
|
|
136
150
|
status: RunStateSchema.fields.status,
|
|
137
151
|
kind: Schema.NullOr(Schema.String),
|
|
138
152
|
definition_name: Schema.NullOr(Schema.String),
|
|
153
|
+
attributes: Schema.String,
|
|
139
154
|
});
|
|
140
155
|
const decodeHeaderRow = Schema.decodeUnknownSync(HeaderRowSchema);
|
|
156
|
+
const encodeAttributes = Schema.encodeSync(Schema.fromJsonString(RunAttributesSchema));
|
|
157
|
+
const encodeSecrets = Schema.encodeSync(Schema.fromJsonString(Schema.Record(Schema.String, Schema.String)));
|
|
158
|
+
const decodeAttributesColumn = Schema.decodeUnknownOption(Schema.fromJsonString(RunAttributesSchema));
|
|
159
|
+
const decodeSecretsColumn = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Record(Schema.String, Schema.String)));
|
|
141
160
|
function headerFromRow(row) {
|
|
142
161
|
return {
|
|
143
162
|
runId: row.run_id,
|
|
144
163
|
status: row.status,
|
|
145
164
|
kind: row.kind,
|
|
146
165
|
definitionName: row.definition_name,
|
|
166
|
+
attributes: Option.getOrElse(decodeAttributesColumn(row.attributes), () => ({})),
|
|
147
167
|
};
|
|
148
168
|
}
|
|
149
169
|
function createSqliteSnapshotStore(exec) {
|
|
@@ -199,23 +219,54 @@ function createSqliteSnapshotStore(exec) {
|
|
|
199
219
|
}),
|
|
200
220
|
saveHeader: (header) => Effect.try({
|
|
201
221
|
try: () => {
|
|
202
|
-
exec.run(`INSERT INTO looms_run_headers (run_id, status, kind, definition_name)
|
|
203
|
-
VALUES (?, ?, ?, ?)
|
|
222
|
+
exec.run(`INSERT INTO looms_run_headers (run_id, status, kind, definition_name, attributes)
|
|
223
|
+
VALUES (?, ?, ?, ?, ?)
|
|
204
224
|
ON CONFLICT (run_id) DO UPDATE SET
|
|
205
225
|
status = excluded.status,
|
|
206
226
|
kind = excluded.kind,
|
|
207
|
-
definition_name = excluded.definition_name
|
|
227
|
+
definition_name = excluded.definition_name,
|
|
228
|
+
attributes = excluded.attributes`, [
|
|
229
|
+
header.runId,
|
|
230
|
+
header.status,
|
|
231
|
+
header.kind,
|
|
232
|
+
header.definitionName,
|
|
233
|
+
encodeAttributes(header.attributes),
|
|
234
|
+
]);
|
|
208
235
|
},
|
|
209
236
|
catch: (cause) => new SnapshotStoreError(`Failed to save run header for ${header.runId}`, cause),
|
|
210
237
|
}),
|
|
211
238
|
listHeaders: Effect.try({
|
|
212
239
|
try: () => exec
|
|
213
|
-
.rows('SELECT run_id, status, kind, definition_name FROM looms_run_headers')
|
|
240
|
+
.rows('SELECT run_id, status, kind, definition_name, attributes FROM looms_run_headers')
|
|
214
241
|
.map((row) => headerFromRow(decodeHeaderRow(row))),
|
|
215
242
|
catch: (cause) => new SnapshotStoreError('Failed to list run headers', cause),
|
|
216
243
|
}),
|
|
217
244
|
};
|
|
218
245
|
}
|
|
246
|
+
const SecretRowSchema = Schema.Struct({ body: Schema.String });
|
|
247
|
+
const decodeSecretRow = Schema.decodeUnknownSync(SecretRowSchema);
|
|
248
|
+
function createSqliteSecrets(exec) {
|
|
249
|
+
return {
|
|
250
|
+
get: (runId) => Effect.try({
|
|
251
|
+
try: () => {
|
|
252
|
+
const [row] = exec.rows('SELECT body FROM looms_run_secrets WHERE run_id = ?', [runId]);
|
|
253
|
+
if (row === undefined) {
|
|
254
|
+
return {};
|
|
255
|
+
}
|
|
256
|
+
return Option.getOrElse(decodeSecretsColumn(decodeSecretRow(row).body), () => ({}));
|
|
257
|
+
},
|
|
258
|
+
catch: (cause) => new EventStoreError(`Failed to read secret context for ${runId}`, cause),
|
|
259
|
+
}),
|
|
260
|
+
put: (runId, secrets) => Effect.try({
|
|
261
|
+
try: () => {
|
|
262
|
+
exec.run(`INSERT INTO looms_run_secrets (run_id, body)
|
|
263
|
+
VALUES (?, ?)
|
|
264
|
+
ON CONFLICT (run_id) DO UPDATE SET body = excluded.body`, [runId, encodeSecrets(secrets)]);
|
|
265
|
+
},
|
|
266
|
+
catch: (cause) => new EventStoreError(`Failed to store secret context for ${runId}`, cause),
|
|
267
|
+
}),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
219
270
|
function createSqliteEventStore(exec) {
|
|
220
271
|
const waiters = new Map();
|
|
221
272
|
const getStream = (runId) => {
|
|
@@ -398,6 +449,7 @@ function createSqliteEventStore(exec) {
|
|
|
398
449
|
.map((row) => decodeRunIdRow(row).run_id),
|
|
399
450
|
catch: (cause) => new EventStoreError('listRuns failed', cause),
|
|
400
451
|
}),
|
|
452
|
+
runSecrets: createSqliteSecrets(exec),
|
|
401
453
|
};
|
|
402
454
|
return service;
|
|
403
455
|
}
|
package/dist/core/state.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Schema } from 'effect';
|
|
2
2
|
import { type RuntimeEffect, type WaitCondition } from './effects';
|
|
3
|
+
import { type ChildClose, type RunLaunchSource } from './launcher';
|
|
4
|
+
import { type RunAttributes } from './run-context';
|
|
5
|
+
import { type TraceContext } from './trace';
|
|
3
6
|
import type { JsonValue, ThreadStatus, RunStatus } from './types';
|
|
4
7
|
export interface ThreadRecord {
|
|
5
8
|
threadId: string;
|
|
@@ -35,6 +38,8 @@ export interface EffectExecutionRecord {
|
|
|
35
38
|
/** When the current attempt started executing, locally or on a worker. */
|
|
36
39
|
startedAt: number | null;
|
|
37
40
|
lastHeartbeatAt: number | null;
|
|
41
|
+
/** Progress reported by the latest heartbeat. Survives retries so the next attempt can resume. */
|
|
42
|
+
heartbeatDetails: JsonValue | null;
|
|
38
43
|
lastError: string | null;
|
|
39
44
|
}
|
|
40
45
|
export interface RunStartIdentity {
|
|
@@ -45,18 +50,29 @@ export interface RunStartIdentity {
|
|
|
45
50
|
requestedThreadId: string | null;
|
|
46
51
|
idempotencyKey: string | null;
|
|
47
52
|
rootThreadId: string;
|
|
53
|
+
launchedBy: RunLaunchSource | null;
|
|
54
|
+
correlationId: string | null;
|
|
55
|
+
attributes: RunAttributes;
|
|
56
|
+
/** The caller's W3C trace context. Effects, workers, and launched runs inherit it. */
|
|
57
|
+
trace: TraceContext | null;
|
|
48
58
|
}
|
|
49
59
|
/** The run and last sequence a fork copied its history from. */
|
|
50
60
|
export interface RunForkSource {
|
|
51
61
|
runId: string;
|
|
52
62
|
seq: number;
|
|
53
63
|
}
|
|
64
|
+
export interface LaunchedRun {
|
|
65
|
+
runId: string;
|
|
66
|
+
close: ChildClose;
|
|
67
|
+
}
|
|
54
68
|
export interface RunState {
|
|
55
69
|
runId: string;
|
|
56
70
|
status: RunStatus;
|
|
57
71
|
rootThreadId: string | null;
|
|
58
72
|
startIdentity: RunStartIdentity | null;
|
|
59
73
|
forkedFrom: RunForkSource | null;
|
|
74
|
+
/** Immutable labels copied from `runtime.run.started`. Safe for every reader of the run. */
|
|
75
|
+
attributes: RunAttributes;
|
|
60
76
|
threads: {
|
|
61
77
|
[threadId: string]: ThreadRecord;
|
|
62
78
|
};
|
|
@@ -69,6 +85,12 @@ export interface RunState {
|
|
|
69
85
|
};
|
|
70
86
|
completedEffectIds: readonly string[];
|
|
71
87
|
processedIdempotencyKeys: readonly string[];
|
|
88
|
+
/** Child runs this run launched and has not yet seen settle. */
|
|
89
|
+
launchedRuns: readonly LaunchedRun[];
|
|
90
|
+
/** The run is cancelling and will not finish until `wait` children settle. */
|
|
91
|
+
closeWaiting: boolean;
|
|
92
|
+
/** Child runs were already asked to stop because this run closed. */
|
|
93
|
+
childCloseSent: boolean;
|
|
72
94
|
}
|
|
73
95
|
export declare const RunStateSchema: Schema.Struct<{
|
|
74
96
|
readonly runId: Schema.String;
|
|
@@ -82,7 +104,21 @@ export declare const RunStateSchema: Schema.Struct<{
|
|
|
82
104
|
readonly requestedThreadId: Schema.NullOr<Schema.String>;
|
|
83
105
|
readonly idempotencyKey: Schema.NullOr<Schema.String>;
|
|
84
106
|
readonly rootThreadId: Schema.String;
|
|
107
|
+
readonly launchedBy: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Struct<{
|
|
108
|
+
readonly runId: Schema.String;
|
|
109
|
+
readonly threadId: Schema.String;
|
|
110
|
+
readonly effectId: Schema.String;
|
|
111
|
+
readonly causationId: Schema.String;
|
|
112
|
+
readonly causationSeq: Schema.Finite;
|
|
113
|
+
}>>, never>;
|
|
114
|
+
readonly correlationId: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.String>, never>;
|
|
115
|
+
readonly attributes: Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>;
|
|
116
|
+
readonly trace: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Struct<{
|
|
117
|
+
readonly traceparent: Schema.String;
|
|
118
|
+
readonly tracestate: Schema.optional<Schema.String>;
|
|
119
|
+
}>>, never>;
|
|
85
120
|
}>>, never>;
|
|
121
|
+
readonly attributes: Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>;
|
|
86
122
|
readonly forkedFrom: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Struct<{
|
|
87
123
|
readonly runId: Schema.String;
|
|
88
124
|
readonly seq: Schema.Finite;
|
|
@@ -150,6 +186,9 @@ export declare const RunStateSchema: Schema.Struct<{
|
|
|
150
186
|
readonly actorId: Schema.optional<Schema.String>;
|
|
151
187
|
}>, Schema.Struct<{
|
|
152
188
|
readonly type: Schema.Literal<"system">;
|
|
189
|
+
}>, Schema.Struct<{
|
|
190
|
+
readonly type: Schema.Literal<"run">;
|
|
191
|
+
readonly runId: Schema.String;
|
|
153
192
|
}>]>>;
|
|
154
193
|
readonly ephemeral: Schema.optional<Schema.Boolean>;
|
|
155
194
|
readonly id: Schema.optional<Schema.String>;
|
|
@@ -167,10 +206,24 @@ export declare const RunStateSchema: Schema.Struct<{
|
|
|
167
206
|
readonly type: Schema.Literal<"runtime.cancel">;
|
|
168
207
|
readonly threadId: Schema.String;
|
|
169
208
|
readonly tag: Schema.optional<Schema.String>;
|
|
209
|
+
}>, Schema.Struct<{
|
|
210
|
+
readonly type: Schema.Literal<"runtime.launch">;
|
|
211
|
+
readonly runId: Schema.String;
|
|
212
|
+
readonly kind: Schema.String;
|
|
213
|
+
readonly definitionName: Schema.String;
|
|
214
|
+
readonly definitionVersion: Schema.withDecodingDefaultKey<Schema.String, never>;
|
|
215
|
+
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
216
|
+
readonly close: Schema.withDecodingDefaultKey<Schema.Union<readonly [Schema.Literal<"terminate">, Schema.Literal<"wait">]>, never>;
|
|
217
|
+
readonly tag: Schema.optional<Schema.String>;
|
|
218
|
+
}>, Schema.Struct<{
|
|
219
|
+
readonly type: Schema.Literal<"runtime.cancelRun">;
|
|
220
|
+
readonly runId: Schema.String;
|
|
221
|
+
readonly tag: Schema.optional<Schema.String>;
|
|
170
222
|
}>, Schema.Struct<{
|
|
171
223
|
readonly type: Schema.String;
|
|
172
224
|
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
173
225
|
readonly tag: Schema.optional<Schema.String>;
|
|
226
|
+
readonly at: Schema.optional<Schema.Finite>;
|
|
174
227
|
}>]>;
|
|
175
228
|
}>>;
|
|
176
229
|
readonly effectExecutions: Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.Struct<{
|
|
@@ -181,10 +234,17 @@ export declare const RunStateSchema: Schema.Struct<{
|
|
|
181
234
|
readonly deadlineAt: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Finite>, never>;
|
|
182
235
|
readonly startedAt: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Finite>, never>;
|
|
183
236
|
readonly lastHeartbeatAt: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Finite>, never>;
|
|
237
|
+
readonly heartbeatDetails: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Codec<Schema.Json, Schema.Json, never, never>>, never>;
|
|
184
238
|
readonly lastError: Schema.NullOr<Schema.String>;
|
|
185
239
|
}>>, never>;
|
|
186
240
|
readonly completedEffectIds: Schema.withDecodingDefaultKey<Schema.$Array<Schema.String>, never>;
|
|
187
241
|
readonly processedIdempotencyKeys: Schema.withDecodingDefaultKey<Schema.$Array<Schema.String>, never>;
|
|
242
|
+
readonly launchedRuns: Schema.withDecodingDefaultKey<Schema.$Array<Schema.Struct<{
|
|
243
|
+
readonly runId: Schema.String;
|
|
244
|
+
readonly close: Schema.Union<readonly [Schema.Literal<"terminate">, Schema.Literal<"wait">]>;
|
|
245
|
+
}>>, never>;
|
|
246
|
+
readonly closeWaiting: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
|
|
247
|
+
readonly childCloseSent: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
|
|
188
248
|
}>;
|
|
189
249
|
export declare function emptyRunState(runId: string): RunState;
|
|
190
250
|
export declare function isRunTerminal(state: RunState): boolean;
|
package/dist/core/state.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Effect, Predicate, Schema } from 'effect';
|
|
2
2
|
import { RuntimeEffectSchema, WaitConditionSchema, } from './effects.js';
|
|
3
3
|
import { JsonValueSchema } from './envelope.js';
|
|
4
|
+
import { RunLaunchSourceSchema } from './launcher.js';
|
|
4
5
|
import { DEFAULT_DEFINITION_VERSION } from './module.js';
|
|
6
|
+
import { RunAttributesSchema } from './run-context.js';
|
|
5
7
|
import { isTerminalStatus } from './thread.js';
|
|
8
|
+
import { TraceContextSchema } from './trace.js';
|
|
6
9
|
export const RunStateSchema = Schema.Struct({
|
|
7
10
|
runId: Schema.String,
|
|
8
11
|
status: Schema.Union([
|
|
@@ -20,7 +23,12 @@ export const RunStateSchema = Schema.Struct({
|
|
|
20
23
|
requestedThreadId: Schema.NullOr(Schema.String),
|
|
21
24
|
idempotencyKey: Schema.NullOr(Schema.String),
|
|
22
25
|
rootThreadId: Schema.String,
|
|
26
|
+
launchedBy: Schema.NullOr(RunLaunchSourceSchema).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
27
|
+
correlationId: Schema.NullOr(Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
28
|
+
attributes: RunAttributesSchema.pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),
|
|
29
|
+
trace: Schema.NullOr(TraceContextSchema).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
23
30
|
})).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
31
|
+
attributes: RunAttributesSchema.pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),
|
|
24
32
|
forkedFrom: Schema.NullOr(Schema.Struct({ runId: Schema.String, seq: Schema.Finite })).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
25
33
|
threads: Schema.Record(Schema.String, Schema.Struct({
|
|
26
34
|
threadId: Schema.String,
|
|
@@ -71,10 +79,17 @@ export const RunStateSchema = Schema.Struct({
|
|
|
71
79
|
deadlineAt: Schema.NullOr(Schema.Finite).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
72
80
|
startedAt: Schema.NullOr(Schema.Finite).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
73
81
|
lastHeartbeatAt: Schema.NullOr(Schema.Finite).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
82
|
+
heartbeatDetails: Schema.NullOr(JsonValueSchema).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
74
83
|
lastError: Schema.NullOr(Schema.String),
|
|
75
84
|
})).pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),
|
|
76
85
|
completedEffectIds: Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
|
|
77
86
|
processedIdempotencyKeys: Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
|
|
87
|
+
launchedRuns: Schema.Array(Schema.Struct({
|
|
88
|
+
runId: Schema.String,
|
|
89
|
+
close: Schema.Union([Schema.Literal('terminate'), Schema.Literal('wait')]),
|
|
90
|
+
})).pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
|
|
91
|
+
closeWaiting: Schema.Boolean.pipe(Schema.withDecodingDefaultKey(Effect.succeed(false))),
|
|
92
|
+
childCloseSent: Schema.Boolean.pipe(Schema.withDecodingDefaultKey(Effect.succeed(false))),
|
|
78
93
|
});
|
|
79
94
|
export function emptyRunState(runId) {
|
|
80
95
|
return {
|
|
@@ -83,12 +98,16 @@ export function emptyRunState(runId) {
|
|
|
83
98
|
rootThreadId: null,
|
|
84
99
|
startIdentity: null,
|
|
85
100
|
forkedFrom: null,
|
|
101
|
+
attributes: {},
|
|
86
102
|
threads: {},
|
|
87
103
|
waits: {},
|
|
88
104
|
outstandingEffects: [],
|
|
89
105
|
effectExecutions: {},
|
|
90
106
|
completedEffectIds: [],
|
|
91
107
|
processedIdempotencyKeys: [],
|
|
108
|
+
launchedRuns: [],
|
|
109
|
+
closeWaiting: false,
|
|
110
|
+
childCloseSent: false,
|
|
92
111
|
};
|
|
93
112
|
}
|
|
94
113
|
export function isRunTerminal(state) {
|
package/dist/core/store.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Context, Effect, Layer, Stream } from 'effect';
|
|
2
2
|
import { type AppendableEvent, type EventEnvelope } from './envelope';
|
|
3
3
|
import { EventPayloadTooLargeError } from './limits';
|
|
4
|
+
import { type RunSecretStore } from './run-context';
|
|
4
5
|
declare const EventStoreError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
5
6
|
readonly _tag: "EventStoreError";
|
|
6
7
|
} & Readonly<A>;
|
|
@@ -165,6 +166,11 @@ export interface EventStore {
|
|
|
165
166
|
fromSeq?: number;
|
|
166
167
|
}) => Stream.Stream<EventEnvelope, EventStoreError>;
|
|
167
168
|
readonly listRuns: Effect.Effect<string[], EventStoreError>;
|
|
169
|
+
/**
|
|
170
|
+
* Run-scoped bearer material. Absent on stores that cannot keep it out of the event log.
|
|
171
|
+
* A start that supplies secrets fails closed when this is missing.
|
|
172
|
+
*/
|
|
173
|
+
readonly runSecrets?: RunSecretStore;
|
|
168
174
|
}
|
|
169
175
|
/**
|
|
170
176
|
* Utility to read an EventStore as a Stream.Stream, using `store.readStream` if implemented
|
package/dist/core/store.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Context, Data, Effect, Layer, Option, Queue, Ref, Stream } from 'effect';
|
|
2
2
|
import { withAssignedSeq } from './envelope.js';
|
|
3
3
|
import { assertEventByteLimits, EventPayloadTooLargeError } from './limits.js';
|
|
4
|
+
import { readSecretContext } from './run-context.js';
|
|
4
5
|
export class EventStoreError extends Data.TaggedError('EventStoreError') {
|
|
5
6
|
conflict;
|
|
6
7
|
cause;
|
|
@@ -117,6 +118,11 @@ export class EventStoreTag extends Context.Service()('looms/EventStore') {
|
|
|
117
118
|
}
|
|
118
119
|
export const makeMemoryEventStore = Effect.gen(function* () {
|
|
119
120
|
const logs = yield* Ref.make(new Map());
|
|
121
|
+
const secrets = yield* Ref.make(new Map());
|
|
122
|
+
const runSecrets = {
|
|
123
|
+
get: (runId) => Ref.get(secrets).pipe(Effect.map((map) => readSecretContext(map.get(runId) ?? {}))),
|
|
124
|
+
put: (runId, value) => Ref.update(secrets, (map) => new Map(map).set(runId, value)),
|
|
125
|
+
};
|
|
120
126
|
const getOrCreate = (map, runId) => {
|
|
121
127
|
const existing = map.get(runId);
|
|
122
128
|
if (existing) {
|
|
@@ -278,6 +284,7 @@ export const makeMemoryEventStore = Effect.gen(function* () {
|
|
|
278
284
|
}));
|
|
279
285
|
})),
|
|
280
286
|
listRuns: Ref.get(logs).pipe(Effect.map((map) => [...map.keys()])),
|
|
287
|
+
runSecrets,
|
|
281
288
|
};
|
|
282
289
|
return service;
|
|
283
290
|
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { EventEnvelope } from './envelope';
|
|
2
|
+
import { type JsonValue } from './types';
|
|
3
|
+
/** A socket is closed with this code when the client must resume from `head`. */
|
|
4
|
+
export declare const SUBSCRIPTION_RESYNC_CODE = 4000;
|
|
5
|
+
/** Close a socket that has fallen this far behind instead of buffering without bound. */
|
|
6
|
+
export declare const SUBSCRIPTION_BACKPRESSURE_BYTES: number;
|
|
7
|
+
export type SubscriptionTransport = 'websocket' | 'sse' | 'auto';
|
|
8
|
+
export type SubscriptionResyncReason = 'trimmed' | 'backpressure';
|
|
9
|
+
export interface SubscriptionHello {
|
|
10
|
+
readonly type: 'hello';
|
|
11
|
+
readonly head: number;
|
|
12
|
+
readonly tail: number;
|
|
13
|
+
}
|
|
14
|
+
export interface SubscriptionBatch {
|
|
15
|
+
readonly type: 'batch';
|
|
16
|
+
readonly batch: readonly JsonValue[];
|
|
17
|
+
}
|
|
18
|
+
export interface SubscriptionResync {
|
|
19
|
+
readonly type: 'resync';
|
|
20
|
+
readonly head: number;
|
|
21
|
+
readonly reason: SubscriptionResyncReason;
|
|
22
|
+
}
|
|
23
|
+
export type SubscriptionFrame = SubscriptionHello | SubscriptionBatch | SubscriptionResync;
|
|
24
|
+
export interface SubscriptionFilter {
|
|
25
|
+
readonly threadId: string | null;
|
|
26
|
+
readonly includeEphemeral: boolean;
|
|
27
|
+
}
|
|
28
|
+
/** State hibernated with a Durable Object WebSocket. Writes stay on HTTP. */
|
|
29
|
+
export interface SubscriptionAttachment {
|
|
30
|
+
readonly principal: string | null;
|
|
31
|
+
readonly cursor: number;
|
|
32
|
+
readonly threadId: string | null;
|
|
33
|
+
readonly includeEphemeral: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface SubscriptionSender {
|
|
36
|
+
send(data: string): void;
|
|
37
|
+
close(code: number, reason: string): void;
|
|
38
|
+
readonly bufferedAmount: number;
|
|
39
|
+
}
|
|
40
|
+
export interface AttachedSubscriptionSocket extends SubscriptionSender {
|
|
41
|
+
attachment(): SubscriptionAttachment | undefined;
|
|
42
|
+
setAttachment(attachment: SubscriptionAttachment): void;
|
|
43
|
+
}
|
|
44
|
+
export interface SubscriptionPushOptions {
|
|
45
|
+
readonly bufferLimitBytes?: number;
|
|
46
|
+
readonly head?: number;
|
|
47
|
+
}
|
|
48
|
+
export type SubscriptionOpening = {
|
|
49
|
+
readonly kind: 'resync';
|
|
50
|
+
readonly head: number;
|
|
51
|
+
} | {
|
|
52
|
+
readonly kind: 'open';
|
|
53
|
+
readonly hello: SubscriptionHello;
|
|
54
|
+
readonly events: readonly EventEnvelope[];
|
|
55
|
+
};
|
|
56
|
+
export type SubscriptionRead = {
|
|
57
|
+
readonly kind: 'events';
|
|
58
|
+
readonly events: readonly EventEnvelope[];
|
|
59
|
+
} | {
|
|
60
|
+
readonly kind: 'hello';
|
|
61
|
+
readonly head: number;
|
|
62
|
+
readonly tail: number;
|
|
63
|
+
} | {
|
|
64
|
+
readonly kind: 'resync';
|
|
65
|
+
readonly head: number;
|
|
66
|
+
readonly reason: SubscriptionResyncReason;
|
|
67
|
+
} | {
|
|
68
|
+
readonly kind: 'ignore';
|
|
69
|
+
};
|
|
70
|
+
export declare function encodeSubscriptionFrame(frame: SubscriptionFrame): string;
|
|
71
|
+
export declare function decodeSubscriptionFrame(data: string): SubscriptionFrame | undefined;
|
|
72
|
+
/** One cursor for SSE and WebSocket. `Last-Event-ID` is the last seen seq. */
|
|
73
|
+
export declare function subscriptionFromSeq(url: URL, lastEventId: string | null): {
|
|
74
|
+
readonly ok: true;
|
|
75
|
+
readonly fromSeq: number;
|
|
76
|
+
} | {
|
|
77
|
+
readonly ok: false;
|
|
78
|
+
readonly message: string;
|
|
79
|
+
};
|
|
80
|
+
export declare function subscriptionFilter(url: URL): SubscriptionFilter;
|
|
81
|
+
export declare function subscriptionReplay(head: number, fromSeq: number): {
|
|
82
|
+
readonly kind: 'resync';
|
|
83
|
+
readonly head: number;
|
|
84
|
+
} | {
|
|
85
|
+
readonly kind: 'play';
|
|
86
|
+
readonly fromSeq: number;
|
|
87
|
+
};
|
|
88
|
+
export declare function eventMatchesSubscription(event: EventEnvelope, filter: SubscriptionFilter): boolean;
|
|
89
|
+
export declare function attachmentFromFilter(filter: SubscriptionFilter, fromSeq: number, principal: string | null): SubscriptionAttachment;
|
|
90
|
+
export declare function readSubscriptionData(data: string, runId: string): SubscriptionRead;
|
|
91
|
+
/**
|
|
92
|
+
* Sends the events this attachment still needs. Returns the advanced attachment,
|
|
93
|
+
* or `undefined` after the socket is closed for resync.
|
|
94
|
+
*/
|
|
95
|
+
export declare function pushSubscriptionEvents(socket: SubscriptionSender, events: readonly EventEnvelope[], attachment: SubscriptionAttachment, options?: SubscriptionPushOptions): SubscriptionAttachment | undefined;
|
|
96
|
+
export declare function openSubscription(socket: SubscriptionSender, attachment: SubscriptionAttachment, opening: SubscriptionOpening, options?: SubscriptionPushOptions): SubscriptionAttachment | undefined;
|
|
97
|
+
export declare function fanoutSubscription(sockets: readonly AttachedSubscriptionSocket[], events: readonly EventEnvelope[], options?: SubscriptionPushOptions): void;
|