@liveblocks/core 1.12.0-test1 → 1.12.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.mts +52 -4
- package/dist/index.d.ts +52 -4
- package/dist/index.js +172 -71
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +133 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
var PKG_NAME = "@liveblocks/core";
|
|
9
|
-
var PKG_VERSION = "1.12.0
|
|
9
|
+
var PKG_VERSION = "1.12.0";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -782,9 +782,13 @@ function logPrematureErrorOrCloseEvent(e) {
|
|
|
782
782
|
};
|
|
783
783
|
}
|
|
784
784
|
function logCloseEvent(event) {
|
|
785
|
+
const details = [`code: ${event.code}`];
|
|
786
|
+
if (event.reason) {
|
|
787
|
+
details.push(`reason: ${event.reason}`);
|
|
788
|
+
}
|
|
785
789
|
return (ctx) => {
|
|
786
790
|
warn(
|
|
787
|
-
`Connection to Liveblocks websocket server closed (
|
|
791
|
+
`Connection to Liveblocks websocket server closed (${details.join(", ")}). Retrying in ${ctx.backoffDelay}ms.`
|
|
788
792
|
);
|
|
789
793
|
};
|
|
790
794
|
}
|
|
@@ -1385,7 +1389,6 @@ function createAuthManager(authOptions) {
|
|
|
1385
1389
|
room: options.roomId
|
|
1386
1390
|
});
|
|
1387
1391
|
const parsed = parseAuthToken(response.token);
|
|
1388
|
-
verifyTokenPermissions(parsed, options);
|
|
1389
1392
|
if (seenTokens.has(parsed.raw)) {
|
|
1390
1393
|
throw new StopRetrying(
|
|
1391
1394
|
"The same Liveblocks auth token was issued from the backend before. Caching Liveblocks tokens is not supported."
|
|
@@ -1398,7 +1401,6 @@ function createAuthManager(authOptions) {
|
|
|
1398
1401
|
if (response && typeof response === "object") {
|
|
1399
1402
|
if (typeof response.token === "string") {
|
|
1400
1403
|
const parsed = parseAuthToken(response.token);
|
|
1401
|
-
verifyTokenPermissions(parsed, options);
|
|
1402
1404
|
return parsed;
|
|
1403
1405
|
} else if (typeof response.error === "string") {
|
|
1404
1406
|
const reason = `Authentication failed: ${"reason" in response && typeof response.reason === "string" ? response.reason : "Forbidden"}`;
|
|
@@ -1417,23 +1419,6 @@ function createAuthManager(authOptions) {
|
|
|
1417
1419
|
"Unexpected authentication type. Must be private or custom."
|
|
1418
1420
|
);
|
|
1419
1421
|
}
|
|
1420
|
-
function verifyTokenPermissions(parsedToken, options) {
|
|
1421
|
-
if (!options.roomId && parsedToken.parsed.k === "acc" /* ACCESS_TOKEN */) {
|
|
1422
|
-
if (Object.entries(parsedToken.parsed.perms).length === 0) {
|
|
1423
|
-
return;
|
|
1424
|
-
}
|
|
1425
|
-
for (const [resource, scopes] of Object.entries(
|
|
1426
|
-
parsedToken.parsed.perms
|
|
1427
|
-
)) {
|
|
1428
|
-
if (resource.includes("*") && hasCorrespondingScopes(options.requestedScope, scopes)) {
|
|
1429
|
-
return;
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
throw new StopRetrying(
|
|
1433
|
-
"The issued access token doesn't grant enough permissions. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/access-tokens-not-enough-permissions"
|
|
1434
|
-
);
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
1422
|
async function getAuthValue(requestOptions) {
|
|
1438
1423
|
if (authentication.type === "public") {
|
|
1439
1424
|
return { type: "public", publicApiKey: authentication.publicApiKey };
|
|
@@ -4776,6 +4761,115 @@ function isJsonObject(data) {
|
|
|
4776
4761
|
return !isJsonScalar(data) && !isJsonArray(data);
|
|
4777
4762
|
}
|
|
4778
4763
|
|
|
4764
|
+
// src/lib/objectToQuery.ts
|
|
4765
|
+
var identifierRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
4766
|
+
function objectToQuery(obj) {
|
|
4767
|
+
let filterList = [];
|
|
4768
|
+
const entries2 = Object.entries(obj);
|
|
4769
|
+
const keyValuePairs = [];
|
|
4770
|
+
const keyValuePairsWithOperator = [];
|
|
4771
|
+
const indexedKeys = [];
|
|
4772
|
+
entries2.forEach(([key, value]) => {
|
|
4773
|
+
if (!identifierRegex.test(key)) {
|
|
4774
|
+
throw new Error("Key must only contain letters, numbers, _");
|
|
4775
|
+
}
|
|
4776
|
+
if (isSimpleValue(value)) {
|
|
4777
|
+
keyValuePairs.push([key, value]);
|
|
4778
|
+
} else if (isValueWithOperator(value)) {
|
|
4779
|
+
keyValuePairsWithOperator.push([key, value]);
|
|
4780
|
+
} else if (typeof value === "object" && !("startsWith" in value)) {
|
|
4781
|
+
indexedKeys.push([key, value]);
|
|
4782
|
+
}
|
|
4783
|
+
});
|
|
4784
|
+
filterList = [
|
|
4785
|
+
...getFiltersFromKeyValuePairs(keyValuePairs),
|
|
4786
|
+
...getFiltersFromKeyValuePairsWithOperator(keyValuePairsWithOperator)
|
|
4787
|
+
];
|
|
4788
|
+
indexedKeys.forEach(([key, value]) => {
|
|
4789
|
+
const nestedEntries = Object.entries(value);
|
|
4790
|
+
const nKeyValuePairs = [];
|
|
4791
|
+
const nKeyValuePairsWithOperator = [];
|
|
4792
|
+
nestedEntries.forEach(([nestedKey, nestedValue]) => {
|
|
4793
|
+
if (isStringEmpty(nestedKey)) {
|
|
4794
|
+
throw new Error("Key cannot be empty");
|
|
4795
|
+
}
|
|
4796
|
+
if (isSimpleValue(nestedValue)) {
|
|
4797
|
+
nKeyValuePairs.push([formatFilterKey(key, nestedKey), nestedValue]);
|
|
4798
|
+
} else if (isValueWithOperator(nestedValue)) {
|
|
4799
|
+
nKeyValuePairsWithOperator.push([
|
|
4800
|
+
formatFilterKey(key, nestedKey),
|
|
4801
|
+
nestedValue
|
|
4802
|
+
]);
|
|
4803
|
+
}
|
|
4804
|
+
});
|
|
4805
|
+
filterList = [
|
|
4806
|
+
...filterList,
|
|
4807
|
+
...getFiltersFromKeyValuePairs(nKeyValuePairs),
|
|
4808
|
+
...getFiltersFromKeyValuePairsWithOperator(nKeyValuePairsWithOperator)
|
|
4809
|
+
];
|
|
4810
|
+
});
|
|
4811
|
+
return filterList.map(
|
|
4812
|
+
({ key, operator, value }) => formatFilter(key, operator, formatFilterValue(value))
|
|
4813
|
+
).join(" AND ");
|
|
4814
|
+
}
|
|
4815
|
+
var getFiltersFromKeyValuePairs = (keyValuePairs) => {
|
|
4816
|
+
const filters = [];
|
|
4817
|
+
keyValuePairs.forEach(([key, value]) => {
|
|
4818
|
+
filters.push({
|
|
4819
|
+
key,
|
|
4820
|
+
operator: ":",
|
|
4821
|
+
value
|
|
4822
|
+
});
|
|
4823
|
+
});
|
|
4824
|
+
return filters;
|
|
4825
|
+
};
|
|
4826
|
+
var getFiltersFromKeyValuePairsWithOperator = (keyValuePairsWithOperator) => {
|
|
4827
|
+
const filters = [];
|
|
4828
|
+
keyValuePairsWithOperator.forEach(([key, value]) => {
|
|
4829
|
+
if ("startsWith" in value && typeof value.startsWith === "string") {
|
|
4830
|
+
filters.push({
|
|
4831
|
+
key,
|
|
4832
|
+
operator: "^",
|
|
4833
|
+
value: value.startsWith
|
|
4834
|
+
});
|
|
4835
|
+
}
|
|
4836
|
+
});
|
|
4837
|
+
return filters;
|
|
4838
|
+
};
|
|
4839
|
+
var isSimpleValue = (value) => {
|
|
4840
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
4841
|
+
return true;
|
|
4842
|
+
}
|
|
4843
|
+
return false;
|
|
4844
|
+
};
|
|
4845
|
+
var isValueWithOperator = (value) => {
|
|
4846
|
+
if (typeof value === "object" && value !== null && "startsWith" in value) {
|
|
4847
|
+
return true;
|
|
4848
|
+
}
|
|
4849
|
+
return false;
|
|
4850
|
+
};
|
|
4851
|
+
var formatFilter = (key, operator, value) => {
|
|
4852
|
+
return `${key}${operator}${value}`;
|
|
4853
|
+
};
|
|
4854
|
+
var formatFilterKey = (key, nestedKey) => {
|
|
4855
|
+
if (nestedKey) {
|
|
4856
|
+
return `${key}[${JSON.stringify(nestedKey)}]`;
|
|
4857
|
+
}
|
|
4858
|
+
return key;
|
|
4859
|
+
};
|
|
4860
|
+
var formatFilterValue = (value) => {
|
|
4861
|
+
if (typeof value === "string") {
|
|
4862
|
+
if (isStringEmpty(value)) {
|
|
4863
|
+
throw new Error("Value cannot be empty");
|
|
4864
|
+
}
|
|
4865
|
+
return JSON.stringify(value);
|
|
4866
|
+
}
|
|
4867
|
+
return value.toString();
|
|
4868
|
+
};
|
|
4869
|
+
var isStringEmpty = (value) => {
|
|
4870
|
+
return !value || value.toString().trim() === "";
|
|
4871
|
+
};
|
|
4872
|
+
|
|
4779
4873
|
// src/protocol/ClientMsg.ts
|
|
4780
4874
|
var ClientMsgCode = /* @__PURE__ */ ((ClientMsgCode2) => {
|
|
4781
4875
|
ClientMsgCode2[ClientMsgCode2["UPDATE_PRESENCE"] = 100] = "UPDATE_PRESENCE";
|
|
@@ -5078,19 +5172,20 @@ function createCommentsApi(roomId, getAuthValue, fetchClientApi) {
|
|
|
5078
5172
|
return body;
|
|
5079
5173
|
}
|
|
5080
5174
|
async function getThreads(options) {
|
|
5175
|
+
let query;
|
|
5176
|
+
if (options?.query) {
|
|
5177
|
+
query = objectToQuery(options.query);
|
|
5178
|
+
}
|
|
5081
5179
|
const response = await fetchCommentsApi(
|
|
5082
|
-
"/threads
|
|
5180
|
+
"/threads",
|
|
5083
5181
|
{
|
|
5084
|
-
since: options?.since?.toISOString()
|
|
5182
|
+
since: options?.since?.toISOString(),
|
|
5183
|
+
query
|
|
5085
5184
|
},
|
|
5086
5185
|
{
|
|
5087
|
-
body: JSON.stringify({
|
|
5088
|
-
...options?.query?.metadata && { metadata: options.query.metadata }
|
|
5089
|
-
}),
|
|
5090
5186
|
headers: {
|
|
5091
5187
|
"Content-Type": "application/json"
|
|
5092
|
-
}
|
|
5093
|
-
method: "POST"
|
|
5188
|
+
}
|
|
5094
5189
|
}
|
|
5095
5190
|
);
|
|
5096
5191
|
if (response.ok) {
|
|
@@ -5444,7 +5539,9 @@ function createRoom(options, config) {
|
|
|
5444
5539
|
}
|
|
5445
5540
|
}
|
|
5446
5541
|
if (activeBatch) {
|
|
5447
|
-
|
|
5542
|
+
for (const op of ops) {
|
|
5543
|
+
activeBatch.ops.push(op);
|
|
5544
|
+
}
|
|
5448
5545
|
for (const [key, value] of storageUpdates) {
|
|
5449
5546
|
activeBatch.updates.storageUpdates.set(
|
|
5450
5547
|
key,
|
|
@@ -6123,7 +6220,10 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6123
6220
|
flushNowOrSoon();
|
|
6124
6221
|
}
|
|
6125
6222
|
function dispatchOps(ops) {
|
|
6126
|
-
context.buffer
|
|
6223
|
+
const { storageOperations } = context.buffer;
|
|
6224
|
+
for (const op of ops) {
|
|
6225
|
+
storageOperations.push(op);
|
|
6226
|
+
}
|
|
6127
6227
|
flushNowOrSoon();
|
|
6128
6228
|
}
|
|
6129
6229
|
let _getStorage$ = null;
|
|
@@ -6620,7 +6720,7 @@ function createClientStore() {
|
|
|
6620
6720
|
threads: deleteKeyImmutable(state.threads, threadId),
|
|
6621
6721
|
inboxNotifications: Object.fromEntries(
|
|
6622
6722
|
Object.entries(state.inboxNotifications).filter(
|
|
6623
|
-
([_id, notification]) => notification.kind === "thread" && notification.threadId
|
|
6723
|
+
([_id, notification]) => notification.kind === "thread" && notification.threadId === threadId
|
|
6624
6724
|
)
|
|
6625
6725
|
)
|
|
6626
6726
|
};
|
|
@@ -6762,7 +6862,7 @@ function applyOptimisticUpdates(state) {
|
|
|
6762
6862
|
optimisticUpdate.comment
|
|
6763
6863
|
);
|
|
6764
6864
|
const inboxNotification = Object.values(result.inboxNotifications).find(
|
|
6765
|
-
(notification) => notification.kind === "thread" && notification.threadId
|
|
6865
|
+
(notification) => notification.kind === "thread" && notification.threadId === thread.id
|
|
6766
6866
|
);
|
|
6767
6867
|
if (inboxNotification === void 0) {
|
|
6768
6868
|
break;
|
|
@@ -8148,6 +8248,7 @@ export {
|
|
|
8148
8248
|
makePoller,
|
|
8149
8249
|
makePosition,
|
|
8150
8250
|
nn,
|
|
8251
|
+
objectToQuery,
|
|
8151
8252
|
patchLiveObjectKey,
|
|
8152
8253
|
raise,
|
|
8153
8254
|
removeReaction,
|