@liveblocks/redux 0.18.5 → 0.19.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.
package/dist/index.d.ts CHANGED
@@ -1,57 +1,72 @@
1
- import { JsonObject, BaseUserMeta, User, Client } from '@liveblocks/client';
1
+ import { JsonObject, BaseUserMeta, Client, User } from '@liveblocks/client';
2
2
  import { StoreEnhancer } from 'redux';
3
3
 
4
4
  declare type Mapping<T> = {
5
5
  [K in keyof T]?: boolean;
6
6
  };
7
- declare type LiveblocksState<TState, TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = TState & {
7
+ declare type LiveblocksContext<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
8
8
  /**
9
- * Liveblocks extra state attached by the enhancer
9
+ * Other users in the room. Empty no room is currently synced
10
10
  */
11
- readonly liveblocks: {
12
- /**
13
- * Other users in the room. Empty no room is currently synced
14
- */
15
- readonly others: Array<User<TPresence, TUserMeta>>;
16
- /**
17
- * Whether or not the room storage is currently loading
18
- */
19
- readonly isStorageLoading: boolean;
20
- /**
21
- * Connection state of the room
22
- */
23
- readonly connection: "closed" | "authenticating" | "unavailable" | "failed" | "open" | "connecting";
24
- };
11
+ readonly others: readonly User<TPresence, TUserMeta>[];
12
+ /**
13
+ * Whether or not the room storage is currently loading
14
+ */
15
+ readonly isStorageLoading: boolean;
16
+ /**
17
+ * Connection state of the room
18
+ */
19
+ readonly connection: "closed" | "authenticating" | "unavailable" | "failed" | "open" | "connecting";
20
+ };
21
+ /**
22
+ * @deprecated Please rename to WithLiveblocks<...>
23
+ */
24
+ declare type LiveblocksState<TState, TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = WithLiveblocks<TState, TPresence, TUserMeta>;
25
+ /**
26
+ * Adds the `liveblocks` property to your custom Redux state.
27
+ */
28
+ declare type WithLiveblocks<TState, TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = TState & {
29
+ readonly liveblocks: LiveblocksContext<TPresence, TUserMeta>;
25
30
  };
26
31
  /**
27
32
  * Actions used to interact with Liveblocks
28
33
  */
29
34
  declare const actions: {
30
35
  /**
31
- * Enters a room and starts sync it with zustand state
36
+ * Enters a room and starts sync it with Redux state
32
37
  * @param roomId The id of the room
33
- * @param initialState The initial state of the room storage. If a key does not exist if your room storage root, initialState[key] will be used.
34
38
  */
35
39
  enterRoom: typeof enterRoom;
36
40
  /**
37
- * Leaves a room and stops sync it with zustand state.
41
+ * Leaves a room and stops sync it with Redux state.
38
42
  * @param roomId The id of the room
39
43
  */
40
44
  leaveRoom: typeof leaveRoom;
41
45
  };
42
- declare function enterRoom<T>(roomId: string, initialState?: T): {
46
+ declare function enterRoom(roomId: string): {
43
47
  type: string;
44
48
  roomId: string;
45
- initialState?: T;
46
49
  };
47
50
  declare function leaveRoom(roomId: string): {
48
51
  type: string;
49
52
  roomId: string;
50
53
  };
51
- declare const enhancer: <T>(options: {
54
+ /**
55
+ * Redux store enhancer that will make the `liveblocks` key available on your
56
+ * Redux store.
57
+ */
58
+ declare const liveblocksEnhancer: <TState>(options: {
59
+ client: Client;
60
+ storageMapping?: Mapping<TState> | undefined;
61
+ presenceMapping?: Mapping<TState> | undefined;
62
+ }) => StoreEnhancer;
63
+ /**
64
+ * @deprecated Renamed to `liveblocksEnhancer`.
65
+ */
66
+ declare const enhancer: <TState>(options: {
52
67
  client: Client;
53
- storageMapping?: Mapping<T> | undefined;
54
- presenceMapping?: Mapping<T> | undefined;
68
+ storageMapping?: Mapping<TState> | undefined;
69
+ presenceMapping?: Mapping<TState> | undefined;
55
70
  }) => StoreEnhancer;
56
71
 
57
- export { LiveblocksState, Mapping, actions, enhancer };
72
+ export { LiveblocksState, Mapping, WithLiveblocks, actions, enhancer, liveblocksEnhancer };
package/dist/index.js CHANGED
@@ -77,186 +77,182 @@ var internalEnhancer = (options) => {
77
77
  if (process.env.NODE_ENV !== "production") {
78
78
  validateNoDuplicateKeys(mapping, presenceMapping);
79
79
  }
80
- return (createStore) => (reducer, initialState, enhancer2) => {
81
- let room = null;
82
- let isPatching = false;
83
- let storageRoot = null;
84
- let unsubscribeCallbacks = [];
85
- const newReducer = (state, action) => {
86
- switch (action.type) {
87
- case ACTION_TYPES.PATCH_REDUX_STATE:
88
- return __spreadValues(__spreadValues({}, state), action.state);
89
- case ACTION_TYPES.INIT_STORAGE:
90
- return __spreadProps(__spreadValues(__spreadValues({}, state), action.state), {
91
- liveblocks: __spreadProps(__spreadValues({}, state.liveblocks), {
92
- isStorageLoading: false
93
- })
94
- });
95
- case ACTION_TYPES.START_LOADING_STORAGE:
96
- return __spreadProps(__spreadValues({}, state), {
97
- liveblocks: __spreadProps(__spreadValues({}, state.liveblocks), {
98
- isStorageLoading: true
99
- })
100
- });
101
- case ACTION_TYPES.UPDATE_CONNECTION: {
102
- return __spreadProps(__spreadValues({}, state), {
103
- liveblocks: __spreadProps(__spreadValues({}, state.liveblocks), {
104
- connection: action.connection
105
- })
106
- });
107
- }
108
- case ACTION_TYPES.UPDATE_OTHERS: {
109
- return __spreadProps(__spreadValues({}, state), {
110
- liveblocks: __spreadProps(__spreadValues({}, state.liveblocks), {
111
- others: action.others
112
- })
113
- });
114
- }
115
- default: {
116
- const newState = reducer(state, action);
117
- if (room) {
118
- isPatching = true;
119
- updatePresence(room, state, newState, presenceMapping);
120
- room.batch(() => {
121
- if (storageRoot) {
122
- patchLiveblocksStorage(
123
- storageRoot,
124
- state,
125
- newState,
126
- mapping
127
- );
128
- }
80
+ return (createStore) => {
81
+ return (reducer, initialState, enhancer2) => {
82
+ let room = null;
83
+ let isPatching = false;
84
+ let storageRoot = null;
85
+ let unsubscribeCallbacks = [];
86
+ const newReducer = (state, action) => {
87
+ switch (action.type) {
88
+ case ACTION_TYPES.PATCH_REDUX_STATE:
89
+ return __spreadValues(__spreadValues({}, state), action.state);
90
+ case ACTION_TYPES.INIT_STORAGE:
91
+ return __spreadProps(__spreadValues(__spreadValues({}, state), action.state), {
92
+ liveblocks: __spreadProps(__spreadValues({}, state.liveblocks), {
93
+ isStorageLoading: false
94
+ })
95
+ });
96
+ case ACTION_TYPES.START_LOADING_STORAGE:
97
+ return __spreadProps(__spreadValues({}, state), {
98
+ liveblocks: __spreadProps(__spreadValues({}, state.liveblocks), {
99
+ isStorageLoading: true
100
+ })
101
+ });
102
+ case ACTION_TYPES.UPDATE_CONNECTION: {
103
+ return __spreadProps(__spreadValues({}, state), {
104
+ liveblocks: __spreadProps(__spreadValues({}, state.liveblocks), {
105
+ connection: action.connection
106
+ })
129
107
  });
130
- isPatching = false;
131
108
  }
132
- if (newState.liveblocks == null) {
133
- return __spreadProps(__spreadValues({}, newState), {
134
- liveblocks: {
135
- others: [],
136
- isStorageLoading: false,
137
- connection: "closed"
138
- }
109
+ case ACTION_TYPES.UPDATE_OTHERS: {
110
+ return __spreadProps(__spreadValues({}, state), {
111
+ liveblocks: __spreadProps(__spreadValues({}, state.liveblocks), {
112
+ others: action.others
113
+ })
139
114
  });
140
115
  }
141
- return newState;
116
+ default: {
117
+ const newState = reducer(state, action);
118
+ if (room) {
119
+ isPatching = true;
120
+ updatePresence(room, state, newState, presenceMapping);
121
+ room.batch(() => {
122
+ if (storageRoot) {
123
+ patchLiveblocksStorage(
124
+ storageRoot,
125
+ state,
126
+ newState,
127
+ mapping
128
+ );
129
+ }
130
+ });
131
+ isPatching = false;
132
+ }
133
+ if (newState.liveblocks == null) {
134
+ return __spreadProps(__spreadValues({}, newState), {
135
+ liveblocks: {
136
+ others: [],
137
+ isStorageLoading: false,
138
+ connection: "closed"
139
+ }
140
+ });
141
+ }
142
+ return newState;
143
+ }
142
144
  }
143
- }
144
- };
145
- const store = createStore(newReducer, initialState, enhancer2);
146
- function enterRoom2(roomId, storageInitialState = {}, reduxState) {
147
- if (storageRoot) {
148
- return;
149
- }
150
- room = client.enter(roomId, { initialPresence: {} });
151
- broadcastInitialPresence(room, reduxState, presenceMapping);
152
- unsubscribeCallbacks.push(
153
- room.events.connection.subscribe(() => {
154
- store.dispatch({
155
- type: ACTION_TYPES.UPDATE_CONNECTION,
156
- connection: room.getConnectionState()
157
- });
158
- })
159
- );
160
- unsubscribeCallbacks.push(
161
- room.events.others.subscribe(({ others }) => {
162
- store.dispatch({
163
- type: ACTION_TYPES.UPDATE_OTHERS,
164
- others: others.toArray()
165
- });
166
- })
167
- );
168
- unsubscribeCallbacks.push(
169
- room.events.me.subscribe(() => {
170
- if (isPatching === false) {
145
+ };
146
+ const store = createStore(newReducer, initialState, enhancer2);
147
+ function enterRoom2(roomId) {
148
+ if (storageRoot) {
149
+ return;
150
+ }
151
+ const initialPresence = selectFields(
152
+ store.getState(),
153
+ presenceMapping
154
+ );
155
+ room = client.enter(roomId, { initialPresence });
156
+ unsubscribeCallbacks.push(
157
+ room.events.connection.subscribe(() => {
171
158
  store.dispatch({
172
- type: ACTION_TYPES.PATCH_REDUX_STATE,
173
- state: patchPresenceState(
174
- room.getPresence(),
175
- presenceMapping
176
- )
159
+ type: ACTION_TYPES.UPDATE_CONNECTION,
160
+ connection: room.getConnectionState()
177
161
  });
178
- }
179
- })
180
- );
181
- store.dispatch({
182
- type: ACTION_TYPES.START_LOADING_STORAGE
183
- });
184
- room.getStorage().then(({ root }) => {
185
- const updates = {};
186
- room.batch(() => {
187
- for (const key in mapping) {
188
- const liveblocksStatePart = root.get(key);
189
- if (liveblocksStatePart == null) {
190
- updates[key] = storageInitialState[key];
191
- _core.patchLiveObjectKey.call(void 0,
192
- root,
193
- key,
194
- void 0,
195
- storageInitialState[key]
196
- );
197
- } else {
198
- updates[key] = _core.lsonToJson.call(void 0, liveblocksStatePart);
162
+ })
163
+ );
164
+ unsubscribeCallbacks.push(
165
+ room.events.others.subscribe(({ others }) => {
166
+ store.dispatch({
167
+ type: ACTION_TYPES.UPDATE_OTHERS,
168
+ others
169
+ });
170
+ })
171
+ );
172
+ unsubscribeCallbacks.push(
173
+ room.events.me.subscribe(() => {
174
+ if (isPatching === false) {
175
+ store.dispatch({
176
+ type: ACTION_TYPES.PATCH_REDUX_STATE,
177
+ state: selectFields(room.getPresence(), presenceMapping)
178
+ });
199
179
  }
200
- }
201
- });
180
+ })
181
+ );
202
182
  store.dispatch({
203
- type: ACTION_TYPES.INIT_STORAGE,
204
- state: updates
183
+ type: ACTION_TYPES.START_LOADING_STORAGE
205
184
  });
206
- storageRoot = root;
207
- unsubscribeCallbacks.push(
208
- room.subscribe(
209
- root,
210
- (updates2) => {
211
- if (isPatching === false) {
212
- store.dispatch({
213
- type: ACTION_TYPES.PATCH_REDUX_STATE,
214
- state: patchState(
215
- store.getState(),
216
- updates2,
217
- mapping
218
- )
219
- });
185
+ room.getStorage().then(({ root }) => {
186
+ const updates = {};
187
+ room.batch(() => {
188
+ for (const key in mapping) {
189
+ const liveblocksStatePart = root.get(key);
190
+ if (liveblocksStatePart == null) {
191
+ updates[key] = store.getState()[key];
192
+ _core.patchLiveObjectKey.call(void 0, root, key, void 0, store.getState()[key]);
193
+ } else {
194
+ updates[key] = _core.lsonToJson.call(void 0, liveblocksStatePart);
220
195
  }
221
- },
222
- { isDeep: true }
223
- )
224
- );
225
- });
226
- }
227
- function leaveRoom2(roomId) {
228
- for (const unsubscribe of unsubscribeCallbacks) {
229
- unsubscribe();
196
+ }
197
+ });
198
+ store.dispatch({
199
+ type: ACTION_TYPES.INIT_STORAGE,
200
+ state: updates
201
+ });
202
+ storageRoot = root;
203
+ unsubscribeCallbacks.push(
204
+ room.subscribe(
205
+ root,
206
+ (updates2) => {
207
+ if (isPatching === false) {
208
+ store.dispatch({
209
+ type: ACTION_TYPES.PATCH_REDUX_STATE,
210
+ state: patchState(
211
+ store.getState(),
212
+ updates2,
213
+ mapping
214
+ )
215
+ });
216
+ }
217
+ },
218
+ { isDeep: true }
219
+ )
220
+ );
221
+ });
230
222
  }
231
- storageRoot = null;
232
- room = null;
233
- isPatching = false;
234
- unsubscribeCallbacks = [];
235
- client.leave(roomId);
236
- }
237
- function newDispatch(action, state) {
238
- if (action.type === ACTION_TYPES.ENTER) {
239
- enterRoom2(action.roomId, action.initialState, store.getState());
240
- } else if (action.type === ACTION_TYPES.LEAVE) {
241
- leaveRoom2(action.roomId);
242
- } else {
243
- store.dispatch(action, state);
223
+ function leaveRoom2(roomId) {
224
+ for (const unsubscribe of unsubscribeCallbacks) {
225
+ unsubscribe();
226
+ }
227
+ storageRoot = null;
228
+ room = null;
229
+ isPatching = false;
230
+ unsubscribeCallbacks = [];
231
+ client.leave(roomId);
244
232
  }
245
- }
246
- return __spreadProps(__spreadValues({}, store), {
247
- dispatch: newDispatch
248
- });
233
+ function newDispatch(action) {
234
+ if (action.type === ACTION_TYPES.ENTER) {
235
+ enterRoom2(action.roomId);
236
+ } else if (action.type === ACTION_TYPES.LEAVE) {
237
+ leaveRoom2(action.roomId);
238
+ } else {
239
+ store.dispatch(action);
240
+ }
241
+ }
242
+ return __spreadProps(__spreadValues({}, store), {
243
+ dispatch: newDispatch
244
+ });
245
+ };
249
246
  };
250
247
  };
251
248
  var actions = {
252
249
  enterRoom,
253
250
  leaveRoom
254
251
  };
255
- function enterRoom(roomId, initialState) {
252
+ function enterRoom(roomId) {
256
253
  return {
257
254
  type: ACTION_TYPES.ENTER,
258
- roomId,
259
- initialState
255
+ roomId
260
256
  };
261
257
  }
262
258
  function leaveRoom(roomId) {
@@ -265,22 +261,20 @@ function leaveRoom(roomId) {
265
261
  roomId
266
262
  };
267
263
  }
268
- var enhancer = internalEnhancer;
264
+ var liveblocksEnhancer = internalEnhancer;
265
+ var enhancer = liveblocksEnhancer;
269
266
  function patchLiveblocksStorage(root, oldState, newState, mapping) {
270
267
  for (const key in mapping) {
271
268
  if (process.env.NODE_ENV !== "production" && typeof newState[key] === "function") {
272
269
  throw mappingToFunctionIsNotAllowed("value");
273
270
  }
274
271
  if (oldState[key] !== newState[key]) {
275
- _core.patchLiveObjectKey.call(void 0, root, key, oldState[key], newState[key]);
272
+ const oldVal = oldState[key];
273
+ const newVal = newState[key];
274
+ _core.patchLiveObjectKey.call(void 0, root, key, oldVal, newVal);
276
275
  }
277
276
  }
278
277
  }
279
- function broadcastInitialPresence(room, state, mapping) {
280
- for (const key in mapping) {
281
- room == null ? void 0 : room.updatePresence({ [key]: state[key] });
282
- }
283
- }
284
278
  function updatePresence(room, oldState, newState, presenceMapping) {
285
279
  for (const key in presenceMapping) {
286
280
  if (typeof newState[key] === "function") {
@@ -301,7 +295,7 @@ function validateNoDuplicateKeys(storageMapping, presenceMapping) {
301
295
  }
302
296
  }
303
297
  }
304
- function patchPresenceState(presence, mapping) {
298
+ function selectFields(presence, mapping) {
305
299
  const partialState = {};
306
300
  for (const key in mapping) {
307
301
  partialState[key] = presence[key];
@@ -340,4 +334,5 @@ function validateMapping(mapping, mappingType) {
340
334
 
341
335
 
342
336
 
343
- exports.actions = actions; exports.enhancer = enhancer;
337
+
338
+ exports.actions = actions; exports.enhancer = enhancer; exports.liveblocksEnhancer = liveblocksEnhancer;
package/dist/index.mjs CHANGED
@@ -3,3 +3,4 @@ import mod from "./index.js";
3
3
  export default mod;
4
4
  export const actions = mod.actions;
5
5
  export const enhancer = mod.enhancer;
6
+ export const liveblocksEnhancer = mod.liveblocksEnhancer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/redux",
3
- "version": "0.18.5",
3
+ "version": "0.19.0",
4
4
  "description": "A store enhancer to integrate Liveblocks into Redux stores.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -23,8 +23,7 @@
23
23
  "format": "eslint --fix src/ && prettier --write src/",
24
24
  "lint": "eslint src/",
25
25
  "test": "jest --silent --verbose",
26
- "test:watch": "jest --silent --verbose --watch",
27
- "dtslint": "dtslint --localTs node_modules/typescript/lib --expectOnly types"
26
+ "test:watch": "jest --silent --verbose --watch"
28
27
  },
29
28
  "license": "Apache-2.0",
30
29
  "repository": {
@@ -33,14 +32,13 @@
33
32
  "directory": "packages/liveblocks-redux"
34
33
  },
35
34
  "dependencies": {
36
- "@liveblocks/client": "0.18.5",
37
- "@liveblocks/core": "0.18.5"
35
+ "@liveblocks/client": "0.19.0",
36
+ "@liveblocks/core": "0.19.0"
38
37
  },
39
38
  "peerDependencies": {
40
39
  "redux": "^4"
41
40
  },
42
41
  "devDependencies": {
43
- "@definitelytyped/dtslint": "^0.0.103",
44
42
  "@liveblocks/eslint-config": "*",
45
43
  "@liveblocks/jest-config": "*",
46
44
  "@reduxjs/toolkit": "^1.7.2",