@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,181 @@
1
+ import { DurableObject } from "cloudflare:workers";
2
+ import { Operation } from "fast-json-patch";
3
+ import type { AnyEventObject, AnyStateMachine, SnapshotFrom, StateMachine, StateValueFrom } from "xstate";
4
+ import type { z } from "zod";
5
+ import type { AnyEventSchema, CallerSchema, RequestInfoSchema, SystemEventSchema } from "./schemas";
6
+ import type { AlarmManager } from "./alarms";
7
+ import type { ActorKitStorage } from "./storage";
8
+ export type EnvWithDurableObjects = {
9
+ ACTOR_KIT_SECRET: string;
10
+ [key: string]: DurableObjectNamespace<ActorServer<any>> | unknown;
11
+ };
12
+ export type AnyEvent = z.infer<typeof AnyEventSchema>;
13
+ export interface ActorServerMethods<TMachine extends BaseActorKitStateMachine> {
14
+ fetch(request: Request): Promise<Response>;
15
+ spawn(props: {
16
+ actorType: string;
17
+ actorId: string;
18
+ caller: Caller;
19
+ input: Record<string, unknown>;
20
+ }): void;
21
+ send(event: ClientEventFrom<TMachine> | ServiceEventFrom<TMachine>): void;
22
+ getSnapshot(caller: Caller, options?: {
23
+ waitForEvent?: ClientEventFrom<TMachine>;
24
+ waitForState?: StateValueFrom<TMachine>;
25
+ timeout?: number;
26
+ errorOnWaitTimeout?: boolean;
27
+ }): Promise<{
28
+ checksum: string;
29
+ snapshot: CallerSnapshotFrom<TMachine>;
30
+ }>;
31
+ }
32
+ export type ActorServer<TMachine extends AnyActorKitStateMachine> = DurableObject & ActorServerMethods<TMachine>;
33
+ export type AnyActorServer = ActorServer<any>;
34
+ export type Caller = z.infer<typeof CallerSchema>;
35
+ export type RequestInfo = z.infer<typeof RequestInfoSchema>;
36
+ export type ActorKitInputProps = {
37
+ id: string;
38
+ caller: Caller;
39
+ storage: DurableObjectStorage;
40
+ [key: string]: unknown;
41
+ };
42
+ export type CallerType = "client" | "system" | "service";
43
+ type EventObject = {
44
+ type: string;
45
+ };
46
+ type EventSchemaUnion = z.ZodDiscriminatedUnion<"type", [
47
+ z.ZodObject<z.ZodRawShape & {
48
+ type: z.ZodString;
49
+ }>,
50
+ ...z.ZodObject<z.ZodRawShape & {
51
+ type: z.ZodString;
52
+ }>[]
53
+ ]>;
54
+ export type EventSchemas = {
55
+ client: EventSchemaUnion;
56
+ service: EventSchemaUnion;
57
+ };
58
+ export type BaseActorKitContext<TPublicProps extends {
59
+ [key: string]: unknown;
60
+ }, TPrivateProps extends {
61
+ [key: string]: unknown;
62
+ }> = {
63
+ public: TPublicProps;
64
+ private: Record<string, TPrivateProps>;
65
+ };
66
+ export type ActorKitStateMachine<TEvent extends BaseActorKitEvent<EnvWithDurableObjects>, TInput extends {
67
+ id: string;
68
+ caller: Caller;
69
+ storage: DurableObjectStorage;
70
+ }, TContext extends BaseActorKitContext<any, any> & {
71
+ [key: string]: unknown;
72
+ }> = StateMachine<TContext, TEvent & EventObject, any, any, any, any, any, any, any, TInput, any, any, any, any>;
73
+ export type BaseActorKitInput<TEnv = EnvWithDurableObjects> = {
74
+ id: string;
75
+ caller: Caller;
76
+ env: TEnv;
77
+ storage: DurableObjectStorage;
78
+ };
79
+ export type WithActorKitInput<TInputProps extends {
80
+ [key: string]: unknown;
81
+ }, TEnv extends EnvWithDurableObjects> = TInputProps & BaseActorKitInput<TEnv>;
82
+ export type AnyActorKitStateMachine = ActorKitStateMachine<any, any, any>;
83
+ type AnyActorKitEvent = (WithActorKitEvent<AnyEventObject, "client"> | WithActorKitEvent<AnyEventObject, "service"> | ActorKitSystemEvent) & BaseActorKitEvent<EnvWithDurableObjects>;
84
+ type AnyActorKitInput = WithActorKitInput<{
85
+ [key: string]: unknown;
86
+ }, EnvWithDurableObjects> & {
87
+ storage: DurableObjectStorage;
88
+ };
89
+ type AnyActorKitContext = {
90
+ public: {
91
+ [key: string]: unknown;
92
+ };
93
+ private: Record<string, {
94
+ [key: string]: unknown;
95
+ }>;
96
+ };
97
+ export type BaseActorKitStateMachine = ActorKitStateMachine<AnyActorKitEvent, AnyActorKitInput, AnyActorKitContext>;
98
+ export type ExtraContext = {
99
+ requestId: string;
100
+ };
101
+ export interface BaseActorKitEvent<TEnv extends EnvWithDurableObjects> {
102
+ caller: Caller;
103
+ storage: DurableObjectStorage;
104
+ requestInfo?: RequestInfo;
105
+ env: TEnv;
106
+ }
107
+ export type ActorKitSystemEvent = z.infer<typeof SystemEventSchema>;
108
+ export type WithActorKitEvent<T extends {
109
+ type: string;
110
+ }, C extends CallerType> = T & BaseActorKitEvent<EnvWithDurableObjects> & {
111
+ caller: {
112
+ type: C;
113
+ };
114
+ };
115
+ export type WithActorKitContext<TExtraProps extends {
116
+ [key: string]: unknown;
117
+ }, TPrivateProps extends {
118
+ [key: string]: unknown;
119
+ }, TPublicProps extends {
120
+ [key: string]: unknown;
121
+ }> = TExtraProps & {
122
+ public: TPublicProps;
123
+ private: Record<string, TPrivateProps>;
124
+ };
125
+ export type CallerSnapshotFrom<TMachine extends AnyStateMachine> = {
126
+ public: SnapshotFrom<TMachine> extends {
127
+ context: {
128
+ public: infer P;
129
+ };
130
+ } ? P : unknown;
131
+ private: SnapshotFrom<TMachine> extends {
132
+ context: {
133
+ private: Partial<Record<string, infer PR>>;
134
+ };
135
+ } ? PR : unknown;
136
+ value: SnapshotFrom<TMachine> extends {
137
+ value: infer V;
138
+ } ? V : unknown;
139
+ };
140
+ export type ClientEventFrom<T extends AnyActorKitStateMachine> = T extends StateMachine<any, infer TEvent, any, any, any, any, any, any, any, any, any, any, any, any> ? TEvent extends WithActorKitEvent<infer E, "client"> ? Omit<E, keyof BaseActorKitEvent<EnvWithDurableObjects>> : never : never;
141
+ export type ServiceEventFrom<T extends AnyActorKitStateMachine> = T extends StateMachine<any, infer TEvent, any, any, any, any, any, any, any, any, any, any, any, any> ? TEvent extends WithActorKitEvent<infer E, "service"> ? Omit<E, keyof BaseActorKitEvent<EnvWithDurableObjects>> : never : never;
142
+ export type ScreamingSnakeToKebab<S extends string> = S extends `${infer T}_${infer U}` ? `${Lowercase<T>}-${ScreamingSnakeToKebab<U>}` : Lowercase<S>;
143
+ export type DurableObjectActor<TMachine extends AnyActorKitStateMachine> = ActorServer<TMachine>;
144
+ type CamelToSnakeCase<S extends string> = S extends `${infer T}${infer U}` ? U extends Uncapitalize<U> ? `${Lowercase<T>}${CamelToSnakeCase<U>}` : `${Lowercase<T>}_${CamelToSnakeCase<U>}` : S;
145
+ type KebabToCamelCase<S extends string> = S extends `${infer T}-${infer U}` ? `${T}${Capitalize<KebabToCamelCase<U>>}` : S;
146
+ export type KebabToScreamingSnake<S extends string> = Uppercase<CamelToSnakeCase<KebabToCamelCase<S>>>;
147
+ export interface MatchesProps<TMachine extends AnyActorKitStateMachine> {
148
+ state: StateValueFrom<TMachine>;
149
+ and?: StateValueFrom<TMachine>;
150
+ or?: StateValueFrom<TMachine>;
151
+ not?: boolean;
152
+ initialValueOverride?: boolean;
153
+ }
154
+ export type MachineFromServer<T> = T extends ActorServer<infer M> ? M : never;
155
+ export type ActorKitEmittedEvent = {
156
+ operations: Operation[];
157
+ checksum: string;
158
+ };
159
+ export type ActorKitClient<TMachine extends AnyActorKitStateMachine> = {
160
+ connect: () => Promise<void>;
161
+ disconnect: () => void;
162
+ send: (event: ClientEventFrom<TMachine>) => void;
163
+ getState: () => CallerSnapshotFrom<TMachine>;
164
+ subscribe: (listener: (state: CallerSnapshotFrom<TMachine>) => void) => () => void;
165
+ waitFor: (predicateFn: (state: CallerSnapshotFrom<TMachine>) => boolean, timeoutMs?: number) => Promise<void>;
166
+ };
167
+ type ExtractEventType<TMachine> = TMachine extends ActorKitStateMachine<infer TEvent, any, any> ? TEvent : never;
168
+ type ExtractEnvType<TEvent> = TEvent extends {
169
+ env: infer TEnv;
170
+ } ? TEnv : never;
171
+ export type EnvFromMachine<TMachine extends AnyActorKitStateMachine> = ExtractEnvType<ExtractEventType<TMachine>> extends never ? EnvWithDurableObjects : ExtractEnvType<ExtractEventType<TMachine>> & EnvWithDurableObjects;
172
+ export interface MachineServerOptions {
173
+ persisted?: boolean;
174
+ enableAlarms?: boolean;
175
+ }
176
+ export interface MachineServerServices {
177
+ storage: ActorKitStorage;
178
+ alarmManager: AlarmManager | null;
179
+ }
180
+ export {};
181
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { Caller } from "./types";
2
+ export declare enum LogLevel {
3
+ ERROR = 0,
4
+ WARN = 1,
5
+ INFO = 2,
6
+ DEBUG = 3
7
+ }
8
+ declare global {
9
+ var DEBUG_LEVEL: LogLevel | undefined;
10
+ }
11
+ export declare function debug(message: string, level?: LogLevel, data?: any): void;
12
+ export declare const logError: (message: string, data?: any) => void;
13
+ export declare const logWarn: (message: string, data?: any) => void;
14
+ export declare const logInfo: (message: string, data?: any) => void;
15
+ export declare const json: <T>(data: T, status?: number) => Response;
16
+ export declare const ok: () => Response;
17
+ export declare const error: (err: string | {
18
+ message: string;
19
+ }, status?: number) => Response;
20
+ export declare const notFound: () => Response;
21
+ export declare const parseQueryParams: (url: string) => URLSearchParams;
22
+ export declare function assert<T>(expression: T, errorMessage: string): asserts expression;
23
+ export declare function getCallerFromRequest(request: Request, actorType: string, actorId: string, secret: string): Promise<Caller>;
24
+ export declare function parseAccessTokenForCaller({ accessToken, type, id, secret, }: {
25
+ accessToken: string;
26
+ type: string;
27
+ id: string;
28
+ secret: string;
29
+ }): Promise<Caller>;
30
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,WAAW,EAAE,QAAQ,GAAG,SAAS,CAAC;CACvC;AAgBD,wBAAgB,KAAK,CACnB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,QAAyB,EAChC,IAAI,CAAC,EAAE,GAAG,QAsBX;AAGD,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,EAAE,OAAO,GAAG,SACd,CAAC;AACvC,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,EAAE,OAAO,GAAG,SACd,CAAC;AACtC,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,EAAE,OAAO,GAAG,SACd,CAAC;AAEtC,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,MAAM,CAAC,EAAE,eAAY,aACZ,CAAC;AAElC,eAAO,MAAM,EAAE,gBAA2B,CAAC;AAE3C,eAAO,MAAM,KAAK,GAAI,KAAK,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,eAAY,aASpE,CAAC;AAEF,eAAO,MAAM,QAAQ,gBAAgC,CAAC;AAOtD,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,oBAI3C,CAAC;AAEF,wBAAgB,MAAM,CAAC,CAAC,EACtB,UAAU,EAAE,CAAC,EACb,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,CAYpB;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAED,wBAAsB,yBAAyB,CAAC,EAC9C,WAAW,EACX,IAAI,EACJ,EAAE,EACF,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlB"}
@@ -0,0 +1,9 @@
1
+ import type { StoryContext, StoryFn } from "@storybook/react";
2
+ import React from "react";
3
+ import { createActorKitContext } from "./createActorKitContext";
4
+ import type { AnyActorKitStateMachine } from "./types";
5
+ export declare const withActorKit: <TMachine extends AnyActorKitStateMachine>({ actorType, context, }: {
6
+ actorType: string;
7
+ context: ReturnType<typeof createActorKitContext<TMachine>>;
8
+ }) => (Story: StoryFn, storyContext: StoryContext) => React.ReactElement;
9
+ //# sourceMappingURL=withActorKit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withActorKit.d.ts","sourceRoot":"","sources":["../../src/withActorKit.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,KAAK,EAAE,uBAAuB,EAAsB,MAAM,SAAS,CAAC;AAqD3E,eAAO,MAAM,YAAY,GAAI,QAAQ,SAAS,uBAAuB,EAAE,yBAGpE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC;CAC7D,MACS,OAAO,OAAO,EAAE,cAAc,YAAY,KAAG,KAAK,CAAC,YAsC5D,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createActorKitRouter } from "./createActorKitRouter";
2
+ export { createMachineServer } from "./createMachineServer";
3
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "@methodacting/actor-kit",
3
+ "version": "0.47.0",
4
+ "main": "./src/index.ts",
5
+ "module": "./src/index.ts",
6
+ "types": "./src/index.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./browser": {
13
+ "types": "./dist/browser.d.ts",
14
+ "import": "./dist/browser.js"
15
+ },
16
+ "./server": {
17
+ "types": "./src/server.ts",
18
+ "import": "./src/server.ts"
19
+ },
20
+ "./react": {
21
+ "types": "./dist/react.d.ts",
22
+ "import": "./dist/react.js"
23
+ },
24
+ "./storybook": {
25
+ "types": "./src/storybook.ts",
26
+ "import": "./src/storybook.ts"
27
+ },
28
+ "./test": {
29
+ "types": "./src/test.ts",
30
+ "import": "./src/test.ts"
31
+ },
32
+ "./worker": {
33
+ "types": "./src/worker.ts",
34
+ "import": "./src/worker.ts"
35
+ }
36
+ },
37
+ "files": [
38
+ "src",
39
+ "dist"
40
+ ],
41
+ "scripts": {
42
+ "build": "rollup -c --bundleConfigAsCjs",
43
+ "prepublishOnly": "npm run build"
44
+ },
45
+ "keywords": [
46
+ "xstate",
47
+ "partykit",
48
+ "actor",
49
+ "state-machine"
50
+ ],
51
+ "author": "jonmumm",
52
+ "license": "ISC",
53
+ "peerDependencies": {
54
+ "@cloudflare/workers-types": "^4.20240925.0",
55
+ "react": "^17.0.0 || ^18.0.0",
56
+ "xstate": "^5.18.0",
57
+ "zod": "^3.23.0"
58
+ },
59
+ "dependencies": {
60
+ "cloudflare": "^3.5.0",
61
+ "fast-json-patch": "^3.1.1",
62
+ "immer": "^10.1.1",
63
+ "jose": "^5.8.0",
64
+ "xstate-migrate": "^0.0.5"
65
+ },
66
+ "devDependencies": {
67
+ "@cloudflare/workers-types": "^4.20260116.0",
68
+ "@rollup/plugin-alias": "^5.1.1",
69
+ "@rollup/plugin-terser": "^0.4.4",
70
+ "@storybook/react": "^8.4.2",
71
+ "@types/node": "^22.7.4",
72
+ "@types/react": "^18.3.9",
73
+ "@types/use-sync-external-store": "^0.0.6",
74
+ "react": "^18.3.1",
75
+ "rollup": "^4.24.0",
76
+ "rollup-plugin-dts": "^6.1.1",
77
+ "rollup-plugin-preserve-directives": "^0.4.0",
78
+ "rollup-plugin-typescript2": "^0.36.0",
79
+ "typescript": "^5.6.2",
80
+ "xstate": "^5.18.2",
81
+ "zod": "^3.23.8"
82
+ },
83
+ "type": "module",
84
+ "imports": {
85
+ "cloudflare:workers": "@cloudflare/workers-types"
86
+ }
87
+ }
package/src/alarms.ts ADDED
@@ -0,0 +1,237 @@
1
+ import type {
2
+ ActorKitStorage,
3
+ AlarmRecord,
4
+ AlarmScheduleOptions,
5
+ } from "./storage";
6
+
7
+ /**
8
+ * Supported alarm types
9
+ */
10
+ export type AlarmType = "xstate-delay" | "cache-cleanup" | "custom";
11
+
12
+ /**
13
+ * Alarm data from the database with parsed payload
14
+ */
15
+ export interface Alarm {
16
+ id: string;
17
+ type: AlarmType;
18
+ scheduledAt: number;
19
+ repeatInterval?: number;
20
+ payload: Record<string, unknown>;
21
+ createdAt: number;
22
+ }
23
+
24
+ /**
25
+ * Options for scheduling a new alarm
26
+ */
27
+ export interface ScheduleAlarmOptions {
28
+ id: string;
29
+ type: AlarmType;
30
+ scheduledAt: number;
31
+ repeatInterval?: number;
32
+ payload: Record<string, unknown>;
33
+ }
34
+
35
+ /**
36
+ * Result from handling an alarm
37
+ */
38
+ export interface AlarmHandleResult {
39
+ id: string;
40
+ type: AlarmType;
41
+ rescheduled?: boolean;
42
+ deleted: boolean;
43
+ }
44
+
45
+ /**
46
+ * Manages alarms for a Durable Object using SQLite storage
47
+ * and the Durable Object alarm API
48
+ */
49
+ export class AlarmManager {
50
+ private storage: ActorKitStorage;
51
+ private state: DurableObjectState;
52
+ private currentAlarmId: string | null = null;
53
+ private currentAlarmTime: number | null = null;
54
+
55
+ constructor(storage: ActorKitStorage, state: DurableObjectState) {
56
+ this.storage = storage;
57
+ this.state = state;
58
+ }
59
+
60
+ /**
61
+ * Schedule a new alarm
62
+ */
63
+ async schedule(options: ScheduleAlarmOptions): Promise<void> {
64
+ await this.storage.insertAlarm(options);
65
+ await this.rescheduleNextAlarm();
66
+ }
67
+
68
+ /**
69
+ * Cancel an alarm by ID
70
+ */
71
+ async cancel(id: string): Promise<void> {
72
+ await this.storage.deleteAlarm(id);
73
+ // If we canceled the current alarm, reschedule
74
+ if (this.currentAlarmId === id) {
75
+ await this.rescheduleNextAlarm();
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Cancel all alarms of a specific type
81
+ */
82
+ async cancelByType(type: AlarmType): Promise<void> {
83
+ await this.storage.deleteAlarmsByType(type);
84
+ await this.rescheduleNextAlarm();
85
+ }
86
+
87
+ /**
88
+ * Get all pending alarms
89
+ */
90
+ async getPendingAlarms(): Promise<Alarm[]> {
91
+ const records = await this.storage.getAlarms();
92
+ return records.map(this.parseAlarmRecord);
93
+ }
94
+
95
+ /**
96
+ * Get alarms that are due now or before a given time
97
+ */
98
+ async getDueAlarms(before: number = Date.now()): Promise<Alarm[]> {
99
+ const records = await this.storage.getDueAlarms(before);
100
+ return records.map(this.parseAlarmRecord);
101
+ }
102
+
103
+ /**
104
+ * Delete an alarm after it has been handled
105
+ */
106
+ async deleteAlarm(id: string): Promise<void> {
107
+ await this.storage.deleteAlarm(id);
108
+ }
109
+
110
+ /**
111
+ * Update an alarm (for rescheduling recurring alarms)
112
+ */
113
+ async updateAlarm(options: ScheduleAlarmOptions): Promise<void> {
114
+ await this.storage.updateAlarm(options);
115
+ }
116
+
117
+ /**
118
+ * Reschedule the next DO alarm based on the earliest alarm in storage
119
+ * This sets the actual Durable Object alarm that will trigger the alarm() handler
120
+ */
121
+ async rescheduleNextAlarm(): Promise<void> {
122
+ const earliest = await this.storage.getEarliestAlarm();
123
+
124
+ if (!earliest) {
125
+ // No alarms pending, clear the DO alarm
126
+ this.currentAlarmId = null;
127
+ this.currentAlarmTime = null;
128
+ // Note: There's no way to "clear" a DO alarm, but we can set one far in the future
129
+ // or just let it expire naturally
130
+ return;
131
+ }
132
+
133
+ // Only set a new alarm if the earliest one is different from current
134
+ if (this.currentAlarmId !== earliest.id || this.currentAlarmTime !== earliest.scheduled_at) {
135
+ this.currentAlarmId = earliest.id;
136
+ this.currentAlarmTime = earliest.scheduled_at;
137
+ await this.state.storage.setAlarm(earliest.scheduled_at);
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Handle due alarms and return results
143
+ * This should be called from the Durable Object's alarm() handler
144
+ */
145
+ async handleDueAlarms(handler: (alarm: Alarm) => Promise<boolean>): Promise<AlarmHandleResult[]> {
146
+ const now = Date.now();
147
+ const dueAlarms = await this.getDueAlarms(now);
148
+ const results: AlarmHandleResult[] = [];
149
+
150
+ for (const alarm of dueAlarms) {
151
+ let rescheduled = false;
152
+ let deleted = true;
153
+
154
+ if (alarm.repeatInterval) {
155
+ // Recurring alarm - reschedule it
156
+ const nextScheduledAt = now + alarm.repeatInterval;
157
+ await this.updateAlarm({
158
+ id: alarm.id,
159
+ type: alarm.type,
160
+ scheduledAt: nextScheduledAt,
161
+ repeatInterval: alarm.repeatInterval,
162
+ payload: alarm.payload,
163
+ });
164
+ rescheduled = true;
165
+ deleted = false;
166
+ } else {
167
+ // One-time alarm - delete it
168
+ await this.deleteAlarm(alarm.id);
169
+ }
170
+
171
+ // Call the handler and let it perform the alarm-specific action
172
+ try {
173
+ await handler(alarm);
174
+ } catch (error) {
175
+ console.error(`Error handling alarm ${alarm.id}:`, error);
176
+ }
177
+
178
+ results.push({
179
+ id: alarm.id,
180
+ type: alarm.type,
181
+ rescheduled,
182
+ deleted,
183
+ });
184
+ }
185
+
186
+ // Reschedule the next DO alarm
187
+ await this.rescheduleNextAlarm();
188
+
189
+ return results;
190
+ }
191
+
192
+ /**
193
+ * Get the current scheduled DO alarm info
194
+ */
195
+ getCurrentAlarm(): { id: string | null; time: number | null } {
196
+ return {
197
+ id: this.currentAlarmId,
198
+ time: this.currentAlarmTime,
199
+ };
200
+ }
201
+
202
+ /**
203
+ * Parse an alarm record from the database into an Alarm object
204
+ */
205
+ private parseAlarmRecord(record: AlarmRecord): Alarm {
206
+ return {
207
+ id: record.id,
208
+ type: record.type as AlarmType,
209
+ scheduledAt: record.scheduled_at,
210
+ repeatInterval: record.repeat_interval ?? undefined,
211
+ payload: record.payload ? JSON.parse(record.payload) : {},
212
+ createdAt: record.created_at,
213
+ };
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Generate a unique alarm ID
219
+ */
220
+ export function generateAlarmId(): string {
221
+ return `alarm-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
222
+ }
223
+
224
+ /**
225
+ * Calculate the next scheduled time for a recurring alarm
226
+ */
227
+ export function calculateNextRecurringAlarm(
228
+ baseTime: number,
229
+ interval: number,
230
+ now: number = Date.now()
231
+ ): number {
232
+ let next = baseTime;
233
+ while (next < now) {
234
+ next += interval;
235
+ }
236
+ return next;
237
+ }
package/src/browser.ts ADDED
@@ -0,0 +1 @@
1
+ export { createActorKitClient } from "./createActorKitClient";
@@ -0,0 +1,31 @@
1
+ import { CallerType } from "./types";
2
+ import type { AlarmType } from "./alarms";
3
+
4
+ export const HEADERS = {
5
+ X_CALLER_ID: "X-Caller-ID",
6
+ X_CALLER_TYPE: "X-Caller-Type",
7
+ X_ACTOR_ID: "X-Actor-ID",
8
+ X_ACTOR_TYPE: "X-Actor-Type",
9
+ };
10
+
11
+ /**
12
+ * Defines the types of callers that can interact with the actor system.
13
+ * Each type represents a different source of events with varying levels of trust and permissions.
14
+ * Note: SYSTEM events are handled internally by Actor Kit and are not defined by the user.
15
+ */
16
+ export const CallerTypes: Record<CallerType, CallerType> = {
17
+ client: "client",
18
+ system: "system", // Handled internally by Actor Kit
19
+ service: "service",
20
+ };
21
+
22
+ /**
23
+ * Alarm types supported by the alarm system
24
+ */
25
+ export const AlarmTypes: Record<AlarmType, AlarmType> = {
26
+ "xstate-delay": "xstate-delay",
27
+ "cache-cleanup": "cache-cleanup",
28
+ custom: "custom",
29
+ };
30
+
31
+ export const PERSISTED_SNAPSHOT_KEY = "persistedSnapshot";
@@ -0,0 +1,29 @@
1
+ import { SignJWT } from "jose";
2
+ import { CallerStringSchema } from "./schemas";
3
+ import { CallerType } from "./types";
4
+
5
+ // Export utility functions
6
+ export const createAccessToken = async ({
7
+ signingKey,
8
+ actorId,
9
+ actorType,
10
+ callerId,
11
+ callerType,
12
+ }: {
13
+ signingKey: string;
14
+ actorId: string;
15
+ actorType: string;
16
+ callerId: string;
17
+ callerType: CallerType;
18
+ }) => {
19
+ const subject = `${callerType}-${callerId}`;
20
+ CallerStringSchema.parse(subject);
21
+ const token = await new SignJWT({})
22
+ .setProtectedHeader({ alg: "HS256" })
23
+ .setJti(actorId)
24
+ .setSubject(subject)
25
+ .setAudience(actorType)
26
+ .setExpirationTime("30d")
27
+ .sign(new TextEncoder().encode(signingKey));
28
+ return token;
29
+ };