@effect-agent/storage-memory 0.1.0-beta.84 → 0.1.0-beta.85

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.
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { ScheduleInstant } from "@effect-agent/thread/Schedule";
3
3
  import { Effect, Layer, Ref, Schema, Semaphore } from "effect";
4
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";
5
+ import { MessageDeliveryChange, MessageDeliveryError, MessageDeliveryFailpoint, MessageDeliveryKey, MessageDeliveryPageRequest, MessageDeliveryRecord, MessageDeliveryStore, MessageDeliveryStoreLimits, applyMessageDeliveryChange, defaultMessageDeliveryStoreLimits, isWorkerUpdateDelivery, messageDeliveryCapacity, messageDeliveryDeadline, messageDeliveryKeyString, messageDeliveryUsesCapacity, sameMessageDeliveryIdentity, validateMessageDelivery } from "@effect-agent/thread/MessageDelivery";
6
6
  //#region src/MemoryMessageDeliveryStore.ts
7
7
  var MemoryMessageDeliveryStore_exports = /* @__PURE__ */ __exportAll({
8
8
  MemoryMessageDeliveryStoreLive: () => MemoryMessageDeliveryStoreLive,
@@ -63,8 +63,9 @@ const memoryMessageDeliveryStoreLayer = (limits = defaultMessageDeliveryStoreLim
63
63
  });
64
64
  return existing;
65
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({
66
+ const owned = (yield* all()).filter((record) => record.key.ownerThreadId === input.key.ownerThreadId && isWorkerUpdateDelivery(record) === isWorkerUpdateDelivery(input));
67
+ const capacity = messageDeliveryCapacity(config, isWorkerUpdateDelivery(input));
68
+ if (owned.length >= capacity.retained || owned.filter(messageDeliveryUsesCapacity).length >= capacity.pending) return yield* MessageDeliveryError.make({
68
69
  reason: "capacity",
69
70
  operation: "insert"
70
71
  });
@@ -99,6 +100,8 @@ const memoryMessageDeliveryStoreLayer = (limits = defaultMessageDeliveryStoreLim
99
100
  return yield* decode(yield* encode(changed));
100
101
  });
101
102
  return MessageDeliveryStore.of({
103
+ limits: config,
104
+ maxStoredValueBytes,
102
105
  insert,
103
106
  get,
104
107
  change,
@@ -1 +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":";;;;;;;;;;AAqBA,MAAM,QAAQ,OAAO,eAAe,qBAAqB;AAEzD,MAAM,UAAU,SACd,OAAO,aAAa,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,KAC/B,OAAO,eAAe,qBAAqB,KAAK;CAAE,QAAQ;CAAW,WAAW;AAAS,CAAC,CAAC,CAC7F;AAEF,MAAM,OAAO,OAAO,OAAO;CACzB,WAAW;CACX,OAAO,OAAO,IAAI,MAAM,OAAO,cAAc,CAAC,GAAG,OAAO,oBAAoB,GAAG,CAAC;CAChF,eAAe,OAAO,YAAY,QAAQ;AAC5C,CAAC;;AAQD,MAAa,mCACX,SAAqC,mCACrC,UAA6C,CAAC,MAE9C,MAAM,OACJ,sBACA,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO,wBAAwB,4BAA4B,QAAQ,QAAQ;CAE1F,MAAM,sBAAsB,OAAO,wBACjC,OAAO,IAAI,MAAM,OAAO,cAAc,CAAC,CAAC,GACxC,QAAQ,uBAAuB,UAC/B,oBACF;CAEA,MAAM,QAAQ,OAAO,IAAI,qBAAkC,IAAI,IAAI,CAAC;CACpE,MAAM,OAAO,OAAO,UAAU,KAAK,CAAC;CACpC,MAAM,YAAY,OAAO;CAEzB,MAAM,SAAS,OAAO,GAAG,mCAAmC,CAAC,CAAC,WAC5D,QACA;EACA,MAAM,OAAO,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KACrD,OAAO,eACL,qBAAqB,KAAK;GAAE,QAAQ;GAAW,WAAW;EAAS,CAAC,CACtE,CACF;EAEA,IAAI,IAAI,YAAY,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,aAAa,qBAC9C,OAAO,OAAO,qBAAqB,KAAK;GACtC,QAAQ;GACR,WAAW;EACb,CAAC;EAGH,OAAO;CACT,CAAC;CAED,MAAM,MAAM,OAAO,GAAG,gCAAgC,CAAC,CAAC,aAAa;EACnE,OAAO,OAAO,OAAO,SAAS,OAAO,IAAI,IAAI,KAAK,EAAA,CAAG,OAAO,GAAG,MAAM;CACvE,CAAC;CAED,MAAM,SAAoD,OAAO,GAC/D,mCACF,CAAC,CAAC,WAAW,QAAQ;EACnB,MAAM,UAAU,OAAO,OAAO,MAAM;EACpC,MAAM,QAAQ,OAAO,OAAO,OAAO;EAEnC,IACE,MAAM,YAAY,KAClB,MAAM,WAAW,aACjB,MAAM,qBAAqB,QAC3B,MAAM,MAAM,aAAa,KACzB,MAAM,MAAM,eAAe,KAC3B,MAAM,MAAM,sBAAsB,KAClC,MAAM,MAAM,wBAAwB,MAAM,mBAC1C,MAAM,MAAM,wBAAwB,QACpC,MAAM,MAAM,gBAAgB,QAC5B,MAAM,qBAAqB,MAAM,yBAEjC,OAAO,OAAO,qBAAqB,KAAK;GACtC,QAAQ;GACR,WAAW;EACb,CAAC;EAEH,IACE,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,UAAU,MAAM,QAAQ,CAAC,CAAC,CAAC,aACzD,OAAO,kBAEP,OAAO,OAAO,qBAAqB,KAAK;GACtC,QAAQ;GACR,WAAW;EACb,CAAC;EAEH,OAAO,UAAU,IAAI,gCAAgC;EAErD,MAAM,WAAW,OAAO,KAAK,WAC3B,OAAO,gBACL,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,IAAI,IAAI,KAAK;GACpC,MAAM,MAAM,yBAAyB,MAAM,GAAG;GAC9C,MAAM,eAAe,QAAQ,IAAI,GAAG;GAEpC,IAAI,iBAAiB,KAAA,GAAW;IAC9B,MAAM,WAAW,OAAO,OAAO,YAAY;IAE3C,IAAI,CAAC,4BAA4B,UAAU,KAAK,GAC9C,OAAO,OAAO,qBAAqB,KAAK;KACtC,QAAQ;KACR,WAAW;IACb,CAAC;IAEH,OAAO;GACT;GAEA,MAAM,SAAS,OAAO,IAAI,EAAA,CAAG,QAC1B,WAAW,OAAO,IAAI,kBAAkB,MAAM,IAAI,aACrD;GAEA,IACE,MAAM,UAAU,OAAO,uBACvB,MAAM,OAAO,2BAA2B,CAAC,CAAC,UAAU,OAAO,oBAE3D,OAAO,OAAO,qBAAqB,KAAK;IACtC,QAAQ;IACR,WAAW;GACb,CAAC;GAEH,OAAO,IAAI,IAAI,OAAO,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC;GAExD,OAAO;EACT,CAAC,CACH,CACF;EAEA,OAAO,UAAU,IAAI,+BAA+B;EAEpD,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,CAAC;CAC9C,CAAC;CAED,MAAM,MAA8C,OAAO,GACzD,gCACF,CAAC,CAAC,WAAW,KAAK;EAChB,MAAM,QAAQ,OAAO,wBAAwB,oBAAoB,KAAK,KAAK;EAC3E,MAAM,QAAQ,OAAO,IAAI,IAAI,KAAK,EAAA,CAAG,IAAI,yBAAyB,KAAK,CAAC;EAExE,OAAO,SAAS,KAAA,IAAY,OAAO,OAAO,OAAO,IAAI;CACvD,CAAC;CAED,MAAM,SAAoD,OAAO,GAC/D,mCACF,CAAC,CAAC,WAAW,KAAK,QAAQ;EACxB,MAAM,QAAQ,OAAO,wBAAwB,uBAAuB,QAAQ,QAAQ;EACpF,MAAM,aAAa,OAAO,wBAAwB,oBAAoB,KAAK,QAAQ;EACnF,MAAM,QAAQ,oBAAoB,MAAM,KAAK,YAAY;EAEzD,OAAO,UAAU,IAAI,GAAG,MAAM,QAAQ;EAEtC,MAAM,UAAU,OAAO,KAAK,WAC1B,OAAO,gBACL,OAAO,IAAI,aAAa;GACtB,MAAM,WAAW,OAAO,IAAI,UAAU;GAEtC,IAAI,aAAa,MACf,OAAO,OAAO,qBAAqB,KAAK;IACtC,QAAQ;IACR,WAAW;GACb,CAAC;GACH,MAAM,OAAO,OAAO,OAAO,WAAW,2BAA2B,UAAU,KAAK,CAAC;GACjF,MAAM,UAAU,OAAO,OAAO,IAAI;GAElC,OAAO,IAAI,OAAO,QAAQ,YACxB,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,yBAAyB,UAAU,GAAG,OAAO,CACpE;GAEA,OAAO;EACT,CAAC,CACH,CACF;EAEA,OAAO,UAAU,IAAI,GAAG,MAAM,OAAO;EAErC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,CAAC;CAC7C,CAAC;CAED,OAAO,qBAAqB,GAAG;EAC7B;EACA;EACA;EACA,MAAM,OAAO,GAAG,iCAAiC,CAAC,CAAC,WAAW,SAAS;GACrE,MAAM,QAAQ,OAAO,wBAAwB,4BAA4B,SAAS,MAAM;GAExF,MAAM,WAAW,OAAO,IAAI,EAAA,CACzB,QACE,WACC,OAAO,IAAI,kBAAkB,MAAM,kBAClC,MAAM,UAAU,KAAA,KAAa,OAAO,IAAI,YAAY,MAAM,MAC/D,CAAC,CACA,MAAM,MAAM,UACX,KAAK,IAAI,YAAY,MAAM,IAAI,YAC3B,KACA,KAAK,IAAI,YAAY,MAAM,IAAI,YAC7B,IACA,CACR;GAEF,MAAM,QAAQ,QAAQ,MAAM,GAAG,MAAM,KAAK;GAE1C,OAAO;IACL;IACA,MAAM,QAAQ,SAAS,MAAM,QAAS,MAAM,GAAG,EAAE,CAAC,EAAE,IAAI,aAAa,OAAQ;GAC/E;EACF,CAAC;EACD,KAAK,OAAO,GAAG,gCAAgC,CAAC,CAC9C,WAAW,WAAW,OAAO,eAAe;GAC1C,MAAM,QAAQ,OAAO,wBACnB,MACA;IAAE;IAAW;IAAO,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc;GAAG,GAC9E,KACF;GAEA,QAAQ,OAAO,IAAI,EAAA,CAChB,SAAS,WAAW;IACnB,MAAM,WAAW,wBAAwB,MAAM;IAE/C,OAAO,aAAa,QAClB,YAAY,MAAM,cACjB,MAAM,kBAAkB,KAAA,KACvB,MAAM,kBAAkB,OAAO,IAAI,iBACnC,CAAC;KAAE,KAAK,OAAO;KAAK;IAAS,CAAC,IAC9B,CAAC;GACP,CAAC,CAAC,CACD,MACE,MAAM,UACL,KAAK,WAAW,MAAM,aACrB,yBAAyB,KAAK,GAAG,IAAI,yBAAyB,MAAM,GAAG,IACpE,KACA,EACR,CAAC,CACA,MAAM,GAAG,MAAM,KAAK,CAAC,CACrB,KAAK,WAAW,OAAO,GAAG;EAC/B,CACF;EACA,cAAc,OAAO,GAAG,yCAAyC,CAAC,CAChE,WAAW,eAAe;GACxB,IAAI,kBAAkB,KAAA,GACpB,OAAO,wBAAwB,UAAU,eAAe,cAAc;GACxE,IAAI,OAAsB;GAE1B,KAAK,MAAM,UAAU,OAAO,IAAI,GAAG;IACjC,IAAI,kBAAkB,KAAA,KAAa,kBAAkB,OAAO,IAAI,eAC9D;IACF,MAAM,WAAW,wBAAwB,MAAM;IAE/C,IAAI,aAAa,SAAS,SAAS,QAAQ,WAAW,OAAO,OAAO;GACtE;GAEA,OAAO;EACT,CACF;CACF,CAAC;AACH,CAAC,CACH;AAEF,MAAa,iCAAiC,gCAAgC"}
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 isWorkerUpdateDelivery,\n messageDeliveryCapacity,\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) =>\n record.key.ownerThreadId === input.key.ownerThreadId &&\n isWorkerUpdateDelivery(record) === isWorkerUpdateDelivery(input),\n );\n\n const capacity = messageDeliveryCapacity(config, isWorkerUpdateDelivery(input));\n\n if (\n owned.length >= capacity.retained ||\n owned.filter(messageDeliveryUsesCapacity).length >= capacity.pending\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 limits: config,\n maxStoredValueBytes,\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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"}
@@ -103,7 +103,7 @@ const makeScheduleStore = Effect.gen(function* () {
103
103
  if (!scheduleUsesCapacity(decoded.success) && scheduleUsesCapacity(applied.success)) {
104
104
  let count = 0;
105
105
  for (const text of current.records.values()) {
106
- const candidate = Schema.decodeUnknownResult(Schema.fromJsonString(ScheduleRecord))(text);
106
+ const candidate = Schema.decodeResult(Schema.fromJsonString(ScheduleRecord))(text);
107
107
  if (Result.isFailure(candidate)) return [Result.fail(storageError("change", "corrupt")), current];
108
108
  if (sameOwner(candidate.success, decodedKey.owner) && scheduleUsesCapacity(candidate.success)) count += 1;
109
109
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryScheduleStore.mjs","names":[],"sources":["../src/MemoryScheduleStore.ts"],"sourcesContent":["import {\n ScheduleCapacityError,\n ScheduleDueCursor,\n defaultSchedulingLimits,\n ScheduleChange,\n ScheduleConflict,\n ScheduleFailpoint,\n ScheduleKey,\n ScheduleNotFound,\n ScheduleOwner,\n SchedulePageRequest,\n ScheduleRecord,\n ScheduleStorageError,\n ScheduleStore,\n} from \"@effect-agent/thread/Schedule\";\nimport {\n scheduleUsesCapacity,\n applyScheduleChange,\n compareScheduleKeys,\n compareScheduleNames,\n scheduleDeadline,\n scheduleKeyString,\n scheduleKeyOf,\n scheduleOwnerKey,\n} from \"@effect-agent/thread/ScheduleTransition\";\nimport { Effect, Layer, Ref, Result, Schema } from \"effect\";\n\ninterface MemoryScheduleState {\n readonly records: ReadonlyMap<string, string>;\n}\n\nconst storageError = (operation: string, reason: \"unavailable\" | \"corrupt\") =>\n ScheduleStorageError.make({ operation, reason });\n\nconst encodeRecord = (operation: string, record: ScheduleRecord) =>\n Effect.try({\n try: () => Schema.encodeSync(Schema.fromJsonString(ScheduleRecord))(record),\n catch: () => storageError(operation, \"corrupt\"),\n });\n\nconst decodeRecord = (operation: string, encoded: string) =>\n Effect.try({\n try: () => Schema.decodeSync(Schema.fromJsonString(ScheduleRecord))(encoded),\n catch: () => storageError(operation, \"corrupt\"),\n });\n\nconst decodeInput = <A, I>(operation: string, schema: Schema.Codec<A, I>, value: unknown) =>\n Effect.try({\n try: () => Schema.decodeUnknownSync(schema)(value),\n catch: () => storageError(operation, \"corrupt\"),\n });\n\nconst sameOwner = (record: ScheduleRecord, owner: ScheduleOwner): boolean =>\n scheduleOwnerKey(record.owner) === scheduleOwnerKey(owner);\n\nconst makeScheduleStore = Effect.gen(function* () {\n const state = yield* Ref.make<MemoryScheduleState>({ records: new Map() });\n const failpoint = yield* ScheduleFailpoint;\n\n const insert: ScheduleStore[\"Service\"][\"insert\"] = Effect.fn(\"MemoryScheduleStore.insert\")(\n (record, ownerLimit) =>\n Effect.gen(function* () {\n const encoded = yield* encodeRecord(\"insert\", record);\n\n yield* failpoint.hit(\"schedule:insert:before\");\n\n const decision = yield* Effect.uninterruptible(\n Ref.modify(\n state,\n (\n current,\n ): readonly [\n Result.Result<\n ScheduleRecord,\n ScheduleConflict | ScheduleCapacityError | ScheduleStorageError\n >,\n MemoryScheduleState,\n ] => {\n const key = scheduleKeyString(record);\n const existingText = current.records.get(key);\n\n if (existingText !== undefined) {\n const decoded = Result.try({\n try: () => Schema.decodeSync(Schema.fromJsonString(ScheduleRecord))(existingText),\n catch: () => storageError(\"insert\", \"corrupt\"),\n });\n\n if (Result.isFailure(decoded)) {\n return [Result.fail(decoded.failure), current];\n }\n if (decoded.success.creationFingerprint === record.creationFingerprint) {\n return [Result.succeed(decoded.success), current];\n }\n\n return [\n Result.fail(\n ScheduleConflict.make({ reason: \"creation\", key: scheduleKeyOf(record) }),\n ),\n current,\n ];\n }\n\n let ownerCount = 0;\n\n for (const text of current.records.values()) {\n const decoded = Result.try({\n try: () => Schema.decodeSync(Schema.fromJsonString(ScheduleRecord))(text),\n catch: () => storageError(\"insert\", \"corrupt\"),\n });\n\n if (Result.isFailure(decoded)) {\n return [Result.fail(decoded.failure), current];\n }\n if (\n sameOwner(decoded.success, record.owner) &&\n scheduleUsesCapacity(decoded.success)\n )\n ownerCount += 1;\n }\n if (ownerCount >= ownerLimit) {\n return [Result.fail(ScheduleCapacityError.make({ limit: ownerLimit })), current];\n }\n const records = new Map(current.records);\n\n records.set(key, encoded);\n const next = { records };\n\n return [Result.succeed(record), next];\n },\n ),\n );\n\n const inserted = yield* Effect.fromResult(decision);\n\n yield* failpoint.hit(\"schedule:insert:after\");\n\n return yield* decodeRecord(\"insert\", yield* encodeRecord(\"insert\", inserted));\n }),\n );\n\n const get: ScheduleStore[\"Service\"][\"get\"] = Effect.fn(\"MemoryScheduleStore.get\")(\n function* (key) {\n const decodedKey = yield* decodeInput(\"get\", ScheduleKey, key);\n const text = (yield* Ref.get(state)).records.get(scheduleKeyString(decodedKey));\n\n return text === undefined ? null : yield* decodeRecord(\"get\", text);\n },\n );\n\n const list: ScheduleStore[\"Service\"][\"list\"] = Effect.fn(\"MemoryScheduleStore.list\")(\n function* (request) {\n const decodedRequest = yield* decodeInput(\"list\", SchedulePageRequest, request);\n const records: Array<ScheduleRecord> = [];\n\n for (const text of (yield* Ref.get(state)).records.values()) {\n const record = yield* decodeRecord(\"list\", text);\n\n if (\n sameOwner(record, decodedRequest.owner) &&\n (decodedRequest.after === undefined ||\n compareScheduleNames(record.scheduleId, decodedRequest.after) > 0)\n ) {\n records.push(record);\n }\n }\n records.sort((left, right) => compareScheduleNames(left.scheduleId, right.scheduleId));\n const hasNext = records.length > decodedRequest.limit;\n const items = records.slice(0, decodedRequest.limit);\n\n return {\n items,\n next: hasNext ? (items.at(-1)?.scheduleId ?? null) : null,\n };\n },\n );\n\n const change: ScheduleStore[\"Service\"][\"change\"] = Effect.fn(\"MemoryScheduleStore.change\")(\n (key, command, ownerLimit = defaultSchedulingLimits.maxSchedulesPerOwner) =>\n Effect.gen(function* () {\n const decodedKey = yield* decodeInput(\"change\", ScheduleKey, key);\n const decodedCommand = yield* decodeInput(\"change\", ScheduleChange, command);\n\n yield* failpoint.hit(`schedule:${decodedCommand._tag.toLowerCase()}:before`);\n\n const decision = yield* Effect.uninterruptible(\n Ref.modify(\n state,\n (\n current,\n ): readonly [\n Result.Result<\n ScheduleRecord,\n ScheduleConflict | ScheduleStorageError | ScheduleNotFound | ScheduleCapacityError\n >,\n MemoryScheduleState,\n ] => {\n const storageKey = scheduleKeyString(decodedKey);\n const text = current.records.get(storageKey);\n\n if (text === undefined) {\n return [Result.fail(ScheduleNotFound.make({ key: decodedKey })), current];\n }\n\n const decoded = Result.try({\n try: () => Schema.decodeSync(Schema.fromJsonString(ScheduleRecord))(text),\n catch: () => storageError(\"change\", \"corrupt\"),\n });\n\n if (Result.isFailure(decoded)) {\n return [Result.fail(decoded.failure), current];\n }\n const applied = applyScheduleChange(decoded.success, decodedCommand);\n\n if (Result.isFailure(applied)) {\n return [Result.fail(applied.failure), current];\n }\n if (applied.success === decoded.success) {\n return [Result.succeed(decoded.success), current];\n }\n if (!scheduleUsesCapacity(decoded.success) && scheduleUsesCapacity(applied.success)) {\n let count = 0;\n\n for (const text of current.records.values()) {\n const candidate = Schema.decodeUnknownResult(\n Schema.fromJsonString(ScheduleRecord),\n )(text);\n\n if (Result.isFailure(candidate))\n return [Result.fail(storageError(\"change\", \"corrupt\")), current];\n if (\n sameOwner(candidate.success, decodedKey.owner) &&\n scheduleUsesCapacity(candidate.success)\n )\n count += 1;\n }\n if (count >= ownerLimit)\n return [Result.fail(ScheduleCapacityError.make({ limit: ownerLimit })), current];\n }\n\n const encoded = Result.try({\n try: () =>\n Schema.encodeSync(Schema.fromJsonString(ScheduleRecord))(applied.success),\n catch: () => storageError(\"change\", \"corrupt\"),\n });\n\n if (Result.isFailure(encoded)) {\n return [Result.fail(encoded.failure), current];\n }\n const records = new Map(current.records);\n\n records.set(storageKey, encoded.success);\n const next = { records };\n\n return [Result.succeed(applied.success), next];\n },\n ),\n );\n\n const changed = yield* Effect.fromResult(decision);\n\n yield* failpoint.hit(`schedule:${decodedCommand._tag.toLowerCase()}:after`);\n\n return yield* decodeRecord(\"change\", yield* encodeRecord(\"change\", changed));\n }),\n );\n\n const due: ScheduleStore[\"Service\"][\"due\"] = Effect.fn(\"MemoryScheduleStore.due\")(\n function* (nowMillis, limit, owner, after) {\n const decodedOwner =\n owner === undefined ? undefined : yield* decodeInput(\"due\", ScheduleOwner, owner);\n\n const cursor =\n after === undefined ? undefined : yield* decodeInput(\"due\", ScheduleDueCursor, after);\n\n const records: Array<ScheduleDueCursor> = [];\n\n for (const text of (yield* Ref.get(state)).records.values()) {\n const record = yield* decodeRecord(\"due\", text);\n const deadline = scheduleDeadline(record);\n\n if (\n deadline !== null &&\n deadline <= nowMillis &&\n (decodedOwner === undefined || sameOwner(record, decodedOwner)) &&\n (cursor === undefined ||\n deadline > cursor.deadlineAtMillis ||\n (deadline === cursor.deadlineAtMillis && compareScheduleKeys(record, cursor) > 0))\n ) {\n records.push({ ...scheduleKeyOf(record), deadlineAtMillis: deadline });\n }\n }\n records.sort((left, right) => {\n const byDeadline = left.deadlineAtMillis - right.deadlineAtMillis;\n\n return byDeadline !== 0 ? byDeadline : compareScheduleKeys(left, right);\n });\n\n return records.slice(0, limit);\n },\n );\n\n const nextDeadline: ScheduleStore[\"Service\"][\"nextDeadline\"] = Effect.fn(\n \"MemoryScheduleStore.nextDeadline\",\n )(function* (owner) {\n const decodedOwner =\n owner === undefined ? undefined : yield* decodeInput(\"nextDeadline\", ScheduleOwner, owner);\n\n let earliest: number | null = null;\n\n for (const text of (yield* Ref.get(state)).records.values()) {\n const record = yield* decodeRecord(\"nextDeadline\", text);\n\n if (decodedOwner !== undefined && !sameOwner(record, decodedOwner)) continue;\n const deadline = scheduleDeadline(record);\n\n if (deadline !== null && (earliest === null || deadline < earliest)) earliest = deadline;\n }\n\n return earliest;\n });\n\n return ScheduleStore.of({ insert, get, list, change, due, nextDeadline });\n});\n\nexport const memoryScheduleStoreLayer = (): Layer.Layer<ScheduleStore> =>\n Layer.effect(ScheduleStore, makeScheduleStore);\n\nexport const MemoryScheduleStoreLive: Layer.Layer<ScheduleStore> = memoryScheduleStoreLayer();\n"],"mappings":"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"}
1
+ {"version":3,"file":"MemoryScheduleStore.mjs","names":[],"sources":["../src/MemoryScheduleStore.ts"],"sourcesContent":["import {\n ScheduleCapacityError,\n ScheduleDueCursor,\n defaultSchedulingLimits,\n ScheduleChange,\n ScheduleConflict,\n ScheduleFailpoint,\n ScheduleKey,\n ScheduleNotFound,\n ScheduleOwner,\n SchedulePageRequest,\n ScheduleRecord,\n ScheduleStorageError,\n ScheduleStore,\n} from \"@effect-agent/thread/Schedule\";\nimport {\n scheduleUsesCapacity,\n applyScheduleChange,\n compareScheduleKeys,\n compareScheduleNames,\n scheduleDeadline,\n scheduleKeyString,\n scheduleKeyOf,\n scheduleOwnerKey,\n} from \"@effect-agent/thread/ScheduleTransition\";\nimport { Effect, Layer, Ref, Result, Schema } from \"effect\";\n\ninterface MemoryScheduleState {\n readonly records: ReadonlyMap<string, string>;\n}\n\nconst storageError = (operation: string, reason: \"unavailable\" | \"corrupt\") =>\n ScheduleStorageError.make({ operation, reason });\n\nconst encodeRecord = (operation: string, record: ScheduleRecord) =>\n Effect.try({\n try: () => Schema.encodeSync(Schema.fromJsonString(ScheduleRecord))(record),\n catch: () => storageError(operation, \"corrupt\"),\n });\n\nconst decodeRecord = (operation: string, encoded: string) =>\n Effect.try({\n try: () => Schema.decodeSync(Schema.fromJsonString(ScheduleRecord))(encoded),\n catch: () => storageError(operation, \"corrupt\"),\n });\n\nconst decodeInput = <A, I>(operation: string, schema: Schema.Codec<A, I>, value: unknown) =>\n Effect.try({\n try: () => Schema.decodeUnknownSync(schema)(value),\n catch: () => storageError(operation, \"corrupt\"),\n });\n\nconst sameOwner = (record: ScheduleRecord, owner: ScheduleOwner): boolean =>\n scheduleOwnerKey(record.owner) === scheduleOwnerKey(owner);\n\nconst makeScheduleStore = Effect.gen(function* () {\n const state = yield* Ref.make<MemoryScheduleState>({ records: new Map() });\n const failpoint = yield* ScheduleFailpoint;\n\n const insert: ScheduleStore[\"Service\"][\"insert\"] = Effect.fn(\"MemoryScheduleStore.insert\")(\n (record, ownerLimit) =>\n Effect.gen(function* () {\n const encoded = yield* encodeRecord(\"insert\", record);\n\n yield* failpoint.hit(\"schedule:insert:before\");\n\n const decision = yield* Effect.uninterruptible(\n Ref.modify(\n state,\n (\n current,\n ): readonly [\n Result.Result<\n ScheduleRecord,\n ScheduleConflict | ScheduleCapacityError | ScheduleStorageError\n >,\n MemoryScheduleState,\n ] => {\n const key = scheduleKeyString(record);\n const existingText = current.records.get(key);\n\n if (existingText !== undefined) {\n const decoded = Result.try({\n try: () => Schema.decodeSync(Schema.fromJsonString(ScheduleRecord))(existingText),\n catch: () => storageError(\"insert\", \"corrupt\"),\n });\n\n if (Result.isFailure(decoded)) {\n return [Result.fail(decoded.failure), current];\n }\n if (decoded.success.creationFingerprint === record.creationFingerprint) {\n return [Result.succeed(decoded.success), current];\n }\n\n return [\n Result.fail(\n ScheduleConflict.make({ reason: \"creation\", key: scheduleKeyOf(record) }),\n ),\n current,\n ];\n }\n\n let ownerCount = 0;\n\n for (const text of current.records.values()) {\n const decoded = Result.try({\n try: () => Schema.decodeSync(Schema.fromJsonString(ScheduleRecord))(text),\n catch: () => storageError(\"insert\", \"corrupt\"),\n });\n\n if (Result.isFailure(decoded)) {\n return [Result.fail(decoded.failure), current];\n }\n if (\n sameOwner(decoded.success, record.owner) &&\n scheduleUsesCapacity(decoded.success)\n )\n ownerCount += 1;\n }\n if (ownerCount >= ownerLimit) {\n return [Result.fail(ScheduleCapacityError.make({ limit: ownerLimit })), current];\n }\n const records = new Map(current.records);\n\n records.set(key, encoded);\n const next = { records };\n\n return [Result.succeed(record), next];\n },\n ),\n );\n\n const inserted = yield* Effect.fromResult(decision);\n\n yield* failpoint.hit(\"schedule:insert:after\");\n\n return yield* decodeRecord(\"insert\", yield* encodeRecord(\"insert\", inserted));\n }),\n );\n\n const get: ScheduleStore[\"Service\"][\"get\"] = Effect.fn(\"MemoryScheduleStore.get\")(\n function* (key) {\n const decodedKey = yield* decodeInput(\"get\", ScheduleKey, key);\n const text = (yield* Ref.get(state)).records.get(scheduleKeyString(decodedKey));\n\n return text === undefined ? null : yield* decodeRecord(\"get\", text);\n },\n );\n\n const list: ScheduleStore[\"Service\"][\"list\"] = Effect.fn(\"MemoryScheduleStore.list\")(\n function* (request) {\n const decodedRequest = yield* decodeInput(\"list\", SchedulePageRequest, request);\n const records: Array<ScheduleRecord> = [];\n\n for (const text of (yield* Ref.get(state)).records.values()) {\n const record = yield* decodeRecord(\"list\", text);\n\n if (\n sameOwner(record, decodedRequest.owner) &&\n (decodedRequest.after === undefined ||\n compareScheduleNames(record.scheduleId, decodedRequest.after) > 0)\n ) {\n records.push(record);\n }\n }\n records.sort((left, right) => compareScheduleNames(left.scheduleId, right.scheduleId));\n const hasNext = records.length > decodedRequest.limit;\n const items = records.slice(0, decodedRequest.limit);\n\n return {\n items,\n next: hasNext ? (items.at(-1)?.scheduleId ?? null) : null,\n };\n },\n );\n\n const change: ScheduleStore[\"Service\"][\"change\"] = Effect.fn(\"MemoryScheduleStore.change\")(\n (key, command, ownerLimit = defaultSchedulingLimits.maxSchedulesPerOwner) =>\n Effect.gen(function* () {\n const decodedKey = yield* decodeInput(\"change\", ScheduleKey, key);\n const decodedCommand = yield* decodeInput(\"change\", ScheduleChange, command);\n\n yield* failpoint.hit(`schedule:${decodedCommand._tag.toLowerCase()}:before`);\n\n const decision = yield* Effect.uninterruptible(\n Ref.modify(\n state,\n (\n current,\n ): readonly [\n Result.Result<\n ScheduleRecord,\n ScheduleConflict | ScheduleStorageError | ScheduleNotFound | ScheduleCapacityError\n >,\n MemoryScheduleState,\n ] => {\n const storageKey = scheduleKeyString(decodedKey);\n const text = current.records.get(storageKey);\n\n if (text === undefined) {\n return [Result.fail(ScheduleNotFound.make({ key: decodedKey })), current];\n }\n\n const decoded = Result.try({\n try: () => Schema.decodeSync(Schema.fromJsonString(ScheduleRecord))(text),\n catch: () => storageError(\"change\", \"corrupt\"),\n });\n\n if (Result.isFailure(decoded)) {\n return [Result.fail(decoded.failure), current];\n }\n const applied = applyScheduleChange(decoded.success, decodedCommand);\n\n if (Result.isFailure(applied)) {\n return [Result.fail(applied.failure), current];\n }\n if (applied.success === decoded.success) {\n return [Result.succeed(decoded.success), current];\n }\n if (!scheduleUsesCapacity(decoded.success) && scheduleUsesCapacity(applied.success)) {\n let count = 0;\n\n for (const text of current.records.values()) {\n const candidate = Schema.decodeResult(Schema.fromJsonString(ScheduleRecord))(\n text,\n );\n\n if (Result.isFailure(candidate))\n return [Result.fail(storageError(\"change\", \"corrupt\")), current];\n if (\n sameOwner(candidate.success, decodedKey.owner) &&\n scheduleUsesCapacity(candidate.success)\n )\n count += 1;\n }\n if (count >= ownerLimit)\n return [Result.fail(ScheduleCapacityError.make({ limit: ownerLimit })), current];\n }\n\n const encoded = Result.try({\n try: () =>\n Schema.encodeSync(Schema.fromJsonString(ScheduleRecord))(applied.success),\n catch: () => storageError(\"change\", \"corrupt\"),\n });\n\n if (Result.isFailure(encoded)) {\n return [Result.fail(encoded.failure), current];\n }\n const records = new Map(current.records);\n\n records.set(storageKey, encoded.success);\n const next = { records };\n\n return [Result.succeed(applied.success), next];\n },\n ),\n );\n\n const changed = yield* Effect.fromResult(decision);\n\n yield* failpoint.hit(`schedule:${decodedCommand._tag.toLowerCase()}:after`);\n\n return yield* decodeRecord(\"change\", yield* encodeRecord(\"change\", changed));\n }),\n );\n\n const due: ScheduleStore[\"Service\"][\"due\"] = Effect.fn(\"MemoryScheduleStore.due\")(\n function* (nowMillis, limit, owner, after) {\n const decodedOwner =\n owner === undefined ? undefined : yield* decodeInput(\"due\", ScheduleOwner, owner);\n\n const cursor =\n after === undefined ? undefined : yield* decodeInput(\"due\", ScheduleDueCursor, after);\n\n const records: Array<ScheduleDueCursor> = [];\n\n for (const text of (yield* Ref.get(state)).records.values()) {\n const record = yield* decodeRecord(\"due\", text);\n const deadline = scheduleDeadline(record);\n\n if (\n deadline !== null &&\n deadline <= nowMillis &&\n (decodedOwner === undefined || sameOwner(record, decodedOwner)) &&\n (cursor === undefined ||\n deadline > cursor.deadlineAtMillis ||\n (deadline === cursor.deadlineAtMillis && compareScheduleKeys(record, cursor) > 0))\n ) {\n records.push({ ...scheduleKeyOf(record), deadlineAtMillis: deadline });\n }\n }\n records.sort((left, right) => {\n const byDeadline = left.deadlineAtMillis - right.deadlineAtMillis;\n\n return byDeadline !== 0 ? byDeadline : compareScheduleKeys(left, right);\n });\n\n return records.slice(0, limit);\n },\n );\n\n const nextDeadline: ScheduleStore[\"Service\"][\"nextDeadline\"] = Effect.fn(\n \"MemoryScheduleStore.nextDeadline\",\n )(function* (owner) {\n const decodedOwner =\n owner === undefined ? undefined : yield* decodeInput(\"nextDeadline\", ScheduleOwner, owner);\n\n let earliest: number | null = null;\n\n for (const text of (yield* Ref.get(state)).records.values()) {\n const record = yield* decodeRecord(\"nextDeadline\", text);\n\n if (decodedOwner !== undefined && !sameOwner(record, decodedOwner)) continue;\n const deadline = scheduleDeadline(record);\n\n if (deadline !== null && (earliest === null || deadline < earliest)) earliest = deadline;\n }\n\n return earliest;\n });\n\n return ScheduleStore.of({ insert, get, list, change, due, nextDeadline });\n});\n\nexport const memoryScheduleStoreLayer = (): Layer.Layer<ScheduleStore> =>\n Layer.effect(ScheduleStore, makeScheduleStore);\n\nexport const MemoryScheduleStoreLive: Layer.Layer<ScheduleStore> = memoryScheduleStoreLayer();\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
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 { MessageAdmission } from "@effect-agent/core/Messaging";
4
+ import { InputMessage } from "@effect-agent/core/Messaging";
5
5
  import { PersistedJson, ProducerEpoch, WorkerAdmission } from "@effect-agent/thread/Records";
6
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";
7
7
  //#region src/MemorySubmissionLedger.ts
@@ -85,7 +85,7 @@ const toSnapshot = (row) => SubmissionSnapshot.make({
85
85
  ...row.admissionGroup === void 0 ? {} : { admissionGroup: row.admissionGroup },
86
86
  ...row.admissionFence === void 0 ? {} : { admissionFence: row.admissionFence },
87
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) },
88
+ ...row.messageAdmissionJson === void 0 ? {} : { messageAdmission: Schema.decodeSync(Schema.fromJsonString(InputMessage))(row.messageAdmissionJson) },
89
89
  ...row.settledOutcome === void 0 ? {} : { settledOutcome: row.settledOutcome },
90
90
  ...row.readyAtMillis === void 0 ? {} : { readyAt: utc(row.readyAtMillis) },
91
91
  ...row.parentLinkage === void 0 ? {} : { parentLinkage: row.parentLinkage }
@@ -176,7 +176,7 @@ const makeSubmissionLedger = (options = {}) => Effect.gen(function* () {
176
176
  const admit = Effect.fn("MemorySubmissionLedger.admit")((unvalidated) => Effect.gen(function* () {
177
177
  const request = yield* validate(AdmissionRequest, "admit", unvalidated);
178
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")));
179
+ const messageAdmissionJson = request.messageAdmission === void 0 ? void 0 : yield* Schema.encodeEffect(Schema.fromJsonString(InputMessage))(request.messageAdmission).pipe(Effect.mapError(() => ledgerError("admit", "Invalid message admission metadata")));
180
180
  const nowMillis = yield* Clock.currentTimeMillis;
181
181
  const services = yield* Effect.context();
182
182
  const decision = yield* Ref.modify(state, (current) => {
@@ -185,7 +185,7 @@ const makeSubmissionLedger = (options = {}) => Effect.gen(function* () {
185
185
  if (existingId !== void 0) {
186
186
  const existing = current.submissions.get(existingId);
187
187
  if (existing === void 0) return [failure(ledgerError("admit", "Admission index references a missing Submission")), current];
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({
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(InputMessage))(existing.row.messageAdmissionJson === void 0 ? void 0 : Schema.decodeSync(Schema.fromJsonString(InputMessage))(existing.row.messageAdmissionJson), request.messageAdmission) || !Schema.toEquivalence(Schema.optional(Schema.Json))(existing.row.admissionFence, request.admissionFence)) return [failure(AdmissionConflict.make({
189
189
  threadId: request.threadId,
190
190
  principal: request.principal,
191
191
  idempotencyKey: request.idempotencyKey,