@effect-agent/platform-cloudflare 0.1.0-beta.6 → 0.1.0-beta.60

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.
Files changed (95) hide show
  1. package/dist/Alarm.d.mts +168 -0
  2. package/dist/Alarm.mjs +415 -0
  3. package/dist/Alarm.mjs.map +1 -0
  4. package/dist/BrowserRestCapture.d.mts +35 -0
  5. package/dist/BrowserRestCapture.mjs +238 -0
  6. package/dist/BrowserRestCapture.mjs.map +1 -0
  7. package/dist/BrowserRestCrawl.d.mts +17 -0
  8. package/dist/BrowserRestCrawl.mjs +244 -0
  9. package/dist/BrowserRestCrawl.mjs.map +1 -0
  10. package/dist/CloudflareBindings.d.mts +105 -0
  11. package/dist/CloudflareBindings.mjs +98 -0
  12. package/dist/CloudflareBindings.mjs.map +1 -0
  13. package/dist/CloudflareBrowser-Bj22nNUT.mjs +466 -0
  14. package/dist/CloudflareBrowser-Bj22nNUT.mjs.map +1 -0
  15. package/dist/CloudflareBrowser-DJq53niJ.d.mts +80 -0
  16. package/dist/CloudflareBrowser.d.mts +2 -0
  17. package/dist/CloudflareBrowser.mjs +2 -0
  18. package/dist/CloudflareCodeMode.d.mts +44 -0
  19. package/dist/CloudflareCodeMode.mjs +611 -0
  20. package/dist/CloudflareCodeMode.mjs.map +1 -0
  21. package/dist/CloudflareConfig-f3CqTel1.d.mts +101 -0
  22. package/dist/CloudflareConfig.d.mts +2 -0
  23. package/dist/CloudflareConfig.mjs +122 -0
  24. package/dist/CloudflareConfig.mjs.map +1 -0
  25. package/dist/CloudflareMemory.d.mts +140 -0
  26. package/dist/CloudflareMemory.mjs +168 -0
  27. package/dist/CloudflareMemory.mjs.map +1 -0
  28. package/dist/CloudflareScheduling.d.mts +52 -0
  29. package/dist/CloudflareScheduling.mjs +389 -0
  30. package/dist/CloudflareScheduling.mjs.map +1 -0
  31. package/dist/CloudflareSubscriptions.d.mts +87 -0
  32. package/dist/CloudflareSubscriptions.mjs +524 -0
  33. package/dist/CloudflareSubscriptions.mjs.map +1 -0
  34. package/dist/CloudflareThreadClient.d.mts +1214 -0
  35. package/dist/CloudflareThreadClient.mjs +386 -0
  36. package/dist/CloudflareThreadClient.mjs.map +1 -0
  37. package/dist/InteractiveBrowser.d.mts +144 -0
  38. package/dist/InteractiveBrowser.mjs +1090 -0
  39. package/dist/InteractiveBrowser.mjs.map +1 -0
  40. package/dist/ProtectedBrowser.d.mts +65 -0
  41. package/dist/ProtectedBrowser.mjs +859 -0
  42. package/dist/ProtectedBrowser.mjs.map +1 -0
  43. package/dist/ThreadObject-CvnEnVQH.d.mts +772 -0
  44. package/dist/ThreadObject-s5w3V_co.mjs +675 -0
  45. package/dist/ThreadObject-s5w3V_co.mjs.map +1 -0
  46. package/dist/ThreadObject.d.mts +2 -0
  47. package/dist/ThreadObject.mjs +3 -0
  48. package/dist/WakeScheduler.d.mts +23 -0
  49. package/dist/WakeScheduler.mjs +60 -0
  50. package/dist/WakeScheduler.mjs.map +1 -0
  51. package/dist/boundary-BguazVkh.mjs +42 -0
  52. package/dist/boundary-BguazVkh.mjs.map +1 -0
  53. package/dist/browser-session-lifecycle-CUbVfEgP.mjs +84 -0
  54. package/dist/browser-session-lifecycle-CUbVfEgP.mjs.map +1 -0
  55. package/dist/browser-session-lifecycle-DJpqLXy_.d.mts +21 -0
  56. package/dist/index.d.mts +12 -1543
  57. package/dist/index.mjs +12 -1636
  58. package/dist/prepared-admission-G7N4DDqS.mjs +73 -0
  59. package/dist/prepared-admission-G7N4DDqS.mjs.map +1 -0
  60. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  61. package/package.json +1 -53
  62. package/src/Alarm.ts +862 -0
  63. package/src/BrowserRestCapture.ts +477 -0
  64. package/src/BrowserRestCrawl.ts +540 -0
  65. package/src/CloudflareBindings.ts +171 -0
  66. package/src/CloudflareBrowser.ts +15 -0
  67. package/src/{code-mode-executor.ts → CloudflareCodeMode.ts} +367 -204
  68. package/src/{config.ts → CloudflareConfig.ts} +9 -8
  69. package/src/CloudflareMemory.ts +359 -0
  70. package/src/CloudflareScheduling.ts +733 -0
  71. package/src/CloudflareSubscriptions.ts +1045 -0
  72. package/src/CloudflareThreadClient.ts +807 -0
  73. package/src/InteractiveBrowser.ts +2357 -0
  74. package/src/ProtectedBrowser.ts +2 -0
  75. package/src/{conversation-object.ts → ThreadObject.ts} +423 -239
  76. package/src/{wake-scheduler.ts → WakeScheduler.ts} +23 -23
  77. package/src/index.ts +11 -23
  78. package/src/internal/boundary.ts +55 -0
  79. package/src/internal/browser-quick-action.ts +818 -0
  80. package/src/internal/browser-session-lifecycle.ts +160 -0
  81. package/src/internal/layers.ts +615 -0
  82. package/src/internal/message-delivery.ts +90 -0
  83. package/src/internal/prepared-admission.ts +116 -0
  84. package/src/internal/progress-wait.ts +121 -0
  85. package/src/internal/transport.ts +42 -0
  86. package/src/protected-browser/binding.ts +187 -0
  87. package/src/protected-browser/inspect-frame.ts +125 -0
  88. package/src/protected-browser/native.ts +429 -0
  89. package/src/protected-browser/policy.ts +719 -0
  90. package/dist/index.mjs.map +0 -1
  91. package/src/alarm.ts +0 -334
  92. package/src/bindings.ts +0 -145
  93. package/src/client.ts +0 -646
  94. package/src/layers.ts +0 -376
  95. package/src/transport.ts +0 -38
@@ -0,0 +1,168 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import { Principal } from "@effect-agent/thread/SubmissionLedger";
3
+ import { Clock, Context, Effect, Layer, Schema } from "effect";
4
+ import * as Memory from "@effect-agent/core/Memory";
5
+ import * as MemoryNamespace from "@effect-agent/core/MemoryNamespace";
6
+ import { MemoryNamespaceAddress } from "@effect-agent/core/MemoryNamespace";
7
+ import { MemoryRecallLimits } from "@effect-agent/core/MemoryReference";
8
+ import { MemoryAccess } from "@effect-agent/core/MemoryRevalidation";
9
+ import { MemoryDocument, MemoryMutationFailpoint, MemoryStorageError, MemoryWriter } from "@effect-agent/core/MemoryStore";
10
+ import "@effect-agent/core/SemanticMemoryIndex";
11
+ import "@effect-agent/core/SemanticMemoryRevalidation";
12
+ import { defaultDoMemoryStorageLimits, doMemoryStoreLayerWithFailpoints } from "@effect-agent/storage-cloudflare/DoMemoryStore";
13
+ import { MemoryOwnerIdentity, MemoryOwnerRequest, MemoryOwnerResponse, MemoryRpcError, MemoryRpcLimits, decodeMemoryWire, defaultMemoryRpcLimits, encodeMemoryWire, handleMemoryOwnerRequest } from "@effect-agent/storage-cloudflare/MemoryProtocol";
14
+ import { DurableObject, DurableObjectState } from "effect-cf";
15
+ //#region src/CloudflareMemory.ts
16
+ var CloudflareMemory_exports = /* @__PURE__ */ __exportAll({
17
+ CloudflareMemoryClient: () => CloudflareMemoryClient,
18
+ MemoryObject: () => MemoryObject,
19
+ MemoryObjectNamespace: () => MemoryObjectNamespace,
20
+ cloudflareMemoryWriterLayer: () => cloudflareMemoryWriterLayer,
21
+ memoryObjectName: () => memoryObjectName
22
+ });
23
+ var MemoryObjectNamespace = class extends Context.Service()("@effect-agent/platform-cloudflare/MemoryObjectNamespace") {};
24
+ /** Namespace version and identity are already canonicalized by MemoryNamespace. */
25
+ const memoryObjectName = (namespace) => namespace.address;
26
+ /**
27
+ * Effect-native, host-bound memory client. Recall revalidates the entire admitted lookup
28
+ * in one RPC and renders it locally. No retries or per-source splitting occur here.
29
+ * Interrupted callers stop waiting; the owner has its own deadline. A timed-out write
30
+ * may have committed: reconcile by sending the identical operation ID and command.
31
+ */
32
+ const makeMemoryClient = Effect.fn("CloudflareMemoryClient.make")(function* (access, principal, rpcLimits = defaultMemoryRpcLimits) {
33
+ const validated = yield* Schema.decodeUnknownEffect(MemoryRpcLimits)(rpcLimits).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
34
+ const bound = yield* Schema.decodeUnknownEffect(MemoryAccess.Wire)(access).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
35
+ principal = yield* Schema.decodeUnknownEffect(Principal)(principal).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
36
+ const { namespace } = yield* MemoryObjectNamespace;
37
+ const call = Effect.fn("CloudflareMemoryClient.call")(function* (request) {
38
+ const decoded = yield* Schema.decodeUnknownEffect(MemoryOwnerRequest)(request).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
39
+ const encoded = yield* encodeMemoryWire(MemoryOwnerRequest, decoded, validated.maxRequestBytes);
40
+ const raw = yield* Effect.tryPromise({
41
+ try: () => namespace.get(namespace.idFromName(memoryObjectName(bound.namespace))).memory(encoded),
42
+ catch: () => MemoryRpcError.make({ reason: "unavailable" })
43
+ });
44
+ const response = yield* decodeMemoryWire(MemoryOwnerResponse, raw, validated.maxResponseBytes);
45
+ if (response._tag === "Failed") return yield* response.failure;
46
+ if (!MemoryNamespace.equals(response.access.namespace, bound.namespace) || response.access.scope !== bound.scope) return yield* MemoryRpcError.make({ reason: "protocol" });
47
+ return response;
48
+ });
49
+ const withinDeadline = (effect, timeoutMillis) => effect.pipe(Effect.timeoutOrElse({
50
+ duration: timeoutMillis,
51
+ orElse: () => Effect.fail(MemoryRpcError.make({ reason: "timeout" }))
52
+ }));
53
+ const revalidate = Effect.fn("CloudflareMemoryClient.revalidate")(function* (lookup, limits) {
54
+ limits = yield* Schema.decodeUnknownEffect(MemoryRecallLimits)(limits).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
55
+ const timeoutMillis = Math.min(validated.timeoutMillis, limits.timeoutMillis);
56
+ return yield* Effect.gen(function* () {
57
+ const response = yield* call({
58
+ _tag: "Revalidate",
59
+ version: 1,
60
+ access: bound,
61
+ principal,
62
+ lookup,
63
+ limits,
64
+ deadlineMillis: (yield* Clock.currentTimeMillis) + timeoutMillis
65
+ });
66
+ if (response._tag !== "Lookup") return yield* MemoryRpcError.make({ reason: "protocol" });
67
+ return response.lookup;
68
+ }).pipe((effect) => withinDeadline(effect, timeoutMillis));
69
+ });
70
+ const change = Effect.fn("CloudflareMemoryClient.change")(function* (write) {
71
+ if (!MemoryNamespace.equals(write.key.namespace, bound.namespace)) return yield* MemoryRpcError.make({ reason: "denied" });
72
+ return yield* Effect.gen(function* () {
73
+ const response = yield* call({
74
+ _tag: "Change",
75
+ version: 1,
76
+ access: bound,
77
+ principal,
78
+ write,
79
+ deadlineMillis: (yield* Clock.currentTimeMillis) + validated.timeoutMillis
80
+ });
81
+ if (response._tag !== "Changed" || response.document.key.id !== write.key.id) return yield* MemoryRpcError.make({ reason: "protocol" });
82
+ return yield* MemoryDocument.restore(access.namespace, response.document);
83
+ }).pipe((effect) => withinDeadline(effect, validated.timeoutMillis));
84
+ });
85
+ const revalidateSemantic = Effect.fn("CloudflareMemoryClient.revalidateSemantic")(function* (found, profile, limits) {
86
+ return yield* Effect.gen(function* () {
87
+ const response = yield* call({
88
+ _tag: "RevalidateSemantic",
89
+ version: 1,
90
+ access: bound,
91
+ principal,
92
+ found,
93
+ profile,
94
+ limits,
95
+ deadlineMillis: (yield* Clock.currentTimeMillis) + validated.timeoutMillis
96
+ });
97
+ if (response._tag !== "Semantic") return yield* MemoryRpcError.make({ reason: "protocol" });
98
+ return response.result;
99
+ }).pipe((effect) => withinDeadline(effect, validated.timeoutMillis));
100
+ });
101
+ return {
102
+ recall: Effect.fn("CloudflareMemoryClient.recall")(function* (lookup, limits, estimateTokens) {
103
+ return yield* Memory.recall([{
104
+ id: "memory",
105
+ essential: true,
106
+ read: revalidate(lookup, limits)
107
+ }], limits, estimateTokens);
108
+ }),
109
+ revalidate,
110
+ revalidateSemantic,
111
+ change
112
+ };
113
+ });
114
+ const CloudflareMemoryClient = {
115
+ /** Bind access and principal using the MemoryObjectNamespace supplied by the application. */
116
+ make: makeMemoryClient,
117
+ /** Use a resolved Worker or Durable Object binding without manual service provisioning. */
118
+ fromBinding: Effect.fn("CloudflareMemoryClient.fromBinding")(function* (binding, options) {
119
+ return yield* makeMemoryClient(options.access, options.principal, options.rpcLimits).pipe(Effect.provideService(MemoryObjectNamespace, { namespace: binding }));
120
+ })
121
+ };
122
+ /**
123
+ * Optional activity-processor destination. Keeps domain write errors intact; transport,
124
+ * authorization and deadline failures become the existing MemoryStorageError contract.
125
+ * Receipts remain authoritative, including after caller interruption or lost replies.
126
+ */
127
+ const cloudflareMemoryWriterLayer = (access, principal, limits = defaultMemoryRpcLimits) => Layer.effect(MemoryWriter, Effect.gen(function* () {
128
+ const client = yield* CloudflareMemoryClient.make(access, principal, limits);
129
+ return MemoryWriter.fromAdapter({ change: (write) => client.change(write).pipe(Effect.catchTag("MemoryRpcError", (error) => Effect.fail(MemoryStorageError.make({
130
+ operation: `memory RPC ${error.reason}`,
131
+ reason: error.reason === "unavailable" || error.reason === "timeout" ? "unavailable" : "invalid-input"
132
+ }))), Effect.catchTag([
133
+ "MemoryRecallError",
134
+ "MemoryIndexError",
135
+ "SemanticMemoryError"
136
+ ], () => Effect.fail(MemoryStorageError.make({
137
+ operation: "memory RPC response",
138
+ reason: "corrupt"
139
+ })))) });
140
+ }));
141
+ /**
142
+ * Dedicated SQLite owner, independent of Thread lifetimes. The host binds authorization
143
+ * after restoring its namespace definition from MemoryOwnerIdentity. Do not retain
144
+ * cleanup-scoped resources in the host Layer; it lives for the DO incarnation.
145
+ */
146
+ const makeMemoryObject = (host, options = {}) => {
147
+ const identity = Layer.effect(MemoryOwnerIdentity, Effect.gen(function* () {
148
+ const state = yield* DurableObjectState.DurableObjectState;
149
+ const address = yield* Schema.decodeUnknownEffect(MemoryNamespaceAddress)(state.raw.id.name).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "denied" })));
150
+ return { namespace: MemoryNamespace.Any.make({ address }) };
151
+ }));
152
+ const store = Layer.unwrap(Effect.map(DurableObjectState.DurableObjectState, (state) => doMemoryStoreLayerWithFailpoints(state.raw.storage, options.storageLimits ?? defaultDoMemoryStorageLimits))).pipe(Layer.provide(options.failpoints ?? MemoryMutationFailpoint.layer));
153
+ const application = Layer.merge(store, host).pipe(Layer.provideMerge(identity));
154
+ const runtime = Layer.effectContext(Effect.gen(function* () {
155
+ const state = yield* DurableObjectState.DurableObjectState;
156
+ const scope = yield* Effect.scope;
157
+ yield* Schema.decodeUnknownEffect(MemoryRpcLimits)(options.rpcLimits ?? defaultMemoryRpcLimits).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
158
+ return yield* state.blockConcurrencyWhile(Layer.buildWithScope(application, scope));
159
+ }));
160
+ return DurableObject.make(runtime, { rpc: { memory: (encoded) => handleMemoryOwnerRequest(encoded, options.rpcLimits) } });
161
+ };
162
+ const MemoryObject = {
163
+ /** Build the SQLite Durable Object class with the application's owner authorization Layer. */
164
+ make: makeMemoryObject };
165
+ //#endregion
166
+ export { CloudflareMemoryClient, MemoryObject, MemoryObjectNamespace, cloudflareMemoryWriterLayer, memoryObjectName, CloudflareMemory_exports as t };
167
+
168
+ //# sourceMappingURL=CloudflareMemory.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CloudflareMemory.mjs","names":["EffectCfDurableObject"],"sources":["../src/CloudflareMemory.ts"],"sourcesContent":["import * as Memory from \"@effect-agent/core/Memory\";\nimport * as MemoryNamespace from \"@effect-agent/core/MemoryNamespace\";\nimport { MemoryNamespaceAddress } from \"@effect-agent/core/MemoryNamespace\";\nimport { type MemoryLookup, MemoryRecallLimits } from \"@effect-agent/core/MemoryReference\";\nimport { MemoryAccess } from \"@effect-agent/core/MemoryRevalidation\";\nimport {\n type MemoryReader,\n type MemoryWrite,\n MemoryDocument,\n MemoryMutationFailpoint,\n MemoryStorageError,\n MemoryWriter,\n} from \"@effect-agent/core/MemoryStore\";\nimport {\n type MemoryIndexSearch,\n type SemanticMemoryProfile,\n} from \"@effect-agent/core/SemanticMemoryIndex\";\nimport { type SemanticCandidateLimits } from \"@effect-agent/core/SemanticMemoryRevalidation\";\nimport {\n type DoMemoryStorageLimits,\n defaultDoMemoryStorageLimits,\n doMemoryStoreLayerWithFailpoints,\n} from \"@effect-agent/storage-cloudflare/DoMemoryStore\";\nimport {\n type MemoryOwnerAuthorizer,\n decodeMemoryWire,\n defaultMemoryRpcLimits,\n encodeMemoryWire,\n handleMemoryOwnerRequest,\n MemoryOwnerIdentity,\n MemoryOwnerRequest,\n MemoryOwnerResponse,\n MemoryRpcError,\n MemoryRpcLimits,\n type MemoryOwnerFailure,\n} from \"@effect-agent/storage-cloudflare/MemoryProtocol\";\nimport { Principal } from \"@effect-agent/thread/SubmissionLedger\";\nimport { Clock, Context, Effect, Layer, Schema } from \"effect\";\nimport {\n DurableObject as EffectCfDurableObject,\n DurableObjectState,\n type WorkerEnvironment,\n} from \"effect-cf\";\n\nexport interface MemoryObjectRpc extends Rpc.DurableObjectBranded {\n memory(encoded: string): Promise<string>;\n}\n\nexport class MemoryObjectNamespace extends Context.Service<\n MemoryObjectNamespace,\n {\n readonly namespace: DurableObjectNamespace<MemoryObjectRpc>;\n }\n>()(\"@effect-agent/platform-cloudflare/MemoryObjectNamespace\") {}\n\n/** Namespace version and identity are already canonicalized by MemoryNamespace. */\nexport const memoryObjectName = (namespace: MemoryNamespace.Any): string => namespace.address;\n\n/**\n * Effect-native, host-bound memory client. Recall revalidates the entire admitted lookup\n * in one RPC and renders it locally. No retries or per-source splitting occur here.\n * Interrupted callers stop waiting; the owner has its own deadline. A timed-out write\n * may have committed: reconcile by sending the identical operation ID and command.\n */\nconst makeMemoryClient = Effect.fn(\"CloudflareMemoryClient.make\")(function* <\n Namespace extends MemoryNamespace.Any,\n>(\n access: MemoryAccess<Namespace>,\n principal: Principal,\n rpcLimits: MemoryRpcLimits = defaultMemoryRpcLimits,\n) {\n const validated = yield* Schema.decodeUnknownEffect(MemoryRpcLimits)(rpcLimits).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n const bound = yield* Schema.decodeUnknownEffect(MemoryAccess.Wire)(access).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n principal = yield* Schema.decodeUnknownEffect(Principal)(principal).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n const { namespace } = yield* MemoryObjectNamespace;\n\n const call = Effect.fn(\"CloudflareMemoryClient.call\")(function* (request: MemoryOwnerRequest) {\n const decoded = yield* Schema.decodeUnknownEffect(MemoryOwnerRequest)(request).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n const encoded = yield* encodeMemoryWire(MemoryOwnerRequest, decoded, validated.maxRequestBytes);\n\n const raw = yield* Effect.tryPromise({\n try: () =>\n namespace.get(namespace.idFromName(memoryObjectName(bound.namespace))).memory(encoded),\n catch: () => MemoryRpcError.make({ reason: \"unavailable\" }),\n });\n\n const response = yield* decodeMemoryWire(MemoryOwnerResponse, raw, validated.maxResponseBytes);\n\n if (response._tag === \"Failed\") return yield* response.failure;\n if (\n !MemoryNamespace.equals(response.access.namespace, bound.namespace) ||\n response.access.scope !== bound.scope\n )\n return yield* MemoryRpcError.make({ reason: \"protocol\" });\n\n return response;\n });\n\n const withinDeadline = <A, E, R>(effect: Effect.Effect<A, E, R>, timeoutMillis: number) =>\n effect.pipe(\n Effect.timeoutOrElse({\n duration: timeoutMillis,\n orElse: () => Effect.fail(MemoryRpcError.make({ reason: \"timeout\" })),\n }),\n );\n\n const revalidate = Effect.fn(\"CloudflareMemoryClient.revalidate\")(function* (\n lookup: MemoryLookup,\n limits: MemoryRecallLimits,\n ) {\n limits = yield* Schema.decodeUnknownEffect(MemoryRecallLimits)(limits).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n const timeoutMillis = Math.min(validated.timeoutMillis, limits.timeoutMillis);\n\n return yield* Effect.gen(function* () {\n const response = yield* call({\n _tag: \"Revalidate\",\n version: 1,\n access: bound,\n principal,\n lookup,\n limits,\n deadlineMillis: (yield* Clock.currentTimeMillis) + timeoutMillis,\n });\n\n if (response._tag !== \"Lookup\") return yield* MemoryRpcError.make({ reason: \"protocol\" });\n\n return response.lookup;\n }).pipe((effect) => withinDeadline(effect, timeoutMillis));\n });\n\n const change = Effect.fn(\"CloudflareMemoryClient.change\")(function* (\n write: MemoryWrite<Namespace>,\n ) {\n if (!MemoryNamespace.equals(write.key.namespace, bound.namespace))\n return yield* MemoryRpcError.make({ reason: \"denied\" });\n\n return yield* Effect.gen(function* () {\n const response = yield* call({\n _tag: \"Change\",\n version: 1,\n access: bound,\n principal,\n write,\n deadlineMillis: (yield* Clock.currentTimeMillis) + validated.timeoutMillis,\n });\n\n if (response._tag !== \"Changed\" || response.document.key.id !== write.key.id)\n return yield* MemoryRpcError.make({ reason: \"protocol\" });\n\n return yield* MemoryDocument.restore(access.namespace, response.document);\n }).pipe((effect) => withinDeadline(effect, validated.timeoutMillis));\n });\n\n const revalidateSemantic = Effect.fn(\"CloudflareMemoryClient.revalidateSemantic\")(function* (\n found: MemoryIndexSearch<Namespace>,\n profile: SemanticMemoryProfile,\n limits: SemanticCandidateLimits,\n ) {\n return yield* Effect.gen(function* () {\n const response = yield* call({\n _tag: \"RevalidateSemantic\",\n version: 1,\n access: bound,\n principal,\n found,\n profile,\n limits,\n deadlineMillis: (yield* Clock.currentTimeMillis) + validated.timeoutMillis,\n });\n\n if (response._tag !== \"Semantic\") return yield* MemoryRpcError.make({ reason: \"protocol\" });\n\n return response.result;\n }).pipe((effect) => withinDeadline(effect, validated.timeoutMillis));\n });\n\n /**\n * Revalidate in one owner RPC, then render whole passages within the caller's budget.\n * The bound source is essential: unavailable/stale results and matches that cannot fit\n * fail instead of silently producing empty context. No-match remains successful.\n * The single outcome has sourceId \"memory\". No embedding or candidate search is performed.\n * Use revalidate with Memory.recall for multiple readers sharing one output budget.\n */\n const recall = Effect.fn(\"CloudflareMemoryClient.recall\")(function* (\n lookup: MemoryLookup,\n limits: MemoryRecallLimits,\n estimateTokens?: (text: string) => number,\n ) {\n return yield* Memory.recall(\n [{ id: \"memory\", essential: true, read: revalidate(lookup, limits) }],\n limits,\n estimateTokens,\n );\n });\n\n return { recall, revalidate, revalidateSemantic, change };\n});\n\nexport const CloudflareMemoryClient = {\n /** Bind access and principal using the MemoryObjectNamespace supplied by the application. */\n make: makeMemoryClient,\n /** Use a resolved Worker or Durable Object binding without manual service provisioning. */\n fromBinding: Effect.fn(\"CloudflareMemoryClient.fromBinding\")(function* <\n Namespace extends MemoryNamespace.Any,\n >(\n binding: DurableObjectNamespace<MemoryObjectRpc>,\n options: {\n readonly access: MemoryAccess<Namespace>;\n readonly principal: Principal;\n readonly rpcLimits?: MemoryRpcLimits;\n },\n ) {\n return yield* makeMemoryClient(options.access, options.principal, options.rpcLimits).pipe(\n Effect.provideService(MemoryObjectNamespace, { namespace: binding }),\n );\n }),\n};\n\n/**\n * Optional activity-processor destination. Keeps domain write errors intact; transport,\n * authorization and deadline failures become the existing MemoryStorageError contract.\n * Receipts remain authoritative, including after caller interruption or lost replies.\n */\nexport const cloudflareMemoryWriterLayer = (\n access: MemoryAccess,\n principal: Principal,\n limits: MemoryRpcLimits = defaultMemoryRpcLimits,\n) =>\n Layer.effect(\n MemoryWriter,\n Effect.gen(function* () {\n const client = yield* CloudflareMemoryClient.make(access, principal, limits);\n\n return MemoryWriter.fromAdapter({\n change: (write) =>\n client.change(write).pipe(\n Effect.catchTag(\"MemoryRpcError\", (error) =>\n Effect.fail(\n MemoryStorageError.make({\n operation: `memory RPC ${error.reason}`,\n reason:\n error.reason === \"unavailable\" || error.reason === \"timeout\"\n ? \"unavailable\"\n : \"invalid-input\",\n }),\n ),\n ),\n Effect.catchTag([\"MemoryRecallError\", \"MemoryIndexError\", \"SemanticMemoryError\"], () =>\n Effect.fail(\n MemoryStorageError.make({ operation: \"memory RPC response\", reason: \"corrupt\" }),\n ),\n ),\n ),\n });\n }),\n );\n\ntype OwnerServices = MemoryReader | MemoryWriter | MemoryOwnerAuthorizer | MemoryOwnerIdentity;\n\nexport interface MemoryObjectInstance extends InstanceType<\n EffectCfDurableObject.DurableObjectClass<Record<never, never>, OwnerServices>\n> {\n memory(encoded: string): Promise<string>;\n}\n\nexport interface MemoryObjectClass {\n new (ctx: globalThis.DurableObjectState, env: Cloudflare.Env): MemoryObjectInstance;\n}\n\n/**\n * Dedicated SQLite owner, independent of Thread lifetimes. The host binds authorization\n * after restoring its namespace definition from MemoryOwnerIdentity. Do not retain\n * cleanup-scoped resources in the host Layer; it lives for the DO incarnation.\n */\nconst makeMemoryObject = <E>(\n host: Layer.Layer<\n MemoryOwnerAuthorizer,\n E,\n MemoryOwnerIdentity | DurableObjectState.DurableObjectState | WorkerEnvironment\n >,\n options: {\n readonly storageLimits?: DoMemoryStorageLimits;\n readonly rpcLimits?: MemoryRpcLimits;\n readonly failpoints?: Layer.Layer<\n MemoryMutationFailpoint,\n never,\n DurableObjectState.DurableObjectState\n >;\n } = {},\n): MemoryObjectClass => {\n const identity = Layer.effect(\n MemoryOwnerIdentity,\n Effect.gen(function* () {\n const state = yield* DurableObjectState.DurableObjectState;\n\n const address = yield* Schema.decodeUnknownEffect(MemoryNamespaceAddress)(\n state.raw.id.name,\n ).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: \"denied\" })));\n\n return { namespace: MemoryNamespace.Any.make({ address }) };\n }),\n );\n\n const store = Layer.unwrap(\n Effect.map(DurableObjectState.DurableObjectState, (state) =>\n doMemoryStoreLayerWithFailpoints(\n state.raw.storage,\n options.storageLimits ?? defaultDoMemoryStorageLimits,\n ),\n ),\n ).pipe(Layer.provide(options.failpoints ?? MemoryMutationFailpoint.layer));\n\n const application = Layer.merge(store, host).pipe(Layer.provideMerge(identity));\n\n const runtime: Layer.Layer<\n OwnerServices,\n E | MemoryOwnerFailure,\n DurableObjectState.DurableObjectState | WorkerEnvironment\n > = Layer.effectContext(\n Effect.gen(function* () {\n const state = yield* DurableObjectState.DurableObjectState;\n const scope = yield* Effect.scope;\n\n yield* Schema.decodeUnknownEffect(MemoryRpcLimits)(\n options.rpcLimits ?? defaultMemoryRpcLimits,\n ).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })));\n\n return yield* state.blockConcurrencyWhile(Layer.buildWithScope(application, scope));\n }),\n );\n\n const rpc = { memory: (encoded: string) => handleMemoryOwnerRequest(encoded, options.rpcLimits) };\n\n return EffectCfDurableObject.make<\n OwnerServices,\n E | MemoryOwnerFailure,\n never,\n never,\n typeof rpc\n >(runtime, { rpc });\n};\n\nexport const MemoryObject = {\n /** Build the SQLite Durable Object class with the application's owner authorization Layer. */\n make: makeMemoryObject,\n};\n"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { ThreadObjectNamespace } from "./CloudflareBindings.mjs";
2
+ import { Context, Effect, Layer, Schema } from "effect";
3
+ import { DurableObject, DurableObjectAlarm, DurableObjectState as DurableObjectState$1, WorkerEnvironment } from "effect-cf";
4
+ import { DoScheduleAlarmControl } from "@effect-agent/storage-cloudflare/DoScheduleStore";
5
+ import { ScheduleAuthorizer, ScheduleFailpointError, ScheduleOwner, ScheduleStorageError, SchedulingLimits } from "@effect-agent/thread/Schedule";
6
+ import { ScheduleDriver, Scheduling } from "@effect-agent/thread/Scheduling";
7
+ declare namespace CloudflareScheduling_d_exports {
8
+ export { CloudflareSchedulingClient, ScheduleAlarmProtocolError, ScheduleOwnerIdentity, ScheduleOwnerNamespace, ScheduleOwnerObjectClass, ScheduleOwnerObjectInstance, ScheduleOwnerObjectRpc, ScheduleOwnerProtocolError, makeScheduleOwnerObjectClass, scheduleAlarmHandler };
9
+ }
10
+ declare const ScheduleAlarmProtocolError_base: Schema.Class<ScheduleAlarmProtocolError, Schema.TaggedStruct<"ScheduleAlarmProtocolError", {
11
+ readonly message: Schema.String;
12
+ }>, import("effect/Cause").YieldableError>;
13
+ declare class ScheduleAlarmProtocolError extends ScheduleAlarmProtocolError_base {}
14
+ declare const ScheduleOwnerProtocolError_base: Schema.Class<ScheduleOwnerProtocolError, Schema.TaggedStruct<"ScheduleOwnerProtocolError", {
15
+ readonly message: Schema.String;
16
+ }>, import("effect/Cause").YieldableError>;
17
+ declare class ScheduleOwnerProtocolError extends ScheduleOwnerProtocolError_base {}
18
+ interface ScheduleOwnerObjectRpc extends Rpc.DurableObjectBranded {
19
+ schedule(encoded: unknown): Promise<unknown>;
20
+ }
21
+ declare const ScheduleOwnerNamespace_base: Context.ServiceClass<ScheduleOwnerNamespace, "@effect-agent/platform-cloudflare/ScheduleOwnerNamespace", {
22
+ readonly namespace: DurableObjectNamespace<ScheduleOwnerObjectRpc>;
23
+ }>;
24
+ declare class ScheduleOwnerNamespace extends ScheduleOwnerNamespace_base {}
25
+ /** Provides the same authorized management service as NodeScheduling.layer. */
26
+ declare class CloudflareSchedulingClient {
27
+ static readonly layer: Layer.Layer<Scheduling, never, ScheduleOwnerNamespace>;
28
+ }
29
+ declare const ScheduleOwnerIdentity_base: Context.ServiceClass<ScheduleOwnerIdentity, "@effect-agent/platform-cloudflare/ScheduleOwnerIdentity", {
30
+ readonly owner: ScheduleOwner;
31
+ }>;
32
+ declare class ScheduleOwnerIdentity extends ScheduleOwnerIdentity_base {}
33
+ type ScheduleRuntimeServices = Scheduling | ScheduleDriver | DoScheduleAlarmControl | ScheduleOwnerIdentity | DurableObjectAlarm.DurableObjectAlarm;
34
+ /** @internal The complete native alarm operation, including its event deadline. */
35
+ declare const scheduleAlarmHandler: (limits: SchedulingLimits) => Effect.Effect<void, ScheduleAlarmProtocolError | ScheduleFailpointError | ScheduleStorageError | import("effect/Cause").TimeoutError | DurableObjectAlarm.DurableObjectAlarmError, DoScheduleAlarmControl | DurableObjectAlarm.DurableObjectAlarm | ScheduleDriver | ScheduleOwnerIdentity>;
36
+ interface ScheduleOwnerObjectInstance extends InstanceType<DurableObject.DurableObjectClass<Record<never, never>, ScheduleRuntimeServices>> {
37
+ schedule(encoded: unknown): Promise<unknown>;
38
+ alarm(alarmInfo?: AlarmInvocationInfo): Promise<void> | void;
39
+ }
40
+ interface ScheduleOwnerObjectClass {
41
+ new (ctx: DurableObjectState, env: Cloudflare.Env): ScheduleOwnerObjectInstance;
42
+ }
43
+ /**
44
+ * The host Layer supplies authorization and routing and is cached for the object incarnation.
45
+ * Cloudflare eviction does not guarantee its finalizers run. Do not acquire resources requiring
46
+ * cleanup in this Layer; acquire them inside scoped `manage` / `prepare` operations instead.
47
+ * Native services belong to effect-cf; the database and alarm runtime remain instance-owned.
48
+ */
49
+ declare const makeScheduleOwnerObjectClass: <E>(host: Layer.Layer<ScheduleAuthorizer | ThreadObjectNamespace, E, DurableObjectState$1.DurableObjectState | WorkerEnvironment | ScheduleOwnerIdentity>, limits?: SchedulingLimits) => ScheduleOwnerObjectClass;
50
+ //#endregion
51
+ export { CloudflareSchedulingClient, ScheduleAlarmProtocolError, ScheduleOwnerIdentity, ScheduleOwnerNamespace, ScheduleOwnerObjectClass, ScheduleOwnerObjectInstance, ScheduleOwnerObjectRpc, ScheduleOwnerProtocolError, makeScheduleOwnerObjectClass, scheduleAlarmHandler, CloudflareScheduling_d_exports as t };
52
+ //# sourceMappingURL=CloudflareScheduling.d.mts.map
@@ -0,0 +1,389 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import { CloudflareThreadClient } from "./CloudflareThreadClient.mjs";
3
+ import { n as cloudflareScheduledInputAdmissionLayer, t as cloudflarePreparedInputAdmissionLayer } from "./prepared-admission-G7N4DDqS.mjs";
4
+ import "@effect-agent/thread/DurableAgentRuntime";
5
+ import { AdmissionFence } from "@effect-agent/thread/SubmissionLedger";
6
+ import { Clock, Context, DateTime, Effect, Layer, Schema } from "effect";
7
+ import { AgentId } from "@effect-agent/core/Identifiers";
8
+ import { DefinitionDigests, PersistedJson } from "@effect-agent/thread/Records";
9
+ import { DurableObject, DurableObjectAlarm, DurableObjectState } from "effect-cf";
10
+ import { DoScheduleAlarmControl, DoScheduleTransaction, scheduleStoreLayer } from "@effect-agent/storage-cloudflare/DoScheduleStore";
11
+ import { ScheduleAuthorizationError, ScheduleCapacityError, ScheduleConflict, ScheduleDestination, ScheduleFailpointError, ScheduleId, ScheduleNotFound, ScheduleOwner, ScheduleScope, ScheduleSnapshot, ScheduleSnapshotPage, ScheduleStorageError, ScheduleTimingRequest, ScheduleValidationError, defaultSchedulingLimits } from "@effect-agent/thread/Schedule";
12
+ import { scheduleOwnerKey } from "@effect-agent/thread/ScheduleTransition";
13
+ import { ScheduleDriver, ScheduleWakeNoop, Scheduling } from "@effect-agent/thread/Scheduling";
14
+ import { BrowserCrypto } from "@effect/platform-browser";
15
+ import { SqliteClient } from "@effect/sql-sqlite-do";
16
+ //#region src/CloudflareScheduling.ts
17
+ var CloudflareScheduling_exports = /* @__PURE__ */ __exportAll({
18
+ CloudflareSchedulingClient: () => CloudflareSchedulingClient,
19
+ ScheduleAlarmProtocolError: () => ScheduleAlarmProtocolError,
20
+ ScheduleOwnerIdentity: () => ScheduleOwnerIdentity,
21
+ ScheduleOwnerNamespace: () => ScheduleOwnerNamespace,
22
+ ScheduleOwnerProtocolError: () => ScheduleOwnerProtocolError,
23
+ makeScheduleOwnerObjectClass: () => makeScheduleOwnerObjectClass,
24
+ scheduleAlarmHandler: () => scheduleAlarmHandler
25
+ });
26
+ const SCHEDULE_ALARM_TAG = "effect-agent/ScheduleOwnerWake";
27
+ const SCHEDULE_ALARM_ID = "driver";
28
+ const ScheduleAlarmPayload = Schema.Struct({
29
+ schemaVersion: Schema.Literal(1),
30
+ generation: Schema.Int.check(Schema.isGreaterThan(0))
31
+ });
32
+ var ScheduleAlarmProtocolError = class extends Schema.TaggedError()("ScheduleAlarmProtocolError", { message: Schema.String }) {};
33
+ const boundedProtocolMessage = (message) => message.length <= 4096 ? message : `${message.slice(0, 4093)}...`;
34
+ var ScheduleOwnerProtocolError = class extends Schema.TaggedError()("ScheduleOwnerProtocolError", { message: Schema.String.check(Schema.isMaxLength(4096)) }) {};
35
+ const ScheduleMutationRequestFields = {
36
+ schemaVersion: Schema.Literal(1),
37
+ agentId: AgentId,
38
+ input: PersistedJson,
39
+ scope: ScheduleScope,
40
+ scheduleId: ScheduleId,
41
+ timing: ScheduleTimingRequest,
42
+ destination: ScheduleDestination,
43
+ deliveryPrincipal: ScheduleScope.fields.principal,
44
+ definitions: DefinitionDigests,
45
+ admissionGroup: Schema.optionalKey(Schema.NonEmptyString.check(Schema.isMaxLength(256))),
46
+ admissionFence: Schema.optionalKey(AdmissionFence)
47
+ };
48
+ const ScheduleCreateRequest = Schema.TaggedStruct("Create", ScheduleMutationRequestFields);
49
+ const ScheduleUpdateRequest = Schema.TaggedStruct("Update", {
50
+ ...ScheduleMutationRequestFields,
51
+ expectedRevision: Schema.Int.check(Schema.isGreaterThan(0))
52
+ });
53
+ const ScheduleGetRequest = Schema.TaggedStruct("Get", {
54
+ schemaVersion: Schema.Literal(1),
55
+ scope: ScheduleScope,
56
+ scheduleId: ScheduleId
57
+ });
58
+ const ScheduleListRequest = Schema.TaggedStruct("List", {
59
+ schemaVersion: Schema.Literal(1),
60
+ scope: ScheduleScope,
61
+ after: Schema.optionalKey(ScheduleId),
62
+ limit: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(100)))
63
+ });
64
+ const ScheduleControlRequest = Schema.TaggedStruct("Control", {
65
+ schemaVersion: Schema.Literal(1),
66
+ operation: Schema.Literals([
67
+ "pause",
68
+ "resume",
69
+ "cancel"
70
+ ]),
71
+ scope: ScheduleScope,
72
+ scheduleId: ScheduleId,
73
+ expectedRevision: Schema.Int.check(Schema.isGreaterThan(0))
74
+ });
75
+ const ScheduleRecoverRequest = Schema.TaggedStruct("Recover", {
76
+ schemaVersion: Schema.Literal(1),
77
+ scope: ScheduleScope,
78
+ scheduleId: ScheduleId,
79
+ expectedRevision: Schema.Int.check(Schema.isGreaterThan(0)),
80
+ expectedGeneration: Schema.Natural
81
+ });
82
+ const ScheduleOwnerRequest = Schema.Union([
83
+ ScheduleRecoverRequest,
84
+ ScheduleCreateRequest,
85
+ ScheduleUpdateRequest,
86
+ ScheduleGetRequest,
87
+ ScheduleListRequest,
88
+ ScheduleControlRequest
89
+ ]);
90
+ const ScheduleOwnerFailure = Schema.Union([
91
+ ScheduleValidationError,
92
+ ScheduleAuthorizationError,
93
+ ScheduleConflict,
94
+ ScheduleNotFound,
95
+ ScheduleCapacityError,
96
+ ScheduleStorageError,
97
+ ScheduleFailpointError,
98
+ ScheduleOwnerProtocolError
99
+ ]);
100
+ const ScheduleOwnerResponse = Schema.Union([
101
+ Schema.TaggedStruct("Snapshot", { value: ScheduleSnapshot }),
102
+ Schema.TaggedStruct("Page", { value: ScheduleSnapshotPage }),
103
+ Schema.TaggedStruct("Failed", { failure: ScheduleOwnerFailure })
104
+ ]);
105
+ const decodeScheduleOwnerRequest = Schema.decodeUnknownEffect(ScheduleOwnerRequest);
106
+ const encodeScheduleOwnerRequest = Schema.encodeEffect(ScheduleOwnerRequest);
107
+ const decodeScheduleOwnerResponse = Schema.decodeUnknownEffect(ScheduleOwnerResponse);
108
+ const encodeScheduleOwnerResponse = Schema.encodeEffect(ScheduleOwnerResponse);
109
+ const scheduleProtocolFailure = (message) => ({
110
+ _tag: "Failed",
111
+ failure: ScheduleOwnerProtocolError.make({ message: boundedProtocolMessage(message) })
112
+ });
113
+ var ScheduleOwnerNamespace = class extends Context.Service()("@effect-agent/platform-cloudflare/ScheduleOwnerNamespace") {};
114
+ const passthroughAgent = (agentId) => ({ definition: {
115
+ id: agentId,
116
+ input: PersistedJson
117
+ } });
118
+ const requestOwner = (request) => request.scope.owner;
119
+ /** Provides the same authorized management service as NodeScheduling.layer. */
120
+ var CloudflareSchedulingClient = class {
121
+ static layer = Layer.effect(Scheduling, Effect.gen(function* () {
122
+ const { namespace } = yield* ScheduleOwnerNamespace;
123
+ const call = Effect.fn("CloudflareSchedulingClient.call")(function* (owner, request) {
124
+ const encoded = yield* encodeScheduleOwnerRequest(request).pipe(Effect.mapError(() => ScheduleStorageError.make({
125
+ operation: "Schedule Owner protocol",
126
+ reason: "corrupt"
127
+ })));
128
+ const raw = yield* Effect.tryPromise({
129
+ try: () => namespace.get(namespace.idFromName(scheduleOwnerKey(owner))).schedule(encoded),
130
+ catch: () => ScheduleStorageError.make({
131
+ operation: "call Schedule Owner",
132
+ reason: "unavailable"
133
+ })
134
+ });
135
+ const response = yield* decodeScheduleOwnerResponse(raw).pipe(Effect.mapError(() => ScheduleStorageError.make({
136
+ operation: "Schedule Owner protocol",
137
+ reason: "corrupt"
138
+ })));
139
+ if (response._tag !== "Failed") return response;
140
+ return yield* response.failure._tag === "ScheduleOwnerProtocolError" ? ScheduleStorageError.make({
141
+ operation: "Schedule Owner protocol",
142
+ reason: "corrupt"
143
+ }) : response.failure;
144
+ });
145
+ const encodeInput = Effect.fn("CloudflareSchedulingClient.encodeInput")(function* (agent, input) {
146
+ const encoded = yield* Schema.encodeEffect(agent.definition.input)(input).pipe(Effect.mapError(() => ScheduleValidationError.make({ message: "Unable to encode Agent input" })));
147
+ return yield* Schema.decodeUnknownEffect(PersistedJson)(encoded).pipe(Effect.mapError(() => ScheduleValidationError.make({ message: "Agent input does not satisfy the canonical persistence bounds" })));
148
+ });
149
+ const create = (agent, input, options) => Effect.gen(function* () {
150
+ const payload = yield* encodeInput(agent, input);
151
+ const response = yield* call(options.scope.owner, {
152
+ _tag: "Create",
153
+ schemaVersion: 1,
154
+ agentId: agent.definition.id,
155
+ input: payload,
156
+ ...options
157
+ });
158
+ return response._tag === "Snapshot" ? response.value : yield* ScheduleStorageError.make({
159
+ operation: "Schedule Owner protocol",
160
+ reason: "corrupt"
161
+ });
162
+ });
163
+ const update = (agent, input, options) => Effect.gen(function* () {
164
+ const payload = yield* encodeInput(agent, input);
165
+ const response = yield* call(options.scope.owner, {
166
+ _tag: "Update",
167
+ schemaVersion: 1,
168
+ agentId: agent.definition.id,
169
+ input: payload,
170
+ ...options
171
+ });
172
+ return response._tag === "Snapshot" ? response.value : yield* ScheduleStorageError.make({
173
+ operation: "Schedule Owner protocol",
174
+ reason: "corrupt"
175
+ });
176
+ });
177
+ const get = (scope, scheduleId) => Effect.gen(function* () {
178
+ const response = yield* call(scope.owner, {
179
+ _tag: "Get",
180
+ schemaVersion: 1,
181
+ scope,
182
+ scheduleId
183
+ });
184
+ return response._tag === "Snapshot" ? response.value : yield* ScheduleStorageError.make({
185
+ operation: "Schedule Owner protocol",
186
+ reason: "corrupt"
187
+ });
188
+ });
189
+ const list = (scope, options = {}) => Effect.gen(function* () {
190
+ const response = yield* call(scope.owner, {
191
+ _tag: "List",
192
+ schemaVersion: 1,
193
+ scope,
194
+ ...options.after === void 0 ? {} : { after: options.after },
195
+ ...options.limit === void 0 ? {} : { limit: options.limit }
196
+ });
197
+ return response._tag === "Page" ? response.value : yield* ScheduleStorageError.make({
198
+ operation: "Schedule Owner protocol",
199
+ reason: "corrupt"
200
+ });
201
+ });
202
+ const control = (operation, scope, scheduleId, expectedRevision) => Effect.gen(function* () {
203
+ const response = yield* call(scope.owner, {
204
+ _tag: "Control",
205
+ schemaVersion: 1,
206
+ operation,
207
+ scope,
208
+ scheduleId,
209
+ expectedRevision
210
+ });
211
+ return response._tag === "Snapshot" ? response.value : yield* ScheduleStorageError.make({
212
+ operation: "Schedule Owner protocol",
213
+ reason: "corrupt"
214
+ });
215
+ });
216
+ return Scheduling.of({
217
+ create,
218
+ update,
219
+ get,
220
+ list,
221
+ pause: (scope, id, revision) => control("pause", scope, id, revision),
222
+ resume: (scope, id, revision) => control("resume", scope, id, revision),
223
+ recover: (scope, scheduleId, expectedRevision, expectedGeneration) => Effect.gen(function* () {
224
+ const response = yield* call(scope.owner, {
225
+ _tag: "Recover",
226
+ schemaVersion: 1,
227
+ scope,
228
+ scheduleId,
229
+ expectedRevision,
230
+ expectedGeneration
231
+ });
232
+ return response._tag === "Snapshot" ? response.value : yield* ScheduleStorageError.make({
233
+ operation: "Schedule Owner protocol",
234
+ reason: "corrupt"
235
+ });
236
+ }),
237
+ cancel: (scope, id, revision) => control("cancel", scope, id, revision)
238
+ });
239
+ }));
240
+ };
241
+ var ScheduleOwnerIdentity = class extends Context.Service()("@effect-agent/platform-cloudflare/ScheduleOwnerIdentity") {};
242
+ const decodeOwnerName = Effect.fn("decodeScheduleOwnerName")(function* (name) {
243
+ if (name === null || name === void 0) return yield* ScheduleOwnerProtocolError.make({ message: "Schedule Owner objects require an idFromName identity" });
244
+ const tuple = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Tuple([Schema.String, Schema.String])))(name).pipe(Effect.mapError(() => ScheduleOwnerProtocolError.make({ message: "Schedule Owner object name is malformed" })));
245
+ return yield* Schema.decodeUnknownEffect(ScheduleOwner)({
246
+ tenantId: tuple[0],
247
+ ownerId: tuple[1]
248
+ }).pipe(Effect.mapError(() => ScheduleOwnerProtocolError.make({ message: "Schedule Owner object identity is invalid" })));
249
+ });
250
+ const alarmStorageError = (operation) => (error) => ScheduleStorageError.make({
251
+ operation,
252
+ reason: error._tag === "StorageOperationError" ? "unavailable" : "corrupt"
253
+ });
254
+ const transactionLayer = Layer.effect(DoScheduleTransaction, Effect.gen(function* () {
255
+ const alarms = yield* DurableObjectAlarm.DurableObjectAlarm;
256
+ return DoScheduleTransaction.of({ run: (body) => Effect.gen(function* () {
257
+ const nowMillis = yield* Clock.currentTimeMillis;
258
+ return yield* alarms.transaction((transaction) => body((replacement) => replacement.deadlineAtMillis === null ? transaction.cancelAlarm({
259
+ id: SCHEDULE_ALARM_ID,
260
+ tag: SCHEDULE_ALARM_TAG
261
+ }).pipe(Effect.mapError(alarmStorageError("cancel Schedule Owner alarm"))) : Effect.fromOption(DateTime.make(Math.max(replacement.deadlineAtMillis, nowMillis + 1))).pipe(Effect.mapError(() => ScheduleStorageError.make({
262
+ operation: "validate Schedule Owner alarm deadline",
263
+ reason: "corrupt"
264
+ })), Effect.flatMap((runAt) => transaction.scheduleAlarm({
265
+ id: SCHEDULE_ALARM_ID,
266
+ tag: SCHEDULE_ALARM_TAG,
267
+ runAt,
268
+ payload: {
269
+ schemaVersion: 1,
270
+ generation: replacement.generation
271
+ }
272
+ }).pipe(Effect.mapError(alarmStorageError("schedule Schedule Owner alarm"))))))).pipe(Effect.catchTag("StorageOperationError", () => ScheduleStorageError.make({
273
+ operation: "commit Schedule Owner transaction",
274
+ reason: "unavailable"
275
+ })));
276
+ }) });
277
+ }));
278
+ const ensureOwner = (expected, request) => {
279
+ const observed = requestOwner(request);
280
+ return observed.tenantId === expected.tenantId && observed.ownerId === expected.ownerId ? Effect.void : Effect.fail(ScheduleOwnerProtocolError.make({ message: "The request owner does not match the addressed Schedule Owner object" }));
281
+ };
282
+ const handleScheduleRequest = Effect.fn("ScheduleOwner.handleRequest")(function* (encoded) {
283
+ const decoded = yield* decodeScheduleOwnerRequest(encoded).pipe(Effect.result);
284
+ if (decoded._tag === "Failure") return yield* encodeScheduleOwnerResponse(scheduleProtocolFailure("The Schedule request could not be decoded")).pipe(Effect.orDie);
285
+ const request = decoded.success;
286
+ const { owner } = yield* ScheduleOwnerIdentity;
287
+ const scheduling = yield* Scheduling;
288
+ const response = yield* Effect.gen(function* () {
289
+ yield* ensureOwner(owner, request);
290
+ switch (request._tag) {
291
+ case "Create": return {
292
+ _tag: "Snapshot",
293
+ value: yield* scheduling.create(passthroughAgent(request.agentId), request.input, {
294
+ scope: request.scope,
295
+ scheduleId: request.scheduleId,
296
+ timing: request.timing,
297
+ destination: request.destination,
298
+ deliveryPrincipal: request.deliveryPrincipal,
299
+ definitions: request.definitions,
300
+ ...request.admissionGroup === void 0 ? {} : { admissionGroup: request.admissionGroup },
301
+ ...request.admissionFence === void 0 ? {} : { admissionFence: request.admissionFence }
302
+ })
303
+ };
304
+ case "Update": return {
305
+ _tag: "Snapshot",
306
+ value: yield* scheduling.update(passthroughAgent(request.agentId), request.input, {
307
+ scope: request.scope,
308
+ scheduleId: request.scheduleId,
309
+ timing: request.timing,
310
+ destination: request.destination,
311
+ deliveryPrincipal: request.deliveryPrincipal,
312
+ definitions: request.definitions,
313
+ ...request.admissionGroup === void 0 ? {} : { admissionGroup: request.admissionGroup },
314
+ ...request.admissionFence === void 0 ? {} : { admissionFence: request.admissionFence },
315
+ expectedRevision: request.expectedRevision
316
+ })
317
+ };
318
+ case "Get": return {
319
+ _tag: "Snapshot",
320
+ value: yield* scheduling.get(request.scope, request.scheduleId)
321
+ };
322
+ case "List": return {
323
+ _tag: "Page",
324
+ value: yield* scheduling.list(request.scope, {
325
+ ...request.after === void 0 ? {} : { after: request.after },
326
+ ...request.limit === void 0 ? {} : { limit: request.limit }
327
+ })
328
+ };
329
+ case "Recover": return {
330
+ _tag: "Snapshot",
331
+ value: yield* scheduling.recover(request.scope, request.scheduleId, request.expectedRevision, request.expectedGeneration)
332
+ };
333
+ case "Control": return {
334
+ _tag: "Snapshot",
335
+ value: request.operation === "pause" ? yield* scheduling.pause(request.scope, request.scheduleId, request.expectedRevision) : request.operation === "resume" ? yield* scheduling.resume(request.scope, request.scheduleId, request.expectedRevision) : yield* scheduling.cancel(request.scope, request.scheduleId, request.expectedRevision)
336
+ };
337
+ }
338
+ }).pipe(Effect.map((value) => value), Effect.catch((failure) => Schema.is(ScheduleOwnerFailure)(failure) ? Effect.succeed({
339
+ _tag: "Failed",
340
+ failure
341
+ }) : Effect.succeed(scheduleProtocolFailure("The Schedule operation failed outside its public contract"))));
342
+ return yield* encodeScheduleOwnerResponse(response).pipe(Effect.orDie);
343
+ });
344
+ /** @internal The complete native alarm operation, including its event deadline. */
345
+ const scheduleAlarmHandler = (limits) => DurableObjectAlarm.processDue((event) => Effect.gen(function* () {
346
+ if (event.tag !== SCHEDULE_ALARM_TAG || event.id !== SCHEDULE_ALARM_ID) return yield* ScheduleAlarmProtocolError.make({ message: `Unsupported Schedule Owner alarm ${event.tag}/${event.id}` });
347
+ yield* Schema.decodeUnknownEffect(ScheduleAlarmPayload)(event.payload).pipe(Effect.mapError(() => ScheduleAlarmProtocolError.make({ message: "Unsupported Schedule Owner alarm payload version" })));
348
+ const scheduling = yield* ScheduleDriver;
349
+ const alarmControl = yield* DoScheduleAlarmControl;
350
+ const { owner } = yield* ScheduleOwnerIdentity;
351
+ const nowMillis = yield* Clock.currentTimeMillis;
352
+ yield* alarmControl.prearm(nowMillis + limits.recoveryPollMillis);
353
+ if ((yield* scheduling.runDue(owner)).failed > 0) yield* alarmControl.prearm((yield* Clock.currentTimeMillis) + limits.recoveryPollMillis);
354
+ else yield* alarmControl.reconcile;
355
+ }), { mode: "ordered" }).pipe(Effect.timeout("14 minutes"), Effect.asVoid);
356
+ /**
357
+ * The host Layer supplies authorization and routing and is cached for the object incarnation.
358
+ * Cloudflare eviction does not guarantee its finalizers run. Do not acquire resources requiring
359
+ * cleanup in this Layer; acquire them inside scoped `manage` / `prepare` operations instead.
360
+ * Native services belong to effect-cf; the database and alarm runtime remain instance-owned.
361
+ */
362
+ const makeScheduleOwnerObjectClass = (host, limits = defaultSchedulingLimits) => {
363
+ const ownerLayer = Layer.effect(ScheduleOwnerIdentity, Effect.gen(function* () {
364
+ const state = yield* DurableObjectState.DurableObjectState;
365
+ return ScheduleOwnerIdentity.of({ owner: yield* decodeOwnerName(state.raw.id.name) });
366
+ }));
367
+ const sqlLayer = Layer.unwrap(Effect.map(DurableObjectState.DurableObjectState, (state) => SqliteClient.layer({ storage: state.raw.storage })));
368
+ const application = Layer.merge(Scheduling.layer(limits), ScheduleDriver.layer(limits)).pipe(Layer.provideMerge(scheduleStoreLayer.pipe(Layer.provide(transactionLayer), Layer.provide(sqlLayer))), Layer.provide(cloudflareScheduledInputAdmissionLayer.pipe(Layer.provide(cloudflarePreparedInputAdmissionLayer), Layer.provide(CloudflareThreadClient.layer))), Layer.provide(ScheduleWakeNoop), Layer.provide(BrowserCrypto.layer), Layer.provideMerge(DurableObjectAlarm.DurableObjectAlarm.layer), Layer.provide(host), Layer.provideMerge(ownerLayer));
369
+ const runtime = Layer.effectContext(Effect.gen(function* () {
370
+ const state = yield* DurableObjectState.DurableObjectState;
371
+ const scope = yield* Effect.scope;
372
+ return yield* state.blockConcurrencyWhile(Layer.buildWithScope(application, scope));
373
+ }));
374
+ const Base = DurableObject.make(runtime, {
375
+ initialize: Effect.void,
376
+ rpc: { schedule: (encoded) => handleScheduleRequest(encoded) },
377
+ alarms: scheduleAlarmHandler(limits)
378
+ });
379
+ class ScheduleOwnerObject extends Base {
380
+ alarm(alarmInfo) {
381
+ return super.alarm?.(alarmInfo);
382
+ }
383
+ }
384
+ return ScheduleOwnerObject;
385
+ };
386
+ //#endregion
387
+ export { CloudflareSchedulingClient, ScheduleAlarmProtocolError, ScheduleOwnerIdentity, ScheduleOwnerNamespace, ScheduleOwnerProtocolError, makeScheduleOwnerObjectClass, scheduleAlarmHandler, CloudflareScheduling_exports as t };
388
+
389
+ //# sourceMappingURL=CloudflareScheduling.mjs.map