@effect-agent/storage-memory 0.1.0-beta.55 → 0.1.0-beta.57
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/dist/MemoryMessageDeliveryStore.d.mts +15 -0
- package/dist/MemoryMessageDeliveryStore.mjs +144 -0
- package/dist/MemoryMessageDeliveryStore.mjs.map +1 -0
- package/dist/MemorySubmissionLedger.mjs +17 -2
- package/dist/MemorySubmissionLedger.mjs.map +1 -1
- package/dist/MemoryThreadStore.d.mts +6 -2
- package/dist/MemoryThreadStore.mjs +12 -5
- package/dist/MemoryThreadStore.mjs.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/package.json +1 -1
- package/src/MemoryMessageDeliveryStore.ts +285 -0
- package/src/MemorySubmissionLedger.ts +84 -0
- package/src/MemoryThreadStore.ts +32 -3
- package/src/index.ts +1 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Layer } from "effect";
|
|
2
|
+
import { MessageDeliveryError, MessageDeliveryStore, MessageDeliveryStoreLimits } from "@effect-agent/thread/MessageDelivery";
|
|
3
|
+
declare namespace MemoryMessageDeliveryStore_d_exports {
|
|
4
|
+
export { MemoryMessageDeliveryStoreLive, MemoryMessageDeliveryStoreOptions, memoryMessageDeliveryStoreLayer };
|
|
5
|
+
}
|
|
6
|
+
interface MemoryMessageDeliveryStoreOptions {
|
|
7
|
+
/** UTF-8 bound on the complete stored record, including a processed Settlement. */
|
|
8
|
+
readonly maxStoredValueBytes?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Reference adapter. All retained rows are bounded; completed deduplication evidence is never evicted. */
|
|
11
|
+
declare const memoryMessageDeliveryStoreLayer: (limits?: MessageDeliveryStoreLimits, options?: MemoryMessageDeliveryStoreOptions) => Layer.Layer<MessageDeliveryStore, MessageDeliveryError>;
|
|
12
|
+
declare const MemoryMessageDeliveryStoreLive: Layer.Layer<MessageDeliveryStore, MessageDeliveryError, never>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { MemoryMessageDeliveryStoreLive, MemoryMessageDeliveryStoreOptions, memoryMessageDeliveryStoreLayer, MemoryMessageDeliveryStore_d_exports as t };
|
|
15
|
+
//# sourceMappingURL=MemoryMessageDeliveryStore.d.mts.map
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import { ScheduleInstant } from "@effect-agent/thread/Schedule";
|
|
3
|
+
import { Effect, Layer, Ref, Schema, Semaphore } from "effect";
|
|
4
|
+
import { ThreadId } from "@effect-agent/core/Identifiers";
|
|
5
|
+
import { MessageDeliveryChange, MessageDeliveryError, MessageDeliveryFailpoint, MessageDeliveryKey, MessageDeliveryPageRequest, MessageDeliveryRecord, MessageDeliveryStore, MessageDeliveryStoreLimits, applyMessageDeliveryChange, defaultMessageDeliveryStoreLimits, messageDeliveryDeadline, messageDeliveryKeyString, messageDeliveryUsesCapacity, sameMessageDeliveryIdentity, validateMessageDelivery } from "@effect-agent/thread/MessageDelivery";
|
|
6
|
+
//#region src/MemoryMessageDeliveryStore.ts
|
|
7
|
+
var MemoryMessageDeliveryStore_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
MemoryMessageDeliveryStoreLive: () => MemoryMessageDeliveryStoreLive,
|
|
9
|
+
memoryMessageDeliveryStoreLayer: () => memoryMessageDeliveryStoreLayer
|
|
10
|
+
});
|
|
11
|
+
const codec = Schema.fromJsonString(MessageDeliveryRecord);
|
|
12
|
+
const decode = (text) => Schema.decodeEffect(codec)(text).pipe(Effect.mapError(() => MessageDeliveryError.make({
|
|
13
|
+
reason: "corrupt",
|
|
14
|
+
operation: "decode"
|
|
15
|
+
})));
|
|
16
|
+
const Scan = Schema.Struct({
|
|
17
|
+
nowMillis: ScheduleInstant,
|
|
18
|
+
limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(100)),
|
|
19
|
+
ownerThreadId: Schema.optionalKey(ThreadId)
|
|
20
|
+
});
|
|
21
|
+
/** Reference adapter. All retained rows are bounded; completed deduplication evidence is never evicted. */
|
|
22
|
+
const memoryMessageDeliveryStoreLayer = (limits = defaultMessageDeliveryStoreLimits, options = {}) => Layer.effect(MessageDeliveryStore, Effect.gen(function* () {
|
|
23
|
+
const config = yield* validateMessageDelivery(MessageDeliveryStoreLimits, limits, "limits");
|
|
24
|
+
const maxStoredValueBytes = yield* validateMessageDelivery(Schema.Int.check(Schema.isGreaterThan(0)), options.maxStoredValueBytes ?? 16777216, "stored-value-limit");
|
|
25
|
+
const state = yield* Ref.make(/* @__PURE__ */ new Map());
|
|
26
|
+
const lock = yield* Semaphore.make(1);
|
|
27
|
+
const failpoint = yield* MessageDeliveryFailpoint;
|
|
28
|
+
const encode = Effect.fn("MemoryMessageDeliveryStore.encode")(function* (record) {
|
|
29
|
+
const text = yield* Schema.encodeEffect(codec)(record).pipe(Effect.mapError(() => MessageDeliveryError.make({
|
|
30
|
+
reason: "corrupt",
|
|
31
|
+
operation: "encode"
|
|
32
|
+
})));
|
|
33
|
+
if (new TextEncoder().encode(text).byteLength > maxStoredValueBytes) return yield* MessageDeliveryError.make({
|
|
34
|
+
reason: "capacity",
|
|
35
|
+
operation: "stored-value-bytes"
|
|
36
|
+
});
|
|
37
|
+
return text;
|
|
38
|
+
});
|
|
39
|
+
const all = Effect.fn("MemoryMessageDeliveryStore.all")(function* () {
|
|
40
|
+
return yield* Effect.forEach((yield* Ref.get(state)).values(), decode);
|
|
41
|
+
});
|
|
42
|
+
const insert = Effect.fn("MemoryMessageDeliveryStore.insert")(function* (record) {
|
|
43
|
+
const encoded = yield* encode(record);
|
|
44
|
+
const input = yield* decode(encoded);
|
|
45
|
+
if (input.version !== 1 || input.status !== "pending" || input.leaseUntilMillis !== null || input.retry.attempts !== 0 || input.retry.generation !== 0 || input.retry.automaticAttempts !== 0 || input.retry.nextAttemptAtMillis !== input.createdAtMillis || input.retry.lastAttemptAtMillis !== null || input.retry.lastFailure !== null || input.deadlineAtMillis !== input.initialDeadlineAtMillis) return yield* MessageDeliveryError.make({
|
|
46
|
+
reason: "validation",
|
|
47
|
+
operation: "insert-state"
|
|
48
|
+
});
|
|
49
|
+
if (new TextEncoder().encode(JSON.stringify(input.envelope)).byteLength > config.maxEnvelopeBytes) return yield* MessageDeliveryError.make({
|
|
50
|
+
reason: "capacity",
|
|
51
|
+
operation: "envelope-bytes"
|
|
52
|
+
});
|
|
53
|
+
yield* failpoint.hit("message-delivery:insert:before");
|
|
54
|
+
const inserted = yield* lock.withPermit(Effect.uninterruptible(Effect.gen(function* () {
|
|
55
|
+
const records = yield* Ref.get(state);
|
|
56
|
+
const key = messageDeliveryKeyString(input.key);
|
|
57
|
+
const existingText = records.get(key);
|
|
58
|
+
if (existingText !== void 0) {
|
|
59
|
+
const existing = yield* decode(existingText);
|
|
60
|
+
if (!sameMessageDeliveryIdentity(existing, input)) return yield* MessageDeliveryError.make({
|
|
61
|
+
reason: "conflict",
|
|
62
|
+
operation: "insert"
|
|
63
|
+
});
|
|
64
|
+
return existing;
|
|
65
|
+
}
|
|
66
|
+
const owned = (yield* all()).filter((record) => record.key.ownerThreadId === input.key.ownerThreadId);
|
|
67
|
+
if (owned.length >= config.maxRetainedPerOwner || owned.filter(messageDeliveryUsesCapacity).length >= config.maxPendingPerOwner) return yield* MessageDeliveryError.make({
|
|
68
|
+
reason: "capacity",
|
|
69
|
+
operation: "insert"
|
|
70
|
+
});
|
|
71
|
+
yield* Ref.set(state, new Map(records).set(key, encoded));
|
|
72
|
+
return input;
|
|
73
|
+
})));
|
|
74
|
+
yield* failpoint.hit("message-delivery:insert:after");
|
|
75
|
+
return yield* decode(yield* encode(inserted));
|
|
76
|
+
});
|
|
77
|
+
const get = Effect.fn("MemoryMessageDeliveryStore.get")(function* (key) {
|
|
78
|
+
const input = yield* validateMessageDelivery(MessageDeliveryKey, key, "get");
|
|
79
|
+
const text = (yield* Ref.get(state)).get(messageDeliveryKeyString(input));
|
|
80
|
+
return text === void 0 ? null : yield* decode(text);
|
|
81
|
+
});
|
|
82
|
+
const change = Effect.fn("MemoryMessageDeliveryStore.change")(function* (key, change) {
|
|
83
|
+
const input = yield* validateMessageDelivery(MessageDeliveryChange, change, "change");
|
|
84
|
+
const decodedKey = yield* validateMessageDelivery(MessageDeliveryKey, key, "change");
|
|
85
|
+
const point = `message-delivery:${input._tag.toLowerCase()}`;
|
|
86
|
+
yield* failpoint.hit(`${point}:before`);
|
|
87
|
+
const changed = yield* lock.withPermit(Effect.uninterruptible(Effect.gen(function* () {
|
|
88
|
+
const existing = yield* get(decodedKey);
|
|
89
|
+
if (existing === null) return yield* MessageDeliveryError.make({
|
|
90
|
+
reason: "not-found",
|
|
91
|
+
operation: "change"
|
|
92
|
+
});
|
|
93
|
+
const next = yield* Effect.fromResult(applyMessageDeliveryChange(existing, input));
|
|
94
|
+
const encoded = yield* encode(next);
|
|
95
|
+
yield* Ref.update(state, (records) => new Map(records).set(messageDeliveryKeyString(decodedKey), encoded));
|
|
96
|
+
return next;
|
|
97
|
+
})));
|
|
98
|
+
yield* failpoint.hit(`${point}:after`);
|
|
99
|
+
return yield* decode(yield* encode(changed));
|
|
100
|
+
});
|
|
101
|
+
return MessageDeliveryStore.of({
|
|
102
|
+
insert,
|
|
103
|
+
get,
|
|
104
|
+
change,
|
|
105
|
+
list: Effect.fn("MemoryMessageDeliveryStore.list")(function* (request) {
|
|
106
|
+
const input = yield* validateMessageDelivery(MessageDeliveryPageRequest, request, "list");
|
|
107
|
+
const records = (yield* all()).filter((record) => record.key.ownerThreadId === input.ownerThreadId && (input.after === void 0 || record.key.messageId > input.after)).sort((left, right) => left.key.messageId < right.key.messageId ? -1 : left.key.messageId > right.key.messageId ? 1 : 0);
|
|
108
|
+
const items = records.slice(0, input.limit);
|
|
109
|
+
return {
|
|
110
|
+
items,
|
|
111
|
+
next: records.length > input.limit ? items.at(-1)?.key.messageId ?? null : null
|
|
112
|
+
};
|
|
113
|
+
}),
|
|
114
|
+
due: Effect.fn("MemoryMessageDeliveryStore.due")(function* (nowMillis, limit, ownerThreadId) {
|
|
115
|
+
const input = yield* validateMessageDelivery(Scan, {
|
|
116
|
+
nowMillis,
|
|
117
|
+
limit,
|
|
118
|
+
...ownerThreadId === void 0 ? {} : { ownerThreadId }
|
|
119
|
+
}, "due");
|
|
120
|
+
return (yield* all()).flatMap((record) => {
|
|
121
|
+
const deadline = messageDeliveryDeadline(record);
|
|
122
|
+
return deadline !== null && deadline <= input.nowMillis && (input.ownerThreadId === void 0 || input.ownerThreadId === record.key.ownerThreadId) ? [{
|
|
123
|
+
key: record.key,
|
|
124
|
+
deadline
|
|
125
|
+
}] : [];
|
|
126
|
+
}).sort((left, right) => left.deadline - right.deadline || (messageDeliveryKeyString(left.key) < messageDeliveryKeyString(right.key) ? -1 : 1)).slice(0, input.limit).map((record) => record.key);
|
|
127
|
+
}),
|
|
128
|
+
nextDeadline: Effect.fn("MemoryMessageDeliveryStore.nextDeadline")(function* (ownerThreadId) {
|
|
129
|
+
if (ownerThreadId !== void 0) yield* validateMessageDelivery(ThreadId, ownerThreadId, "nextDeadline");
|
|
130
|
+
let next = null;
|
|
131
|
+
for (const record of yield* all()) {
|
|
132
|
+
if (ownerThreadId !== void 0 && ownerThreadId !== record.key.ownerThreadId) continue;
|
|
133
|
+
const deadline = messageDeliveryDeadline(record);
|
|
134
|
+
if (deadline !== null && (next === null || deadline < next)) next = deadline;
|
|
135
|
+
}
|
|
136
|
+
return next;
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
}));
|
|
140
|
+
const MemoryMessageDeliveryStoreLive = memoryMessageDeliveryStoreLayer();
|
|
141
|
+
//#endregion
|
|
142
|
+
export { MemoryMessageDeliveryStoreLive, memoryMessageDeliveryStoreLayer, MemoryMessageDeliveryStore_exports as t };
|
|
143
|
+
|
|
144
|
+
//# sourceMappingURL=MemoryMessageDeliveryStore.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemoryMessageDeliveryStore.mjs","names":[],"sources":["../src/MemoryMessageDeliveryStore.ts"],"sourcesContent":["import { ThreadId } from \"@effect-agent/core/Identifiers\";\nimport {\n applyMessageDeliveryChange,\n defaultMessageDeliveryStoreLimits,\n MessageDeliveryChange,\n MessageDeliveryError,\n MessageDeliveryFailpoint,\n MessageDeliveryKey,\n MessageDeliveryPageRequest,\n MessageDeliveryRecord,\n MessageDeliveryStore,\n MessageDeliveryStoreLimits,\n messageDeliveryDeadline,\n messageDeliveryKeyString,\n messageDeliveryUsesCapacity,\n sameMessageDeliveryIdentity,\n validateMessageDelivery,\n} from \"@effect-agent/thread/MessageDelivery\";\nimport { ScheduleInstant } from \"@effect-agent/thread/Schedule\";\nimport { Effect, Layer, Ref, Schema, Semaphore } from \"effect\";\n\nconst codec = Schema.fromJsonString(MessageDeliveryRecord);\n\nconst decode = (text: string) =>\n Schema.decodeEffect(codec)(text).pipe(\n Effect.mapError(() => MessageDeliveryError.make({ reason: \"corrupt\", operation: \"decode\" })),\n );\n\nconst Scan = Schema.Struct({\n nowMillis: ScheduleInstant,\n limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(100)),\n ownerThreadId: Schema.optionalKey(ThreadId),\n});\n\nexport interface MemoryMessageDeliveryStoreOptions {\n /** UTF-8 bound on the complete stored record, including a processed Settlement. */\n readonly maxStoredValueBytes?: number;\n}\n\n/** Reference adapter. All retained rows are bounded; completed deduplication evidence is never evicted. */\nexport const memoryMessageDeliveryStoreLayer = (\n limits: MessageDeliveryStoreLimits = defaultMessageDeliveryStoreLimits,\n options: MemoryMessageDeliveryStoreOptions = {},\n): Layer.Layer<MessageDeliveryStore, MessageDeliveryError> =>\n Layer.effect(\n MessageDeliveryStore,\n Effect.gen(function* () {\n const config = yield* validateMessageDelivery(MessageDeliveryStoreLimits, limits, \"limits\");\n\n const maxStoredValueBytes = yield* validateMessageDelivery(\n Schema.Int.check(Schema.isGreaterThan(0)),\n options.maxStoredValueBytes ?? 16 * 1_024 * 1_024,\n \"stored-value-limit\",\n );\n\n const state = yield* Ref.make<ReadonlyMap<string, string>>(new Map());\n const lock = yield* Semaphore.make(1);\n const failpoint = yield* MessageDeliveryFailpoint;\n\n const encode = Effect.fn(\"MemoryMessageDeliveryStore.encode\")(function* (\n record: MessageDeliveryRecord,\n ) {\n const text = yield* Schema.encodeEffect(codec)(record).pipe(\n Effect.mapError(() =>\n MessageDeliveryError.make({ reason: \"corrupt\", operation: \"encode\" }),\n ),\n );\n\n if (new TextEncoder().encode(text).byteLength > maxStoredValueBytes) {\n return yield* MessageDeliveryError.make({\n reason: \"capacity\",\n operation: \"stored-value-bytes\",\n });\n }\n\n return text;\n });\n\n const all = Effect.fn(\"MemoryMessageDeliveryStore.all\")(function* () {\n return yield* Effect.forEach((yield* Ref.get(state)).values(), decode);\n });\n\n const insert: MessageDeliveryStore[\"Service\"][\"insert\"] = Effect.fn(\n \"MemoryMessageDeliveryStore.insert\",\n )(function* (record) {\n const encoded = yield* encode(record);\n const input = yield* decode(encoded);\n\n if (\n input.version !== 1 ||\n input.status !== \"pending\" ||\n input.leaseUntilMillis !== null ||\n input.retry.attempts !== 0 ||\n input.retry.generation !== 0 ||\n input.retry.automaticAttempts !== 0 ||\n input.retry.nextAttemptAtMillis !== input.createdAtMillis ||\n input.retry.lastAttemptAtMillis !== null ||\n input.retry.lastFailure !== null ||\n input.deadlineAtMillis !== input.initialDeadlineAtMillis\n ) {\n return yield* MessageDeliveryError.make({\n reason: \"validation\",\n operation: \"insert-state\",\n });\n }\n if (\n new TextEncoder().encode(JSON.stringify(input.envelope)).byteLength >\n config.maxEnvelopeBytes\n ) {\n return yield* MessageDeliveryError.make({\n reason: \"capacity\",\n operation: \"envelope-bytes\",\n });\n }\n yield* failpoint.hit(\"message-delivery:insert:before\");\n\n const inserted = yield* lock.withPermit(\n Effect.uninterruptible(\n Effect.gen(function* () {\n const records = yield* Ref.get(state);\n const key = messageDeliveryKeyString(input.key);\n const existingText = records.get(key);\n\n if (existingText !== undefined) {\n const existing = yield* decode(existingText);\n\n if (!sameMessageDeliveryIdentity(existing, input))\n return yield* MessageDeliveryError.make({\n reason: \"conflict\",\n operation: \"insert\",\n });\n\n return existing;\n }\n\n const owned = (yield* all()).filter(\n (record) => record.key.ownerThreadId === input.key.ownerThreadId,\n );\n\n if (\n owned.length >= config.maxRetainedPerOwner ||\n owned.filter(messageDeliveryUsesCapacity).length >= config.maxPendingPerOwner\n ) {\n return yield* MessageDeliveryError.make({\n reason: \"capacity\",\n operation: \"insert\",\n });\n }\n yield* Ref.set(state, new Map(records).set(key, encoded));\n\n return input;\n }),\n ),\n );\n\n yield* failpoint.hit(\"message-delivery:insert:after\");\n\n return yield* decode(yield* encode(inserted));\n });\n\n const get: MessageDeliveryStore[\"Service\"][\"get\"] = Effect.fn(\n \"MemoryMessageDeliveryStore.get\",\n )(function* (key) {\n const input = yield* validateMessageDelivery(MessageDeliveryKey, key, \"get\");\n const text = (yield* Ref.get(state)).get(messageDeliveryKeyString(input));\n\n return text === undefined ? null : yield* decode(text);\n });\n\n const change: MessageDeliveryStore[\"Service\"][\"change\"] = Effect.fn(\n \"MemoryMessageDeliveryStore.change\",\n )(function* (key, change) {\n const input = yield* validateMessageDelivery(MessageDeliveryChange, change, \"change\");\n const decodedKey = yield* validateMessageDelivery(MessageDeliveryKey, key, \"change\");\n const point = `message-delivery:${input._tag.toLowerCase()}`;\n\n yield* failpoint.hit(`${point}:before`);\n\n const changed = yield* lock.withPermit(\n Effect.uninterruptible(\n Effect.gen(function* () {\n const existing = yield* get(decodedKey);\n\n if (existing === null)\n return yield* MessageDeliveryError.make({\n reason: \"not-found\",\n operation: \"change\",\n });\n const next = yield* Effect.fromResult(applyMessageDeliveryChange(existing, input));\n const encoded = yield* encode(next);\n\n yield* Ref.update(state, (records) =>\n new Map(records).set(messageDeliveryKeyString(decodedKey), encoded),\n );\n\n return next;\n }),\n ),\n );\n\n yield* failpoint.hit(`${point}:after`);\n\n return yield* decode(yield* encode(changed));\n });\n\n return MessageDeliveryStore.of({\n insert,\n get,\n change,\n list: Effect.fn(\"MemoryMessageDeliveryStore.list\")(function* (request) {\n const input = yield* validateMessageDelivery(MessageDeliveryPageRequest, request, \"list\");\n\n const records = (yield* all())\n .filter(\n (record) =>\n record.key.ownerThreadId === input.ownerThreadId &&\n (input.after === undefined || record.key.messageId > input.after),\n )\n .sort((left, right) =>\n left.key.messageId < right.key.messageId\n ? -1\n : left.key.messageId > right.key.messageId\n ? 1\n : 0,\n );\n\n const items = records.slice(0, input.limit);\n\n return {\n items,\n next: records.length > input.limit ? (items.at(-1)?.key.messageId ?? null) : null,\n };\n }),\n due: Effect.fn(\"MemoryMessageDeliveryStore.due\")(\n function* (nowMillis, limit, ownerThreadId) {\n const input = yield* validateMessageDelivery(\n Scan,\n { nowMillis, limit, ...(ownerThreadId === undefined ? {} : { ownerThreadId }) },\n \"due\",\n );\n\n return (yield* all())\n .flatMap((record) => {\n const deadline = messageDeliveryDeadline(record);\n\n return deadline !== null &&\n deadline <= input.nowMillis &&\n (input.ownerThreadId === undefined ||\n input.ownerThreadId === record.key.ownerThreadId)\n ? [{ key: record.key, deadline }]\n : [];\n })\n .sort(\n (left, right) =>\n left.deadline - right.deadline ||\n (messageDeliveryKeyString(left.key) < messageDeliveryKeyString(right.key)\n ? -1\n : 1),\n )\n .slice(0, input.limit)\n .map((record) => record.key);\n },\n ),\n nextDeadline: Effect.fn(\"MemoryMessageDeliveryStore.nextDeadline\")(\n function* (ownerThreadId) {\n if (ownerThreadId !== undefined)\n yield* validateMessageDelivery(ThreadId, ownerThreadId, \"nextDeadline\");\n let next: number | null = null;\n\n for (const record of yield* all()) {\n if (ownerThreadId !== undefined && ownerThreadId !== record.key.ownerThreadId)\n continue;\n const deadline = messageDeliveryDeadline(record);\n\n if (deadline !== null && (next === null || deadline < next)) next = deadline;\n }\n\n return next;\n },\n ),\n });\n }),\n );\n\nexport const MemoryMessageDeliveryStoreLive = memoryMessageDeliveryStoreLayer();\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { Cause, Clock, DateTime, Duration, Effect, Exit, Fiber, Layer, Option, Ref, Schema, Stream } from "effect";
|
|
3
3
|
import { AttemptId, ReceiptId, SubmissionId } from "@effect-agent/core/Identifiers";
|
|
4
|
-
import {
|
|
4
|
+
import { MessageAdmission } from "@effect-agent/core/Messaging";
|
|
5
|
+
import { PersistedJson, ProducerEpoch, WorkerAdmission } from "@effect-agent/thread/Records";
|
|
5
6
|
import { AbortCommand, AbortIntent, AbortIntentRequest, AdmissionAdmitted, AdmissionConflict, AdmissionIndeterminate, AdmissionNotAdmitted, AdmissionPolicyError, AdmissionRequest, AdmissionResult, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, AttachChildToReservationRequest, BeginChildBudgetReleaseRequest, ChildAttachmentSnapshot, ChildBudgetReservationRequest, ChildBudgetReservationSnapshot, ChildReservationConflict, ChildSettledNotification, Claim, ClaimJoiningRequest, ClaimRequest, DEFAULT_OWNERSHIP_LEASE_DURATION, InputAppliedMarker, JoinSnapshot, JoinedToHost, JoiningClaim, LedgerCapabilities, LedgerError, MarkInputAppliedRequest, MarkJoinedRequest, MarkReadyRequest, MarkUnknownRequest, OwnershipLost, OwnershipRenewal, OwnershipSnapshot, OwnershipToken, QueueSequence, RecoverySnapshot, RecoverySnapshotRequest, ReleaseChildBudgetRequest, ReleaseOwnershipRequest, RenewOwnershipRequest, ReservedChildBudget, ReservedSettlement, RevertJoiningRequest, Settlement, SettlementConflict, SettlementFinalization, SettlementReservation, SettlementReservationSnapshot, SubmissionAdmissionFence, SubmissionLedger, SubmissionLookup, SubmissionLookupByKey, SubmissionSnapshot, SuspendRequest, SuspensionSnapshot, UnknownResolution, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, settlementFailureFromRecord } from "@effect-agent/thread/SubmissionLedger";
|
|
6
7
|
//#region src/MemorySubmissionLedger.ts
|
|
7
8
|
var MemorySubmissionLedger_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -83,6 +84,8 @@ const toSnapshot = (row) => SubmissionSnapshot.make({
|
|
|
83
84
|
createdAt: utc(row.createdAtMillis),
|
|
84
85
|
...row.admissionGroup === void 0 ? {} : { admissionGroup: row.admissionGroup },
|
|
85
86
|
...row.admissionFence === void 0 ? {} : { admissionFence: row.admissionFence },
|
|
87
|
+
...row.workerAdmissionJson === void 0 ? {} : { workerAdmission: Schema.decodeSync(Schema.fromJsonString(WorkerAdmission))(row.workerAdmissionJson) },
|
|
88
|
+
...row.messageAdmissionJson === void 0 ? {} : { messageAdmission: Schema.decodeSync(Schema.fromJsonString(MessageAdmission))(row.messageAdmissionJson) },
|
|
86
89
|
...row.settledOutcome === void 0 ? {} : { settledOutcome: row.settledOutcome },
|
|
87
90
|
...row.readyAtMillis === void 0 ? {} : { readyAt: utc(row.readyAtMillis) },
|
|
88
91
|
...row.parentLinkage === void 0 ? {} : { parentLinkage: row.parentLinkage }
|
|
@@ -172,6 +175,8 @@ const makeSubmissionLedger = (options = {}) => Effect.gen(function* () {
|
|
|
172
175
|
const capabilities = Effect.succeed(LedgerCapabilities.make({ durability: "non-durable" }));
|
|
173
176
|
const admit = Effect.fn("MemorySubmissionLedger.admit")((unvalidated) => Effect.gen(function* () {
|
|
174
177
|
const request = yield* validate(AdmissionRequest, "admit", unvalidated);
|
|
178
|
+
const workerAdmissionJson = request.workerAdmission === void 0 ? void 0 : yield* Schema.encodeEffect(Schema.fromJsonString(WorkerAdmission))(request.workerAdmission).pipe(Effect.mapError(() => ledgerError("admit", "Invalid worker admission metadata")));
|
|
179
|
+
const messageAdmissionJson = request.messageAdmission === void 0 ? void 0 : yield* Schema.encodeEffect(Schema.fromJsonString(MessageAdmission))(request.messageAdmission).pipe(Effect.mapError(() => ledgerError("admit", "Invalid message admission metadata")));
|
|
175
180
|
const nowMillis = yield* Clock.currentTimeMillis;
|
|
176
181
|
const services = yield* Effect.context();
|
|
177
182
|
const decision = yield* Ref.modify(state, (current) => {
|
|
@@ -180,7 +185,7 @@ const makeSubmissionLedger = (options = {}) => Effect.gen(function* () {
|
|
|
180
185
|
if (existingId !== void 0) {
|
|
181
186
|
const existing = current.submissions.get(existingId);
|
|
182
187
|
if (existing === void 0) return [failure(ledgerError("admit", "Admission index references a missing Submission")), current];
|
|
183
|
-
if (existing.row.inputDigest !== request.inputDigest || !sameParentLinkage(existing.row.parentLinkage, request.parentLinkage) || existing.row.admissionGroup !== request.admissionGroup || !Schema.toEquivalence(Schema.optional(Schema.Json))(existing.row.admissionFence, request.admissionFence)) return [failure(AdmissionConflict.make({
|
|
188
|
+
if (existing.row.inputDigest !== request.inputDigest || !sameParentLinkage(existing.row.parentLinkage, request.parentLinkage) || existing.row.admissionGroup !== request.admissionGroup || !Schema.toEquivalence(Schema.optional(WorkerAdmission))(existing.row.workerAdmissionJson === void 0 ? void 0 : Schema.decodeSync(Schema.fromJsonString(WorkerAdmission))(existing.row.workerAdmissionJson), request.workerAdmission) || !Schema.toEquivalence(Schema.optional(MessageAdmission))(existing.row.messageAdmissionJson === void 0 ? void 0 : Schema.decodeSync(Schema.fromJsonString(MessageAdmission))(existing.row.messageAdmissionJson), request.messageAdmission) || !Schema.toEquivalence(Schema.optional(Schema.Json))(existing.row.admissionFence, request.admissionFence)) return [failure(AdmissionConflict.make({
|
|
184
189
|
threadId: request.threadId,
|
|
185
190
|
principal: request.principal,
|
|
186
191
|
idempotencyKey: request.idempotencyKey,
|
|
@@ -195,6 +200,14 @@ const makeSubmissionLedger = (options = {}) => Effect.gen(function* () {
|
|
|
195
200
|
replayed: true
|
|
196
201
|
})), current];
|
|
197
202
|
}
|
|
203
|
+
const first = [...current.submissions.values()].find(({ row }) => row.threadId === request.threadId);
|
|
204
|
+
if (first !== void 0) {
|
|
205
|
+
const previous = first.row.workerAdmissionJson === void 0 ? void 0 : Schema.decodeSync(Schema.fromJsonString(WorkerAdmission))(first.row.workerAdmissionJson);
|
|
206
|
+
if (!Schema.toEquivalence(Schema.optional(WorkerAdmission.fields.origin))(previous?.origin, request.workerAdmission?.origin)) return [failure(AdmissionPolicyError.make({
|
|
207
|
+
reason: "refused",
|
|
208
|
+
code: "worker-origin-conflict"
|
|
209
|
+
})), current];
|
|
210
|
+
}
|
|
198
211
|
const checked = Effect.runSyncExitWith(services)(admissionFence.check(request));
|
|
199
212
|
if (Exit.isFailure(checked)) return [{
|
|
200
213
|
_tag: "cause",
|
|
@@ -227,6 +240,8 @@ const makeSubmissionLedger = (options = {}) => Effect.gen(function* () {
|
|
|
227
240
|
createdAtMillis: nowMillis,
|
|
228
241
|
readyAtMillis: void 0,
|
|
229
242
|
parentLinkage: request.parentLinkage,
|
|
243
|
+
...workerAdmissionJson === void 0 ? {} : { workerAdmissionJson },
|
|
244
|
+
...messageAdmissionJson === void 0 ? {} : { messageAdmissionJson },
|
|
230
245
|
...request.admissionGroup === void 0 ? {} : { admissionGroup: request.admissionGroup },
|
|
231
246
|
...request.admissionFence === void 0 ? {} : { admissionFence: request.admissionFence }
|
|
232
247
|
};
|