@pluv/client 0.9.0 → 0.9.1

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,17 +1,18 @@
1
1
 
2
- > @pluv/client@0.9.0 build /home/runner/work/pluv/pluv/packages/client
2
+ > @pluv/client@0.9.1 build /home/runner/work/pluv/pluv/packages/client
3
3
  > tsup src/index.ts --format esm,cjs --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
- CLI tsup v7.0.0
7
+ CLI tsup v7.1.0
8
8
  CLI Target: es6
9
9
  ESM Build start
10
10
  CJS Build start
11
- CJS dist/index.js 40.23 KB
12
- CJS ⚡️ Build success in 98ms
13
11
  ESM dist/index.mjs 39.02 KB
14
- ESM ⚡️ Build success in 100ms
12
+ ESM ⚡️ Build success in 135ms
13
+ CJS dist/index.js 40.23 KB
14
+ CJS ⚡️ Build success in 135ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 4765ms
17
- DTS dist/index.d.ts 12.92 KB
16
+ DTS ⚡️ Build success in 4784ms
17
+ DTS dist/index.d.mts 12.92 KB
18
+ DTS dist/index.d.ts 12.92 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @pluv/client
2
2
 
3
+ ## 0.9.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 8fba48b: fix including incorrect dependency
8
+ - 8997c65: bumped dependencies
9
+ - Updated dependencies [8fba48b]
10
+ - Updated dependencies [8997c65]
11
+ - @pluv/crdt-yjs@0.4.1
12
+ - @pluv/types@0.2.2
13
+
3
14
  ## 0.9.0
4
15
 
5
16
  ### Minor Changes
@@ -0,0 +1,273 @@
1
+ import { InferYjsSharedTypeJson, array, map, object, text } from '@pluv/crdt-yjs';
2
+ export { InferYjsSharedTypeJson } from '@pluv/crdt-yjs';
3
+ import * as _pluv_types from '@pluv/types';
4
+ import { IOLike, InferIOOutput, Id, IOEventMessage, JsonObject, InferIOAuthorizeUser, InferIOAuthorize, InferIOInput, InputZodLike, InferIOAuthorizeRequired } from '@pluv/types';
5
+ export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
6
+ import { AbstractType } from 'yjs';
7
+ export { AbstractType } from 'yjs';
8
+ import { Subject } from 'wonka';
9
+
10
+ type EventNotifierSubscriptionCallback<TIO extends IOLike, TEvent extends keyof InferIOOutput<TIO>> = (value: Id<IOEventMessage<TIO, TEvent>>) => void;
11
+
12
+ interface AuthorizationState<TIO extends IOLike> {
13
+ token: string | null;
14
+ user: InferIOAuthorizeUser<InferIOAuthorize<TIO>> | null;
15
+ }
16
+ declare enum ConnectionState {
17
+ Closed = "Closed",
18
+ Connecting = "Connecting",
19
+ Open = "Open",
20
+ Unavailable = "Unavailable",
21
+ Untouched = "Untouched"
22
+ }
23
+ interface WebSocketConnection {
24
+ count: number;
25
+ id: string | null;
26
+ state: ConnectionState;
27
+ }
28
+ interface WebSocketState<TIO extends IOLike> {
29
+ authorization: AuthorizationState<TIO>;
30
+ connection: WebSocketConnection;
31
+ webSocket: WebSocket | null;
32
+ }
33
+ interface UserInfo<TIO extends IOLike, TPresence extends JsonObject = {}> {
34
+ connectionId: string;
35
+ presence: TPresence;
36
+ user: Id<InferIOAuthorizeUser<InferIOAuthorize<TIO>>>;
37
+ }
38
+
39
+ type OtherNotifierSubscriptionCallback<TIO extends IOLike> = (value: Id<UserInfo<TIO>> | null) => void;
40
+
41
+ interface StateNotifierSubjects<TIO extends IOLike, TPresence extends JsonObject> {
42
+ connection: Subject<Id<WebSocketState<TIO>>>;
43
+ "my-presence": Subject<TPresence | null>;
44
+ myself: Subject<Readonly<Id<UserInfo<TIO>>> | null>;
45
+ others: Subject<readonly Id<UserInfo<TIO>>[]>;
46
+ }
47
+ type InferSubjectValue<TIO extends IOLike, TPresence extends JsonObject, TSubject extends keyof StateNotifierSubjects<TIO, TPresence>> = StateNotifierSubjects<TIO, TPresence>[TSubject] extends Subject<infer IValue> ? Id<IValue> : never;
48
+ type SubscriptionCallback<TIO extends IOLike, TPresence extends JsonObject, TSubject extends keyof StateNotifierSubjects<TIO, TPresence>> = (value: InferSubjectValue<TIO, TPresence, TSubject>) => void;
49
+
50
+ declare abstract class AbstractRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> {
51
+ readonly id: string;
52
+ constructor(room: string);
53
+ abstract broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
54
+ abstract event<TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>): () => void;
55
+ abstract getConnection(): WebSocketConnection;
56
+ abstract getMyPresence(): TPresence;
57
+ abstract getMyself(): Id<UserInfo<TIO, TPresence>> | null;
58
+ abstract getOther(connectionId: string): Id<UserInfo<TIO, TPresence>> | null;
59
+ abstract getOthers(): readonly Id<UserInfo<TIO, TPresence>>[];
60
+ abstract getStorage<TKey extends keyof TStorage>(key: TKey): TStorage[TKey] | null;
61
+ abstract other(connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>): () => void;
62
+ abstract storage<TKey extends keyof TStorage>(key: TKey, fn: (value: InferYjsSharedTypeJson<TStorage[TKey]>) => void): () => void;
63
+ abstract subscribe<TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>): () => void;
64
+ abstract updateMyPresence(presence: Partial<TPresence>): void;
65
+ }
66
+
67
+ declare abstract class AbstractStorageStore {
68
+ room: string;
69
+ constructor(room: string);
70
+ abstract addUpdate(update: string): Promise<void>;
71
+ abstract destroy(): Promise<void>;
72
+ abstract flatten(encodedState: string): Promise<void>;
73
+ abstract getShouldFlatten(): Promise<boolean>;
74
+ abstract getUpdates(start?: number): Promise<readonly string[]>;
75
+ abstract initialize(): Promise<void>;
76
+ }
77
+
78
+ interface CrdtManagerOptions<TStorage extends Record<string, AbstractType<any>> = {}> {
79
+ encodedState?: string | Uint8Array | null;
80
+ initialStorage?: () => TStorage;
81
+ }
82
+
83
+ type UsersManagerConfig<TPresence extends JsonObject = {}> = {
84
+ initialPresence?: TPresence;
85
+ presence?: InputZodLike<TPresence>;
86
+ };
87
+
88
+ declare global {
89
+ var process: {
90
+ env: {
91
+ [key: string]: string | undefined;
92
+ };
93
+ };
94
+ }
95
+ type AuthEndpoint = string | ((room: string) => string | FetchOptions) | true;
96
+ type WsEndpoint = string | ((room: string) => string);
97
+ type FetchOptions = {
98
+ url: string;
99
+ options?: RequestInit;
100
+ };
101
+ type RoomEndpoints<TIO extends IOLike> = {
102
+ wsEndpoint?: WsEndpoint;
103
+ } & (InferIOAuthorizeRequired<InferIOAuthorize<TIO>> extends true ? {
104
+ authEndpoint: AuthEndpoint;
105
+ } : {
106
+ authEndpoint?: undefined;
107
+ });
108
+ type PluvRoomAddon<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = (input: PluvRoomAddonInput<TIO, TPresence, TStorage>) => Partial<PluvRoomAddonResult>;
109
+ interface PluvRoomAddonInput<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> {
110
+ room: PluvRoom<TIO, TPresence, TStorage>;
111
+ }
112
+ interface PluvRoomAddonResult {
113
+ storage: AbstractStorageStore;
114
+ }
115
+ type PluvRoomDebug<TIO extends IOLike> = Id<{
116
+ output: readonly (keyof InferIOOutput<TIO>)[];
117
+ input: readonly (keyof InferIOInput<TIO>)[];
118
+ }>;
119
+ type PluvRoomOptions<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = {
120
+ addons?: readonly PluvRoomAddon<TIO, TPresence, TStorage>[];
121
+ debug?: boolean | PluvRoomDebug<TIO>;
122
+ onAuthorizationFail?: (error: Error) => void;
123
+ } & Omit<CrdtManagerOptions<TStorage>, "encodedState"> & UsersManagerConfig<TPresence>;
124
+ type RoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = RoomEndpoints<TIO> & PluvRoomOptions<TIO, TPresence, TStorage>;
125
+ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
126
+ readonly _endpoints: RoomEndpoints<TIO>;
127
+ private _crdtManager;
128
+ private _crdtNotifier;
129
+ private _debug;
130
+ private _eventNotifier;
131
+ private _intervals;
132
+ private _listeners;
133
+ private _otherNotifier;
134
+ private _state;
135
+ private _stateNotifier;
136
+ private _storageStore;
137
+ private _subscriptions;
138
+ private _timeouts;
139
+ private _windowListeners;
140
+ private _wsListeners;
141
+ private _usersManager;
142
+ constructor(room: string, options: RoomConfig<TIO, TPresence, TStorage>);
143
+ get webSocket(): WebSocket | null;
144
+ broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
145
+ connect(): Promise<void>;
146
+ disconnect(): Promise<void>;
147
+ event: <TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>) => (() => void);
148
+ getConnection(): WebSocketConnection;
149
+ getMyPresence: () => TPresence;
150
+ getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
151
+ getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
152
+ getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
153
+ getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey] | null;
154
+ other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>) => (() => void);
155
+ storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferYjsSharedTypeJson<TStorage[TKey]>) => void) => (() => void);
156
+ subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
157
+ updateMyPresence: (presence: Partial<TPresence>) => void;
158
+ private _addToStorageStore;
159
+ private _applyStorageStore;
160
+ private _attachWindowListeners;
161
+ private _attachWsListeners;
162
+ private _clearInterval;
163
+ private _clearTimeout;
164
+ private _closeWs;
165
+ private _detachWindowListeners;
166
+ private _detachWsListeners;
167
+ private _emitSharedTypes;
168
+ private _flattenStorageStore;
169
+ private _getAddon;
170
+ private _getAuthFetchOptions;
171
+ private _getAuthorization;
172
+ private _getWsEndpoint;
173
+ private _handleExit;
174
+ private _handlePresenceUpdatedMessage;
175
+ private _handleReceiveOthers;
176
+ private _handleRegisteredMessage;
177
+ private _handleStorageReceivedMessage;
178
+ private _handleStorageUpdatedMessage;
179
+ private _handleUserJoinedMessage;
180
+ private _heartbeat;
181
+ private _logDebug;
182
+ private _observeCrdt;
183
+ private _onAuthorizationFail;
184
+ /**
185
+ * TODO
186
+ * @description Determine if ws was closed with a code for closing without retries.
187
+ * Otherwise, attempt to retry again with incremental backoff
188
+ * @author leedavidcs
189
+ * @date August 19, 2022
190
+ */
191
+ private _onClose;
192
+ /**
193
+ * TODO
194
+ * @description Handle websocket errors in a meaningful way, should they occur
195
+ * @author leedavidcs
196
+ * @date August 19, 2022
197
+ */
198
+ private _onError;
199
+ private _onMessage;
200
+ private _onOpen;
201
+ private _onNavigatorOnline;
202
+ private _onVisibilityChange;
203
+ private _parseMessage;
204
+ private _reconnect;
205
+ private _sendMessage;
206
+ private _updateState;
207
+ }
208
+
209
+ type PluvClientOptions<TIO extends IOLike> = RoomEndpoints<TIO> & {
210
+ debug?: boolean;
211
+ };
212
+ declare class PluvClient<TIO extends IOLike = IOLike> {
213
+ private _authEndpoint;
214
+ private _debug;
215
+ private _wsEndpoint;
216
+ private _rooms;
217
+ constructor(options: PluvClientOptions<TIO>);
218
+ createRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}>(room: string, options?: PluvRoomOptions<TIO, TPresence, TStorage>) => PluvRoom<TIO, TPresence, TStorage>;
219
+ enter: (room: string | PluvRoom<TIO, any, any>) => Promise<PluvRoom<TIO, JsonObject, any>>;
220
+ getRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}>(room: string) => PluvRoom<TIO, TPresence, TStorage> | null;
221
+ getRooms: () => readonly PluvRoom<TIO, JsonObject, any>[];
222
+ leave: (room: string | PluvRoom<TIO, any, any>) => Promise<void>;
223
+ private _logDebug;
224
+ }
225
+
226
+ declare const createClient: <TIO extends IOLike<_pluv_types.IOAuthorize<any, any>, {}, {}, {}, {}> = IOLike<_pluv_types.IOAuthorize<any, any>, {}, {}, {}, {}>>(options: PluvClientOptions<TIO>) => PluvClient<TIO>;
227
+
228
+ type MockedRoomEvents<TIO extends IOLike> = Partial<{
229
+ [P in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[P]>) => Partial<InferIOOutput<TIO>>;
230
+ }>;
231
+ type MockedRoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = {
232
+ events?: MockedRoomEvents<TIO>;
233
+ } & Omit<CrdtManagerOptions<TStorage>, "encodedState"> & UsersManagerConfig<TPresence>;
234
+ declare class MockedRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
235
+ private _crdtManager;
236
+ private _crdtNotifier;
237
+ private _eventNotifier;
238
+ private _events?;
239
+ private _otherNotifier;
240
+ private _state;
241
+ private _stateNotifier;
242
+ private _subscriptions;
243
+ private _usersManager;
244
+ constructor(room: string, options: MockedRoomConfig<TIO, TPresence, TStorage>);
245
+ broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
246
+ event: <TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>) => (() => void);
247
+ getConnection(): WebSocketConnection;
248
+ getMyPresence: () => TPresence;
249
+ getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
250
+ getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
251
+ getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
252
+ getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey] | null;
253
+ other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>) => (() => void);
254
+ storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferYjsSharedTypeJson<TStorage[TKey]>) => void) => (() => void);
255
+ subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
256
+ updateMyPresence: (presence: Partial<TPresence>) => void;
257
+ private _observeCrdt;
258
+ }
259
+
260
+ declare const y_array: typeof array;
261
+ declare const y_map: typeof map;
262
+ declare const y_object: typeof object;
263
+ declare const y_text: typeof text;
264
+ declare namespace y {
265
+ export {
266
+ y_array as array,
267
+ y_map as map,
268
+ y_object as object,
269
+ y_text as text,
270
+ };
271
+ }
272
+
273
+ export { AbstractRoom, AbstractStorageStore, ConnectionState, MockedRoom, MockedRoomConfig, MockedRoomEvents, PluvClient, PluvClientOptions, PluvRoom, PluvRoomAddon, PluvRoomAddonInput, PluvRoomAddonResult, PluvRoomDebug, UserInfo, WebSocketConnection, WebSocketState, createClient, y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/client",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "@pluv/io frontend client",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -17,21 +17,20 @@
17
17
  "access": "public"
18
18
  },
19
19
  "dependencies": {
20
- "@playwright/test": "^1.35.1",
21
- "@types/react": "^18.2.13",
20
+ "@types/react": "^18.2.15",
22
21
  "wonka": "^6.3.2",
23
- "@pluv/crdt-yjs": "^0.4.0",
24
- "@pluv/types": "^0.2.1"
22
+ "@pluv/crdt-yjs": "^0.4.1",
23
+ "@pluv/types": "^0.2.2"
25
24
  },
26
25
  "peerDependencies": {
27
26
  "yjs": "^13.0.0"
28
27
  },
29
28
  "devDependencies": {
30
- "tsup": "^7.0.0",
31
- "typescript": "^5.1.3",
32
- "yjs": "^13.6.4",
33
- "@pluv/tsconfig": "^0.1.7",
34
- "eslint-config-pluv": "^0.1.13"
29
+ "tsup": "^7.1.0",
30
+ "typescript": "^5.1.6",
31
+ "yjs": "^13.6.6",
32
+ "@pluv/tsconfig": "^0.1.8",
33
+ "eslint-config-pluv": "^0.1.14"
35
34
  },
36
35
  "scripts": {
37
36
  "build": "tsup src/index.ts --format esm,cjs --dts",
@@ -1,6 +1,6 @@
1
1
  export const debounce = <TFunc extends (...args: any[]) => any>(
2
2
  fn: TFunc,
3
- options?: { wait: number; immediate?: boolean }
3
+ options?: { wait: number; immediate?: boolean },
4
4
  ): ((...args: Parameters<TFunc>) => void) => {
5
5
  const { wait, immediate = false } = options ?? {};
6
6