@liveblocks/zustand 0.17.8 → 0.17.9
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/.built-by-link-script +1 -0
- package/index.d.ts +45 -84
- package/index.js +257 -298
- package/index.mjs +4 -240
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ba5e65b5d95af44c0fcdda18d51bc943741ca13f
|
package/index.d.ts
CHANGED
|
@@ -1,97 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
LsonObject,
|
|
4
|
-
BaseUserMeta,
|
|
5
|
-
Json,
|
|
6
|
-
Room,
|
|
7
|
-
User,
|
|
8
|
-
Client,
|
|
9
|
-
} from "@liveblocks/client";
|
|
10
|
-
import { StateCreator, SetState, GetState, StoreApi } from "zustand";
|
|
1
|
+
import { JsonObject, LsonObject, BaseUserMeta, Json, Room, User, Client } from '@liveblocks/client';
|
|
2
|
+
import { StateCreator, SetState, GetState, StoreApi } from 'zustand';
|
|
11
3
|
|
|
12
4
|
declare type ZustandState = Record<string, unknown>;
|
|
13
|
-
declare type LiveblocksState<
|
|
14
|
-
TState extends ZustandState,
|
|
15
|
-
TPresence extends JsonObject = JsonObject,
|
|
16
|
-
TStorage extends LsonObject = LsonObject,
|
|
17
|
-
TUserMeta extends BaseUserMeta = BaseUserMeta,
|
|
18
|
-
TRoomEvent extends Json = Json
|
|
19
|
-
> = TState & {
|
|
20
|
-
/**
|
|
21
|
-
* Liveblocks extra state attached by the middleware
|
|
22
|
-
*/
|
|
23
|
-
readonly liveblocks: {
|
|
5
|
+
declare type LiveblocksState<TState extends ZustandState, TPresence extends JsonObject = JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = Json> = TState & {
|
|
24
6
|
/**
|
|
25
|
-
*
|
|
26
|
-
* @param roomId The id of the room
|
|
27
|
-
* @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.
|
|
7
|
+
* Liveblocks extra state attached by the middleware
|
|
28
8
|
*/
|
|
29
|
-
readonly
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
9
|
+
readonly liveblocks: {
|
|
10
|
+
/**
|
|
11
|
+
* Enters a room and starts sync it with zustand state
|
|
12
|
+
* @param roomId The id of the room
|
|
13
|
+
* @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.
|
|
14
|
+
*/
|
|
15
|
+
readonly enterRoom: (roomId: string, initialState: Partial<TState>) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Leaves a room and stops sync it with zustand state.
|
|
18
|
+
* @param roomId The id of the room
|
|
19
|
+
*/
|
|
20
|
+
readonly leaveRoom: (roomId: string) => void;
|
|
21
|
+
/**
|
|
22
|
+
* The room currently synced to your zustand state.
|
|
23
|
+
*/
|
|
24
|
+
readonly room: Room<TPresence, TStorage, TUserMeta, TRoomEvent> | null;
|
|
25
|
+
/**
|
|
26
|
+
* Other users in the room. Empty no room is currently synced
|
|
27
|
+
*/
|
|
28
|
+
readonly others: Array<User<TPresence, TUserMeta>>;
|
|
29
|
+
/**
|
|
30
|
+
* Whether or not the room storage is currently loading
|
|
31
|
+
*/
|
|
32
|
+
readonly isStorageLoading: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Connection state of the room
|
|
35
|
+
*/
|
|
36
|
+
readonly connection: "closed" | "authenticating" | "unavailable" | "failed" | "open" | "connecting";
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
declare type Mapping<T> = {
|
|
40
|
+
[K in keyof T]?: boolean;
|
|
41
|
+
};
|
|
42
|
+
declare type Options<T> = {
|
|
39
43
|
/**
|
|
40
|
-
*
|
|
44
|
+
* Liveblocks client created by @liveblocks/client createClient
|
|
41
45
|
*/
|
|
42
|
-
|
|
46
|
+
client: Client;
|
|
43
47
|
/**
|
|
44
|
-
*
|
|
48
|
+
* Mapping used to synchronize a part of your zustand state with one Liveblocks Room storage.
|
|
45
49
|
*/
|
|
46
|
-
|
|
50
|
+
storageMapping?: Mapping<T>;
|
|
47
51
|
/**
|
|
48
|
-
*
|
|
52
|
+
* Mapping used to synchronize a part of your zustand state with one Liveblocks Room presence.
|
|
49
53
|
*/
|
|
50
|
-
|
|
51
|
-
| "closed"
|
|
52
|
-
| "authenticating"
|
|
53
|
-
| "unavailable"
|
|
54
|
-
| "failed"
|
|
55
|
-
| "open"
|
|
56
|
-
| "connecting";
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
declare type Mapping<T> = {
|
|
60
|
-
[K in keyof T]?: boolean;
|
|
61
|
-
};
|
|
62
|
-
declare type Options<T> = {
|
|
63
|
-
/**
|
|
64
|
-
* Liveblocks client created by @liveblocks/client createClient
|
|
65
|
-
*/
|
|
66
|
-
client: Client;
|
|
67
|
-
/**
|
|
68
|
-
* Mapping used to synchronize a part of your zustand state with one Liveblocks Room storage.
|
|
69
|
-
*/
|
|
70
|
-
storageMapping?: Mapping<T>;
|
|
71
|
-
/**
|
|
72
|
-
* Mapping used to synchronize a part of your zustand state with one Liveblocks Room presence.
|
|
73
|
-
*/
|
|
74
|
-
presenceMapping?: Mapping<T>;
|
|
54
|
+
presenceMapping?: Mapping<T>;
|
|
75
55
|
};
|
|
76
|
-
declare function middleware<
|
|
77
|
-
T extends ZustandState,
|
|
78
|
-
TPresence extends JsonObject = JsonObject,
|
|
79
|
-
TStorage extends LsonObject = LsonObject,
|
|
80
|
-
TUserMeta extends BaseUserMeta = BaseUserMeta,
|
|
81
|
-
TRoomEvent extends Json = Json
|
|
82
|
-
>(
|
|
83
|
-
config: StateCreator<
|
|
84
|
-
T,
|
|
85
|
-
SetState<T>,
|
|
86
|
-
GetState<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>>,
|
|
87
|
-
StoreApi<T>
|
|
88
|
-
>,
|
|
89
|
-
options: Options<T>
|
|
90
|
-
): StateCreator<
|
|
91
|
-
LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>,
|
|
92
|
-
SetState<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>>,
|
|
93
|
-
GetState<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>>,
|
|
94
|
-
StoreApi<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>>
|
|
95
|
-
>;
|
|
56
|
+
declare function middleware<T extends ZustandState, TPresence extends JsonObject = JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = Json>(config: StateCreator<T, SetState<T>, GetState<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>>, StoreApi<T>>, options: Options<T>): StateCreator<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>, SetState<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>>, GetState<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>>, StoreApi<LiveblocksState<T, TPresence, TStorage, TUserMeta, TRoomEvent>>>;
|
|
96
57
|
|
|
97
58
|
export { LiveblocksState, Mapping, ZustandState, middleware };
|
package/index.js
CHANGED
|
@@ -1,326 +1,285 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
var _internal = require('@liveblocks/client/internal');
|
|
27
|
+
|
|
28
|
+
// src/errors.ts
|
|
29
|
+
var ERROR_PREFIX = "Invalid @liveblocks/zustand middleware config.";
|
|
30
|
+
function missingClient() {
|
|
31
|
+
return new Error(`${ERROR_PREFIX} client is missing`);
|
|
19
32
|
}
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
23
|
-
return arr2;
|
|
33
|
+
function missingMapping(mappingType) {
|
|
34
|
+
return new Error(`${ERROR_PREFIX} ${mappingType} is missing.`);
|
|
24
35
|
}
|
|
25
|
-
function
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (it) return (it = it.call(o)).next.bind(it);
|
|
29
|
-
if (
|
|
30
|
-
Array.isArray(o) ||
|
|
31
|
-
(it = (function (o, minLen) {
|
|
32
|
-
if (o) {
|
|
33
|
-
if ("string" == typeof o) return _arrayLikeToArray(o, minLen);
|
|
34
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
35
|
-
return (
|
|
36
|
-
"Object" === n && o.constructor && (n = o.constructor.name),
|
|
37
|
-
"Map" === n || "Set" === n
|
|
38
|
-
? Array.from(o)
|
|
39
|
-
: "Arguments" === n ||
|
|
40
|
-
/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
|
|
41
|
-
? _arrayLikeToArray(o, minLen)
|
|
42
|
-
: void 0
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
})(o)) ||
|
|
46
|
-
(allowArrayLike && o && "number" == typeof o.length)
|
|
47
|
-
) {
|
|
48
|
-
it && (o = it);
|
|
49
|
-
var i = 0;
|
|
50
|
-
return function () {
|
|
51
|
-
return i >= o.length ? { done: !0 } : { done: !1, value: o[i++] };
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
throw new TypeError(
|
|
55
|
-
"Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
|
|
36
|
+
function mappingShouldBeAnObject(mappingType) {
|
|
37
|
+
return new Error(
|
|
38
|
+
`${ERROR_PREFIX} ${mappingType} should be an object where the values are boolean.`
|
|
56
39
|
);
|
|
57
40
|
}
|
|
58
|
-
var ERROR_PREFIX = "Invalid @liveblocks/zustand middleware config.";
|
|
59
41
|
function mappingValueShouldBeABoolean(mappingType, key) {
|
|
60
42
|
return new Error(
|
|
61
|
-
ERROR_PREFIX
|
|
43
|
+
`${ERROR_PREFIX} ${mappingType}.${key} value should be a boolean`
|
|
62
44
|
);
|
|
63
45
|
}
|
|
64
46
|
function mappingShouldNotHaveTheSameKeys(key) {
|
|
65
47
|
return new Error(
|
|
66
|
-
ERROR_PREFIX
|
|
67
|
-
' "' +
|
|
68
|
-
key +
|
|
69
|
-
"\" is mapped on presenceMapping and storageMapping. A key shouldn't exist on both mapping."
|
|
48
|
+
`${ERROR_PREFIX} "${key}" is mapped on presenceMapping and storageMapping. A key shouldn't exist on both mapping.`
|
|
70
49
|
);
|
|
71
50
|
}
|
|
72
51
|
function mappingToFunctionIsNotAllowed(key) {
|
|
73
52
|
return new Error(
|
|
74
|
-
ERROR_PREFIX
|
|
75
|
-
" mapping." +
|
|
76
|
-
key +
|
|
77
|
-
" is invalid. Mapping to a function is not allowed."
|
|
53
|
+
`${ERROR_PREFIX} mapping.${key} is invalid. Mapping to a function is not allowed.`
|
|
78
54
|
);
|
|
79
55
|
}
|
|
56
|
+
|
|
57
|
+
// src/index.ts
|
|
80
58
|
function isJson(value) {
|
|
81
|
-
return (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
59
|
+
return value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || Array.isArray(value) && value.every(isJson) || typeof value === "object" && Object.values(value).every(isJson);
|
|
60
|
+
}
|
|
61
|
+
function middleware(config, options) {
|
|
62
|
+
if (process.env.NODE_ENV !== "production" && options.client == null) {
|
|
63
|
+
throw missingClient();
|
|
64
|
+
}
|
|
65
|
+
const client = options.client;
|
|
66
|
+
const storageMapping = validateMapping(
|
|
67
|
+
options.storageMapping || {},
|
|
68
|
+
"storageMapping"
|
|
69
|
+
);
|
|
70
|
+
const presenceMapping = validateMapping(
|
|
71
|
+
options.presenceMapping || {},
|
|
72
|
+
"presenceMapping"
|
|
88
73
|
);
|
|
74
|
+
if (process.env.NODE_ENV !== "production") {
|
|
75
|
+
validateNoDuplicateKeys(storageMapping, presenceMapping);
|
|
76
|
+
}
|
|
77
|
+
return (set, get, api) => {
|
|
78
|
+
const typedSet = set;
|
|
79
|
+
let room = null;
|
|
80
|
+
let isPatching = false;
|
|
81
|
+
let storageRoot = null;
|
|
82
|
+
let unsubscribeCallbacks = [];
|
|
83
|
+
const store = config(
|
|
84
|
+
(args) => {
|
|
85
|
+
const oldState = get();
|
|
86
|
+
set(args);
|
|
87
|
+
const newState = get();
|
|
88
|
+
if (room) {
|
|
89
|
+
isPatching = true;
|
|
90
|
+
updatePresence(
|
|
91
|
+
room,
|
|
92
|
+
oldState,
|
|
93
|
+
newState,
|
|
94
|
+
presenceMapping
|
|
95
|
+
);
|
|
96
|
+
room.batch(() => {
|
|
97
|
+
if (storageRoot) {
|
|
98
|
+
patchLiveblocksStorage(
|
|
99
|
+
storageRoot,
|
|
100
|
+
oldState,
|
|
101
|
+
newState,
|
|
102
|
+
storageMapping
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
isPatching = false;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
get,
|
|
110
|
+
api
|
|
111
|
+
);
|
|
112
|
+
function enterRoom(roomId, initialState) {
|
|
113
|
+
if (storageRoot) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
room = client.enter(roomId);
|
|
117
|
+
updateZustandLiveblocksState(set, {
|
|
118
|
+
isStorageLoading: true,
|
|
119
|
+
room
|
|
120
|
+
});
|
|
121
|
+
const state = get();
|
|
122
|
+
broadcastInitialPresence(room, state, presenceMapping);
|
|
123
|
+
unsubscribeCallbacks.push(
|
|
124
|
+
room.subscribe("others", (others) => {
|
|
125
|
+
updateZustandLiveblocksState(set, { others: others.toArray() });
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
unsubscribeCallbacks.push(
|
|
129
|
+
room.subscribe("connection", () => {
|
|
130
|
+
updateZustandLiveblocksState(set, {
|
|
131
|
+
connection: room.getConnectionState()
|
|
132
|
+
});
|
|
133
|
+
})
|
|
134
|
+
);
|
|
135
|
+
unsubscribeCallbacks.push(
|
|
136
|
+
room.subscribe("my-presence", () => {
|
|
137
|
+
if (isPatching === false) {
|
|
138
|
+
set(
|
|
139
|
+
patchPresenceState(room.getPresence(), presenceMapping)
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
room.getStorage().then(({ root }) => {
|
|
145
|
+
const updates = {};
|
|
146
|
+
room.batch(() => {
|
|
147
|
+
for (const key in storageMapping) {
|
|
148
|
+
const liveblocksStatePart = root.get(key);
|
|
149
|
+
if (liveblocksStatePart == null) {
|
|
150
|
+
updates[key] = initialState[key];
|
|
151
|
+
_internal.patchLiveObjectKey.call(void 0, root, key, void 0, initialState[key]);
|
|
152
|
+
} else {
|
|
153
|
+
updates[key] = _internal.lsonToJson.call(void 0, liveblocksStatePart);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
typedSet(updates);
|
|
158
|
+
storageRoot = root;
|
|
159
|
+
unsubscribeCallbacks.push(
|
|
160
|
+
room.subscribe(
|
|
161
|
+
root,
|
|
162
|
+
(updates2) => {
|
|
163
|
+
if (isPatching === false) {
|
|
164
|
+
set(patchState(get(), updates2, storageMapping));
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
{ isDeep: true }
|
|
168
|
+
)
|
|
169
|
+
);
|
|
170
|
+
updateZustandLiveblocksState(set, { isStorageLoading: false });
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function leaveRoom(roomId) {
|
|
174
|
+
for (const unsubscribe of unsubscribeCallbacks) {
|
|
175
|
+
unsubscribe();
|
|
176
|
+
}
|
|
177
|
+
storageRoot = null;
|
|
178
|
+
room = null;
|
|
179
|
+
isPatching = false;
|
|
180
|
+
unsubscribeCallbacks = [];
|
|
181
|
+
client.leave(roomId);
|
|
182
|
+
updateZustandLiveblocksState(set, {
|
|
183
|
+
others: [],
|
|
184
|
+
connection: "closed",
|
|
185
|
+
isStorageLoading: false,
|
|
186
|
+
room: null
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return __spreadProps(__spreadValues({}, store), {
|
|
190
|
+
liveblocks: {
|
|
191
|
+
enterRoom,
|
|
192
|
+
leaveRoom,
|
|
193
|
+
room: null,
|
|
194
|
+
others: [],
|
|
195
|
+
connection: "closed",
|
|
196
|
+
isStorageLoading: false
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function patchState(state, updates, mapping) {
|
|
202
|
+
const partialState = {};
|
|
203
|
+
for (const key in mapping) {
|
|
204
|
+
partialState[key] = state[key];
|
|
205
|
+
}
|
|
206
|
+
const patched = _internal.patchImmutableObject.call(void 0, partialState, updates);
|
|
207
|
+
const result = {};
|
|
208
|
+
for (const key in mapping) {
|
|
209
|
+
result[key] = patched[key];
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
function patchPresenceState(presence, mapping) {
|
|
214
|
+
const partialState = {};
|
|
215
|
+
for (const key in mapping) {
|
|
216
|
+
partialState[key] = presence[key];
|
|
217
|
+
}
|
|
218
|
+
return partialState;
|
|
89
219
|
}
|
|
90
220
|
function updateZustandLiveblocksState(set, partial) {
|
|
91
|
-
set(
|
|
92
|
-
|
|
93
|
-
|
|
221
|
+
set((state) => ({ liveblocks: __spreadValues(__spreadValues({}, state.liveblocks), partial) }));
|
|
222
|
+
}
|
|
223
|
+
function broadcastInitialPresence(room, state, mapping) {
|
|
224
|
+
for (const key in mapping) {
|
|
225
|
+
room == null ? void 0 : room.updatePresence({ [key]: state[key] });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function updatePresence(room, oldState, newState, presenceMapping) {
|
|
229
|
+
for (const key in presenceMapping) {
|
|
230
|
+
if (typeof newState[key] === "function") {
|
|
231
|
+
throw mappingToFunctionIsNotAllowed("value");
|
|
232
|
+
}
|
|
233
|
+
if (oldState[key] !== newState[key]) {
|
|
234
|
+
const val = newState[key];
|
|
235
|
+
room.updatePresence({ [key]: val });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function patchLiveblocksStorage(root, oldState, newState, mapping) {
|
|
240
|
+
for (const key in mapping) {
|
|
241
|
+
if (process.env.NODE_ENV !== "production" && typeof newState[key] === "function") {
|
|
242
|
+
throw mappingToFunctionIsNotAllowed("value");
|
|
243
|
+
}
|
|
244
|
+
if (oldState[key] !== newState[key]) {
|
|
245
|
+
const oldVal = oldState[key];
|
|
246
|
+
const newVal = newState[key];
|
|
247
|
+
if ((oldVal === void 0 || isJson(oldVal)) && (newVal === void 0 || isJson(newVal))) {
|
|
248
|
+
_internal.patchLiveObjectKey.call(void 0, root, key, oldVal, newVal);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function isObject(value) {
|
|
254
|
+
return Object.prototype.toString.call(value) === "[object Object]";
|
|
255
|
+
}
|
|
256
|
+
function validateNoDuplicateKeys(storageMapping, presenceMapping) {
|
|
257
|
+
for (const key in storageMapping) {
|
|
258
|
+
if (presenceMapping[key] !== void 0) {
|
|
259
|
+
throw mappingShouldNotHaveTheSameKeys(key);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
94
262
|
}
|
|
95
263
|
function validateMapping(mapping, mappingType) {
|
|
96
|
-
if (
|
|
97
|
-
if (
|
|
98
|
-
throw (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
"[object Object]" !== Object.prototype.toString.call(value))
|
|
104
|
-
)
|
|
105
|
-
throw (function (mappingType) {
|
|
106
|
-
return new Error(
|
|
107
|
-
ERROR_PREFIX +
|
|
108
|
-
" " +
|
|
109
|
-
mappingType +
|
|
110
|
-
" should be an object where the values are boolean."
|
|
111
|
-
);
|
|
112
|
-
})(mappingType);
|
|
264
|
+
if (process.env.NODE_ENV !== "production") {
|
|
265
|
+
if (mapping == null) {
|
|
266
|
+
throw missingMapping(mappingType);
|
|
267
|
+
}
|
|
268
|
+
if (!isObject(mapping)) {
|
|
269
|
+
throw mappingShouldBeAnObject(mappingType);
|
|
270
|
+
}
|
|
113
271
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (
|
|
118
|
-
"production" !== process.env.NODE_ENV &&
|
|
119
|
-
"boolean" != typeof mapping[key]
|
|
120
|
-
)
|
|
272
|
+
const result = {};
|
|
273
|
+
for (const key in mapping) {
|
|
274
|
+
if (process.env.NODE_ENV !== "production" && typeof mapping[key] !== "boolean") {
|
|
121
275
|
throw mappingValueShouldBeABoolean(mappingType, key);
|
|
122
|
-
|
|
276
|
+
}
|
|
277
|
+
if (mapping[key] === true) {
|
|
278
|
+
result[key] = true;
|
|
279
|
+
}
|
|
123
280
|
}
|
|
124
281
|
return result;
|
|
125
282
|
}
|
|
126
|
-
exports.middleware = function (config, options) {
|
|
127
|
-
if ("production" !== process.env.NODE_ENV && null == options.client)
|
|
128
|
-
throw new Error(ERROR_PREFIX + " client is missing");
|
|
129
|
-
var client = options.client,
|
|
130
|
-
storageMapping = validateMapping(
|
|
131
|
-
options.storageMapping || {},
|
|
132
|
-
"storageMapping"
|
|
133
|
-
),
|
|
134
|
-
presenceMapping = validateMapping(
|
|
135
|
-
options.presenceMapping || {},
|
|
136
|
-
"presenceMapping"
|
|
137
|
-
);
|
|
138
|
-
return (
|
|
139
|
-
"production" !== process.env.NODE_ENV &&
|
|
140
|
-
(function (storageMapping, presenceMapping) {
|
|
141
|
-
for (var key in storageMapping)
|
|
142
|
-
if (void 0 !== presenceMapping[key])
|
|
143
|
-
throw mappingShouldNotHaveTheSameKeys(key);
|
|
144
|
-
})(storageMapping, presenceMapping),
|
|
145
|
-
function (set, get, api) {
|
|
146
|
-
var typedSet = set,
|
|
147
|
-
room = null,
|
|
148
|
-
isPatching = !1,
|
|
149
|
-
storageRoot = null,
|
|
150
|
-
unsubscribeCallbacks = [],
|
|
151
|
-
store = config(
|
|
152
|
-
function (args) {
|
|
153
|
-
var oldState = get();
|
|
154
|
-
set(args);
|
|
155
|
-
var newState = get();
|
|
156
|
-
room &&
|
|
157
|
-
((isPatching = !0),
|
|
158
|
-
(function (room, oldState, newState, presenceMapping) {
|
|
159
|
-
for (var key in presenceMapping) {
|
|
160
|
-
if ("function" == typeof newState[key])
|
|
161
|
-
throw mappingToFunctionIsNotAllowed("value");
|
|
162
|
-
if (oldState[key] !== newState[key]) {
|
|
163
|
-
var _room$updatePresence2,
|
|
164
|
-
val = newState[key];
|
|
165
|
-
room.updatePresence(
|
|
166
|
-
(((_room$updatePresence2 = {})[key] = val),
|
|
167
|
-
_room$updatePresence2)
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
})(room, oldState, newState, presenceMapping),
|
|
172
|
-
room.batch(function () {
|
|
173
|
-
storageRoot &&
|
|
174
|
-
(function (root, oldState, newState, mapping) {
|
|
175
|
-
for (var key in mapping) {
|
|
176
|
-
if (
|
|
177
|
-
"production" !== process.env.NODE_ENV &&
|
|
178
|
-
"function" == typeof newState[key]
|
|
179
|
-
)
|
|
180
|
-
throw mappingToFunctionIsNotAllowed("value");
|
|
181
|
-
if (oldState[key] !== newState[key]) {
|
|
182
|
-
var oldVal = oldState[key],
|
|
183
|
-
newVal = newState[key];
|
|
184
|
-
(void 0 !== oldVal && !isJson(oldVal)) ||
|
|
185
|
-
(void 0 !== newVal && !isJson(newVal)) ||
|
|
186
|
-
internal.patchLiveObjectKey(
|
|
187
|
-
root,
|
|
188
|
-
key,
|
|
189
|
-
oldVal,
|
|
190
|
-
newVal
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
})(storageRoot, oldState, newState, storageMapping);
|
|
195
|
-
}),
|
|
196
|
-
(isPatching = !1));
|
|
197
|
-
},
|
|
198
|
-
get,
|
|
199
|
-
api
|
|
200
|
-
);
|
|
201
|
-
return _extends({}, store, {
|
|
202
|
-
liveblocks: {
|
|
203
|
-
enterRoom: function (roomId, initialState) {
|
|
204
|
-
if (!storageRoot) {
|
|
205
|
-
(room = client.enter(roomId)),
|
|
206
|
-
updateZustandLiveblocksState(set, {
|
|
207
|
-
isStorageLoading: !0,
|
|
208
|
-
room: room,
|
|
209
|
-
});
|
|
210
|
-
var state = get();
|
|
211
|
-
!(function (room, state, mapping) {
|
|
212
|
-
for (var key in mapping) {
|
|
213
|
-
var _room$updatePresence;
|
|
214
|
-
null == room ||
|
|
215
|
-
room.updatePresence(
|
|
216
|
-
(((_room$updatePresence = {})[key] = state[key]),
|
|
217
|
-
_room$updatePresence)
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
})(room, state, presenceMapping),
|
|
221
|
-
unsubscribeCallbacks.push(
|
|
222
|
-
room.subscribe("others", function (others) {
|
|
223
|
-
updateZustandLiveblocksState(set, {
|
|
224
|
-
others: others.toArray(),
|
|
225
|
-
});
|
|
226
|
-
})
|
|
227
|
-
),
|
|
228
|
-
unsubscribeCallbacks.push(
|
|
229
|
-
room.subscribe("connection", function () {
|
|
230
|
-
updateZustandLiveblocksState(set, {
|
|
231
|
-
connection: room.getConnectionState(),
|
|
232
|
-
});
|
|
233
|
-
})
|
|
234
|
-
),
|
|
235
|
-
unsubscribeCallbacks.push(
|
|
236
|
-
room.subscribe("my-presence", function () {
|
|
237
|
-
!1 === isPatching &&
|
|
238
|
-
set(
|
|
239
|
-
(function (presence, mapping) {
|
|
240
|
-
var partialState = {};
|
|
241
|
-
for (var key in mapping)
|
|
242
|
-
partialState[key] = presence[key];
|
|
243
|
-
return partialState;
|
|
244
|
-
})(room.getPresence(), presenceMapping)
|
|
245
|
-
);
|
|
246
|
-
})
|
|
247
|
-
),
|
|
248
|
-
room.getStorage().then(function (_ref) {
|
|
249
|
-
var root = _ref.root,
|
|
250
|
-
updates = {};
|
|
251
|
-
room.batch(function () {
|
|
252
|
-
for (var key in storageMapping) {
|
|
253
|
-
var liveblocksStatePart = root.get(key);
|
|
254
|
-
null == liveblocksStatePart
|
|
255
|
-
? ((updates[key] = initialState[key]),
|
|
256
|
-
internal.patchLiveObjectKey(
|
|
257
|
-
root,
|
|
258
|
-
key,
|
|
259
|
-
void 0,
|
|
260
|
-
initialState[key]
|
|
261
|
-
))
|
|
262
|
-
: (updates[key] =
|
|
263
|
-
internal.lsonToJson(liveblocksStatePart));
|
|
264
|
-
}
|
|
265
|
-
}),
|
|
266
|
-
typedSet(updates),
|
|
267
|
-
(storageRoot = root),
|
|
268
|
-
unsubscribeCallbacks.push(
|
|
269
|
-
room.subscribe(
|
|
270
|
-
root,
|
|
271
|
-
function (updates) {
|
|
272
|
-
!1 === isPatching &&
|
|
273
|
-
set(
|
|
274
|
-
(function (state, updates, mapping) {
|
|
275
|
-
var partialState = {};
|
|
276
|
-
for (var key in mapping)
|
|
277
|
-
partialState[key] = state[key];
|
|
278
|
-
var patched = internal.patchImmutableObject(
|
|
279
|
-
partialState,
|
|
280
|
-
updates
|
|
281
|
-
),
|
|
282
|
-
result = {};
|
|
283
|
-
for (var _key in mapping)
|
|
284
|
-
result[_key] = patched[_key];
|
|
285
|
-
return result;
|
|
286
|
-
})(get(), updates, storageMapping)
|
|
287
|
-
);
|
|
288
|
-
},
|
|
289
|
-
{ isDeep: !0 }
|
|
290
|
-
)
|
|
291
|
-
),
|
|
292
|
-
updateZustandLiveblocksState(set, { isStorageLoading: !1 });
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
},
|
|
296
|
-
leaveRoom: function (roomId) {
|
|
297
|
-
for (
|
|
298
|
-
var _step,
|
|
299
|
-
_iterator =
|
|
300
|
-
_createForOfIteratorHelperLoose(unsubscribeCallbacks);
|
|
301
|
-
!(_step = _iterator()).done;
|
|
302
283
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
(storageRoot = null),
|
|
307
|
-
(room = null),
|
|
308
|
-
(isPatching = !1),
|
|
309
|
-
(unsubscribeCallbacks = []),
|
|
310
|
-
client.leave(roomId),
|
|
311
|
-
updateZustandLiveblocksState(set, {
|
|
312
|
-
others: [],
|
|
313
|
-
connection: "closed",
|
|
314
|
-
isStorageLoading: !1,
|
|
315
|
-
room: null,
|
|
316
|
-
});
|
|
317
|
-
},
|
|
318
|
-
room: null,
|
|
319
|
-
others: [],
|
|
320
|
-
connection: "closed",
|
|
321
|
-
isStorageLoading: !1,
|
|
322
|
-
},
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
);
|
|
326
|
-
};
|
|
284
|
+
|
|
285
|
+
exports.middleware = middleware;
|
package/index.mjs
CHANGED
|
@@ -1,240 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from "@liveblocks/client/internal";
|
|
6
|
-
const ERROR_PREFIX = "Invalid @liveblocks/zustand middleware config.";
|
|
7
|
-
function mappingValueShouldBeABoolean(mappingType, key) {
|
|
8
|
-
return new Error(
|
|
9
|
-
`${ERROR_PREFIX} ${mappingType}.${key} value should be a boolean`
|
|
10
|
-
);
|
|
11
|
-
}
|
|
12
|
-
function mappingShouldNotHaveTheSameKeys(key) {
|
|
13
|
-
return new Error(
|
|
14
|
-
`${ERROR_PREFIX} "${key}" is mapped on presenceMapping and storageMapping. A key shouldn't exist on both mapping.`
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
function mappingToFunctionIsNotAllowed(key) {
|
|
18
|
-
return new Error(
|
|
19
|
-
`${ERROR_PREFIX} mapping.${key} is invalid. Mapping to a function is not allowed.`
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
function isJson(value) {
|
|
23
|
-
return (
|
|
24
|
-
null === value ||
|
|
25
|
-
"string" == typeof value ||
|
|
26
|
-
"number" == typeof value ||
|
|
27
|
-
"boolean" == typeof value ||
|
|
28
|
-
(Array.isArray(value) && value.every(isJson)) ||
|
|
29
|
-
("object" == typeof value && Object.values(value).every(isJson))
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
function middleware(config, options) {
|
|
33
|
-
if ("production" !== process.env.NODE_ENV && null == options.client)
|
|
34
|
-
throw new Error(`${ERROR_PREFIX} client is missing`);
|
|
35
|
-
const client = options.client,
|
|
36
|
-
storageMapping = validateMapping(
|
|
37
|
-
options.storageMapping || {},
|
|
38
|
-
"storageMapping"
|
|
39
|
-
),
|
|
40
|
-
presenceMapping = validateMapping(
|
|
41
|
-
options.presenceMapping || {},
|
|
42
|
-
"presenceMapping"
|
|
43
|
-
);
|
|
44
|
-
return (
|
|
45
|
-
"production" !== process.env.NODE_ENV &&
|
|
46
|
-
(function (storageMapping, presenceMapping) {
|
|
47
|
-
for (const key in storageMapping)
|
|
48
|
-
if (void 0 !== presenceMapping[key])
|
|
49
|
-
throw mappingShouldNotHaveTheSameKeys(key);
|
|
50
|
-
})(storageMapping, presenceMapping),
|
|
51
|
-
(set, get, api) => {
|
|
52
|
-
const typedSet = set;
|
|
53
|
-
let room = null,
|
|
54
|
-
isPatching = !1,
|
|
55
|
-
storageRoot = null,
|
|
56
|
-
unsubscribeCallbacks = [];
|
|
57
|
-
const store = config(
|
|
58
|
-
(args) => {
|
|
59
|
-
const oldState = get();
|
|
60
|
-
set(args);
|
|
61
|
-
const newState = get();
|
|
62
|
-
room &&
|
|
63
|
-
((isPatching = !0),
|
|
64
|
-
(function (room, oldState, newState, presenceMapping) {
|
|
65
|
-
for (const key in presenceMapping) {
|
|
66
|
-
if ("function" == typeof newState[key])
|
|
67
|
-
throw mappingToFunctionIsNotAllowed("value");
|
|
68
|
-
if (oldState[key] !== newState[key]) {
|
|
69
|
-
const val = newState[key];
|
|
70
|
-
room.updatePresence({ [key]: val });
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
})(room, oldState, newState, presenceMapping),
|
|
74
|
-
room.batch(() => {
|
|
75
|
-
storageRoot &&
|
|
76
|
-
(function (root, oldState, newState, mapping) {
|
|
77
|
-
for (const key in mapping) {
|
|
78
|
-
if (
|
|
79
|
-
"production" !== process.env.NODE_ENV &&
|
|
80
|
-
"function" == typeof newState[key]
|
|
81
|
-
)
|
|
82
|
-
throw mappingToFunctionIsNotAllowed("value");
|
|
83
|
-
if (oldState[key] !== newState[key]) {
|
|
84
|
-
const oldVal = oldState[key],
|
|
85
|
-
newVal = newState[key];
|
|
86
|
-
(void 0 !== oldVal && !isJson(oldVal)) ||
|
|
87
|
-
(void 0 !== newVal && !isJson(newVal)) ||
|
|
88
|
-
patchLiveObjectKey(root, key, oldVal, newVal);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
})(storageRoot, oldState, newState, storageMapping);
|
|
92
|
-
}),
|
|
93
|
-
(isPatching = !1));
|
|
94
|
-
},
|
|
95
|
-
get,
|
|
96
|
-
api
|
|
97
|
-
);
|
|
98
|
-
return Object.assign(Object.assign({}, store), {
|
|
99
|
-
liveblocks: {
|
|
100
|
-
enterRoom: function (roomId, initialState) {
|
|
101
|
-
if (storageRoot) return;
|
|
102
|
-
(room = client.enter(roomId)),
|
|
103
|
-
updateZustandLiveblocksState(set, {
|
|
104
|
-
isStorageLoading: !0,
|
|
105
|
-
room: room,
|
|
106
|
-
});
|
|
107
|
-
const state = get();
|
|
108
|
-
!(function (room, state, mapping) {
|
|
109
|
-
for (const key in mapping)
|
|
110
|
-
null == room || room.updatePresence({ [key]: state[key] });
|
|
111
|
-
})(room, state, presenceMapping),
|
|
112
|
-
unsubscribeCallbacks.push(
|
|
113
|
-
room.subscribe("others", (others) => {
|
|
114
|
-
updateZustandLiveblocksState(set, {
|
|
115
|
-
others: others.toArray(),
|
|
116
|
-
});
|
|
117
|
-
})
|
|
118
|
-
),
|
|
119
|
-
unsubscribeCallbacks.push(
|
|
120
|
-
room.subscribe("connection", () => {
|
|
121
|
-
updateZustandLiveblocksState(set, {
|
|
122
|
-
connection: room.getConnectionState(),
|
|
123
|
-
});
|
|
124
|
-
})
|
|
125
|
-
),
|
|
126
|
-
unsubscribeCallbacks.push(
|
|
127
|
-
room.subscribe("my-presence", () => {
|
|
128
|
-
!1 === isPatching &&
|
|
129
|
-
set(
|
|
130
|
-
(function (presence, mapping) {
|
|
131
|
-
const partialState = {};
|
|
132
|
-
for (const key in mapping)
|
|
133
|
-
partialState[key] = presence[key];
|
|
134
|
-
return partialState;
|
|
135
|
-
})(room.getPresence(), presenceMapping)
|
|
136
|
-
);
|
|
137
|
-
})
|
|
138
|
-
),
|
|
139
|
-
room.getStorage().then(({ root: root }) => {
|
|
140
|
-
const updates = {};
|
|
141
|
-
room.batch(() => {
|
|
142
|
-
for (const key in storageMapping) {
|
|
143
|
-
const liveblocksStatePart = root.get(key);
|
|
144
|
-
null == liveblocksStatePart
|
|
145
|
-
? ((updates[key] = initialState[key]),
|
|
146
|
-
patchLiveObjectKey(
|
|
147
|
-
root,
|
|
148
|
-
key,
|
|
149
|
-
void 0,
|
|
150
|
-
initialState[key]
|
|
151
|
-
))
|
|
152
|
-
: (updates[key] = lsonToJson(liveblocksStatePart));
|
|
153
|
-
}
|
|
154
|
-
}),
|
|
155
|
-
typedSet(updates),
|
|
156
|
-
(storageRoot = root),
|
|
157
|
-
unsubscribeCallbacks.push(
|
|
158
|
-
room.subscribe(
|
|
159
|
-
root,
|
|
160
|
-
(updates) => {
|
|
161
|
-
!1 === isPatching &&
|
|
162
|
-
set(
|
|
163
|
-
(function (state, updates, mapping) {
|
|
164
|
-
const partialState = {};
|
|
165
|
-
for (const key in mapping)
|
|
166
|
-
partialState[key] = state[key];
|
|
167
|
-
const patched = patchImmutableObject(
|
|
168
|
-
partialState,
|
|
169
|
-
updates
|
|
170
|
-
),
|
|
171
|
-
result = {};
|
|
172
|
-
for (const key in mapping)
|
|
173
|
-
result[key] = patched[key];
|
|
174
|
-
return result;
|
|
175
|
-
})(get(), updates, storageMapping)
|
|
176
|
-
);
|
|
177
|
-
},
|
|
178
|
-
{ isDeep: !0 }
|
|
179
|
-
)
|
|
180
|
-
),
|
|
181
|
-
updateZustandLiveblocksState(set, { isStorageLoading: !1 });
|
|
182
|
-
});
|
|
183
|
-
},
|
|
184
|
-
leaveRoom: function (roomId) {
|
|
185
|
-
for (const unsubscribe of unsubscribeCallbacks) unsubscribe();
|
|
186
|
-
(storageRoot = null),
|
|
187
|
-
(room = null),
|
|
188
|
-
(isPatching = !1),
|
|
189
|
-
(unsubscribeCallbacks = []),
|
|
190
|
-
client.leave(roomId),
|
|
191
|
-
updateZustandLiveblocksState(set, {
|
|
192
|
-
others: [],
|
|
193
|
-
connection: "closed",
|
|
194
|
-
isStorageLoading: !1,
|
|
195
|
-
room: null,
|
|
196
|
-
});
|
|
197
|
-
},
|
|
198
|
-
room: null,
|
|
199
|
-
others: [],
|
|
200
|
-
connection: "closed",
|
|
201
|
-
isStorageLoading: !1,
|
|
202
|
-
},
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
function updateZustandLiveblocksState(set, partial) {
|
|
208
|
-
set((state) => ({
|
|
209
|
-
liveblocks: Object.assign(Object.assign({}, state.liveblocks), partial),
|
|
210
|
-
}));
|
|
211
|
-
}
|
|
212
|
-
function validateMapping(mapping, mappingType) {
|
|
213
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
214
|
-
if (null == mapping)
|
|
215
|
-
throw (function (mappingType) {
|
|
216
|
-
return new Error(`${ERROR_PREFIX} ${mappingType} is missing.`);
|
|
217
|
-
})(mappingType);
|
|
218
|
-
if (
|
|
219
|
-
((value = mapping),
|
|
220
|
-
"[object Object]" !== Object.prototype.toString.call(value))
|
|
221
|
-
)
|
|
222
|
-
throw (function (mappingType) {
|
|
223
|
-
return new Error(
|
|
224
|
-
`${ERROR_PREFIX} ${mappingType} should be an object where the values are boolean.`
|
|
225
|
-
);
|
|
226
|
-
})(mappingType);
|
|
227
|
-
}
|
|
228
|
-
var value;
|
|
229
|
-
const result = {};
|
|
230
|
-
for (const key in mapping) {
|
|
231
|
-
if (
|
|
232
|
-
"production" !== process.env.NODE_ENV &&
|
|
233
|
-
"boolean" != typeof mapping[key]
|
|
234
|
-
)
|
|
235
|
-
throw mappingValueShouldBeABoolean(mappingType, key);
|
|
236
|
-
!0 === mapping[key] && (result[key] = !0);
|
|
237
|
-
}
|
|
238
|
-
return result;
|
|
239
|
-
}
|
|
240
|
-
export { middleware };
|
|
1
|
+
import mod from "./index.js";
|
|
2
|
+
|
|
3
|
+
export default mod;
|
|
4
|
+
export const middleware = mod.middleware;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/zustand",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.9",
|
|
4
4
|
"description": "A middleware to integrate Liveblocks into Zustand stores.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.mjs",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"directory": "packages/liveblocks-zustand"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@liveblocks/client": "0.17.
|
|
23
|
+
"@liveblocks/client": "0.17.9",
|
|
24
24
|
"zustand": "^3"
|
|
25
25
|
},
|
|
26
26
|
"sideEffects": false
|