@ixo/oracle-runtime-workers 0.39.0 → 0.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ixo/oracle-runtime-workers",
3
- "version": "0.39.0",
3
+ "version": "0.40.1",
4
4
  "description": "QiForge oracle runtime for Cloudflare Workers — Durable Object per user (SQLite in WASM over DO storage), Matrix E2EE gateway Durable Object, Hono HTTP/SSE shell.",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -68,8 +68,9 @@
68
68
  "@ixo/topic-protocol": "1.0.0-rc.8",
69
69
  "survey-core": "2.3.11",
70
70
  "@ixo/common": "1.8.0",
71
- "@ixo/ucan": "2.3.0",
72
- "@ixo/ixo-transaction": "0.2.0"
71
+ "@ixo/ixo-transaction": "0.2.0",
72
+ "@ixo/action-interactions": "0.1.1",
73
+ "@ixo/ucan": "2.3.0"
73
74
  },
74
75
  "devDependencies": {
75
76
  "@cloudflare/vitest-pool-workers": "^0.22.0",
@@ -0,0 +1,78 @@
1
+ import {
2
+ ActionInteractionError,
3
+ PrepareInteractionSchema,
4
+ UpdateInteractionSchema,
5
+ ReserveInteractionSchema,
6
+ ObserveInteractionSchema,
7
+ } from '@ixo/action-interactions';
8
+ import { z } from 'zod';
9
+ import type { InteractionCommand } from './store';
10
+
11
+ const InteractionIdSchema = z.string().uuid();
12
+ const InteractionSessionIdSchema = z.string().min(1).max(512);
13
+
14
+ /**
15
+ * Structural parsing happens before the authenticated per-user object is
16
+ * called. Only these shapes exist: `POST /` prepares, `PATCH /:id` updates
17
+ * or cancels, `POST /:id/reserve` and `POST /:id/observe` are the host's.
18
+ * Anything else, including a path id that is not a UUID, is not found.
19
+ */
20
+ export async function parseInteractionCommand(
21
+ request: Request,
22
+ id?: string,
23
+ hostOperation?: string,
24
+ ): Promise<InteractionCommand> {
25
+ const notFound = () =>
26
+ new ActionInteractionError(
27
+ 404,
28
+ 'not_found',
29
+ 'Unknown interaction operation',
30
+ );
31
+ if (id !== undefined && !InteractionIdSchema.safeParse(id).success)
32
+ throw notFound();
33
+ const method = request.method;
34
+ const body: unknown = await request.json().catch(() => null);
35
+ if (method === 'POST' && id === undefined && hostOperation === undefined)
36
+ return { kind: 'prepare', input: PrepareInteractionSchema.parse(body) };
37
+ if (method === 'PATCH' && id !== undefined && hostOperation === undefined)
38
+ return { kind: 'update', id, input: UpdateInteractionSchema.parse(body) };
39
+ if (method === 'POST' && id !== undefined && hostOperation === 'reserve')
40
+ return { kind: 'reserve', id, input: ReserveInteractionSchema.parse(body) };
41
+ if (method === 'POST' && id !== undefined && hostOperation === 'observe')
42
+ return { kind: 'observe', id, input: ObserveInteractionSchema.parse(body) };
43
+ throw notFound();
44
+ }
45
+
46
+ /** A read: `GET /?sessionId=` lists, `GET /:id?sessionId=` reads one. */
47
+ export function parseInteractionRead(
48
+ sessionId: string | undefined,
49
+ id?: string,
50
+ operation?: string,
51
+ ): { sessionId: string; id?: string } {
52
+ if (
53
+ operation !== undefined ||
54
+ (id !== undefined && !InteractionIdSchema.safeParse(id).success)
55
+ )
56
+ throw new ActionInteractionError(404, 'not_found', 'Interaction not found');
57
+ const session = InteractionSessionIdSchema.safeParse(sessionId);
58
+ if (!session.success)
59
+ throw new ActionInteractionError(
60
+ 400,
61
+ 'invalid_request',
62
+ 'sessionId is required',
63
+ );
64
+ return { sessionId: session.data, ...(id !== undefined ? { id } : {}) };
65
+ }
66
+
67
+ /** The HTTP status for an owner refusal; anything unexpected is a conflict. */
68
+ export function interactionStatus(
69
+ status: number,
70
+ ): 400 | 403 | 404 | 409 | 410 | 413 {
71
+ return status === 400 ||
72
+ status === 403 ||
73
+ status === 404 ||
74
+ status === 410 ||
75
+ status === 413
76
+ ? status
77
+ : 409;
78
+ }