@rivetkit/effect 0.0.0-main.879b6a2 → 0.0.0-sqlite-uds.4e59a38

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 (67) hide show
  1. package/dist/Actor.d.ts +2 -3
  2. package/dist/Actor.d.ts.map +1 -1
  3. package/dist/Actor.js +2 -2
  4. package/dist/Actor.js.map +1 -1
  5. package/dist/Client.d.ts.map +1 -1
  6. package/dist/Client.js +6 -4
  7. package/dist/Client.js.map +1 -1
  8. package/dist/Registry.d.ts +69 -7
  9. package/dist/Registry.d.ts.map +1 -1
  10. package/dist/Registry.js +93 -40
  11. package/dist/Registry.js.map +1 -1
  12. package/dist/RivetError.d.ts +18 -3
  13. package/dist/RivetError.d.ts.map +1 -1
  14. package/dist/RivetError.js +31 -0
  15. package/dist/RivetError.js.map +1 -1
  16. package/dist/RivetLogger.d.ts +41 -0
  17. package/dist/RivetLogger.d.ts.map +1 -0
  18. package/dist/RivetLogger.js +41 -0
  19. package/dist/RivetLogger.js.map +1 -0
  20. package/dist/State.d.ts +92 -56
  21. package/dist/State.d.ts.map +1 -1
  22. package/dist/State.js +51 -57
  23. package/dist/State.js.map +1 -1
  24. package/dist/internal/ActionDispatcher.d.ts.map +1 -1
  25. package/dist/internal/ActionDispatcher.js.map +1 -1
  26. package/dist/internal/ActorInstanceManager.d.ts.map +1 -1
  27. package/dist/internal/ActorInstanceManager.js +4 -4
  28. package/dist/internal/ActorInstanceManager.js.map +1 -1
  29. package/dist/internal/ActorStateAdapter.d.ts +1 -1
  30. package/dist/internal/ActorStateAdapter.d.ts.map +1 -1
  31. package/dist/internal/ActorStateAdapter.js +2 -7
  32. package/dist/internal/ActorStateAdapter.js.map +1 -1
  33. package/dist/internal/StateOptions.d.ts +1 -0
  34. package/dist/internal/StateOptions.d.ts.map +1 -1
  35. package/dist/internal/logging.d.ts +6 -7
  36. package/dist/internal/logging.d.ts.map +1 -1
  37. package/dist/internal/logging.js +78 -102
  38. package/dist/internal/logging.js.map +1 -1
  39. package/dist/mod.d.ts +1 -1
  40. package/dist/mod.d.ts.map +1 -1
  41. package/dist/mod.js +1 -1
  42. package/dist/mod.js.map +1 -1
  43. package/package.json +3 -2
  44. package/src/Actor.test-d.ts +32 -0
  45. package/src/Actor.test.ts +4 -1
  46. package/src/Actor.ts +29 -4
  47. package/src/Client.test.ts +22 -26
  48. package/src/Client.ts +6 -4
  49. package/src/Registry.test.ts +12 -23
  50. package/src/Registry.ts +131 -70
  51. package/src/RivetError.test.ts +11 -0
  52. package/src/RivetError.ts +37 -0
  53. package/src/RivetLogger.ts +60 -0
  54. package/src/State.test.ts +163 -4
  55. package/src/State.ts +293 -97
  56. package/src/internal/ActionDispatcher.ts +8 -11
  57. package/src/internal/ActorInstanceManager.ts +32 -38
  58. package/src/internal/ActorStateAdapter.ts +5 -11
  59. package/src/internal/StateOptions.ts +4 -0
  60. package/src/internal/logging.test.ts +107 -121
  61. package/src/internal/logging.ts +103 -143
  62. package/src/mod.ts +1 -1
  63. package/dist/Logger.d.ts +0 -29
  64. package/dist/Logger.d.ts.map +0 -1
  65. package/dist/Logger.js +0 -31
  66. package/dist/Logger.js.map +0 -1
  67. package/src/Logger.ts +0 -43
package/src/Actor.ts CHANGED
@@ -175,7 +175,8 @@ type WakeOptionsFor<
175
175
  : {
176
176
  readonly state: State.State<
177
177
  StateOptions.Decoded<StateDefinition>,
178
- Schema.SchemaError
178
+ Schema.SchemaError,
179
+ StateOptions.Services<StateDefinition>
179
180
  >;
180
181
  });
181
182
 
@@ -232,6 +233,7 @@ type ToLayerRequirements<
232
233
  | ExcludeBuiltInWakeServices<R, State>
233
234
  | ExcludeBuiltInWakeServices<RX, State>
234
235
  | UnknownToNever<ActionHandlerServices<ActionHandlers>>
236
+ | UnknownToNever<StateOptions.Services<State>>
235
237
  | UnknownToNever<Action.ServicesServer<Actions>>
236
238
  | UnknownToNever<Action.ServicesClient<Actions>>
237
239
  | Registry.Registry;
@@ -334,9 +336,9 @@ const Proto: Omit<Actor<any, any>, "name" | "actions"> = {
334
336
  >(wake),
335
337
  options,
336
338
  }).pipe(
337
- Effect.flatMap((rivetKitActor) =>
339
+ Effect.tap((rivetKitActor) =>
338
340
  Registry.Registry.pipe(
339
- Effect.flatMap((registry) =>
341
+ Effect.tap((registry) =>
340
342
  Effect.sync(() =>
341
343
  registry.rivetkitActors.set(
342
344
  this.name,
@@ -375,6 +377,29 @@ export const make = <
375
377
  return self;
376
378
  };
377
379
 
380
+ /**
381
+ * Normalizes any supported actor wake declaration into a wake function.
382
+ *
383
+ * @remarks
384
+ * {@link Actor.toLayer|`Actor.toLayer()`} accepts several equivalent shapes so actor
385
+ * implementations can choose the amount of initialization they need:
386
+ *
387
+ * - a plain action-handler object
388
+ * - an `Effect` that builds an action-handler object
389
+ * - a wake function that receives `wakeOptions` and returns handlers
390
+ * - a wake function that returns an `Effect` of handlers
391
+ * - an `Effect` that builds one of those wake functions
392
+ *
393
+ * This helper resolves those forms lazily for each actor wake and returns a
394
+ * single `(wakeOptions) => Effect<handlers>` representation. It does not run a
395
+ * wake function until the returned function is invoked, so per-wake resources,
396
+ * services, and state are scoped to the specific actor instance that is waking.
397
+ *
398
+ * @param wake - A supported wake declaration shape.
399
+ * @returns A function that resolves action handlers for one actor wake.
400
+ *
401
+ * @internal
402
+ */
378
403
  export function toWakeHandler<
379
404
  ActionHandlers extends object,
380
405
  R,
@@ -443,7 +468,7 @@ export function toWakeHandler<
443
468
 
444
469
  return wakeEffect.pipe(
445
470
  Effect.flatMap((resolvedWake) => {
446
- if (typeof resolvedWake === "function") {
471
+ if (Predicate.isFunction(resolvedWake)) {
447
472
  const actionHandlers = resolvedWake(wakeOptions);
448
473
  return Effect.isEffect(actionHandlers)
449
474
  ? actionHandlers
@@ -1,12 +1,8 @@
1
1
  import { assert, describe, it } from "@effect/vitest";
2
- import { Client, Logger, RivetError } from "@rivetkit/effect";
2
+ import { Client, RivetError, RivetLogger } from "@rivetkit/effect";
3
3
  import { Effect, Layer, Schema } from "effect";
4
4
  import * as RivetkitErrors from "rivetkit/errors";
5
- import {
6
- configureDefaultLogger,
7
- getBaseLogger,
8
- type Logger as PinoLogger,
9
- } from "rivetkit/log";
5
+ import * as RivetkitLog from "rivetkit/log";
10
6
  import * as ActionErrorEnvelope from "./internal/ActionErrorEnvelope";
11
7
 
12
8
  function makeTestLogger(
@@ -15,19 +11,12 @@ function makeTestLogger(
15
11
  readonly fields: Record<string, unknown>;
16
12
  readonly msg: string | undefined;
17
13
  }>,
18
- ): PinoLogger {
14
+ ): RivetkitLog.Logger {
19
15
  const logger: Record<string, unknown> = {
20
16
  level: "debug",
21
17
  child: () => logger,
22
18
  };
23
- for (const level of [
24
- "trace",
25
- "debug",
26
- "info",
27
- "warn",
28
- "error",
29
- "fatal",
30
- ]) {
19
+ for (const level of ["trace", "debug", "info", "warn", "error", "fatal"]) {
31
20
  logger[level] = (
32
21
  fields: Record<string, unknown>,
33
22
  msg?: string,
@@ -36,7 +25,7 @@ function makeTestLogger(
36
25
  };
37
26
  }
38
27
 
39
- return logger as unknown as PinoLogger;
28
+ return logger as unknown as RivetkitLog.Logger;
40
29
  }
41
30
 
42
31
  describe("Client", () => {
@@ -46,13 +35,15 @@ describe("Client", () => {
46
35
  const baseLogger = makeTestLogger();
47
36
 
48
37
  yield* Effect.addFinalizer(() =>
49
- Effect.sync(() => configureDefaultLogger("silent")),
38
+ Effect.sync(() =>
39
+ RivetkitLog.configureDefaultLogger("silent"),
40
+ ),
50
41
  );
51
42
  yield* Client.make({
52
43
  endpoint: "http://127.0.0.1:6420",
53
- }).pipe(Effect.provide(Logger.layerPino(baseLogger)));
44
+ }).pipe(Effect.provide(RivetLogger.layerFromPino(baseLogger)));
54
45
 
55
- assert.strictEqual(getBaseLogger(), baseLogger);
46
+ assert.strictEqual(RivetkitLog.getBaseLogger(), baseLogger);
56
47
  }),
57
48
  ),
58
49
  );
@@ -68,7 +59,9 @@ describe("Client", () => {
68
59
  const baseLogger = makeTestLogger(entries);
69
60
 
70
61
  yield* Effect.addFinalizer(() =>
71
- Effect.sync(() => configureDefaultLogger("silent")),
62
+ Effect.sync(() =>
63
+ RivetkitLog.configureDefaultLogger("silent"),
64
+ ),
72
65
  );
73
66
  yield* Effect.gen(function* () {
74
67
  yield* Client.Client;
@@ -80,16 +73,19 @@ describe("Client", () => {
80
73
  Client.layer({
81
74
  endpoint: "http://127.0.0.1:6420",
82
75
  }).pipe(
83
- Layer.provideMerge(Logger.layerPino(baseLogger)),
76
+ Layer.provideMerge(
77
+ RivetLogger.layerFromPino(baseLogger),
78
+ ),
84
79
  ),
85
80
  ),
86
81
  );
87
82
 
88
- assert.deepStrictEqual(entries[0], {
89
- level: "info",
90
- fields: { clientId: "test-client" },
91
- msg: "client effect log",
92
- });
83
+ const entry = entries[0];
84
+ assert.ok(entry !== undefined);
85
+ assert.strictEqual(entry.level, "info");
86
+ assert.strictEqual(entry.msg, "client effect log");
87
+ assert.strictEqual(entry.fields.clientId, "test-client");
88
+ assert.strictEqual(typeof entry.fields.fiberId, "string");
93
89
  assert.ok(
94
90
  entries.some(
95
91
  (entry) =>
package/src/Client.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import { Context, Effect, Layer, Record, Result, Schema } from "effect";
2
2
  import * as RivetkitClient from "rivetkit/client";
3
3
  import * as RivetkitErrors from "rivetkit/errors";
4
- import { configureBaseLogger } from "rivetkit/log";
4
+ import * as RivetkitLog from "rivetkit/log";
5
5
  import type * as Action from "./Action.ts";
6
6
  import type * as Actor from "./Actor.ts";
7
7
  import * as ActionErrorEnvelope from "./internal/ActionErrorEnvelope.ts";
8
8
  import { getOrCreateBaseLogger } from "./internal/logging.ts";
9
9
  import { rpcSystem, type TraceMeta } from "./internal/tracing.ts";
10
- import * as Logger from "./Logger.ts";
10
+ import * as RivetLogger from "./RivetLogger.ts";
11
11
  import * as RivetError from "./RivetError.ts";
12
12
 
13
13
  const TypeId = "~@rivetkit/effect/Client";
@@ -49,7 +49,9 @@ export const make = Effect.fnUntraced(function* (options: Options = {}) {
49
49
  const baseLogger = yield* getOrCreateBaseLogger;
50
50
  const rivetkitClient = yield* Effect.acquireRelease(
51
51
  Effect.sync(() => {
52
- configureBaseLogger(baseLogger);
52
+ // Raw RivetKit clients do not accept a logger in their config,
53
+ // so install the Effect-selected logger before construction.
54
+ RivetkitLog.configureBaseLogger(baseLogger);
53
55
  return RivetkitClient.createClient(options);
54
56
  }),
55
57
  (c) => Effect.promise(() => c.dispose()),
@@ -146,7 +148,7 @@ export const layer = (options: Options = {}): Layer.Layer<Client> =>
146
148
  Layer.unwrap(
147
149
  Effect.map(getOrCreateBaseLogger, (baseLogger) =>
148
150
  Layer.effect(Client, make(options)).pipe(
149
- Layer.provideMerge(Logger.layerPino(baseLogger)),
151
+ Layer.provideMerge(RivetLogger.layerFromPino(baseLogger)),
150
152
  ),
151
153
  ),
152
154
  );
@@ -1,12 +1,8 @@
1
1
  import { assert, describe, it } from "@effect/vitest";
2
- import { Action, Actor, Logger, Registry } from "@rivetkit/effect";
2
+ import { Action, Actor, Registry, RivetLogger } from "@rivetkit/effect";
3
3
  import { Effect, Layer } from "effect";
4
4
  import { HttpEffect } from "effect/unstable/http";
5
- import {
6
- configureDefaultLogger,
7
- getBaseLogger,
8
- type Logger as PinoLogger,
9
- } from "rivetkit/log";
5
+ import * as RivetkitLog from "rivetkit/log";
10
6
  import { vi } from "vitest";
11
7
 
12
8
  const TestActor = Actor.make("TestActor", {
@@ -28,23 +24,16 @@ const RegistryLive = ActorsLayer.pipe(
28
24
  ),
29
25
  );
30
26
 
31
- function makeTestLogger(): PinoLogger {
27
+ function makeTestLogger(): RivetkitLog.Logger {
32
28
  const logger: Record<string, unknown> = {
33
29
  level: "debug",
34
30
  child: () => logger,
35
31
  };
36
- for (const level of [
37
- "trace",
38
- "debug",
39
- "info",
40
- "warn",
41
- "error",
42
- "fatal",
43
- ]) {
32
+ for (const level of ["trace", "debug", "info", "warn", "error", "fatal"]) {
44
33
  logger[level] = (): void => {};
45
34
  }
46
35
 
47
- return logger as unknown as PinoLogger;
36
+ return logger as unknown as RivetkitLog.Logger;
48
37
  }
49
38
 
50
39
  describe("Registry.toWebHandler", () => {
@@ -207,8 +196,7 @@ describe("Registry.toWebHandler", () => {
207
196
  }),
208
197
  ),
209
198
  );
210
- const { handler, dispose } =
211
- Registry.toWebHandler(WelcomeRegistryLive);
199
+ const { handler, dispose } = Registry.toWebHandler(WelcomeRegistryLive);
212
200
 
213
201
  try {
214
202
  const first = await handler(
@@ -232,10 +220,11 @@ describe("Registry.toWebHandler", () => {
232
220
  it("uses a custom logger layer for the underlying RivetKit registry", async () => {
233
221
  const baseLogger = makeTestLogger();
234
222
  const CustomLoggerRegistryLive = RegistryLive.pipe(
235
- Layer.provide(Logger.layerPino(baseLogger)),
223
+ Layer.provide(RivetLogger.layerFromPino(baseLogger)),
224
+ );
225
+ const { handler, dispose } = Registry.toWebHandler(
226
+ CustomLoggerRegistryLive,
236
227
  );
237
- const { handler, dispose } =
238
- Registry.toWebHandler(CustomLoggerRegistryLive);
239
228
 
240
229
  try {
241
230
  const response = await handler(
@@ -243,10 +232,10 @@ describe("Registry.toWebHandler", () => {
243
232
  );
244
233
 
245
234
  assert.strictEqual(response.status, 200);
246
- assert.strictEqual(getBaseLogger(), baseLogger);
235
+ assert.strictEqual(RivetkitLog.getBaseLogger(), baseLogger);
247
236
  } finally {
248
237
  await dispose();
249
- configureDefaultLogger("silent");
238
+ RivetkitLog.configureDefaultLogger("silent");
250
239
  }
251
240
  });
252
241
 
package/src/Registry.ts CHANGED
@@ -7,13 +7,10 @@ import {
7
7
  type HttpServerResponse,
8
8
  } from "effect/unstable/http";
9
9
  import * as Rivetkit from "rivetkit";
10
- import {
11
- configureBaseLogger,
12
- type Logger as PinoLogger,
13
- } from "rivetkit/log";
10
+ import * as RivetkitLog from "rivetkit/log";
14
11
  import * as Client from "./Client.ts";
15
12
  import { BaseLogger, getOrCreateBaseLogger } from "./internal/logging.ts";
16
- import * as Logger from "./Logger.ts";
13
+ import * as RivetLogger from "./RivetLogger.ts";
17
14
 
18
15
  const TypeId = "~@rivetkit/effect/Registry";
19
16
  type ServerlessOptions = NonNullable<
@@ -22,7 +19,7 @@ type ServerlessOptions = NonNullable<
22
19
 
23
20
  export type Options = Pick<
24
21
  Rivetkit.RegistryConfigInput<Rivetkit.RegistryActors>,
25
- "endpoint" | "token" | "namespace" | "noWelcome"
22
+ "endpoint" | "token" | "namespace" | "noWelcome" | "sqlite"
26
23
  >;
27
24
 
28
25
  export interface Registry {
@@ -30,7 +27,7 @@ export interface Registry {
30
27
 
31
28
  readonly options: Options;
32
29
 
33
- readonly baseLogger: PinoLogger;
30
+ readonly baseLogger: RivetkitLog.Logger;
34
31
 
35
32
  readonly rivetkitActors: Map<string, Rivetkit.AnyActorDefinition>;
36
33
  }
@@ -38,20 +35,49 @@ export interface Registry {
38
35
  export const Registry: Context.Service<Registry, Registry> =
39
36
  Context.Service<Registry>("@rivetkit/effect/Registry");
40
37
 
41
- const make = (options: Options, baseLogger: PinoLogger): Registry => {
42
- return Registry.of({
43
- [TypeId]: TypeId,
44
- options,
45
- baseLogger,
46
- rivetkitActors: new Map(),
47
- });
48
- };
49
-
38
+ /**
39
+ * Creates the shared registry that actor layers register into.
40
+ *
41
+ * @remarks
42
+ * Actor layers created with {@link Actor.Actor.toLayer|`Actor.toLayer()`}
43
+ * register into this service. Registry entrypoints such as
44
+ * {@link serve|`Registry.serve()`}, {@link toWebHandler|`Registry.toWebHandler()`},
45
+ * and {@link toHttpEffect|`Registry.toHttpEffect()`} later use the collected
46
+ * actors to create the underlying RivetKit runtime.
47
+ *
48
+ * @param options - RivetKit runtime options shared by the registered actors.
49
+ *
50
+ * @returns A layer that provides the {@link Registry|`Registry.Registry`}
51
+ * service.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { Registry } from "@rivetkit/effect"
56
+ * import { Layer } from "effect"
57
+ *
58
+ * const ActorsLayer = Layer.mergeAll(ChatRoomLive, ModeratorLive)
59
+ *
60
+ * const MainLayer = Registry.serve(ActorsLayer).pipe(
61
+ * Layer.provide(Registry.layer({ endpoint: "http://127.0.0.1:6420" }))
62
+ * )
63
+ * ```
64
+ *
65
+ * @see {@link serve|`Registry.serve()`} for starting a long-running actor
66
+ * server.
67
+ * @see {@link toWebHandler|`Registry.toWebHandler()`} for Fetch-compatible
68
+ * serverless handlers.
69
+ * @see {@link toHttpEffect|`Registry.toHttpEffect()`} for Effect HTTP handlers.
70
+ */
50
71
  export const layer = (options: Options = {}): Layer.Layer<Registry> =>
51
72
  Layer.effect(
52
73
  Registry,
53
74
  Effect.map(getOrCreateBaseLogger, (baseLogger) =>
54
- make(options, baseLogger),
75
+ Registry.of({
76
+ [TypeId]: TypeId,
77
+ options,
78
+ baseLogger,
79
+ rivetkitActors: new Map(),
80
+ }),
55
81
  ),
56
82
  );
57
83
 
@@ -60,40 +86,70 @@ const setupRivetkitRegistry = (
60
86
  options?: {
61
87
  readonly serverless?: ServerlessOptions | undefined;
62
88
  },
63
- ) => {
64
- configureBaseLogger(registry.baseLogger);
65
- return Rivetkit.setup({
66
- use: Object.fromEntries(registry.rivetkitActors),
67
- ...registry.options,
68
- logging: { baseLogger: registry.baseLogger },
69
- ...(options?.serverless === undefined
70
- ? {}
71
- : { serverless: options.serverless }),
72
- });
73
- };
89
+ ) =>
90
+ Effect.sync(() =>
91
+ Rivetkit.setup({
92
+ use: Object.fromEntries(registry.rivetkitActors),
93
+ ...registry.options,
94
+ logging: { baseLogger: registry.baseLogger },
95
+ ...(options?.serverless === undefined
96
+ ? {}
97
+ : { serverless: options.serverless }),
98
+ }),
99
+ );
74
100
 
75
101
  /**
76
- * Runs an actor registration layer against the configured engine.
102
+ * Serves the actors registered by `actorsLayer`.
103
+ *
104
+ * @remarks
105
+ * Provide this with {@link layer|`Registry.layer()`} at the application root.
106
+ * Building the returned layer evaluates the actor layer, collects its registered
107
+ * actors, and starts the underlying RivetKit runtime using the options from
108
+ * {@link layer|`Registry.layer()`}. Launch the resulting layer with
109
+ * {@link Layer.launch|`Layer.launch()`} to keep the server process alive.
110
+ *
111
+ * @param actorsLayer - A layer containing one or more
112
+ * {@link Actor.Actor.toLayer|`Actor.toLayer()`} registrations.
113
+ *
114
+ * @returns A side-effecting startup layer that requires the
115
+ * {@link Registry|`Registry.Registry`} service and the services required by
116
+ * `actorsLayer`.
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * import { Registry } from "@rivetkit/effect"
121
+ * import { Layer } from "effect"
122
+ *
123
+ * const ActorsLayer = Layer.mergeAll(ChatRoomLive, ModeratorLive)
124
+ *
125
+ * const MainLayer = Registry.serve(ActorsLayer).pipe(
126
+ * Layer.provide(Registry.layer({ endpoint: "http://127.0.0.1:6420" }))
127
+ * )
128
+ *
129
+ * Layer.launch(MainLayer).pipe(NodeRuntime.runMain);
130
+ * ```
131
+ *
132
+ * @see {@link toWebHandler|`Registry.toWebHandler()`} for Fetch-compatible
133
+ * serverless handlers.
134
+ * @see {@link toHttpEffect|`Registry.toHttpEffect()`} for Effect HTTP handlers.
77
135
  *
78
- * The actor layer is built in the server layer scope. Registered Rivet Actors
79
- * are collected from `Registry`, materialized into a single underlying RivetKit
80
- * registry, and started.
81
136
  */
82
137
  export const serve = <E, R>(
83
138
  actorsLayer: Layer.Layer<never, E, R>,
84
- ): Layer.Layer<never, E, R | Registry> =>
85
- Layer.effectDiscard(
86
- Effect.gen(function* () {
87
- const registry = yield* Registry;
88
- const baseLogger = registry.baseLogger;
89
- yield* Layer.build(
90
- actorsLayer.pipe(
91
- Layer.provideMerge(Logger.layerPino(baseLogger)),
139
+ ): Layer.Layer<never, E, R | Registry> =>
140
+ Layer.effectDiscard(
141
+ Effect.gen(function* () {
142
+ const registry = yield* Registry;
143
+ yield* Layer.build(
144
+ actorsLayer.pipe(
145
+ Layer.provideMerge(
146
+ RivetLogger.layerFromPino(registry.baseLogger),
92
147
  ),
93
- );
94
- const rivetkitRegistry = setupRivetkitRegistry(registry);
95
- yield* Effect.sync(() => rivetkitRegistry.start());
96
- }),
148
+ ),
149
+ );
150
+ const rivetkitRegistry = yield* setupRivetkitRegistry(registry);
151
+ yield* Effect.sync(() => rivetkitRegistry.start());
152
+ }),
97
153
  );
98
154
 
99
155
  /**
@@ -110,7 +166,7 @@ export const test: Layer.Layer<Client.Client, never, Registry> = Layer.effect(
110
166
  Client.Client,
111
167
  Effect.gen(function* () {
112
168
  const registry = yield* Registry;
113
- const rivetkitRegistry = setupRivetkitRegistry(registry);
169
+ const rivetkitRegistry = yield* setupRivetkitRegistry(registry);
114
170
  rivetkitRegistry.config.test = {
115
171
  ...rivetkitRegistry.config.test,
116
172
  enabled: true,
@@ -137,30 +193,32 @@ export const test: Layer.Layer<Client.Client, never, Registry> = Layer.effect(
137
193
  // to its (warning-emitting) default.
138
194
  const resolvedEndpoint = rivetkitRegistry.parseConfig().endpoint;
139
195
 
140
- return yield* Client.make({
141
- ...registry.options,
142
- endpoint: registry.options.endpoint ?? resolvedEndpoint,
143
- }).pipe(
144
- Effect.provideService(BaseLogger, registry.baseLogger),
145
- );
146
- }),
147
- );
196
+ return yield* Client.make({
197
+ ...registry.options,
198
+ endpoint: registry.options.endpoint ?? resolvedEndpoint,
199
+ }).pipe(Effect.provideService(BaseLogger, registry.baseLogger));
200
+ }),
201
+ );
148
202
 
149
203
  const makeHttpEffect = (
150
204
  registry: Registry,
151
205
  options?: ToHttpEffectOptions,
152
206
  ): Effect.Effect<
153
- HttpServerResponse.HttpServerResponse,
154
- HttpServerError.HttpServerError,
155
- HttpServerRequest.HttpServerRequest
156
- > => {
157
- const rivetkitRegistry = setupRivetkitRegistry(registry, {
158
- serverless: options,
159
- });
160
- return HttpEffect.fromWebHandler((request) =>
161
- rivetkitRegistry.handler(request),
207
+ Effect.Effect<
208
+ HttpServerResponse.HttpServerResponse,
209
+ HttpServerError.HttpServerError,
210
+ HttpServerRequest.HttpServerRequest
211
+ >
212
+ > =>
213
+ Effect.map(
214
+ setupRivetkitRegistry(registry, {
215
+ serverless: options,
216
+ }),
217
+ (rivetkitRegistry) =>
218
+ HttpEffect.fromWebHandler((request) =>
219
+ rivetkitRegistry.handler(request),
220
+ ),
162
221
  );
163
- };
164
222
 
165
223
  export type ToHttpEffectOptions = ServerlessOptions;
166
224
 
@@ -184,12 +242,14 @@ export const toHttpEffect = Effect.fnUntraced(function* <E>(
184
242
  Scope.Scope
185
243
  > {
186
244
  const context = yield* Layer.build(
187
- registryLayer.pipe(Layer.provideMerge(Logger.layer)),
245
+ registryLayer.pipe(Layer.provideMerge(RivetLogger.defaultLayer)),
188
246
  );
189
- // @effect-diagnostics-next-line returnEffectInGen:off
190
- return makeHttpEffect(Context.get(context, Registry), options).pipe(
191
- Effect.provide(context),
247
+ const httpEffect = yield* makeHttpEffect(
248
+ Context.get(context, Registry),
249
+ options,
192
250
  );
251
+ // @effect-diagnostics-next-line returnEffectInGen:off
252
+ return httpEffect.pipe(Effect.provide(context));
193
253
  });
194
254
 
195
255
  export type ToWebHandlerOptions = ServerlessOptions & {
@@ -226,16 +286,17 @@ export const toWebHandler = <E>(
226
286
  }
227
287
 
228
288
  const registryLayerWithLogging = registryLayer.pipe(
229
- Layer.provideMerge(Logger.layer),
289
+ Layer.provideMerge(RivetLogger.defaultLayer),
230
290
  );
231
291
 
232
292
  return HttpEffect.toWebHandlerLayerWith(registryLayerWithLogging, {
233
293
  toHandler: (context) =>
234
- Effect.succeed(
294
+ Effect.map(
235
295
  makeHttpEffect(
236
296
  Context.get(context, Registry),
237
297
  serverlessOptions,
238
- ).pipe(Effect.provide(context)),
298
+ ),
299
+ (httpEffect) => httpEffect.pipe(Effect.provide(context)),
239
300
  ),
240
301
  middleware,
241
302
  memoMap,
@@ -121,6 +121,13 @@ describe("RivetError", () => {
121
121
  "actor ready timeout",
122
122
  ),
123
123
  );
124
+ const wakeRetriesExceeded = RivetError.fromUnknown(
125
+ new RivetkitErrors.RivetError(
126
+ "guard",
127
+ "actor_wake_retries_exceeded",
128
+ "actor wake retries exceeded",
129
+ ),
130
+ );
124
131
  const tunnelTimeout = RivetError.fromUnknown(
125
132
  new RivetkitErrors.RivetError(
126
133
  "guard",
@@ -137,6 +144,10 @@ describe("RivetError", () => {
137
144
  readyTimeout.reason,
138
145
  RivetError.GuardActorReadyTimeout,
139
146
  );
147
+ assert.instanceOf(
148
+ wakeRetriesExceeded.reason,
149
+ RivetError.GuardActorWakeRetriesExceeded,
150
+ );
140
151
  assert.instanceOf(
141
152
  tunnelTimeout.reason,
142
153
  RivetError.GuardTunnelMessageTimeout,
package/src/RivetError.ts CHANGED
@@ -426,6 +426,38 @@ export class GuardActorReadyTimeout extends Schema.TaggedErrorClass<GuardActorRe
426
426
  }
427
427
  }
428
428
 
429
+ export class GuardActorWakeRetriesExceeded extends Schema.TaggedErrorClass<GuardActorWakeRetriesExceeded>(
430
+ `${ReasonTypeId}/GuardActorWakeRetriesExceeded`,
431
+ )("GuardActorWakeRetriesExceeded", {
432
+ cause: Schema.instanceOf(RivetkitErrors.RivetError),
433
+ }) {
434
+ readonly [ReasonTypeId] = ReasonTypeId;
435
+ override get message() {
436
+ return this.cause.message;
437
+ }
438
+ get group() {
439
+ return this.cause.group;
440
+ }
441
+ get code() {
442
+ return this.cause.code;
443
+ }
444
+ get metadata() {
445
+ return this.cause.metadata;
446
+ }
447
+ get actor() {
448
+ return this.cause.actor;
449
+ }
450
+ get statusCode() {
451
+ return this.cause.statusCode;
452
+ }
453
+ get public() {
454
+ return this.cause.public;
455
+ }
456
+ get isRetryable(): boolean {
457
+ return true;
458
+ }
459
+ }
460
+
429
461
  export class GuardActorRunnerFailed extends Schema.TaggedErrorClass<GuardActorRunnerFailed>(
430
462
  `${ReasonTypeId}/GuardActorRunnerFailed`,
431
463
  )("GuardActorRunnerFailed", {
@@ -816,6 +848,7 @@ export type RivetErrorReason =
816
848
  | InvalidEncoding
817
849
  | InvalidRequest
818
850
  | GuardActorReadyTimeout
851
+ | GuardActorWakeRetriesExceeded
819
852
  | GuardActorRunnerFailed
820
853
  | GuardServiceUnavailable
821
854
  | GuardActorStoppedWhileWaiting
@@ -843,6 +876,7 @@ export const RivetErrorReason: Schema.Union<
843
876
  typeof InvalidEncoding,
844
877
  typeof InvalidRequest,
845
878
  typeof GuardActorReadyTimeout,
879
+ typeof GuardActorWakeRetriesExceeded,
846
880
  typeof GuardActorRunnerFailed,
847
881
  typeof GuardServiceUnavailable,
848
882
  typeof GuardActorStoppedWhileWaiting,
@@ -869,6 +903,7 @@ export const RivetErrorReason: Schema.Union<
869
903
  InvalidEncoding,
870
904
  InvalidRequest,
871
905
  GuardActorReadyTimeout,
906
+ GuardActorWakeRetriesExceeded,
872
907
  GuardActorRunnerFailed,
873
908
  GuardServiceUnavailable,
874
909
  GuardActorStoppedWhileWaiting,
@@ -993,6 +1028,8 @@ const reasonByCode: { [key: string]: MakeRivetErrorReason | undefined } = {
993
1028
  "request.invalid": (error) => new InvalidRequest({ cause: error }),
994
1029
  "guard.actor_ready_timeout": (error) =>
995
1030
  new GuardActorReadyTimeout({ cause: error }),
1031
+ "guard.actor_wake_retries_exceeded": (error) =>
1032
+ new GuardActorWakeRetriesExceeded({ cause: error }),
996
1033
  "guard.actor_runner_failed": (error) =>
997
1034
  new GuardActorRunnerFailed({ cause: error }),
998
1035
  "guard.service_unavailable": (error) =>