@pluv/client 2.0.2 → 2.2.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.
@@ -1,7 +1,7 @@
1
- import type { AbstractCrdtDocFactory, CrdtDocLike, CrdtType, InferStorage } from "@pluv/crdt";
1
+ import type { AbstractCrdtDocFactory, InferDocLike, InferStorage } from "@pluv/crdt";
2
2
  import { noop } from "@pluv/crdt";
3
3
 
4
- export type CrdtManagerOptions<TCrdt extends AbstractCrdtDocFactory<any>> = {
4
+ export type CrdtManagerOptions<TCrdt extends AbstractCrdtDocFactory<any, any>> = {
5
5
  initialStorage?: TCrdt;
6
6
  };
7
7
 
@@ -15,8 +15,8 @@ interface ApplyUpdateParams {
15
15
  update: string | readonly string[];
16
16
  }
17
17
 
18
- export class CrdtManager<TCrdt extends AbstractCrdtDocFactory<any>> {
19
- public doc: CrdtDocLike<InferStorage<TCrdt>>;
18
+ export class CrdtManager<TCrdt extends AbstractCrdtDocFactory<any, any>> {
19
+ public doc: InferDocLike<TCrdt>;
20
20
  public initialized: boolean = false;
21
21
 
22
22
  private readonly _docFactory: TCrdt;
@@ -25,7 +25,7 @@ export class CrdtManager<TCrdt extends AbstractCrdtDocFactory<any>> {
25
25
  const { initialStorage = noop.doc({}) as any } = options;
26
26
 
27
27
  this._docFactory = initialStorage;
28
- this.doc = initialStorage.getEmpty();
28
+ this.doc = this._docFactory.getEmpty() as InferDocLike<TCrdt>;
29
29
  }
30
30
 
31
31
  /**
@@ -49,7 +49,7 @@ export class CrdtManager<TCrdt extends AbstractCrdtDocFactory<any>> {
49
49
  public destroy(): void {
50
50
  this.initialized = false;
51
51
  this.doc.destroy();
52
- this.doc = this._docFactory.getEmpty();
52
+ this.doc = this._docFactory.getEmpty() as InferDocLike<TCrdt>;
53
53
  }
54
54
 
55
55
  public get<TKey extends keyof InferStorage<TCrdt>>(key: TKey): InferStorage<TCrdt>[TKey] {
@@ -94,11 +94,7 @@ export class CrdtManager<TCrdt extends AbstractCrdtDocFactory<any>> {
94
94
  const initialized = this._docFactory.getInitialized();
95
95
  const reference = initialized.get();
96
96
 
97
- this.doc = this._applyDocUpdates(
98
- this._docFactory.getEmpty(),
99
- updates,
100
- origin,
101
- ).rebuildStorage(reference);
97
+ this.doc = this._applyDocUpdates(this.doc, updates, origin).rebuildStorage(reference);
102
98
  this.initialized = true;
103
99
  initialized.destroy();
104
100
 
@@ -110,10 +106,10 @@ export class CrdtManager<TCrdt extends AbstractCrdtDocFactory<any>> {
110
106
  }
111
107
 
112
108
  private _applyDocUpdates(
113
- doc: CrdtDocLike<InferStorage<TCrdt>>,
109
+ doc: InferDocLike<TCrdt>,
114
110
  updates: readonly string[],
115
111
  origin?: string,
116
- ): CrdtDocLike<InferStorage<TCrdt>> {
112
+ ): InferDocLike<TCrdt> {
117
113
  doc.transact(() => {
118
114
  doc.batchApplyEncodedState({ origin, updates });
119
115
  }, origin);
@@ -1,4 +1,5 @@
1
1
  import type { CrdtType, InferCrdtJson } from "@pluv/crdt";
2
+ import type { StorageSubscriptionCallback } from "@pluv/types";
2
3
  import type { Subject } from "wonka";
3
4
  import { makeSubject, subscribe } from "wonka";
4
5
 
@@ -36,7 +37,7 @@ export class CrdtNotifier<TStorage extends Record<string, CrdtType<any, any>>> {
36
37
 
37
38
  public subscribe<TKey extends keyof TStorage>(
38
39
  key: TKey,
39
- callback: (value: InferCrdtJson<TStorage[TKey]>) => void,
40
+ callback: StorageSubscriptionCallback<TStorage, TKey>,
40
41
  ): () => void {
41
42
  const subject = this.subject(key);
42
43
 
@@ -0,0 +1,21 @@
1
+ import { makeSubject, subscribe, TypeOfSource } from "wonka";
2
+
3
+ export class ListenerManager {
4
+ public subjects = {
5
+ close: makeSubject<CloseEvent>(),
6
+ error: makeSubject<Event>(),
7
+ message: makeSubject<MessageEvent<any>>(),
8
+ open: makeSubject<Event>(),
9
+ };
10
+
11
+ public subscribe<TKind extends keyof typeof this.subjects>(
12
+ kind: TKind,
13
+ callback: (event: TypeOfSource<(typeof this.subjects)[TKind]["source"]>) => void,
14
+ ): () => void {
15
+ const source = this.subjects[kind]?.source;
16
+
17
+ if (!source) return () => undefined;
18
+
19
+ return subscribe(callback)(source as any).unsubscribe;
20
+ }
21
+ }
package/src/MockedRoom.ts CHANGED
@@ -1,39 +1,53 @@
1
- import type { AbstractCrdtDocFactory, CrdtType, InferCrdtJson, InferStorage } from "@pluv/crdt";
2
1
  import type {
2
+ AbstractCrdtDocFactory,
3
+ InferCrdtJson,
4
+ InferDoc,
5
+ InferDocLike,
6
+ InferStorage,
7
+ } from "@pluv/crdt";
8
+ import type {
9
+ BroadcastProxy,
3
10
  CrdtDocLike,
4
11
  EventNotifierSubscriptionCallback,
12
+ EventProxy,
5
13
  IOLike,
6
14
  Id,
7
15
  InferIOInput,
8
16
  InferIOOutput,
9
- JsonObject,
10
17
  MergeEvents,
11
- OtherNotifierSubscriptionCallback,
18
+ OtherSubscriptionCallback,
19
+ OthersSubscriptionCallback,
20
+ RoomEventListenerMap,
12
21
  RoomLike,
22
+ StateNotifierSubjects,
23
+ StorageProxy,
24
+ StorageRootSubscriptionCallback,
25
+ StorageSubscriptionCallback,
26
+ SubscribeProxy,
27
+ SubscriptionCallback,
13
28
  UpdateMyPresenceAction,
14
29
  UserInfo,
30
+ WebSocketConnection,
15
31
  WebSocketState,
16
32
  } from "@pluv/types";
17
- import { ConnectionState } from "@pluv/types";
33
+ import { ConnectionState, StorageState } from "@pluv/types";
18
34
  import type { CrdtManagerOptions } from "./CrdtManager";
19
35
  import { CrdtManager } from "./CrdtManager";
20
36
  import { CrdtNotifier } from "./CrdtNotifier";
21
37
  import { EventNotifier } from "./EventNotifier";
22
- import { OtherNotifier } from "./OtherNotifier";
23
38
  import { PluvProcedure } from "./PluvProcedure";
24
39
  import type { PluvRouterEventConfig } from "./PluvRouter";
25
40
  import { PluvRouter } from "./PluvRouter";
26
- import type { StateNotifierSubjects, SubscriptionCallback } from "./StateNotifier";
27
41
  import { StateNotifier } from "./StateNotifier";
28
42
  import type { UsersManagerConfig } from "./UsersManager";
29
43
  import { UsersManager } from "./UsersManager";
44
+ import { UsersNotifier } from "./UsersNotifier";
30
45
  import { MAX_PRESENCE_SIZE_BYTES } from "./constants";
31
46
  import type {
32
47
  EventResolver,
33
48
  EventResolverContext,
34
49
  InternalSubscriptions,
35
50
  PluvClientLimits,
36
- WebSocketConnection,
37
51
  } from "./types";
38
52
 
39
53
  export type MockedRoomEvents<TIO extends IOLike> = Partial<{
@@ -42,8 +56,8 @@ export type MockedRoomEvents<TIO extends IOLike> = Partial<{
42
56
 
43
57
  export type MockedRoomConfig<
44
58
  TIO extends IOLike,
45
- TPresence extends JsonObject,
46
- TCrdt extends AbstractCrdtDocFactory<any>,
59
+ TPresence extends Record<string, any>,
60
+ TCrdt extends AbstractCrdtDocFactory<any, any>,
47
61
  TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>>,
48
62
  > = {
49
63
  events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
@@ -54,19 +68,24 @@ export type MockedRoomConfig<
54
68
 
55
69
  export class MockedRoom<
56
70
  TIO extends IOLike,
57
- TPresence extends JsonObject,
58
- TCrdt extends AbstractCrdtDocFactory<any>,
71
+ TPresence extends Record<string, any>,
72
+ TCrdt extends AbstractCrdtDocFactory<any, any>,
59
73
  TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>>,
60
- > implements RoomLike<TIO, TPresence, InferStorage<TCrdt>>
74
+ > implements RoomLike<TIO, InferDoc<TCrdt>, TPresence, InferStorage<TCrdt>>
61
75
  {
62
76
  public readonly id: string;
63
77
 
78
+ /**
79
+ * @deprecated To be removed in v3. Use `getStorageLoaded` instead.
80
+ */
81
+ public readonly storageLoaded: boolean = true;
82
+
64
83
  private readonly _crdtManager: CrdtManager<TCrdt>;
65
84
  private readonly _crdtNotifier = new CrdtNotifier<InferStorage<TCrdt>>();
66
85
  private readonly _eventNotifier = new EventNotifier<MergeEvents<TEvents, TIO>>();
67
86
  private readonly _events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
68
87
  private readonly _limits: PluvClientLimits;
69
- private readonly _otherNotifier = new OtherNotifier<TIO, TPresence>();
88
+ private readonly _usersNotifier = new UsersNotifier<TIO, TPresence>();
70
89
  private readonly _router: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
71
90
  private _state: WebSocketState<TIO> = {
72
91
  authorization: {
@@ -75,10 +94,12 @@ export class MockedRoom<
75
94
  },
76
95
  connection: {
77
96
  attempts: 0,
78
- count: 1,
79
97
  id: null,
80
98
  state: ConnectionState.Untouched,
81
99
  },
100
+ storage: {
101
+ state: StorageState.Unavailable,
102
+ },
82
103
  webSocket: null,
83
104
  };
84
105
  private readonly _stateNotifier = new StateNotifier<TIO, TPresence>();
@@ -113,8 +134,11 @@ export class MockedRoom<
113
134
  this._observeCrdt();
114
135
  }
115
136
 
116
- public get storageLoaded(): boolean {
117
- return true;
137
+ public addEventListener<TKind extends keyof RoomEventListenerMap>(
138
+ kind: TKind,
139
+ handler: RoomEventListenerMap[TKind],
140
+ ): () => void {
141
+ return () => undefined;
118
142
  }
119
143
 
120
144
  public broadcast = new Proxy(
@@ -132,7 +156,8 @@ export class MockedRoom<
132
156
  any,
133
157
  any,
134
158
  TPresence,
135
- InferStorage<TCrdt>
159
+ TCrdt,
160
+ ""
136
161
  > | null;
137
162
 
138
163
  if (!procedure?.config.broadcast) {
@@ -146,7 +171,7 @@ export class MockedRoom<
146
171
  if (!myself) return;
147
172
 
148
173
  const parsed = procedure.config.input ? procedure.config.input.parse(data) : data;
149
- const context: EventResolverContext<TIO, TPresence, InferStorage<TCrdt>> = {
174
+ const context: EventResolverContext<TIO, TPresence, InferDocLike<TCrdt>> = {
150
175
  doc: this._crdtManager.doc,
151
176
  others: this._usersManager.getOthers(),
152
177
  room: this.id,
@@ -176,12 +201,7 @@ export class MockedRoom<
176
201
  };
177
202
  },
178
203
  },
179
- ) as (<TEvent extends keyof InferIOInput<MergeEvents<TEvents, TIO>>>(
180
- event: TEvent,
181
- data: Id<InferIOInput<MergeEvents<TEvents, TIO>>[TEvent]>,
182
- ) => Promise<void>) & {
183
- [event in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[event]>) => Promise<void>;
184
- };
204
+ ) as BroadcastProxy<TIO, TEvents>;
185
205
 
186
206
  public canRedo = (): boolean => {
187
207
  return !!this._crdtManager.doc.canRedo();
@@ -203,21 +223,14 @@ export class MockedRoom<
203
223
  ): (() => void) => fn(prop as any, callback);
204
224
  },
205
225
  },
206
- ) as (<TEvent extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(
207
- event: TEvent,
208
- callback: EventNotifierSubscriptionCallback<MergeEvents<TEvents, TIO>, TEvent>,
209
- ) => () => void) & {
210
- [event in keyof InferIOOutput<MergeEvents<TEvents, TIO>>]: (
211
- callback: EventNotifierSubscriptionCallback<MergeEvents<TEvents, TIO>, any>,
212
- ) => () => void;
213
- };
226
+ ) as EventProxy<TIO, TEvents>;
214
227
 
215
228
  public getConnection = (): WebSocketConnection => {
216
229
  // Create a read-only clone of the connection state
217
230
  return Object.freeze(JSON.parse(JSON.stringify(this._state.connection)));
218
231
  };
219
232
 
220
- public getDoc(): CrdtDocLike<InferStorage<TCrdt>> {
233
+ public getDoc(): CrdtDocLike<InferDoc<TCrdt>, InferStorage<TCrdt>> {
221
234
  return this._crdtManager.doc;
222
235
  }
223
236
 
@@ -253,33 +266,51 @@ export class MockedRoom<
253
266
  ): InferCrdtJson<InferStorage<TCrdt>[TKey]> | null;
254
267
  public getStorageJson<TKey extends keyof InferStorage<TCrdt>>(type?: TKey) {
255
268
  if (this._state.connection.id === null) return null;
256
-
257
269
  if (typeof type === "undefined") return this._crdtManager.doc.toJson();
258
270
 
259
271
  return this._crdtManager.doc.toJson(type);
260
272
  }
261
273
 
274
+ public getStorageLoaded(): boolean {
275
+ return true;
276
+ }
277
+
262
278
  public other = (
263
279
  connectionId: string,
264
- callback: OtherNotifierSubscriptionCallback<TIO, TPresence>,
280
+ callback: OtherSubscriptionCallback<TIO, TPresence>,
265
281
  ): (() => void) => {
266
282
  const clientId = this._usersManager.getClientId(connectionId);
267
283
 
268
284
  if (!clientId) return () => undefined;
269
285
 
270
- return this._otherNotifier.subscribe(clientId, callback);
286
+ return this._usersNotifier.subscribeOther(clientId, callback);
271
287
  };
272
288
 
273
289
  public redo = (): void => {
274
290
  this._crdtManager.doc.redo();
275
291
  };
276
292
 
277
- public storage = <TKey extends keyof InferStorage<TCrdt>>(
278
- key: TKey,
279
- fn: (value: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => void,
280
- ): (() => void) => {
281
- return this._crdtNotifier.subscribe(key, fn);
282
- };
293
+ public storage = new Proxy(
294
+ <TKey extends keyof InferStorage<TCrdt>>(
295
+ key: TKey,
296
+ callback: StorageSubscriptionCallback<InferStorage<TCrdt>, TKey>,
297
+ ): (() => void) => this._crdtNotifier.subscribe(key, callback),
298
+ {
299
+ get: (fn, prop) => {
300
+ type _Storage = InferStorage<TCrdt>;
301
+
302
+ if (!!prop) {
303
+ return (callback: StorageRootSubscriptionCallback<_Storage>) => {
304
+ return this._crdtNotifier.subcribeRoot(callback);
305
+ };
306
+ }
307
+
308
+ return (callback: StorageSubscriptionCallback<_Storage, keyof _Storage>) => {
309
+ return fn(prop as keyof InferStorage<TCrdt>, callback);
310
+ };
311
+ },
312
+ },
313
+ ) as StorageProxy<InferStorage<TCrdt>>;
283
314
 
284
315
  public storageRoot = (
285
316
  fn: (value: {
@@ -289,12 +320,51 @@ export class MockedRoom<
289
320
  return this._crdtNotifier.subcribeRoot(fn);
290
321
  };
291
322
 
292
- public subscribe = <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(
293
- name: TSubject,
294
- callback: SubscriptionCallback<TIO, TPresence, TSubject>,
295
- ): (() => void) => {
296
- return this._stateNotifier.subscribe(name, callback);
297
- };
323
+ public subscribe = new Proxy(
324
+ <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(
325
+ name: TSubject,
326
+ callback: SubscriptionCallback<TIO, TPresence, TSubject>,
327
+ ): (() => void) => {
328
+ return this._stateNotifier.subscribe(name, callback);
329
+ },
330
+ {
331
+ get: (fn, prop) => {
332
+ if (prop === "connection") {
333
+ return (callback: SubscriptionCallback<TIO, TPresence, "connection">) => {
334
+ return fn("connection", callback);
335
+ };
336
+ }
337
+
338
+ if (prop === "myPresence") {
339
+ return (callback: SubscriptionCallback<TIO, TPresence, "my-presence">) => {
340
+ return fn("my-presence", callback);
341
+ };
342
+ }
343
+
344
+ if (prop === "myself") {
345
+ return (callback: SubscriptionCallback<TIO, TPresence, "myself">) => {
346
+ return fn("myself", callback);
347
+ };
348
+ }
349
+
350
+ if (prop === "others") {
351
+ return (callback: OthersSubscriptionCallback<TIO, TPresence>) => {
352
+ return this._usersNotifier.subscribeOthers(callback);
353
+ };
354
+ }
355
+
356
+ if (prop === "storageLoaded") {
357
+ return (callback: SubscriptionCallback<TIO, TPresence, "storage-loaded">) => {
358
+ return fn("storage-loaded", callback);
359
+ };
360
+ }
361
+
362
+ if (prop === "event") return this.event;
363
+ if (prop === "other") return this.other;
364
+ if (prop === "storage") return this.storage;
365
+ },
366
+ },
367
+ ) as SubscribeProxy<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
298
368
 
299
369
  public transact = (fn: (storage: InferStorage<TCrdt>) => void, origin?: string): void => {
300
370
  const _origin = origin ?? this._state.connection.id;
package/src/PluvClient.ts CHANGED
@@ -24,8 +24,8 @@ import type { PluvClientLimits, PublicKey, WithMetadata } from "./types";
24
24
 
25
25
  export type PluvClientOptions<
26
26
  TIO extends IOLike<any, any>,
27
- TPresence extends JsonObject,
28
- TCrdt extends AbstractCrdtDocFactory<any>,
27
+ TPresence extends Record<string, any>,
28
+ TCrdt extends AbstractCrdtDocFactory<any, any>,
29
29
  TMetadata extends JsonObject,
30
30
  > = RoomEndpoints<TIO, TMetadata> & {
31
31
  debug?: boolean;
@@ -43,8 +43,8 @@ export type PluvClientOptions<
43
43
 
44
44
  export type CreateRoomOptions<
45
45
  TIO extends IOLike<any, any>,
46
- TPresence extends JsonObject,
47
- TCrdt extends AbstractCrdtDocFactory<any>,
46
+ TPresence extends Record<string, any>,
47
+ TCrdt extends AbstractCrdtDocFactory<any, any>,
48
48
  TMetadata extends JsonObject,
49
49
  TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},
50
50
  > = {
@@ -63,8 +63,8 @@ export type EnterRoomParams<TMetadata extends JsonObject = {}> = keyof TMetadata
63
63
 
64
64
  export class PluvClient<
65
65
  TIO extends IOLike<any, any>,
66
- TPresence extends JsonObject = {},
67
- TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory,
66
+ TPresence extends Record<string, any> = {},
67
+ TCrdt extends AbstractCrdtDocFactory<any, any> = NoopCrdtDocFactory,
68
68
  TMetadata extends JsonObject = {},
69
69
  > {
70
70
  public readonly metadata?: InputZodLike<TMetadata>;
@@ -84,8 +84,8 @@ export class PluvClient<
84
84
  };
85
85
  }
86
86
 
87
- public get procedure(): PluvProcedure<TIO, {}, {}, TPresence, InferStorage<TCrdt>> {
88
- return new PluvProcedure<TIO, {}, {}, TPresence, InferStorage<TCrdt>>();
87
+ public get procedure(): PluvProcedure<TIO, {}, {}, TPresence, TCrdt, ""> {
88
+ return new PluvProcedure<TIO, {}, {}, TPresence, TCrdt, "">();
89
89
  }
90
90
 
91
91
  constructor(options: PluvClientOptions<TIO, TPresence, TCrdt, TMetadata>) {
@@ -1,29 +1,34 @@
1
- import type { CrdtType } from "@pluv/crdt";
1
+ import type { AbstractCrdtDocFactory, InferDocLike } from "@pluv/crdt";
2
2
  import type { EventRecord, IOLike, InputZodLike, JsonObject, ProcedureLike } from "@pluv/types";
3
3
  import type { EventResolver, MergeEventRecords } from "./types";
4
4
 
5
5
  export interface PluvProcedureConfig<
6
- TIO extends IOLike = IOLike,
7
- TInput extends JsonObject = {},
8
- TOutput extends EventRecord<string, any> = {},
9
- TPresence extends JsonObject = {},
10
- TStorage extends Record<string, CrdtType<any, any>> = {},
6
+ TIO extends IOLike,
7
+ TInput extends JsonObject,
8
+ TOutput extends EventRecord<string, any>,
9
+ TPresence extends Record<string, any>,
10
+ TCrdt extends AbstractCrdtDocFactory<any, any>,
11
11
  > {
12
- broadcast?: EventResolver<TIO, TInput, TOutput, TPresence, TStorage> | null;
12
+ broadcast?: EventResolver<TIO, TInput, TOutput, TPresence, InferDocLike<TCrdt>> | null;
13
13
  input?: InputZodLike<TInput>;
14
14
  }
15
15
 
16
16
  export class PluvProcedure<
17
- TIO extends IOLike = IOLike,
18
- TInput extends JsonObject = {},
19
- TOutput extends EventRecord<string, any> = {},
20
- TPresence extends JsonObject = {},
21
- TStorage extends Record<string, CrdtType<any, any>> = {},
22
- TFilled extends "input" | "broadcast" | "" = "",
17
+ TIO extends IOLike,
18
+ TInput extends JsonObject,
19
+ TOutput extends EventRecord<string, any>,
20
+ TPresence extends Record<string, any>,
21
+ TCrdt extends AbstractCrdtDocFactory<any, any>,
22
+ TFilled extends "input" | "broadcast" | "",
23
23
  > implements ProcedureLike<TInput, TOutput>
24
24
  {
25
- private _broadcast: EventResolver<TIO, TInput, Partial<TOutput>, TPresence, TStorage> | null =
26
- null;
25
+ private _broadcast: EventResolver<
26
+ TIO,
27
+ TInput,
28
+ Partial<TOutput>,
29
+ TPresence,
30
+ InferDocLike<TCrdt>
31
+ > | null = null;
27
32
  private _input: InputZodLike<TInput> | null = null;
28
33
 
29
34
  public get config(): ProcedureLike<TInput, TOutput>["config"] {
@@ -34,7 +39,7 @@ export class PluvProcedure<
34
39
  } as ProcedureLike<TInput, TOutput>["config"];
35
40
  }
36
41
 
37
- constructor(config: PluvProcedureConfig<TIO, TInput, TOutput, TPresence, TStorage> = {}) {
42
+ constructor(config: PluvProcedureConfig<TIO, TInput, TOutput, TPresence, TCrdt> = {}) {
38
43
  const { broadcast, input } = config;
39
44
 
40
45
  this._broadcast = broadcast ?? null;
@@ -42,14 +47,14 @@ export class PluvProcedure<
42
47
  }
43
48
 
44
49
  public broadcast<TResult extends EventRecord<string, any> = {}>(
45
- resolver: EventResolver<TIO, TInput, TResult, TPresence, TStorage>,
50
+ resolver: EventResolver<TIO, TInput, TResult, TPresence, InferDocLike<TCrdt>>,
46
51
  ): Omit<
47
52
  PluvProcedure<
48
53
  TIO,
49
54
  TInput,
50
55
  MergeEventRecords<[TOutput, TResult]>,
51
56
  TPresence,
52
- TStorage,
57
+ TCrdt,
53
58
  TFilled | "input" | "broadcast"
54
59
  >,
55
60
  TFilled | "input" | "broadcast"
@@ -63,7 +68,7 @@ export class PluvProcedure<
63
68
  TInput,
64
69
  MergeEventRecords<[TOutput, TResult]>,
65
70
  TPresence,
66
- TStorage,
71
+ TCrdt,
67
72
  TFilled | "input" | "broadcast"
68
73
  >({
69
74
  ...(this.config as any),
@@ -73,14 +78,11 @@ export class PluvProcedure<
73
78
 
74
79
  public input<TData extends JsonObject>(
75
80
  input: InputZodLike<TData>,
76
- ): Omit<
77
- PluvProcedure<TIO, TData, {}, TPresence, TStorage, TFilled | "input">,
78
- TFilled | "input"
79
- > {
80
- return new PluvProcedure<TIO, TData, {}, TPresence, TStorage, TFilled | "input">({ input });
81
+ ): Omit<PluvProcedure<TIO, TData, {}, TPresence, TCrdt, TFilled | "input">, TFilled | "input"> {
82
+ return new PluvProcedure<TIO, TData, {}, TPresence, TCrdt, TFilled | "input">({ input });
81
83
  }
82
84
 
83
- private _resolver(): EventResolver<TIO, TInput, TOutput, TPresence, TStorage> {
85
+ private _resolver(): EventResolver<TIO, TInput, TOutput, TPresence, InferDocLike<TCrdt>> {
84
86
  return (data, context) => this._broadcast?.(data, context) as TOutput;
85
87
  }
86
88
  }