@methodacting/actor-kit 0.47.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.
- package/LICENSE.md +7 -0
- package/README.md +2042 -0
- package/dist/browser.d.ts +384 -0
- package/dist/browser.js +2 -0
- package/dist/browser.js.map +1 -0
- package/dist/index.d.ts +644 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/react.d.ts +416 -0
- package/dist/react.js +2 -0
- package/dist/react.js.map +1 -0
- package/dist/src/alarms.d.ts +47 -0
- package/dist/src/alarms.d.ts.map +1 -0
- package/dist/src/browser.d.ts +2 -0
- package/dist/src/browser.d.ts.map +1 -0
- package/dist/src/constants.d.ts +12 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/createAccessToken.d.ts +9 -0
- package/dist/src/createAccessToken.d.ts.map +1 -0
- package/dist/src/createActorFetch.d.ts +18 -0
- package/dist/src/createActorFetch.d.ts.map +1 -0
- package/dist/src/createActorKitClient.d.ts +13 -0
- package/dist/src/createActorKitClient.d.ts.map +1 -0
- package/dist/src/createActorKitContext.d.ts +29 -0
- package/dist/src/createActorKitContext.d.ts.map +1 -0
- package/dist/src/createActorKitMockClient.d.ts +11 -0
- package/dist/src/createActorKitMockClient.d.ts.map +1 -0
- package/dist/src/createActorKitRouter.d.ts +4 -0
- package/dist/src/createActorKitRouter.d.ts.map +1 -0
- package/dist/src/createMachineServer.d.ts +20 -0
- package/dist/src/createMachineServer.d.ts.map +1 -0
- package/dist/src/durable-object-system.d.ts +36 -0
- package/dist/src/durable-object-system.d.ts.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/react.d.ts +2 -0
- package/dist/src/react.d.ts.map +1 -0
- package/dist/src/schemas.d.ts +312 -0
- package/dist/src/schemas.d.ts.map +1 -0
- package/dist/src/server.d.ts +3 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/storage.d.ts +64 -0
- package/dist/src/storage.d.ts.map +1 -0
- package/dist/src/storybook.d.ts +13 -0
- package/dist/src/storybook.d.ts.map +1 -0
- package/dist/src/test.d.ts +2 -0
- package/dist/src/test.d.ts.map +1 -0
- package/dist/src/types.d.ts +181 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils.d.ts +30 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/withActorKit.d.ts +9 -0
- package/dist/src/withActorKit.d.ts.map +1 -0
- package/dist/src/worker.d.ts +3 -0
- package/dist/src/worker.d.ts.map +1 -0
- package/package.json +87 -0
- package/src/alarms.ts +237 -0
- package/src/browser.ts +1 -0
- package/src/constants.ts +31 -0
- package/src/createAccessToken.ts +29 -0
- package/src/createActorFetch.ts +111 -0
- package/src/createActorKitClient.ts +224 -0
- package/src/createActorKitContext.tsx +228 -0
- package/src/createActorKitMockClient.ts +138 -0
- package/src/createActorKitRouter.ts +149 -0
- package/src/createMachineServer.ts +844 -0
- package/src/durable-object-system.ts +212 -0
- package/src/global.d.ts +7 -0
- package/src/index.ts +6 -0
- package/src/react.ts +1 -0
- package/src/schemas.ts +95 -0
- package/src/server.ts +3 -0
- package/src/storage.ts +404 -0
- package/src/storybook.ts +42 -0
- package/src/test.ts +1 -0
- package/src/types.ts +334 -0
- package/src/utils.ts +171 -0
- package/src/withActorKit.tsx +103 -0
- package/src/worker.ts +2 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DurableObjectNamespace,
|
|
3
|
+
ExecutionContext,
|
|
4
|
+
} from "@cloudflare/workers-types";
|
|
5
|
+
import { AnyEventSchema } from "./schemas";
|
|
6
|
+
import {
|
|
7
|
+
AnyActorKitStateMachine,
|
|
8
|
+
AnyEvent,
|
|
9
|
+
Caller,
|
|
10
|
+
DurableObjectActor,
|
|
11
|
+
EnvWithDurableObjects,
|
|
12
|
+
KebabToScreamingSnake,
|
|
13
|
+
ScreamingSnakeToKebab,
|
|
14
|
+
} from "./types";
|
|
15
|
+
import { getCallerFromRequest } from "./utils";
|
|
16
|
+
|
|
17
|
+
export const createActorKitRouter = <Env extends EnvWithDurableObjects>(
|
|
18
|
+
routes: Array<ScreamingSnakeToKebab<Extract<keyof Env, string>>>
|
|
19
|
+
) => {
|
|
20
|
+
type ActorType = ScreamingSnakeToKebab<Extract<keyof Env, string>>;
|
|
21
|
+
|
|
22
|
+
// Add a Set to keep track of spawned actors
|
|
23
|
+
const spawnedActors = new Set<string>();
|
|
24
|
+
|
|
25
|
+
function getDurableObjectNamespace<
|
|
26
|
+
T extends ScreamingSnakeToKebab<Extract<keyof Env, string>>
|
|
27
|
+
>(
|
|
28
|
+
env: Env,
|
|
29
|
+
key: T
|
|
30
|
+
):
|
|
31
|
+
| DurableObjectNamespace<DurableObjectActor<AnyActorKitStateMachine>>
|
|
32
|
+
| undefined {
|
|
33
|
+
const envKey = key.toUpperCase() as KebabToScreamingSnake<T> & keyof Env;
|
|
34
|
+
const namespace = env[envKey];
|
|
35
|
+
if (
|
|
36
|
+
namespace &&
|
|
37
|
+
typeof namespace === "object" &&
|
|
38
|
+
"get" in namespace &&
|
|
39
|
+
"idFromName" in namespace
|
|
40
|
+
) {
|
|
41
|
+
return namespace as unknown as DurableObjectNamespace<
|
|
42
|
+
DurableObjectActor<AnyActorKitStateMachine>
|
|
43
|
+
>;
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return async (
|
|
49
|
+
request: Request,
|
|
50
|
+
env: Env,
|
|
51
|
+
ctx: ExecutionContext
|
|
52
|
+
): Promise<Response> => {
|
|
53
|
+
const url = new URL(request.url);
|
|
54
|
+
const pathParts = url.pathname.split("/").filter(Boolean);
|
|
55
|
+
if (pathParts.length !== 3 || pathParts[0] !== "api") {
|
|
56
|
+
return new Response("Not Found", { status: 404 });
|
|
57
|
+
}
|
|
58
|
+
const [, actorType, actorId] = pathParts;
|
|
59
|
+
|
|
60
|
+
if (!routes.includes(actorType as any)) {
|
|
61
|
+
return new Response(`Unknown actor type: ${actorType}`, { status: 400 });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const durableObjectNamespace = getDurableObjectNamespace<ActorType>(
|
|
65
|
+
env,
|
|
66
|
+
actorType as ActorType
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (!durableObjectNamespace) {
|
|
70
|
+
return new Response(
|
|
71
|
+
`Durable Object namespace not found for actor type: ${actorType}`,
|
|
72
|
+
{ status: 500 }
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const durableObjectId = durableObjectNamespace.idFromName(actorId);
|
|
77
|
+
const durableObjectStub = durableObjectNamespace.get(durableObjectId);
|
|
78
|
+
|
|
79
|
+
// Parse the auth header to get the caller token
|
|
80
|
+
let caller: Caller;
|
|
81
|
+
try {
|
|
82
|
+
caller = await getCallerFromRequest(
|
|
83
|
+
request,
|
|
84
|
+
actorType,
|
|
85
|
+
actorId,
|
|
86
|
+
env.ACTOR_KIT_SECRET
|
|
87
|
+
);
|
|
88
|
+
} catch (error: any) {
|
|
89
|
+
return new Response(
|
|
90
|
+
`Error: ${error.message}. API requests must specify a valid caller in Bearer token in the Authorization header using fetch method created from 'createActorFetch' or use 'createAccessToken' directly.`,
|
|
91
|
+
{ status: 401 }
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Create a unique key for the actor
|
|
96
|
+
const actorKey = `${actorType}:${actorId}`;
|
|
97
|
+
|
|
98
|
+
// Check if the actor has already been spawned
|
|
99
|
+
if (!spawnedActors.has(actorKey)) {
|
|
100
|
+
// If not, spawn it and mark it as spawned
|
|
101
|
+
await durableObjectStub.spawn({
|
|
102
|
+
actorType,
|
|
103
|
+
actorId,
|
|
104
|
+
caller,
|
|
105
|
+
input: {},
|
|
106
|
+
});
|
|
107
|
+
spawnedActors.add(actorKey);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (request.headers.get("Upgrade") === "websocket") {
|
|
111
|
+
return durableObjectStub.fetch(request as any) as any; // Handle WebSocket upgrade
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (request.method === "GET") {
|
|
115
|
+
const { waitForEvent, waitForState, timeout, errorOnWaitTimeout } =
|
|
116
|
+
Object.fromEntries(new URL(request.url).searchParams);
|
|
117
|
+
|
|
118
|
+
const result = await durableObjectStub.getSnapshot(caller, {
|
|
119
|
+
waitForEvent: waitForEvent ? JSON.parse(waitForEvent) : undefined,
|
|
120
|
+
waitForState: waitForState ? JSON.parse(waitForState) : undefined,
|
|
121
|
+
timeout: timeout ? parseInt(timeout, 10) : undefined,
|
|
122
|
+
errorOnWaitTimeout: errorOnWaitTimeout ? errorOnWaitTimeout === 'true' : undefined,
|
|
123
|
+
});
|
|
124
|
+
return new Response(JSON.stringify(result), {
|
|
125
|
+
headers: { "Content-Type": "application/json" },
|
|
126
|
+
});
|
|
127
|
+
} else if (request.method === "POST") {
|
|
128
|
+
let event: AnyEvent;
|
|
129
|
+
try {
|
|
130
|
+
const json = await request.json();
|
|
131
|
+
event = AnyEventSchema.parse(json);
|
|
132
|
+
} catch (ex: any) {
|
|
133
|
+
return new Response(JSON.stringify({ error: ex.message }), {
|
|
134
|
+
status: 400,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
durableObjectStub.send({
|
|
139
|
+
...event,
|
|
140
|
+
caller,
|
|
141
|
+
});
|
|
142
|
+
return new Response(JSON.stringify({ success: true }));
|
|
143
|
+
} else {
|
|
144
|
+
return new Response(JSON.stringify({ error: "Method not allowed" }), {
|
|
145
|
+
status: 405,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
};
|