@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.
Files changed (79) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +2042 -0
  3. package/dist/browser.d.ts +384 -0
  4. package/dist/browser.js +2 -0
  5. package/dist/browser.js.map +1 -0
  6. package/dist/index.d.ts +644 -0
  7. package/dist/index.js +2 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/react.d.ts +416 -0
  10. package/dist/react.js +2 -0
  11. package/dist/react.js.map +1 -0
  12. package/dist/src/alarms.d.ts +47 -0
  13. package/dist/src/alarms.d.ts.map +1 -0
  14. package/dist/src/browser.d.ts +2 -0
  15. package/dist/src/browser.d.ts.map +1 -0
  16. package/dist/src/constants.d.ts +12 -0
  17. package/dist/src/constants.d.ts.map +1 -0
  18. package/dist/src/createAccessToken.d.ts +9 -0
  19. package/dist/src/createAccessToken.d.ts.map +1 -0
  20. package/dist/src/createActorFetch.d.ts +18 -0
  21. package/dist/src/createActorFetch.d.ts.map +1 -0
  22. package/dist/src/createActorKitClient.d.ts +13 -0
  23. package/dist/src/createActorKitClient.d.ts.map +1 -0
  24. package/dist/src/createActorKitContext.d.ts +29 -0
  25. package/dist/src/createActorKitContext.d.ts.map +1 -0
  26. package/dist/src/createActorKitMockClient.d.ts +11 -0
  27. package/dist/src/createActorKitMockClient.d.ts.map +1 -0
  28. package/dist/src/createActorKitRouter.d.ts +4 -0
  29. package/dist/src/createActorKitRouter.d.ts.map +1 -0
  30. package/dist/src/createMachineServer.d.ts +20 -0
  31. package/dist/src/createMachineServer.d.ts.map +1 -0
  32. package/dist/src/durable-object-system.d.ts +36 -0
  33. package/dist/src/durable-object-system.d.ts.map +1 -0
  34. package/dist/src/index.d.ts +7 -0
  35. package/dist/src/index.d.ts.map +1 -0
  36. package/dist/src/react.d.ts +2 -0
  37. package/dist/src/react.d.ts.map +1 -0
  38. package/dist/src/schemas.d.ts +312 -0
  39. package/dist/src/schemas.d.ts.map +1 -0
  40. package/dist/src/server.d.ts +3 -0
  41. package/dist/src/server.d.ts.map +1 -0
  42. package/dist/src/storage.d.ts +64 -0
  43. package/dist/src/storage.d.ts.map +1 -0
  44. package/dist/src/storybook.d.ts +13 -0
  45. package/dist/src/storybook.d.ts.map +1 -0
  46. package/dist/src/test.d.ts +2 -0
  47. package/dist/src/test.d.ts.map +1 -0
  48. package/dist/src/types.d.ts +181 -0
  49. package/dist/src/types.d.ts.map +1 -0
  50. package/dist/src/utils.d.ts +30 -0
  51. package/dist/src/utils.d.ts.map +1 -0
  52. package/dist/src/withActorKit.d.ts +9 -0
  53. package/dist/src/withActorKit.d.ts.map +1 -0
  54. package/dist/src/worker.d.ts +3 -0
  55. package/dist/src/worker.d.ts.map +1 -0
  56. package/package.json +87 -0
  57. package/src/alarms.ts +237 -0
  58. package/src/browser.ts +1 -0
  59. package/src/constants.ts +31 -0
  60. package/src/createAccessToken.ts +29 -0
  61. package/src/createActorFetch.ts +111 -0
  62. package/src/createActorKitClient.ts +224 -0
  63. package/src/createActorKitContext.tsx +228 -0
  64. package/src/createActorKitMockClient.ts +138 -0
  65. package/src/createActorKitRouter.ts +149 -0
  66. package/src/createMachineServer.ts +844 -0
  67. package/src/durable-object-system.ts +212 -0
  68. package/src/global.d.ts +7 -0
  69. package/src/index.ts +6 -0
  70. package/src/react.ts +1 -0
  71. package/src/schemas.ts +95 -0
  72. package/src/server.ts +3 -0
  73. package/src/storage.ts +404 -0
  74. package/src/storybook.ts +42 -0
  75. package/src/test.ts +1 -0
  76. package/src/types.ts +334 -0
  77. package/src/utils.ts +171 -0
  78. package/src/withActorKit.tsx +103 -0
  79. 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
+ };