@relaycast/engine 12.2.0 → 12.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/dist/adapters/actor/credential-tag.d.ts +14 -0
  2. package/dist/adapters/actor/credential-tag.d.ts.map +1 -0
  3. package/dist/adapters/actor/credential-tag.js +30 -0
  4. package/dist/adapters/actor/credential-tag.js.map +1 -0
  5. package/dist/adapters/actor/database.d.ts +50 -0
  6. package/dist/adapters/actor/database.d.ts.map +1 -0
  7. package/dist/adapters/actor/database.js +86 -0
  8. package/dist/adapters/actor/database.js.map +1 -0
  9. package/dist/adapters/actor/ephemeral-outbox.d.ts +16 -0
  10. package/dist/adapters/actor/ephemeral-outbox.d.ts.map +1 -0
  11. package/dist/adapters/actor/ephemeral-outbox.js +53 -0
  12. package/dist/adapters/actor/ephemeral-outbox.js.map +1 -0
  13. package/dist/adapters/actor/event-queue.d.ts +23 -0
  14. package/dist/adapters/actor/event-queue.d.ts.map +1 -0
  15. package/dist/adapters/actor/event-queue.js +31 -0
  16. package/dist/adapters/actor/event-queue.js.map +1 -0
  17. package/dist/adapters/actor/files.d.ts +66 -0
  18. package/dist/adapters/actor/files.d.ts.map +1 -0
  19. package/dist/adapters/actor/files.js +83 -0
  20. package/dist/adapters/actor/files.js.map +1 -0
  21. package/dist/adapters/actor/http.d.ts +19 -0
  22. package/dist/adapters/actor/http.d.ts.map +1 -0
  23. package/dist/adapters/actor/http.js +2 -0
  24. package/dist/adapters/actor/http.js.map +1 -0
  25. package/dist/adapters/actor/index.d.ts +90 -0
  26. package/dist/adapters/actor/index.d.ts.map +1 -0
  27. package/dist/adapters/actor/index.js +299 -0
  28. package/dist/adapters/actor/index.js.map +1 -0
  29. package/dist/adapters/actor/kv.d.ts +21 -0
  30. package/dist/adapters/actor/kv.d.ts.map +1 -0
  31. package/dist/adapters/actor/kv.js +33 -0
  32. package/dist/adapters/actor/kv.js.map +1 -0
  33. package/dist/adapters/actor/migrations.d.ts +15 -0
  34. package/dist/adapters/actor/migrations.d.ts.map +1 -0
  35. package/dist/adapters/actor/migrations.generated.d.ts +5 -0
  36. package/dist/adapters/actor/migrations.generated.d.ts.map +1 -0
  37. package/dist/adapters/actor/migrations.generated.js +842 -0
  38. package/dist/adapters/actor/migrations.generated.js.map +1 -0
  39. package/dist/adapters/actor/migrations.js +32 -0
  40. package/dist/adapters/actor/migrations.js.map +1 -0
  41. package/dist/adapters/node/files.d.ts +2 -0
  42. package/dist/adapters/node/files.d.ts.map +1 -1
  43. package/dist/adapters/node/files.js +31 -3
  44. package/dist/adapters/node/files.js.map +1 -1
  45. package/dist/adapters/node/index.js +1 -1
  46. package/dist/adapters/node/index.js.map +1 -1
  47. package/dist/auth/credentialTags.d.ts +43 -0
  48. package/dist/auth/credentialTags.d.ts.map +1 -0
  49. package/dist/auth/credentialTags.js +106 -0
  50. package/dist/auth/credentialTags.js.map +1 -0
  51. package/dist/auth/credentials.d.ts +103 -0
  52. package/dist/auth/credentials.d.ts.map +1 -0
  53. package/dist/auth/credentials.js +147 -0
  54. package/dist/auth/credentials.js.map +1 -0
  55. package/dist/auth/index.d.ts +7 -4
  56. package/dist/auth/index.d.ts.map +1 -1
  57. package/dist/auth/index.js +115 -61
  58. package/dist/auth/index.js.map +1 -1
  59. package/dist/auth/tokenKind.d.ts +17 -26
  60. package/dist/auth/tokenKind.d.ts.map +1 -1
  61. package/dist/auth/tokenKind.js +17 -46
  62. package/dist/auth/tokenKind.js.map +1 -1
  63. package/dist/auth/workspaceExpiry.d.ts +2 -0
  64. package/dist/auth/workspaceExpiry.d.ts.map +1 -1
  65. package/dist/auth/workspaceExpiry.js +7 -0
  66. package/dist/auth/workspaceExpiry.js.map +1 -1
  67. package/dist/bin/secretEnv.d.ts +17 -0
  68. package/dist/bin/secretEnv.d.ts.map +1 -0
  69. package/dist/bin/secretEnv.js +33 -0
  70. package/dist/bin/secretEnv.js.map +1 -0
  71. package/dist/bin/serve.js +42 -4
  72. package/dist/bin/serve.js.map +1 -1
  73. package/dist/config/credentialEnv.d.ts +19 -0
  74. package/dist/config/credentialEnv.d.ts.map +1 -0
  75. package/dist/config/credentialEnv.js +53 -0
  76. package/dist/config/credentialEnv.js.map +1 -0
  77. package/dist/db/migrations/0078_dm_participant_read_cursor.sql +15 -0
  78. package/dist/db/migrations/0079_credential_upgrades.sql +17 -0
  79. package/dist/db/schema.d.ts +183 -2
  80. package/dist/db/schema.d.ts.map +1 -1
  81. package/dist/db/schema.js +23 -0
  82. package/dist/db/schema.js.map +1 -1
  83. package/dist/engine/a2a.d.ts +1 -1
  84. package/dist/engine/a2a.d.ts.map +1 -1
  85. package/dist/engine/a2a.js +2 -2
  86. package/dist/engine/a2a.js.map +1 -1
  87. package/dist/engine/a2aEgress.d.ts +3 -2
  88. package/dist/engine/a2aEgress.d.ts.map +1 -1
  89. package/dist/engine/a2aEgress.js +5 -4
  90. package/dist/engine/a2aEgress.js.map +1 -1
  91. package/dist/engine/action.d.ts +12 -0
  92. package/dist/engine/action.d.ts.map +1 -1
  93. package/dist/engine/action.js +45 -1
  94. package/dist/engine/action.js.map +1 -1
  95. package/dist/engine/agent.d.ts.map +1 -1
  96. package/dist/engine/agent.js +2 -1
  97. package/dist/engine/agent.js.map +1 -1
  98. package/dist/engine/agentIdentity.d.ts.map +1 -1
  99. package/dist/engine/agentIdentity.js +2 -1
  100. package/dist/engine/agentIdentity.js.map +1 -1
  101. package/dist/engine/credentialUpgrade.d.ts +48 -0
  102. package/dist/engine/credentialUpgrade.d.ts.map +1 -0
  103. package/dist/engine/credentialUpgrade.js +176 -0
  104. package/dist/engine/credentialUpgrade.js.map +1 -0
  105. package/dist/engine/delivery.d.ts.map +1 -1
  106. package/dist/engine/delivery.js +70 -31
  107. package/dist/engine/delivery.js.map +1 -1
  108. package/dist/engine/eventDispatch.d.ts.map +1 -1
  109. package/dist/engine/eventDispatch.js +3 -2
  110. package/dist/engine/eventDispatch.js.map +1 -1
  111. package/dist/engine/eventSubscription.d.ts +4 -4
  112. package/dist/engine/file.d.ts +8 -0
  113. package/dist/engine/file.d.ts.map +1 -1
  114. package/dist/engine/file.js +18 -5
  115. package/dist/engine/file.js.map +1 -1
  116. package/dist/engine/inboundWebhook.d.ts +2 -0
  117. package/dist/engine/inboundWebhook.d.ts.map +1 -1
  118. package/dist/engine/inboundWebhook.js +10 -4
  119. package/dist/engine/inboundWebhook.js.map +1 -1
  120. package/dist/engine/inbox.d.ts.map +1 -1
  121. package/dist/engine/inbox.js +10 -5
  122. package/dist/engine/inbox.js.map +1 -1
  123. package/dist/engine/internalAdmin.d.ts +80 -0
  124. package/dist/engine/internalAdmin.d.ts.map +1 -0
  125. package/dist/engine/internalAdmin.js +329 -0
  126. package/dist/engine/internalAdmin.js.map +1 -0
  127. package/dist/engine/invocationCompletion.d.ts.map +1 -1
  128. package/dist/engine/invocationCompletion.js +23 -5
  129. package/dist/engine/invocationCompletion.js.map +1 -1
  130. package/dist/engine/node.d.ts +38 -1
  131. package/dist/engine/node.d.ts.map +1 -1
  132. package/dist/engine/node.js +166 -11
  133. package/dist/engine/node.js.map +1 -1
  134. package/dist/engine/nodeContext.d.ts +2 -1
  135. package/dist/engine/nodeContext.d.ts.map +1 -1
  136. package/dist/engine/nodeContext.js +1 -1
  137. package/dist/engine/nodeContext.js.map +1 -1
  138. package/dist/engine/nodeDeliver.d.ts +2 -1
  139. package/dist/engine/nodeDeliver.d.ts.map +1 -1
  140. package/dist/engine/nodeDeliver.js +1 -1
  141. package/dist/engine/nodeDeliver.js.map +1 -1
  142. package/dist/engine/observerToken.d.ts +4 -0
  143. package/dist/engine/observerToken.d.ts.map +1 -1
  144. package/dist/engine/observerToken.js +14 -5
  145. package/dist/engine/observerToken.js.map +1 -1
  146. package/dist/engine/receipt.d.ts +100 -0
  147. package/dist/engine/receipt.d.ts.map +1 -1
  148. package/dist/engine/receipt.js +12 -0
  149. package/dist/engine/receipt.js.map +1 -1
  150. package/dist/engine/taskInvocation.d.ts +1 -1
  151. package/dist/engine/tokenRotate.d.ts.map +1 -1
  152. package/dist/engine/tokenRotate.js +4 -3
  153. package/dist/engine/tokenRotate.js.map +1 -1
  154. package/dist/engine/workspace.d.ts +8 -2
  155. package/dist/engine/workspace.d.ts.map +1 -1
  156. package/dist/engine/workspace.js +70 -21
  157. package/dist/engine/workspace.js.map +1 -1
  158. package/dist/engine/wsAuth.d.ts.map +1 -1
  159. package/dist/engine/wsAuth.js +14 -3
  160. package/dist/engine/wsAuth.js.map +1 -1
  161. package/dist/engine.d.ts.map +1 -1
  162. package/dist/engine.js +31 -0
  163. package/dist/engine.js.map +1 -1
  164. package/dist/entrypoints/node.d.ts +3 -1
  165. package/dist/entrypoints/node.d.ts.map +1 -1
  166. package/dist/entrypoints/node.js +33 -1
  167. package/dist/entrypoints/node.js.map +1 -1
  168. package/dist/env.d.ts +2 -0
  169. package/dist/env.d.ts.map +1 -1
  170. package/dist/gateway.d.ts +11 -0
  171. package/dist/gateway.d.ts.map +1 -0
  172. package/dist/gateway.js +16 -0
  173. package/dist/gateway.js.map +1 -0
  174. package/dist/index.d.ts +2 -0
  175. package/dist/index.d.ts.map +1 -1
  176. package/dist/index.js +1 -0
  177. package/dist/index.js.map +1 -1
  178. package/dist/lib/credentialNotice.d.ts +32 -0
  179. package/dist/lib/credentialNotice.d.ts.map +1 -0
  180. package/dist/lib/credentialNotice.js +76 -0
  181. package/dist/lib/credentialNotice.js.map +1 -0
  182. package/dist/lib/fileTokens.d.ts +30 -0
  183. package/dist/lib/fileTokens.d.ts.map +1 -0
  184. package/dist/lib/fileTokens.js +76 -0
  185. package/dist/lib/fileTokens.js.map +1 -0
  186. package/dist/lib/httpError.d.ts +1 -1
  187. package/dist/lib/httpResponse.d.ts +6 -6
  188. package/dist/middleware/admission.d.ts +1 -1
  189. package/dist/middleware/auth.d.ts.map +1 -1
  190. package/dist/middleware/auth.js +22 -31
  191. package/dist/middleware/auth.js.map +1 -1
  192. package/dist/middleware/idempotency.d.ts +1 -1
  193. package/dist/middleware/logger.d.ts.map +1 -1
  194. package/dist/middleware/logger.js +4 -1
  195. package/dist/middleware/logger.js.map +1 -1
  196. package/dist/ports/database.d.ts.map +1 -1
  197. package/dist/ports/database.js +8 -2
  198. package/dist/ports/database.js.map +1 -1
  199. package/dist/ports/files.d.ts +7 -1
  200. package/dist/ports/files.d.ts.map +1 -1
  201. package/dist/ports/index.d.ts +64 -1
  202. package/dist/ports/index.d.ts.map +1 -1
  203. package/dist/ports/index.js +4 -0
  204. package/dist/ports/index.js.map +1 -1
  205. package/dist/ports/telemetry.d.ts +1 -0
  206. package/dist/ports/telemetry.d.ts.map +1 -1
  207. package/dist/ports/telemetry.js +1 -0
  208. package/dist/ports/telemetry.js.map +1 -1
  209. package/dist/routes/action.d.ts.map +1 -1
  210. package/dist/routes/action.js +2 -1
  211. package/dist/routes/action.js.map +1 -1
  212. package/dist/routes/credential.d.ts +4 -0
  213. package/dist/routes/credential.d.ts.map +1 -0
  214. package/dist/routes/credential.js +97 -0
  215. package/dist/routes/credential.js.map +1 -0
  216. package/dist/routes/file.js +10 -4
  217. package/dist/routes/file.js.map +1 -1
  218. package/dist/routes/inboundWebhook.d.ts.map +1 -1
  219. package/dist/routes/inboundWebhook.js +11 -2
  220. package/dist/routes/inboundWebhook.js.map +1 -1
  221. package/dist/routes/internal.d.ts +14 -0
  222. package/dist/routes/internal.d.ts.map +1 -0
  223. package/dist/routes/internal.js +157 -0
  224. package/dist/routes/internal.js.map +1 -0
  225. package/dist/routes/node.d.ts.map +1 -1
  226. package/dist/routes/node.js +44 -2
  227. package/dist/routes/node.js.map +1 -1
  228. package/dist/routes/observerToken.js +1 -1
  229. package/dist/routes/observerToken.js.map +1 -1
  230. package/dist/routes/reaction.d.ts.map +1 -1
  231. package/dist/routes/reaction.js +3 -2
  232. package/dist/routes/reaction.js.map +1 -1
  233. package/dist/routes/receipt.d.ts.map +1 -1
  234. package/dist/routes/receipt.js +2 -1
  235. package/dist/routes/receipt.js.map +1 -1
  236. package/dist/routes/workspace.d.ts.map +1 -1
  237. package/dist/routes/workspace.js +12 -1
  238. package/dist/routes/workspace.js.map +1 -1
  239. package/package.json +12 -3
@@ -0,0 +1,14 @@
1
+ import type { ActorSql } from './database.js';
2
+ /**
3
+ * The routing tag of this actor's workspace. The gateway signs it for the
4
+ * workspace id with its keyring and hands it to `create`; the actor never
5
+ * holds the keyring.
6
+ */
7
+ export declare class ActorCredentialTag {
8
+ private readonly sql;
9
+ constructor(sql: ActorSql);
10
+ get(): string | undefined;
11
+ /** Keep `tag`. A workspace's tag never changes, so a different one is refused. */
12
+ set(tag: string): void;
13
+ }
14
+ //# sourceMappingURL=credential-tag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-tag.d.ts","sourceRoot":"","sources":["../../../src/adapters/actor/credential-tag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAK9C;;;;GAIG;AACH,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,QAAQ;IAI1C,GAAG,IAAI,MAAM,GAAG,SAAS;IAKzB,kFAAkF;IAClF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAOvB"}
@@ -0,0 +1,30 @@
1
+ const TABLE = '_actor_credential_tag';
2
+ const TAG = /^[a-z][0-9A-Za-z]{10}$/;
3
+ /**
4
+ * The routing tag of this actor's workspace. The gateway signs it for the
5
+ * workspace id with its keyring and hands it to `create`; the actor never
6
+ * holds the keyring.
7
+ */
8
+ export class ActorCredentialTag {
9
+ sql;
10
+ constructor(sql) {
11
+ this.sql = sql;
12
+ sql.exec(`CREATE TABLE IF NOT EXISTS ${TABLE} (id INTEGER PRIMARY KEY CHECK (id = 1), tag TEXT NOT NULL)`);
13
+ }
14
+ get() {
15
+ const [row] = this.sql.exec(`SELECT tag FROM ${TABLE} WHERE id = 1`);
16
+ return row?.tag;
17
+ }
18
+ /** Keep `tag`. A workspace's tag never changes, so a different one is refused. */
19
+ set(tag) {
20
+ if (!TAG.test(tag))
21
+ throw new Error('A credential tag is a key version letter plus 10 base62 characters');
22
+ const current = this.get();
23
+ if (current === tag)
24
+ return;
25
+ if (current !== undefined)
26
+ throw new Error('This workspace already has a different credential tag');
27
+ this.sql.exec(`INSERT INTO ${TABLE} (id, tag) VALUES (1, ?)`, tag);
28
+ }
29
+ }
30
+ //# sourceMappingURL=credential-tag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-tag.js","sourceRoot":"","sources":["../../../src/adapters/actor/credential-tag.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAG,uBAAuB,CAAC;AACtC,MAAM,GAAG,GAAG,wBAAwB,CAAC;AAErC;;;;GAIG;AACH,MAAM,OAAO,kBAAkB;IACA;IAA7B,YAA6B,GAAa;QAAb,QAAG,GAAH,GAAG,CAAU;QACxC,GAAG,CAAC,IAAI,CAAC,8BAA8B,KAAK,6DAA6D,CAAC,CAAC;IAC7G,CAAC;IAED,GAAG;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,KAAK,eAAe,CAAsB,CAAC;QAC1F,OAAO,GAAG,EAAE,GAAG,CAAC;IAClB,CAAC;IAED,kFAAkF;IAClF,GAAG,CAAC,GAAW;QACb,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QAC1G,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,IAAI,OAAO,KAAK,GAAG;YAAE,OAAO;QAC5B,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACpG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,0BAA0B,EAAE,GAAG,CAAC,CAAC;IACrE,CAAC;CACF"}
@@ -0,0 +1,50 @@
1
+ import type { EngineDb, TransactionCapability } from '../../ports/database.js';
2
+ /** A value SQLite can bind or return through a durable actor's database. */
3
+ export type SqliteValue = string | number | bigint | Uint8Array | null;
4
+ /**
5
+ * An actor's database as `this.db` types it: `exec` and nested `transaction`.
6
+ * The runtime object also carries `query` (durable-actors >= 0.14.5, the
7
+ * method `durable-actors/drizzle` runs on), which `createActorRuntime` checks
8
+ * for.
9
+ */
10
+ export interface ActorDatabase {
11
+ exec(sql: string, ...bindings: SqliteValue[]): object[];
12
+ transaction<T>(operation: () => Promise<T>): Promise<T>;
13
+ }
14
+ /**
15
+ * The durable actor's SQL surface at runtime (durable-actors >= 0.14.5): one
16
+ * statement per call, positional bindings, and nested transactions on runtime
17
+ * savepoints.
18
+ */
19
+ export interface ActorSql extends ActorDatabase {
20
+ /** Run one statement; rows keyed by column name. */
21
+ exec(sql: string, ...bindings: SqliteValue[]): object[];
22
+ /** Run one statement; rows as value arrays in column order. */
23
+ query(sql: string, ...bindings: SqliteValue[]): {
24
+ columns: string[];
25
+ rows: SqliteValue[][];
26
+ };
27
+ /** Run `operation` in a nested transaction: if it throws, only its writes roll back. */
28
+ transaction<T>(operation: () => Promise<T>): Promise<T>;
29
+ }
30
+ /** Engine handle over an actor's database. `withTransaction` is a runtime savepoint. */
31
+ export type ActorEngineDb = EngineDb & TransactionCapability;
32
+ /**
33
+ * SQLite extended result codes for constraint failures, by the names
34
+ * better-sqlite3 reports in `error.code`. The actor runtime reports only the
35
+ * number, inside the message (`UNIQUE constraint failed: t.c: Error code 2067:
36
+ * constraint failed`), and engine classifiers read `code`.
37
+ */
38
+ export declare const SQLITE_CONSTRAINT_CODES: Readonly<Record<number, string>>;
39
+ /**
40
+ * Build the engine's Drizzle handle over an actor database: statements run
41
+ * through `query` (positional rows), and `withTransaction` is a nested actor
42
+ * transaction, so a failed write group rolls back alone and the call goes on.
43
+ * `onGroupStart` sees every write group open, `onGroupFailure` every one
44
+ * that rolled back.
45
+ */
46
+ export declare function createActorEngineDb(sql: ActorSql, options?: {
47
+ onGroupStart?: () => void;
48
+ onGroupFailure?: (error: unknown) => void;
49
+ }): ActorEngineDb;
50
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/adapters/actor/database.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAE/E,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC;IACxD,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAS,SAAQ,aAAa;IAC7C,oDAAoD;IACpD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC;IACxD,+DAA+D;IAC/D,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,WAAW,EAAE,EAAE,CAAA;KAAE,CAAC;IAC7F,wFAAwF;IACxF,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACzD;AAED,wFAAwF;AACxF,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,qBAAqB,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYpE,CAAC;AAuCF;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CAAO,GACrF,aAAa,CAoBf"}
@@ -0,0 +1,86 @@
1
+ import { drizzle } from 'drizzle-orm/sqlite-proxy';
2
+ import * as schema from '../../db/schema.js';
3
+ /**
4
+ * SQLite extended result codes for constraint failures, by the names
5
+ * better-sqlite3 reports in `error.code`. The actor runtime reports only the
6
+ * number, inside the message (`UNIQUE constraint failed: t.c: Error code 2067:
7
+ * constraint failed`), and engine classifiers read `code`.
8
+ */
9
+ export const SQLITE_CONSTRAINT_CODES = {
10
+ 19: 'SQLITE_CONSTRAINT',
11
+ 275: 'SQLITE_CONSTRAINT_CHECK',
12
+ 531: 'SQLITE_CONSTRAINT_COMMITHOOK',
13
+ 787: 'SQLITE_CONSTRAINT_FOREIGNKEY',
14
+ 1043: 'SQLITE_CONSTRAINT_FUNCTION',
15
+ 1299: 'SQLITE_CONSTRAINT_NOTNULL',
16
+ 1555: 'SQLITE_CONSTRAINT_PRIMARYKEY',
17
+ 1811: 'SQLITE_CONSTRAINT_TRIGGER',
18
+ 2067: 'SQLITE_CONSTRAINT_UNIQUE',
19
+ 2323: 'SQLITE_CONSTRAINT_VTAB',
20
+ 2579: 'SQLITE_CONSTRAINT_ROWID',
21
+ };
22
+ const RUNTIME_ERROR_CODE = /: Error code (\d+): /;
23
+ const INTEGER_KEY = /^(?:0|[1-9]\d*)$/;
24
+ /** Run one statement, giving runtime constraint errors the `code` engine classifiers read. */
25
+ function query(sql, statement, params) {
26
+ try {
27
+ return sql.query(statement, ...params.map(binding));
28
+ }
29
+ catch (error) {
30
+ if (error instanceof Error && !error.code) {
31
+ const match = RUNTIME_ERROR_CODE.exec(error.message);
32
+ const code = match ? SQLITE_CONSTRAINT_CODES[Number(match[1])] : undefined;
33
+ if (code)
34
+ Object.assign(error, { code });
35
+ }
36
+ throw error;
37
+ }
38
+ }
39
+ function binding(value) {
40
+ if (typeof value === 'boolean')
41
+ return value ? 1 : 0;
42
+ return value;
43
+ }
44
+ /**
45
+ * A row as both drizzle consumers read it: query builders map by position,
46
+ * raw `db.all(sql\`...\`)` callers read by column name. A repeated name keeps
47
+ * its first column; an integer-like name would overwrite an array slot, so it
48
+ * is positional only.
49
+ */
50
+ function namedRow(columns, values) {
51
+ const named = values;
52
+ columns.forEach((column, index) => {
53
+ if (INTEGER_KEY.test(column) || column === 'length' || Object.hasOwn(named, column))
54
+ return;
55
+ named[column] = values[index];
56
+ });
57
+ return values;
58
+ }
59
+ /**
60
+ * Build the engine's Drizzle handle over an actor database: statements run
61
+ * through `query` (positional rows), and `withTransaction` is a nested actor
62
+ * transaction, so a failed write group rolls back alone and the call goes on.
63
+ * `onGroupStart` sees every write group open, `onGroupFailure` every one
64
+ * that rolled back.
65
+ */
66
+ export function createActorEngineDb(sql, options = {}) {
67
+ const db = drizzle(async (statement, params, method) => {
68
+ const { columns, rows } = query(sql, statement, params);
69
+ if (method === 'run')
70
+ return { rows: [] };
71
+ const named = rows.map((row) => namedRow(columns, row));
72
+ // `get` resolves one row (or undefined); drizzle types it as an array.
73
+ if (method === 'get')
74
+ return { rows: named[0] };
75
+ return { rows: named };
76
+ }, { schema });
77
+ db.withTransaction = (fn) => {
78
+ options.onGroupStart?.();
79
+ return sql.transaction(() => fn(db)).catch((error) => {
80
+ options.onGroupFailure?.(error);
81
+ throw error;
82
+ });
83
+ };
84
+ return db;
85
+ }
86
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/adapters/actor/database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ActorSql } from './database.js';
2
+ export declare function ensureActorOutboundTable(sql: ActorSql): void;
3
+ /**
4
+ * Best-effort ephemeral http_push events queued during a request. Rows are
5
+ * written in the actor call, so a rolled-back call never sends them; the
6
+ * actor alarm sends each once, matching the engine's best-effort contract for
7
+ * these events (no delivery row, no retry).
8
+ */
9
+ export declare class ActorEphemeralOutbox {
10
+ private readonly sql;
11
+ private readonly fetch;
12
+ constructor(sql: ActorSql, fetch: typeof globalThis.fetch);
13
+ enqueue(request: Request): Promise<void>;
14
+ drain(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=ephemeral-outbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ephemeral-outbox.d.ts","sourceRoot":"","sources":["../../../src/adapters/actor/ephemeral-outbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAO9C,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAW5D;AAED;;;;;GAKG;AACH,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK;IAG3C,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAqB7B"}
@@ -0,0 +1,53 @@
1
+ const TABLE = '_actor_outbound';
2
+ /** Ephemeral events are presence-grade signals; older ones are dropped, not sent. */
3
+ const MAX_AGE_MS = 10 * 60_000;
4
+ const DRAIN_BATCH = 100;
5
+ export function ensureActorOutboundTable(sql) {
6
+ sql.exec(`CREATE TABLE IF NOT EXISTS ${TABLE} (
7
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
8
+ created_at INTEGER NOT NULL,
9
+ method TEXT NOT NULL,
10
+ url TEXT NOT NULL,
11
+ headers TEXT NOT NULL,
12
+ body TEXT
13
+ )`);
14
+ }
15
+ /**
16
+ * Best-effort ephemeral http_push events queued during a request. Rows are
17
+ * written in the actor call, so a rolled-back call never sends them; the
18
+ * actor alarm sends each once, matching the engine's best-effort contract for
19
+ * these events (no delivery row, no retry).
20
+ */
21
+ export class ActorEphemeralOutbox {
22
+ sql;
23
+ fetch;
24
+ constructor(sql, fetch) {
25
+ this.sql = sql;
26
+ this.fetch = fetch;
27
+ }
28
+ async enqueue(request) {
29
+ const body = request.body ? await request.text() : null;
30
+ this.sql.exec(`INSERT INTO ${TABLE} (created_at, method, url, headers, body) VALUES (?, ?, ?, ?, ?)`, Date.now(), request.method, request.url, JSON.stringify([...request.headers]), body);
31
+ }
32
+ async drain() {
33
+ this.sql.exec(`DELETE FROM ${TABLE} WHERE created_at < ?`, Date.now() - MAX_AGE_MS);
34
+ for (;;) {
35
+ const rows = this.sql.exec(`DELETE FROM ${TABLE} WHERE id IN (SELECT id FROM ${TABLE} ORDER BY id LIMIT ?)
36
+ RETURNING method, url, headers, body`, DRAIN_BATCH);
37
+ if (rows.length === 0)
38
+ return;
39
+ await Promise.allSettled(rows.map(async (row) => {
40
+ const response = await this.fetch(row.url, {
41
+ method: row.method,
42
+ headers: JSON.parse(row.headers),
43
+ body: row.body,
44
+ signal: AbortSignal.timeout(10_000),
45
+ });
46
+ await response.body?.cancel();
47
+ }));
48
+ if (rows.length < DRAIN_BATCH)
49
+ return;
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=ephemeral-outbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ephemeral-outbox.js","sourceRoot":"","sources":["../../../src/adapters/actor/ephemeral-outbox.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAG,iBAAiB,CAAC;AAChC,qFAAqF;AACrF,MAAM,UAAU,GAAG,EAAE,GAAG,MAAM,CAAC;AAC/B,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,MAAM,UAAU,wBAAwB,CAAC,GAAa;IACpD,GAAG,CAAC,IAAI,CACN,8BAA8B,KAAK;;;;;;;MAOjC,CACH,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAEZ;IACA;IAFnB,YACmB,GAAa,EACb,KAA8B;QAD9B,QAAG,GAAH,GAAG,CAAU;QACb,UAAK,GAAL,KAAK,CAAyB;IAC9C,CAAC;IAEJ,KAAK,CAAC,OAAO,CAAC,OAAgB;QAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACxD,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,eAAe,KAAK,kEAAkE,EACtF,IAAI,CAAC,GAAG,EAAE,EACV,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,GAAG,EACX,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,EACpC,IAAI,CACL,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,uBAAuB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,CAAC;QACpF,SAAS,CAAC;YACR,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CACxB,eAAe,KAAK,gCAAgC,KAAK;8CACnB,EACtC,WAAW,CAC+D,CAAC;YAC7E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAC9B,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC9C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;oBACzC,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAuB;oBACtD,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;iBACpC,CAAC,CAAC;gBACH,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YAChC,CAAC,CAAC,CAAC,CAAC;YACJ,IAAI,IAAI,CAAC,MAAM,GAAG,WAAW;gBAAE,OAAO;QACxC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ import type { EventQueue, QueuedEvent } from '../../ports/event-queue.js';
2
+ import type { EngineDb } from '../../ports/database.js';
3
+ import { type DurableEventQueueOptions } from '../node/event-queue.js';
4
+ /**
5
+ * Webhook outbox for a workspace actor.
6
+ *
7
+ * `send` only makes the event durable (the request path already inserted the
8
+ * `pending_events` row when `outboxId` is set) and asks for maintenance. It
9
+ * never delivers: an actor call holds the actor's mailbox until it returns,
10
+ * so outbound HTTP runs from `drain()`, which the actor's alarm calls.
11
+ */
12
+ export declare class ActorEventQueue implements EventQueue {
13
+ private readonly db;
14
+ private readonly requestMaintenance;
15
+ private readonly outbox;
16
+ constructor(db: EngineDb, requestMaintenance: () => void, onError: (err: unknown, ctx: Record<string, unknown>) => void, options: Omit<DurableEventQueueOptions, 'pollIntervalMs'> & {
17
+ fetch: typeof globalThis.fetch;
18
+ });
19
+ send(message: QueuedEvent): Promise<void>;
20
+ /** Deliver every due outbox row and prune settled ones on the outbox's cadence. */
21
+ drain(): Promise<void>;
22
+ }
23
+ //# sourceMappingURL=event-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-queue.d.ts","sourceRoot":"","sources":["../../../src/adapters/actor/event-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAqB,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAE1F;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,UAAU;IAI9C,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAJrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;gBAGxB,EAAE,EAAE,QAAQ,EACZ,kBAAkB,EAAE,MAAM,IAAI,EAC/C,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAC7D,OAAO,EAAE,IAAI,CAAC,wBAAwB,EAAE,gBAAgB,CAAC,GAAG;QAAE,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;KAAE;IAK1F,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/C,mFAAmF;IACnF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvB"}
@@ -0,0 +1,31 @@
1
+ import { enqueueEvent } from '../../engine/eventQueue.js';
2
+ import { DurableEventQueue } from '../node/event-queue.js';
3
+ /**
4
+ * Webhook outbox for a workspace actor.
5
+ *
6
+ * `send` only makes the event durable (the request path already inserted the
7
+ * `pending_events` row when `outboxId` is set) and asks for maintenance. It
8
+ * never delivers: an actor call holds the actor's mailbox until it returns,
9
+ * so outbound HTTP runs from `drain()`, which the actor's alarm calls.
10
+ */
11
+ export class ActorEventQueue {
12
+ db;
13
+ requestMaintenance;
14
+ outbox;
15
+ constructor(db, requestMaintenance, onError, options) {
16
+ this.db = db;
17
+ this.requestMaintenance = requestMaintenance;
18
+ this.outbox = new DurableEventQueue(db, onError, { ...options, pollIntervalMs: 0 });
19
+ }
20
+ async send(message) {
21
+ if (!message.outboxId) {
22
+ await enqueueEvent(this.db, message.workspaceId, message.type, message.data);
23
+ }
24
+ this.requestMaintenance();
25
+ }
26
+ /** Deliver every due outbox row and prune settled ones on the outbox's cadence. */
27
+ drain() {
28
+ return this.outbox.poll();
29
+ }
30
+ }
31
+ //# sourceMappingURL=event-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-queue.js","sourceRoot":"","sources":["../../../src/adapters/actor/event-queue.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAiC,MAAM,wBAAwB,CAAC;AAE1F;;;;;;;GAOG;AACH,MAAM,OAAO,eAAe;IAIP;IACA;IAJF,MAAM,CAAoB;IAE3C,YACmB,EAAY,EACZ,kBAA8B,EAC/C,OAA6D,EAC7D,OAA8F;QAH7E,OAAE,GAAF,EAAE,CAAU;QACZ,uBAAkB,GAAlB,kBAAkB,CAAY;QAI/C,IAAI,CAAC,MAAM,GAAG,IAAI,iBAAiB,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC7B,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED,mFAAmF;IACnF,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,66 @@
1
+ import type { FileStorage } from '../../ports/files.js';
2
+ /** Path the gateway serves signed file URLs on. */
3
+ export declare const ACTOR_FILE_ROUTE = "/_relayfiles";
4
+ /** Response header a gateway answers a signed `stat` (`HEAD`) with: the stored byte count. */
5
+ export declare const OBJECT_SIZE_HEADER = "x-relaycast-object-size";
6
+ /**
7
+ * File storage for a workspace actor. Blob bytes never pass through the
8
+ * actor: upload, download and delete URLs point at the gateway's
9
+ * `/_relayfiles` route, signed with a secret the gateway shares, and the
10
+ * gateway moves the bytes to and from its blob store (`verifyFileToken`). An
11
+ * upload URL binds the declared size and content type, which the gateway
12
+ * enforces.
13
+ *
14
+ * `statObject` asks the gateway for the stored size (`HEAD` with a signed
15
+ * `stat` token) so upload completion verifies the bytes, as on every adapter.
16
+ * It runs inside the completing request through `statFetch`, bounded by a
17
+ * short timeout. `deleteObjects` calls the gateway through `fetch`, which the
18
+ * actor runtime allows only during maintenance; inside a request it fails, and
19
+ * the engine's durable cleanup queue retries the deletion from maintenance.
20
+ */
21
+ export interface SignedUrlFileStorageOptions {
22
+ /** Public origin of the gateway that serves {@link ACTOR_FILE_ROUTE}. */
23
+ baseUrl: string;
24
+ /** HMAC secret shared with that gateway. */
25
+ secret: string;
26
+ /** Transport for blob deletes. */
27
+ fetch: typeof globalThis.fetch;
28
+ /** Transport for upload completion's size check. */
29
+ statFetch: typeof globalThis.fetch;
30
+ /** Per-delete timeout. Default 10s. */
31
+ deleteTimeoutMs?: number;
32
+ }
33
+ export declare class SignedUrlFileStorage implements FileStorage {
34
+ private readonly baseUrl;
35
+ private readonly secret;
36
+ private readonly fetch;
37
+ private readonly statFetch;
38
+ private readonly deleteTimeoutMs;
39
+ constructor(options: SignedUrlFileStorageOptions);
40
+ /** The stored size, from the gateway; `null` when nothing is stored under `storageKey`. */
41
+ statObject(args: {
42
+ storageKey: string;
43
+ }): Promise<{
44
+ sizeBytes: number;
45
+ } | null>;
46
+ private url;
47
+ createUploadUrl(args: {
48
+ storageKey: string;
49
+ contentType: string;
50
+ sizeBytes: number;
51
+ }): Promise<{
52
+ uploadUrl: string;
53
+ expiresAt: string;
54
+ }>;
55
+ createDownloadUrl(args: {
56
+ storageKey: string;
57
+ }): Promise<string>;
58
+ /** Deletes in order; when one fails (or the pass's budget runs out) it reports the keys already gone. */
59
+ deleteObjects(args: {
60
+ storageKeys: string[];
61
+ }): Promise<void | {
62
+ deletedKeys: string[];
63
+ }>;
64
+ private deleteObject;
65
+ }
66
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/adapters/actor/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAWxD,mDAAmD;AACnD,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,8FAA8F;AAC9F,eAAO,MAAM,kBAAkB,4BAA4B,CAAC;AAE5D;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,2BAA2B;IAC1C,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC/B,oDAAoD;IACpD,SAAS,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACnC,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,oBAAqB,YAAW,WAAW;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,OAAO,EAAE,2BAA2B;IAQhD,2FAA2F;IACrF,UAAU,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;YAevE,GAAG;IAKX,eAAe,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;;;;IAQpF,iBAAiB,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAItE,yGAAyG;IACnG,aAAa,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,GAAG;QAAE,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;YAajF,YAAY;CAU3B"}
@@ -0,0 +1,83 @@
1
+ import { signFileToken } from '../../lib/fileTokens.js';
2
+ const URL_TTL_SECONDS = 3600;
3
+ const DELETE_TTL_SECONDS = 300;
4
+ const STAT_TTL_SECONDS = 60;
5
+ /** Completion waits this long at most for the gateway; it holds the actor's mailbox meanwhile. */
6
+ const STAT_TIMEOUT_MS = 5_000;
7
+ /** A gateway that does not answer must not hold the actor's mailbox. */
8
+ const DELETE_TIMEOUT_MS = 10_000;
9
+ /** Path the gateway serves signed file URLs on. */
10
+ export const ACTOR_FILE_ROUTE = '/_relayfiles';
11
+ /** Response header a gateway answers a signed `stat` (`HEAD`) with: the stored byte count. */
12
+ export const OBJECT_SIZE_HEADER = 'x-relaycast-object-size';
13
+ export class SignedUrlFileStorage {
14
+ baseUrl;
15
+ secret;
16
+ fetch;
17
+ statFetch;
18
+ deleteTimeoutMs;
19
+ constructor(options) {
20
+ this.baseUrl = options.baseUrl;
21
+ this.secret = options.secret;
22
+ this.fetch = options.fetch;
23
+ this.statFetch = options.statFetch;
24
+ this.deleteTimeoutMs = options.deleteTimeoutMs ?? DELETE_TIMEOUT_MS;
25
+ }
26
+ /** The stored size, from the gateway; `null` when nothing is stored under `storageKey`. */
27
+ async statObject(args) {
28
+ const exp = Math.floor(Date.now() / 1000) + STAT_TTL_SECONDS;
29
+ const response = await this.statFetch(await this.url({ key: args.storageKey, op: 'stat', exp }), {
30
+ method: 'HEAD',
31
+ signal: AbortSignal.timeout(STAT_TIMEOUT_MS),
32
+ });
33
+ await response.body?.cancel();
34
+ if (response.status === 404)
35
+ return null;
36
+ const size = Number(response.headers.get(OBJECT_SIZE_HEADER));
37
+ if (!response.ok || !Number.isSafeInteger(size)) {
38
+ throw new Error(`Blob stat failed for ${args.storageKey} (HTTP ${response.status})`);
39
+ }
40
+ return { sizeBytes: size };
41
+ }
42
+ async url(payload) {
43
+ const token = await signFileToken(this.secret, payload);
44
+ return `${this.baseUrl.replace(/\/$/, '')}${ACTOR_FILE_ROUTE}?token=${token}`;
45
+ }
46
+ async createUploadUrl(args) {
47
+ const exp = Math.floor(Date.now() / 1000) + URL_TTL_SECONDS;
48
+ return {
49
+ uploadUrl: await this.url({ key: args.storageKey, op: 'put', exp, size: args.sizeBytes, type: args.contentType }),
50
+ expiresAt: new Date(exp * 1000).toISOString(),
51
+ };
52
+ }
53
+ async createDownloadUrl(args) {
54
+ return this.url({ key: args.storageKey, op: 'get', exp: Math.floor(Date.now() / 1000) + URL_TTL_SECONDS });
55
+ }
56
+ /** Deletes in order; when one fails (or the pass's budget runs out) it reports the keys already gone. */
57
+ async deleteObjects(args) {
58
+ const deletedKeys = [];
59
+ for (const key of args.storageKeys) {
60
+ try {
61
+ await this.deleteObject(key);
62
+ }
63
+ catch (error) {
64
+ if (deletedKeys.length === 0)
65
+ throw error;
66
+ return { deletedKeys };
67
+ }
68
+ deletedKeys.push(key);
69
+ }
70
+ }
71
+ async deleteObject(key) {
72
+ // A fresh token per key: a long batch must not outlive one shared expiry.
73
+ const exp = Math.floor(Date.now() / 1000) + DELETE_TTL_SECONDS;
74
+ const response = await this.fetch(await this.url({ key, op: 'delete', exp }), {
75
+ method: 'DELETE',
76
+ signal: AbortSignal.timeout(this.deleteTimeoutMs),
77
+ });
78
+ await response.body?.cancel();
79
+ if (!response.ok)
80
+ throw new Error(`Blob delete failed for ${key} (HTTP ${response.status})`);
81
+ }
82
+ }
83
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/adapters/actor/files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * HTTP exchanged with a workspace actor as JSON-compatible values: actor
3
+ * method arguments and results cross the durable-actors RPC boundary as JSON.
4
+ * Bodies are text; engine routes speak JSON, and file bytes go through the
5
+ * gateway's blob store, never through an actor.
6
+ */
7
+ export interface ActorHttpRequest {
8
+ method: string;
9
+ /** Absolute URL, as the client sent it to the gateway. */
10
+ url: string;
11
+ headers: [string, string][];
12
+ body: string | null;
13
+ }
14
+ export interface ActorHttpResponse {
15
+ status: number;
16
+ headers: [string, string][];
17
+ body: string;
18
+ }
19
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/adapters/actor/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/adapters/actor/http.ts"],"names":[],"mappings":""}
@@ -0,0 +1,90 @@
1
+ import type { EngineConfig, EngineDeps } from '../../ports/index.js';
2
+ import type { AuthProvider } from '../../ports/auth.js';
3
+ import type { TelemetrySink } from '../../ports/telemetry.js';
4
+ import { type ActorDatabase, type ActorSql } from './database.js';
5
+ export type { ActorDatabase, ActorSql, SqliteValue } from './database.js';
6
+ export type { ActorHttpRequest, ActorHttpResponse } from './http.js';
7
+ import type { ActorHttpRequest, ActorHttpResponse } from './http.js';
8
+ export interface ActorRuntimeOptions {
9
+ /** The actor's database (`this.db`, durable-actors >= 0.14.5). */
10
+ sql: ActorDatabase;
11
+ /** The actor id, which is the workspace id. */
12
+ workspaceId: string;
13
+ /** Public origin clients reach this deployment on; file URLs point at its `/_relayfiles`. */
14
+ baseUrl: string;
15
+ /** HMAC secret shared with the gateway that serves `/_relayfiles`. */
16
+ fileSigningSecret: string;
17
+ /**
18
+ * Outbound HTTP. Called only from {@link ActorRuntime.maintain}. Webhooks,
19
+ * http_push nodes, ephemeral events and A2A egress reach it only for HTTPS
20
+ * URLs whose host is a public name or global IP literal, with redirects off;
21
+ * the host's transport owns DNS-level SSRF protection (resolved-address
22
+ * checks). Blob deletes go to `baseUrl`.
23
+ */
24
+ outboundFetch: typeof globalThis.fetch;
25
+ /**
26
+ * The actor's alarm (`this.alarm`). The runtime arms it after calls and
27
+ * when outbound work is queued, never pushing an earlier pending alarm back.
28
+ */
29
+ alarm: {
30
+ get(): number | null;
31
+ set(timestampMs: number): void;
32
+ };
33
+ /**
34
+ * Total time one maintenance pass may spend deleting blobs through the
35
+ * gateway; the rest wait for the next pass. Positive; default 15s.
36
+ */
37
+ blobDeleteBudgetMs?: number;
38
+ /**
39
+ * Engine config. The runtime sets `workspaceId` (the actor id),
40
+ * `credentialFormat: 'ar'` with the tag the gateway handed {@link
41
+ * ActorRuntime.create} (a gateway routes by credential), and the outbound
42
+ * transports.
43
+ */
44
+ config?: Omit<EngineConfig, 'workspaceId' | 'credentialFormat' | 'credentialTagger' | 'outboundWebhookFetch' | 'ephemeralEventFetch'>;
45
+ auth?: AuthProvider;
46
+ telemetry?: TelemetrySink;
47
+ }
48
+ /** The engine running inside one workspace actor. */
49
+ export interface ActorRuntime {
50
+ readonly deps: EngineDeps;
51
+ /**
52
+ * Serve one HTTP request inside an actor call. Engine background
53
+ * work is awaited, so it commits with the call. Each engine write group is
54
+ * a nested actor transaction: a failed group rolls back alone and the
55
+ * request goes on, as on the Node adapter.
56
+ */
57
+ handle(request: ActorHttpRequest): Promise<ActorHttpResponse>;
58
+ /**
59
+ * Create this actor's workspace (`POST /v1/workspaces`) inside an actor
60
+ * call. `credentialTag` is the routing tag the gateway signed for the
61
+ * workspace id (`createCredentialTagSigner(keyring).tag(id)`); the actor
62
+ * keeps it and every `ar_` credential it mints carries it.
63
+ */
64
+ create(request: ActorHttpRequest, credentialTag: string): Promise<ActorHttpResponse>;
65
+ /**
66
+ * Run maintenance from the actor alarm: deliver the webhook outbox and
67
+ * queued ephemeral events, redrive node deliveries and A2A egress, delete
68
+ * blobs, run liveness and presence sweeps, expiry and retention. Re-arms the
69
+ * alarm for the nearest outstanding deadline (see {@link nextMaintenanceAt}).
70
+ * Each step runs in its own nested transaction: a step or write group that
71
+ * fails rolls back alone, raises a `maintenance_rolled_back` alert, and the
72
+ * rest of the pass commits.
73
+ */
74
+ maintain(): Promise<void>;
75
+ }
76
+ export declare function createActorRuntime(options: ActorRuntimeOptions): ActorRuntime;
77
+ /**
78
+ * When maintenance next has something to do, from the workspace's own
79
+ * outstanding work: the nearest due time of the webhook outbox, unfinished
80
+ * deliveries (redrive and expiry), A2A egress, the invocation timeouts the
81
+ * invocation sweep acts on, including task deadlines (a plain queue waiting
82
+ * for its node to reconnect has none: the reconnect is a request, which
83
+ * re-arms), agent
84
+ * liveness, blob cleanup, workspace expiry, idempotency-record expiry, A2A
85
+ * retention, and queued ephemeral events, and
86
+ * the sweep cadence while nodes are connected. `null` when nothing is
87
+ * outstanding, so an idle workspace's actor goes dormant.
88
+ */
89
+ export declare function nextMaintenanceAt(sql: ActorSql): number | null;
90
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/actor/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAiB9D,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAYvF,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1E,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAQrE,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,GAAG,EAAE,aAAa,CAAC;IACnB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,6FAA6F;IAC7F,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACvC;;;OAGG;IACH,KAAK,EAAE;QAAE,GAAG,IAAI,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChE;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,sBAAsB,GAAG,qBAAqB,CAAC,CAAC;IACtI,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9D;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACrF;;;;;;;;OAQG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AASD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAqN7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAkC9D"}