@liveblocks/core 3.16.0-flow1 → 3.16.0-flow3
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.cjs +876 -653
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +107 -7
- package/dist/index.d.ts +107 -7
- package/dist/index.js +822 -599
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
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 = "3.16.0-
|
|
9
|
+
var PKG_VERSION = "3.16.0-flow3";
|
|
10
10
|
var PKG_FORMAT = "cjs";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -6302,7 +6302,6 @@ var AbstractCrdt = class {
|
|
|
6302
6302
|
}
|
|
6303
6303
|
/**
|
|
6304
6304
|
* @internal
|
|
6305
|
-
*
|
|
6306
6305
|
* Return an snapshot of this Live tree for use in DevTools.
|
|
6307
6306
|
*/
|
|
6308
6307
|
toTreeNode(key) {
|
|
@@ -6312,6 +6311,14 @@ var AbstractCrdt = class {
|
|
|
6312
6311
|
}
|
|
6313
6312
|
return this.#cachedTreeNode;
|
|
6314
6313
|
}
|
|
6314
|
+
/**
|
|
6315
|
+
* @private
|
|
6316
|
+
* Returns true if the cached immutable snapshot exists and is
|
|
6317
|
+
* reference-equal to the given value. Does not trigger a recompute.
|
|
6318
|
+
*/
|
|
6319
|
+
immutableIs(value) {
|
|
6320
|
+
return this.#cachedImmutable !== void 0 && this.#cachedImmutable === value;
|
|
6321
|
+
}
|
|
6315
6322
|
/**
|
|
6316
6323
|
* Return an immutable snapshot of this Live node and its children.
|
|
6317
6324
|
*/
|
|
@@ -7859,161 +7866,561 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7859
7866
|
}
|
|
7860
7867
|
};
|
|
7861
7868
|
|
|
7862
|
-
// src/
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7869
|
+
// src/lib/Json.ts
|
|
7870
|
+
function isJsonScalar(data) {
|
|
7871
|
+
return data === null || typeof data === "string" || typeof data === "number" || typeof data === "boolean";
|
|
7872
|
+
}
|
|
7873
|
+
function isJsonArray(data) {
|
|
7874
|
+
return Array.isArray(data);
|
|
7875
|
+
}
|
|
7876
|
+
function isJsonObject(data) {
|
|
7877
|
+
return !isJsonScalar(data) && !isJsonArray(data);
|
|
7878
|
+
}
|
|
7879
|
+
|
|
7880
|
+
// src/immutable.ts
|
|
7881
|
+
function lsonObjectToJson(obj) {
|
|
7882
|
+
const result = {};
|
|
7883
|
+
for (const key in obj) {
|
|
7884
|
+
const val = obj[key];
|
|
7885
|
+
if (val !== void 0) {
|
|
7886
|
+
result[key] = lsonToJson(val);
|
|
7887
|
+
}
|
|
7888
|
+
}
|
|
7889
|
+
return result;
|
|
7890
|
+
}
|
|
7891
|
+
function liveObjectToJson(liveObject) {
|
|
7892
|
+
return lsonObjectToJson(liveObject.toObject());
|
|
7893
|
+
}
|
|
7894
|
+
function liveMapToJson(map) {
|
|
7895
|
+
const result = {};
|
|
7896
|
+
for (const [key, value] of map.entries()) {
|
|
7897
|
+
result[key] = lsonToJson(value);
|
|
7898
|
+
}
|
|
7899
|
+
return result;
|
|
7900
|
+
}
|
|
7901
|
+
function lsonListToJson(value) {
|
|
7902
|
+
return value.map(lsonToJson);
|
|
7903
|
+
}
|
|
7904
|
+
function liveListToJson(value) {
|
|
7905
|
+
return lsonListToJson(value.toArray());
|
|
7906
|
+
}
|
|
7907
|
+
function lsonToJson(value) {
|
|
7908
|
+
if (value instanceof LiveObject) {
|
|
7909
|
+
return liveObjectToJson(value);
|
|
7910
|
+
} else if (value instanceof LiveList) {
|
|
7911
|
+
return liveListToJson(value);
|
|
7912
|
+
} else if (value instanceof LiveMap) {
|
|
7913
|
+
return liveMapToJson(value);
|
|
7914
|
+
} else if (value instanceof LiveRegister) {
|
|
7915
|
+
return value.data;
|
|
7916
|
+
}
|
|
7917
|
+
if (Array.isArray(value)) {
|
|
7918
|
+
return lsonListToJson(value);
|
|
7919
|
+
} else if (isPlainObject(value)) {
|
|
7920
|
+
return lsonObjectToJson(value);
|
|
7921
|
+
}
|
|
7922
|
+
return value;
|
|
7923
|
+
}
|
|
7924
|
+
function deepLiveify(value, config) {
|
|
7925
|
+
if (Array.isArray(value)) {
|
|
7926
|
+
return new LiveList(value.map((v) => deepLiveify(v, config)));
|
|
7927
|
+
} else if (isPlainObject(value)) {
|
|
7928
|
+
const init = {};
|
|
7929
|
+
const locals = {};
|
|
7930
|
+
for (const key in value) {
|
|
7931
|
+
const val = value[key];
|
|
7932
|
+
if (val === void 0) {
|
|
7933
|
+
continue;
|
|
7934
|
+
}
|
|
7935
|
+
const subConfig = isPlainObject(config) ? config[key] : config;
|
|
7936
|
+
if (subConfig === false) {
|
|
7937
|
+
locals[key] = val;
|
|
7938
|
+
} else if (subConfig === "atomic") {
|
|
7939
|
+
init[key] = val;
|
|
7896
7940
|
} else {
|
|
7897
|
-
|
|
7898
|
-
const children = parentToChildren.get(crdt.parentId);
|
|
7899
|
-
if (children !== void 0) {
|
|
7900
|
-
children.push(node);
|
|
7901
|
-
} else {
|
|
7902
|
-
parentToChildren.set(crdt.parentId, [node]);
|
|
7903
|
-
}
|
|
7941
|
+
init[key] = deepLiveify(val, subConfig);
|
|
7904
7942
|
}
|
|
7905
7943
|
}
|
|
7906
|
-
|
|
7907
|
-
|
|
7944
|
+
const lo = new LiveObject(init);
|
|
7945
|
+
for (const key in locals) {
|
|
7946
|
+
lo.setLocal(key, locals[key]);
|
|
7908
7947
|
}
|
|
7909
|
-
return
|
|
7948
|
+
return lo;
|
|
7949
|
+
} else {
|
|
7950
|
+
return value;
|
|
7910
7951
|
}
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
return
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
);
|
|
7952
|
+
}
|
|
7953
|
+
function reconcile(live, json, config) {
|
|
7954
|
+
if (isLiveObject(live) && isPlainObject(json)) {
|
|
7955
|
+
return reconcileLiveObject(live, json, config);
|
|
7956
|
+
} else if (isLiveList(live) && Array.isArray(json)) {
|
|
7957
|
+
return reconcileLiveList(live, json, config);
|
|
7958
|
+
} else if (isLiveMap(live) && isPlainObject(json)) {
|
|
7959
|
+
return reconcileLiveMap(live, config);
|
|
7960
|
+
} else {
|
|
7961
|
+
return deepLiveify(json, config);
|
|
7919
7962
|
}
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7963
|
+
}
|
|
7964
|
+
function reconcileLiveMap(_liveMap, _config) {
|
|
7965
|
+
throw new Error("Reconciling a LiveMap is not supported yet");
|
|
7966
|
+
}
|
|
7967
|
+
function reconcileLiveObject(liveObj, jsonObj, config) {
|
|
7968
|
+
const currentKeys = liveObj.keys();
|
|
7969
|
+
for (const key in jsonObj) {
|
|
7970
|
+
currentKeys.delete(key);
|
|
7971
|
+
const newVal = jsonObj[key];
|
|
7972
|
+
if (newVal === void 0) {
|
|
7973
|
+
liveObj.delete(key);
|
|
7974
|
+
continue;
|
|
7975
|
+
}
|
|
7976
|
+
const subConfig = isPlainObject(config) ? config[key] : config;
|
|
7977
|
+
if (subConfig === false) {
|
|
7978
|
+
liveObj.setLocal(key, newVal);
|
|
7979
|
+
} else if (subConfig === "atomic") {
|
|
7980
|
+
const curVal = liveObj.get(key);
|
|
7981
|
+
if (curVal !== newVal) {
|
|
7982
|
+
liveObj.set(key, newVal);
|
|
7983
|
+
}
|
|
7984
|
+
} else {
|
|
7985
|
+
const curVal = liveObj.get(key);
|
|
7986
|
+
if (curVal === void 0) {
|
|
7987
|
+
liveObj.set(key, deepLiveify(newVal, subConfig));
|
|
7988
|
+
} else if (isLiveStructure(curVal)) {
|
|
7989
|
+
const next = reconcile(curVal, newVal, subConfig);
|
|
7990
|
+
if (next !== curVal) {
|
|
7991
|
+
liveObj.set(key, next);
|
|
7992
|
+
}
|
|
7993
|
+
} else if (curVal !== newVal) {
|
|
7994
|
+
liveObj.set(key, deepLiveify(newVal, subConfig));
|
|
7928
7995
|
}
|
|
7929
7996
|
}
|
|
7930
|
-
this.#map = new Map(Object.entries(o));
|
|
7931
7997
|
}
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
if (isLiveNode(value)) {
|
|
7948
|
-
for (const childOp of value._toOps(this._id, key)) {
|
|
7949
|
-
ops.push(childOp);
|
|
7950
|
-
}
|
|
7951
|
-
} else {
|
|
7952
|
-
op.data[key] = value;
|
|
7998
|
+
for (const key of currentKeys) {
|
|
7999
|
+
liveObj.delete(key);
|
|
8000
|
+
}
|
|
8001
|
+
return liveObj;
|
|
8002
|
+
}
|
|
8003
|
+
function reconcileLiveList(liveList, jsonArr, config) {
|
|
8004
|
+
const curLen = liveList.length;
|
|
8005
|
+
const newLen = jsonArr.length;
|
|
8006
|
+
for (let i = 0; i < Math.min(curLen, newLen); i++) {
|
|
8007
|
+
const curVal = liveList.get(i);
|
|
8008
|
+
const newVal = jsonArr[i];
|
|
8009
|
+
if (isLiveStructure(curVal)) {
|
|
8010
|
+
const next = reconcile(curVal, newVal, config);
|
|
8011
|
+
if (next !== curVal) {
|
|
8012
|
+
liveList.set(i, next);
|
|
7953
8013
|
}
|
|
8014
|
+
} else if (curVal !== newVal) {
|
|
8015
|
+
liveList.set(i, deepLiveify(newVal, config));
|
|
7954
8016
|
}
|
|
7955
|
-
return ops;
|
|
7956
8017
|
}
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
const liveObj = new _LiveObject(item.data);
|
|
7960
|
-
liveObj._attach(id, pool);
|
|
7961
|
-
return this._deserializeChildren(liveObj, parentToChildren, pool);
|
|
8018
|
+
for (let i = curLen; i < newLen; i++) {
|
|
8019
|
+
liveList.push(deepLiveify(jsonArr[i], config));
|
|
7962
8020
|
}
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
8021
|
+
for (let i = curLen - 1; i >= newLen; i--) {
|
|
8022
|
+
liveList.delete(i);
|
|
8023
|
+
}
|
|
8024
|
+
return liveList;
|
|
8025
|
+
}
|
|
8026
|
+
function legacy_patchLiveList(liveList, prev, next) {
|
|
8027
|
+
let i = 0;
|
|
8028
|
+
let prevEnd = prev.length - 1;
|
|
8029
|
+
let nextEnd = next.length - 1;
|
|
8030
|
+
let prevNode = prev[0];
|
|
8031
|
+
let nextNode = next[0];
|
|
8032
|
+
outer: {
|
|
8033
|
+
while (prevNode === nextNode) {
|
|
8034
|
+
++i;
|
|
8035
|
+
if (i > prevEnd || i > nextEnd) {
|
|
8036
|
+
break outer;
|
|
8037
|
+
}
|
|
8038
|
+
prevNode = prev[i];
|
|
8039
|
+
nextNode = next[i];
|
|
7968
8040
|
}
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
8041
|
+
prevNode = prev[prevEnd];
|
|
8042
|
+
nextNode = next[nextEnd];
|
|
8043
|
+
while (prevNode === nextNode) {
|
|
8044
|
+
prevEnd--;
|
|
8045
|
+
nextEnd--;
|
|
8046
|
+
if (i > prevEnd || i > nextEnd) {
|
|
8047
|
+
break outer;
|
|
7974
8048
|
}
|
|
7975
|
-
|
|
7976
|
-
|
|
8049
|
+
prevNode = prev[prevEnd];
|
|
8050
|
+
nextNode = next[nextEnd];
|
|
7977
8051
|
}
|
|
7978
|
-
return liveObj;
|
|
7979
8052
|
}
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
value._attach(pool.generateId(), pool);
|
|
8053
|
+
if (i > prevEnd) {
|
|
8054
|
+
if (i <= nextEnd) {
|
|
8055
|
+
while (i <= nextEnd) {
|
|
8056
|
+
liveList.insert(deepLiveify(next[i]), i);
|
|
8057
|
+
i++;
|
|
7986
8058
|
}
|
|
7987
8059
|
}
|
|
7988
|
-
}
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
8060
|
+
} else if (i > nextEnd) {
|
|
8061
|
+
let localI = i;
|
|
8062
|
+
while (localI <= prevEnd) {
|
|
8063
|
+
liveList.delete(i);
|
|
8064
|
+
localI++;
|
|
7993
8065
|
}
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
8066
|
+
} else {
|
|
8067
|
+
while (i <= prevEnd && i <= nextEnd) {
|
|
8068
|
+
prevNode = prev[i];
|
|
8069
|
+
nextNode = next[i];
|
|
8070
|
+
const liveListNode = liveList.get(i);
|
|
8071
|
+
if (isLiveObject(liveListNode) && isPlainObject(prevNode) && isPlainObject(nextNode)) {
|
|
8072
|
+
legacy_patchLiveObject(liveListNode, prevNode, nextNode);
|
|
8073
|
+
} else {
|
|
8074
|
+
liveList.set(i, deepLiveify(nextNode));
|
|
7999
8075
|
}
|
|
8000
|
-
|
|
8076
|
+
i++;
|
|
8001
8077
|
}
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
} else if (this.#unackedOpsByKey.get(key) === opId) {
|
|
8006
|
-
this.#unackedOpsByKey.delete(key);
|
|
8007
|
-
return { modified: false };
|
|
8008
|
-
} else {
|
|
8009
|
-
return { modified: false };
|
|
8078
|
+
while (i <= nextEnd) {
|
|
8079
|
+
liveList.insert(deepLiveify(next[i]), i);
|
|
8080
|
+
i++;
|
|
8010
8081
|
}
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8082
|
+
let localI = i;
|
|
8083
|
+
while (localI <= prevEnd) {
|
|
8084
|
+
liveList.delete(i);
|
|
8085
|
+
localI++;
|
|
8086
|
+
}
|
|
8087
|
+
}
|
|
8088
|
+
}
|
|
8089
|
+
function legacy_patchLiveObjectKey(liveObject, key, prev, next) {
|
|
8090
|
+
if (process.env.NODE_ENV !== "production") {
|
|
8091
|
+
const nonSerializableValue = findNonSerializableValue(next);
|
|
8092
|
+
if (nonSerializableValue) {
|
|
8093
|
+
error2(
|
|
8094
|
+
`New state path: '${nonSerializableValue.path}' value: '${String(
|
|
8095
|
+
nonSerializableValue.value
|
|
8096
|
+
)}' is not serializable.
|
|
8097
|
+
Only serializable value can be synced with Liveblocks.`
|
|
8098
|
+
);
|
|
8099
|
+
return;
|
|
8100
|
+
}
|
|
8101
|
+
}
|
|
8102
|
+
const value = liveObject.get(key);
|
|
8103
|
+
if (next === void 0) {
|
|
8104
|
+
liveObject.delete(key);
|
|
8105
|
+
} else if (value === void 0) {
|
|
8106
|
+
liveObject.set(key, deepLiveify(next));
|
|
8107
|
+
} else if (prev === next) {
|
|
8108
|
+
return;
|
|
8109
|
+
} else if (isLiveList(value) && Array.isArray(prev) && Array.isArray(next)) {
|
|
8110
|
+
legacy_patchLiveList(value, prev, next);
|
|
8111
|
+
} else if (isLiveObject(value) && isPlainObject(prev) && isPlainObject(next)) {
|
|
8112
|
+
legacy_patchLiveObject(value, prev, next);
|
|
8113
|
+
} else {
|
|
8114
|
+
liveObject.set(key, deepLiveify(next));
|
|
8115
|
+
}
|
|
8116
|
+
}
|
|
8117
|
+
function legacy_patchLiveObject(root, prev, next) {
|
|
8118
|
+
const updates = {};
|
|
8119
|
+
for (const key in next) {
|
|
8120
|
+
legacy_patchLiveObjectKey(root, key, prev[key], next[key]);
|
|
8121
|
+
}
|
|
8122
|
+
for (const key in prev) {
|
|
8123
|
+
if (next[key] === void 0) {
|
|
8124
|
+
root.delete(key);
|
|
8125
|
+
}
|
|
8126
|
+
}
|
|
8127
|
+
if (Object.keys(updates).length > 0) {
|
|
8128
|
+
root.update(updates);
|
|
8129
|
+
}
|
|
8130
|
+
}
|
|
8131
|
+
function getParentsPath(node) {
|
|
8132
|
+
const path = [];
|
|
8133
|
+
while (node.parent.type === "HasParent") {
|
|
8134
|
+
if (isLiveList(node.parent.node)) {
|
|
8135
|
+
path.push(node.parent.node._indexOfPosition(node.parent.key));
|
|
8136
|
+
} else {
|
|
8137
|
+
path.push(node.parent.key);
|
|
8138
|
+
}
|
|
8139
|
+
node = node.parent.node;
|
|
8140
|
+
}
|
|
8141
|
+
return path;
|
|
8142
|
+
}
|
|
8143
|
+
function legacy_patchImmutableObject(state, updates) {
|
|
8144
|
+
return updates.reduce(
|
|
8145
|
+
(state2, update) => legacy_patchImmutableObjectWithUpdate(state2, update),
|
|
8146
|
+
state
|
|
8147
|
+
);
|
|
8148
|
+
}
|
|
8149
|
+
function legacy_patchImmutableObjectWithUpdate(state, update) {
|
|
8150
|
+
const path = getParentsPath(update.node);
|
|
8151
|
+
return legacy_patchImmutableNode(state, path, update);
|
|
8152
|
+
}
|
|
8153
|
+
function legacy_patchImmutableNode(state, path, update) {
|
|
8154
|
+
const pathItem = path.pop();
|
|
8155
|
+
if (pathItem === void 0) {
|
|
8156
|
+
switch (update.type) {
|
|
8157
|
+
case "LiveObject": {
|
|
8158
|
+
if (!isJsonObject(state)) {
|
|
8159
|
+
throw new Error(
|
|
8160
|
+
"Internal: received update on LiveObject but state was not an object"
|
|
8161
|
+
);
|
|
8162
|
+
}
|
|
8163
|
+
const newState = Object.assign({}, state);
|
|
8164
|
+
for (const key in update.updates) {
|
|
8165
|
+
if (_optionalChain([update, 'access', _192 => _192.updates, 'access', _193 => _193[key], 'optionalAccess', _194 => _194.type]) === "update") {
|
|
8166
|
+
const val = update.node.get(key);
|
|
8167
|
+
if (val !== void 0) {
|
|
8168
|
+
newState[key] = lsonToJson(val);
|
|
8169
|
+
}
|
|
8170
|
+
} else if (_optionalChain([update, 'access', _195 => _195.updates, 'access', _196 => _196[key], 'optionalAccess', _197 => _197.type]) === "delete") {
|
|
8171
|
+
delete newState[key];
|
|
8172
|
+
}
|
|
8173
|
+
}
|
|
8174
|
+
return newState;
|
|
8175
|
+
}
|
|
8176
|
+
case "LiveList": {
|
|
8177
|
+
if (!Array.isArray(state)) {
|
|
8178
|
+
throw new Error(
|
|
8179
|
+
"Internal: received update on LiveList but state was not an array"
|
|
8180
|
+
);
|
|
8181
|
+
}
|
|
8182
|
+
let newState = state.map((x) => x);
|
|
8183
|
+
for (const listUpdate of update.updates) {
|
|
8184
|
+
if (listUpdate.type === "set") {
|
|
8185
|
+
newState = newState.map(
|
|
8186
|
+
(item, index) => index === listUpdate.index ? lsonToJson(listUpdate.item) : item
|
|
8187
|
+
);
|
|
8188
|
+
} else if (listUpdate.type === "insert") {
|
|
8189
|
+
if (listUpdate.index === newState.length) {
|
|
8190
|
+
newState.push(lsonToJson(listUpdate.item));
|
|
8191
|
+
} else {
|
|
8192
|
+
newState = [
|
|
8193
|
+
...newState.slice(0, listUpdate.index),
|
|
8194
|
+
lsonToJson(listUpdate.item),
|
|
8195
|
+
...newState.slice(listUpdate.index)
|
|
8196
|
+
];
|
|
8197
|
+
}
|
|
8198
|
+
} else if (listUpdate.type === "delete") {
|
|
8199
|
+
newState.splice(listUpdate.index, 1);
|
|
8200
|
+
} else if (listUpdate.type === "move") {
|
|
8201
|
+
if (listUpdate.previousIndex > listUpdate.index) {
|
|
8202
|
+
newState = [
|
|
8203
|
+
...newState.slice(0, listUpdate.index),
|
|
8204
|
+
lsonToJson(listUpdate.item),
|
|
8205
|
+
...newState.slice(listUpdate.index, listUpdate.previousIndex),
|
|
8206
|
+
...newState.slice(listUpdate.previousIndex + 1)
|
|
8207
|
+
];
|
|
8208
|
+
} else {
|
|
8209
|
+
newState = [
|
|
8210
|
+
...newState.slice(0, listUpdate.previousIndex),
|
|
8211
|
+
...newState.slice(
|
|
8212
|
+
listUpdate.previousIndex + 1,
|
|
8213
|
+
listUpdate.index + 1
|
|
8214
|
+
),
|
|
8215
|
+
lsonToJson(listUpdate.item),
|
|
8216
|
+
...newState.slice(listUpdate.index + 1)
|
|
8217
|
+
];
|
|
8218
|
+
}
|
|
8219
|
+
}
|
|
8220
|
+
}
|
|
8221
|
+
return newState;
|
|
8222
|
+
}
|
|
8223
|
+
case "LiveMap": {
|
|
8224
|
+
if (!isJsonObject(state)) {
|
|
8225
|
+
throw new Error(
|
|
8226
|
+
"Internal: received update on LiveMap but state was not an object"
|
|
8227
|
+
);
|
|
8228
|
+
}
|
|
8229
|
+
const newState = Object.assign({}, state);
|
|
8230
|
+
for (const key in update.updates) {
|
|
8231
|
+
if (_optionalChain([update, 'access', _198 => _198.updates, 'access', _199 => _199[key], 'optionalAccess', _200 => _200.type]) === "update") {
|
|
8232
|
+
const value = update.node.get(key);
|
|
8233
|
+
if (value !== void 0) {
|
|
8234
|
+
newState[key] = lsonToJson(value);
|
|
8235
|
+
}
|
|
8236
|
+
} else if (_optionalChain([update, 'access', _201 => _201.updates, 'access', _202 => _202[key], 'optionalAccess', _203 => _203.type]) === "delete") {
|
|
8237
|
+
delete newState[key];
|
|
8238
|
+
}
|
|
8239
|
+
}
|
|
8240
|
+
return newState;
|
|
8241
|
+
}
|
|
8242
|
+
}
|
|
8243
|
+
}
|
|
8244
|
+
if (Array.isArray(state)) {
|
|
8245
|
+
const newArray = [...state];
|
|
8246
|
+
newArray[pathItem] = legacy_patchImmutableNode(
|
|
8247
|
+
state[pathItem],
|
|
8248
|
+
path,
|
|
8249
|
+
update
|
|
8250
|
+
);
|
|
8251
|
+
return newArray;
|
|
8252
|
+
} else if (isJsonObject(state)) {
|
|
8253
|
+
const node = state[pathItem];
|
|
8254
|
+
if (node === void 0) {
|
|
8255
|
+
return state;
|
|
8256
|
+
} else {
|
|
8257
|
+
const stateAsObj = state;
|
|
8258
|
+
return {
|
|
8259
|
+
...stateAsObj,
|
|
8260
|
+
[pathItem]: legacy_patchImmutableNode(node, path, update)
|
|
8261
|
+
};
|
|
8262
|
+
}
|
|
8263
|
+
} else {
|
|
8264
|
+
return state;
|
|
8265
|
+
}
|
|
8266
|
+
}
|
|
8267
|
+
|
|
8268
|
+
// src/crdts/LiveObject.ts
|
|
8269
|
+
var MAX_LIVE_OBJECT_SIZE = 128 * 1024;
|
|
8270
|
+
var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
8271
|
+
#synced;
|
|
8272
|
+
#local = /* @__PURE__ */ new Map();
|
|
8273
|
+
/**
|
|
8274
|
+
* Tracks unacknowledged local changes per property to preserve optimistic
|
|
8275
|
+
* updates. Maps property keys to their pending operation IDs.
|
|
8276
|
+
*
|
|
8277
|
+
* INVARIANT: Only locally-generated opIds are ever stored here. Remote opIds
|
|
8278
|
+
* are only compared against (to detect ACKs), never stored.
|
|
8279
|
+
*
|
|
8280
|
+
* When a local change is made, the opId is stored here. When a remote op
|
|
8281
|
+
* arrives for the same key:
|
|
8282
|
+
* - If no entry exists → apply remote op
|
|
8283
|
+
* - If opId matches → it's an ACK, clear the entry
|
|
8284
|
+
* - If opId differs → ignore remote op to preserve optimistic update
|
|
8285
|
+
*/
|
|
8286
|
+
#unackedOpsByKey;
|
|
8287
|
+
/**
|
|
8288
|
+
* Enable or disable detection of too large LiveObjects.
|
|
8289
|
+
* When enabled, throws an error if LiveObject static data exceeds 128KB, which
|
|
8290
|
+
* is the maximum value the server will be able to accept.
|
|
8291
|
+
* By default, this behavior is disabled to avoid the runtime performance
|
|
8292
|
+
* overhead on every LiveObject.set() or LiveObject.update() call.
|
|
8293
|
+
*
|
|
8294
|
+
* @experimental
|
|
8295
|
+
*/
|
|
8296
|
+
static __initStatic() {this.detectLargeObjects = false}
|
|
8297
|
+
static #buildRootAndParentToChildren(nodes) {
|
|
8298
|
+
const parentToChildren = /* @__PURE__ */ new Map();
|
|
8299
|
+
let root = null;
|
|
8300
|
+
for (const node of nodes) {
|
|
8301
|
+
if (isRootStorageNode(node)) {
|
|
8302
|
+
root = node[1];
|
|
8303
|
+
} else {
|
|
8304
|
+
const crdt = node[1];
|
|
8305
|
+
const children = parentToChildren.get(crdt.parentId);
|
|
8306
|
+
if (children !== void 0) {
|
|
8307
|
+
children.push(node);
|
|
8308
|
+
} else {
|
|
8309
|
+
parentToChildren.set(crdt.parentId, [node]);
|
|
8310
|
+
}
|
|
8311
|
+
}
|
|
8312
|
+
}
|
|
8313
|
+
if (root === null) {
|
|
8314
|
+
throw new Error("Root can't be null");
|
|
8315
|
+
}
|
|
8316
|
+
return [root, parentToChildren];
|
|
8317
|
+
}
|
|
8318
|
+
/** @private Do not use this API directly */
|
|
8319
|
+
static _fromItems(nodes, pool) {
|
|
8320
|
+
const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(nodes);
|
|
8321
|
+
return _LiveObject._deserialize(
|
|
8322
|
+
["root", root],
|
|
8323
|
+
parentToChildren,
|
|
8324
|
+
pool
|
|
8325
|
+
);
|
|
8326
|
+
}
|
|
8327
|
+
constructor(obj = {}) {
|
|
8328
|
+
super();
|
|
8329
|
+
this.#unackedOpsByKey = /* @__PURE__ */ new Map();
|
|
8330
|
+
const o = compactObject(obj);
|
|
8331
|
+
for (const key of Object.keys(o)) {
|
|
8332
|
+
const value = o[key];
|
|
8333
|
+
if (isLiveNode(value)) {
|
|
8334
|
+
value._setParentLink(this, key);
|
|
8335
|
+
}
|
|
8336
|
+
}
|
|
8337
|
+
this.#synced = new Map(Object.entries(o));
|
|
8338
|
+
}
|
|
8339
|
+
/** @internal */
|
|
8340
|
+
_toOps(parentId, parentKey) {
|
|
8341
|
+
if (this._id === void 0) {
|
|
8342
|
+
throw new Error("Cannot serialize item is not attached");
|
|
8343
|
+
}
|
|
8344
|
+
const ops = [];
|
|
8345
|
+
const op = {
|
|
8346
|
+
type: OpCode.CREATE_OBJECT,
|
|
8347
|
+
id: this._id,
|
|
8348
|
+
parentId,
|
|
8349
|
+
parentKey,
|
|
8350
|
+
data: {}
|
|
8351
|
+
};
|
|
8352
|
+
ops.push(op);
|
|
8353
|
+
for (const [key, value] of this.#synced) {
|
|
8354
|
+
if (isLiveNode(value)) {
|
|
8355
|
+
for (const childOp of value._toOps(this._id, key)) {
|
|
8356
|
+
ops.push(childOp);
|
|
8357
|
+
}
|
|
8358
|
+
} else {
|
|
8359
|
+
op.data[key] = value;
|
|
8360
|
+
}
|
|
8361
|
+
}
|
|
8362
|
+
return ops;
|
|
8363
|
+
}
|
|
8364
|
+
/** @internal */
|
|
8365
|
+
static _deserialize([id, item], parentToChildren, pool) {
|
|
8366
|
+
const liveObj = new _LiveObject(item.data);
|
|
8367
|
+
liveObj._attach(id, pool);
|
|
8368
|
+
return this._deserializeChildren(liveObj, parentToChildren, pool);
|
|
8369
|
+
}
|
|
8370
|
+
/** @internal */
|
|
8371
|
+
static _deserializeChildren(liveObj, parentToChildren, pool) {
|
|
8372
|
+
const children = parentToChildren.get(nn(liveObj._id));
|
|
8373
|
+
if (children === void 0) {
|
|
8374
|
+
return liveObj;
|
|
8375
|
+
}
|
|
8376
|
+
for (const node of children) {
|
|
8377
|
+
const child = deserializeToLson(node, parentToChildren, pool);
|
|
8378
|
+
const crdt = node[1];
|
|
8379
|
+
if (isLiveStructure(child)) {
|
|
8380
|
+
child._setParentLink(liveObj, crdt.parentKey);
|
|
8381
|
+
}
|
|
8382
|
+
liveObj.#synced.set(crdt.parentKey, child);
|
|
8383
|
+
liveObj.invalidate();
|
|
8384
|
+
}
|
|
8385
|
+
return liveObj;
|
|
8386
|
+
}
|
|
8387
|
+
/** @internal */
|
|
8388
|
+
_attach(id, pool) {
|
|
8389
|
+
super._attach(id, pool);
|
|
8390
|
+
for (const [_key, value] of this.#synced) {
|
|
8391
|
+
if (isLiveNode(value)) {
|
|
8392
|
+
value._attach(pool.generateId(), pool);
|
|
8393
|
+
}
|
|
8394
|
+
}
|
|
8395
|
+
}
|
|
8396
|
+
/** @internal */
|
|
8397
|
+
_attachChild(op, source) {
|
|
8398
|
+
if (this._pool === void 0) {
|
|
8399
|
+
throw new Error("Can't attach child if managed pool is not present");
|
|
8400
|
+
}
|
|
8401
|
+
const { id, opId, parentKey: key } = op;
|
|
8402
|
+
const child = creationOpToLson(op);
|
|
8403
|
+
if (this._pool.getNode(id) !== void 0) {
|
|
8404
|
+
if (this.#unackedOpsByKey.get(key) === opId) {
|
|
8405
|
+
this.#unackedOpsByKey.delete(key);
|
|
8406
|
+
}
|
|
8407
|
+
return { modified: false };
|
|
8408
|
+
}
|
|
8409
|
+
if (source === 0 /* LOCAL */) {
|
|
8410
|
+
this.#unackedOpsByKey.set(key, nn(opId));
|
|
8411
|
+
} else if (this.#unackedOpsByKey.get(key) === void 0) {
|
|
8412
|
+
} else if (this.#unackedOpsByKey.get(key) === opId) {
|
|
8413
|
+
this.#unackedOpsByKey.delete(key);
|
|
8414
|
+
return { modified: false };
|
|
8415
|
+
} else {
|
|
8416
|
+
return { modified: false };
|
|
8417
|
+
}
|
|
8418
|
+
const thisId = nn(this._id);
|
|
8419
|
+
const previousValue = this.#synced.get(key);
|
|
8420
|
+
let reverse;
|
|
8421
|
+
if (isLiveNode(previousValue)) {
|
|
8422
|
+
reverse = previousValue._toOps(thisId, key);
|
|
8423
|
+
previousValue._detach();
|
|
8017
8424
|
} else if (previousValue === void 0) {
|
|
8018
8425
|
reverse = [{ type: OpCode.DELETE_OBJECT_KEY, id: thisId, key }];
|
|
8019
8426
|
} else {
|
|
@@ -8025,7 +8432,8 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8025
8432
|
}
|
|
8026
8433
|
];
|
|
8027
8434
|
}
|
|
8028
|
-
this.#
|
|
8435
|
+
this.#local.delete(key);
|
|
8436
|
+
this.#synced.set(key, child);
|
|
8029
8437
|
this.invalidate();
|
|
8030
8438
|
if (isLiveStructure(child)) {
|
|
8031
8439
|
child._setParentLink(this, key);
|
|
@@ -8046,9 +8454,9 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8046
8454
|
const id = nn(this._id);
|
|
8047
8455
|
const parentKey = nn(child._parentKey);
|
|
8048
8456
|
const reverse = child._toOps(id, parentKey);
|
|
8049
|
-
for (const [key, value] of this.#
|
|
8457
|
+
for (const [key, value] of this.#synced) {
|
|
8050
8458
|
if (value === child) {
|
|
8051
|
-
this.#
|
|
8459
|
+
this.#synced.delete(key);
|
|
8052
8460
|
this.invalidate();
|
|
8053
8461
|
}
|
|
8054
8462
|
}
|
|
@@ -8067,7 +8475,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8067
8475
|
/** @internal */
|
|
8068
8476
|
_detach() {
|
|
8069
8477
|
super._detach();
|
|
8070
|
-
for (const value of this.#
|
|
8478
|
+
for (const value of this.#synced.values()) {
|
|
8071
8479
|
if (isLiveNode(value)) {
|
|
8072
8480
|
value._detach();
|
|
8073
8481
|
}
|
|
@@ -8085,7 +8493,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8085
8493
|
/** @internal */
|
|
8086
8494
|
_serialize() {
|
|
8087
8495
|
const data = {};
|
|
8088
|
-
for (const [key, value] of this.#
|
|
8496
|
+
for (const [key, value] of this.#synced) {
|
|
8089
8497
|
if (!isLiveNode(value)) {
|
|
8090
8498
|
data[key] = value;
|
|
8091
8499
|
}
|
|
@@ -8114,7 +8522,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8114
8522
|
data: {}
|
|
8115
8523
|
};
|
|
8116
8524
|
for (const key in op.data) {
|
|
8117
|
-
const oldValue = this.#
|
|
8525
|
+
const oldValue = this.#synced.get(key);
|
|
8118
8526
|
if (isLiveNode(oldValue)) {
|
|
8119
8527
|
for (const childOp of oldValue._toOps(id, key)) {
|
|
8120
8528
|
reverse.push(childOp);
|
|
@@ -8142,13 +8550,14 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8142
8550
|
} else {
|
|
8143
8551
|
continue;
|
|
8144
8552
|
}
|
|
8145
|
-
const oldValue = this.#
|
|
8553
|
+
const oldValue = this.#synced.get(key);
|
|
8146
8554
|
if (isLiveNode(oldValue)) {
|
|
8147
8555
|
oldValue._detach();
|
|
8148
8556
|
}
|
|
8149
8557
|
isModified = true;
|
|
8150
8558
|
updateDelta[key] = { type: "update" };
|
|
8151
|
-
this.#
|
|
8559
|
+
this.#local.delete(key);
|
|
8560
|
+
this.#synced.set(key, value);
|
|
8152
8561
|
this.invalidate();
|
|
8153
8562
|
}
|
|
8154
8563
|
if (Object.keys(reverseUpdate.data).length !== 0) {
|
|
@@ -8165,7 +8574,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8165
8574
|
}
|
|
8166
8575
|
#applyDeleteObjectKey(op, isLocal) {
|
|
8167
8576
|
const key = op.key;
|
|
8168
|
-
const oldValue = this.#
|
|
8577
|
+
const oldValue = this.#synced.get(key);
|
|
8169
8578
|
if (oldValue === void 0) {
|
|
8170
8579
|
return { modified: false };
|
|
8171
8580
|
}
|
|
@@ -8186,7 +8595,8 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8186
8595
|
}
|
|
8187
8596
|
];
|
|
8188
8597
|
}
|
|
8189
|
-
this.#
|
|
8598
|
+
this.#local.delete(key);
|
|
8599
|
+
this.#synced.delete(key);
|
|
8190
8600
|
this.invalidate();
|
|
8191
8601
|
return {
|
|
8192
8602
|
modified: {
|
|
@@ -8199,11 +8609,23 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8199
8609
|
reverse
|
|
8200
8610
|
};
|
|
8201
8611
|
}
|
|
8612
|
+
/** @private */
|
|
8613
|
+
keys() {
|
|
8614
|
+
const result = new Set(this.#synced.keys());
|
|
8615
|
+
for (const key of this.#local.keys()) {
|
|
8616
|
+
result.add(key);
|
|
8617
|
+
}
|
|
8618
|
+
return result;
|
|
8619
|
+
}
|
|
8202
8620
|
/**
|
|
8203
8621
|
* Transform the LiveObject into a javascript object
|
|
8204
8622
|
*/
|
|
8205
8623
|
toObject() {
|
|
8206
|
-
|
|
8624
|
+
const result = Object.fromEntries(this.#synced);
|
|
8625
|
+
for (const [key, value] of this.#local) {
|
|
8626
|
+
result[key] = value;
|
|
8627
|
+
}
|
|
8628
|
+
return result;
|
|
8207
8629
|
}
|
|
8208
8630
|
/**
|
|
8209
8631
|
* Adds or updates a property with a specified key and a value.
|
|
@@ -8211,49 +8633,109 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8211
8633
|
* @param value The value of the property to add
|
|
8212
8634
|
*/
|
|
8213
8635
|
set(key, value) {
|
|
8214
|
-
_optionalChain([this, 'access', _192 => _192._pool, 'optionalAccess', _193 => _193.assertStorageIsWritable, 'call', _194 => _194()]);
|
|
8215
8636
|
this.update({ [key]: value });
|
|
8216
8637
|
}
|
|
8638
|
+
/**
|
|
8639
|
+
* @experimental
|
|
8640
|
+
*
|
|
8641
|
+
* Sets a local-only property that is not synchronized over the wire.
|
|
8642
|
+
* The value will be visible via get(), toObject(), and toImmutable() on
|
|
8643
|
+
* this client only. Other clients and the server will see `undefined`
|
|
8644
|
+
* for this key.
|
|
8645
|
+
*
|
|
8646
|
+
* Caveat: this method will not add changes to the undo/redo stack.
|
|
8647
|
+
*/
|
|
8648
|
+
setLocal(key, value) {
|
|
8649
|
+
_optionalChain([this, 'access', _204 => _204._pool, 'optionalAccess', _205 => _205.assertStorageIsWritable, 'call', _206 => _206()]);
|
|
8650
|
+
const deleteResult = this.#prepareDelete(key);
|
|
8651
|
+
this.#local.set(key, value);
|
|
8652
|
+
this.invalidate();
|
|
8653
|
+
if (this._pool !== void 0 && this._id !== void 0) {
|
|
8654
|
+
const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _207 => _207[0]]), () => ( []));
|
|
8655
|
+
const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _208 => _208[1]]), () => ( []));
|
|
8656
|
+
const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _209 => _209[2]]), () => ( /* @__PURE__ */ new Map()));
|
|
8657
|
+
const existing = storageUpdates.get(this._id);
|
|
8658
|
+
storageUpdates.set(this._id, {
|
|
8659
|
+
node: this,
|
|
8660
|
+
type: "LiveObject",
|
|
8661
|
+
updates: {
|
|
8662
|
+
..._optionalChain([existing, 'optionalAccess', _210 => _210.updates]),
|
|
8663
|
+
[key]: { type: "update" }
|
|
8664
|
+
}
|
|
8665
|
+
});
|
|
8666
|
+
this._pool.dispatch(ops, reverse, storageUpdates);
|
|
8667
|
+
}
|
|
8668
|
+
}
|
|
8217
8669
|
/**
|
|
8218
8670
|
* Returns a specified property from the LiveObject.
|
|
8219
8671
|
* @param key The key of the property to get
|
|
8220
8672
|
*/
|
|
8221
8673
|
get(key) {
|
|
8222
|
-
return this.#
|
|
8674
|
+
return this.#local.has(key) ? this.#local.get(key) : this.#synced.get(key);
|
|
8223
8675
|
}
|
|
8224
8676
|
/**
|
|
8225
|
-
*
|
|
8226
|
-
*
|
|
8677
|
+
* Removes a synced key, returning the ops, reverse ops, and storage updates
|
|
8678
|
+
* needed to notify the pool. Returns null if the key doesn't exist in
|
|
8679
|
+
* #synced or pool/id are unavailable. Does NOT dispatch.
|
|
8227
8680
|
*/
|
|
8228
|
-
|
|
8229
|
-
_optionalChain([this, 'access',
|
|
8230
|
-
const
|
|
8231
|
-
|
|
8681
|
+
#prepareDelete(key) {
|
|
8682
|
+
_optionalChain([this, 'access', _211 => _211._pool, 'optionalAccess', _212 => _212.assertStorageIsWritable, 'call', _213 => _213()]);
|
|
8683
|
+
const k = key;
|
|
8684
|
+
if (this.#local.has(k) && !this.#synced.has(k)) {
|
|
8685
|
+
const oldValue2 = this.#local.get(k);
|
|
8686
|
+
this.#local.delete(k);
|
|
8687
|
+
this.invalidate();
|
|
8688
|
+
if (this._pool !== void 0 && this._id !== void 0) {
|
|
8689
|
+
const storageUpdates2 = /* @__PURE__ */ new Map();
|
|
8690
|
+
storageUpdates2.set(this._id, {
|
|
8691
|
+
node: this,
|
|
8692
|
+
type: "LiveObject",
|
|
8693
|
+
updates: {
|
|
8694
|
+
[k]: {
|
|
8695
|
+
type: "delete",
|
|
8696
|
+
deletedItem: oldValue2
|
|
8697
|
+
}
|
|
8698
|
+
}
|
|
8699
|
+
});
|
|
8700
|
+
return [[], [], storageUpdates2];
|
|
8701
|
+
}
|
|
8702
|
+
return null;
|
|
8703
|
+
}
|
|
8704
|
+
this.#local.delete(k);
|
|
8705
|
+
const oldValue = this.#synced.get(k);
|
|
8232
8706
|
if (oldValue === void 0) {
|
|
8233
|
-
return;
|
|
8707
|
+
return null;
|
|
8234
8708
|
}
|
|
8235
8709
|
if (this._pool === void 0 || this._id === void 0) {
|
|
8236
8710
|
if (isLiveNode(oldValue)) {
|
|
8237
8711
|
oldValue._detach();
|
|
8238
8712
|
}
|
|
8239
|
-
this.#
|
|
8713
|
+
this.#synced.delete(k);
|
|
8240
8714
|
this.invalidate();
|
|
8241
|
-
return;
|
|
8715
|
+
return null;
|
|
8242
8716
|
}
|
|
8717
|
+
const ops = [
|
|
8718
|
+
{
|
|
8719
|
+
type: OpCode.DELETE_OBJECT_KEY,
|
|
8720
|
+
key: k,
|
|
8721
|
+
id: this._id,
|
|
8722
|
+
opId: this._pool.generateOpId()
|
|
8723
|
+
}
|
|
8724
|
+
];
|
|
8243
8725
|
let reverse;
|
|
8244
8726
|
if (isLiveNode(oldValue)) {
|
|
8245
8727
|
oldValue._detach();
|
|
8246
|
-
reverse = oldValue._toOps(this._id,
|
|
8728
|
+
reverse = oldValue._toOps(this._id, k);
|
|
8247
8729
|
} else {
|
|
8248
8730
|
reverse = [
|
|
8249
8731
|
{
|
|
8250
8732
|
type: OpCode.UPDATE_OBJECT,
|
|
8251
|
-
data: { [
|
|
8733
|
+
data: { [k]: oldValue },
|
|
8252
8734
|
id: this._id
|
|
8253
8735
|
}
|
|
8254
8736
|
];
|
|
8255
8737
|
}
|
|
8256
|
-
this.#
|
|
8738
|
+
this.#synced.delete(k);
|
|
8257
8739
|
this.invalidate();
|
|
8258
8740
|
const storageUpdates = /* @__PURE__ */ new Map();
|
|
8259
8741
|
storageUpdates.set(this._id, {
|
|
@@ -8263,28 +8745,28 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8263
8745
|
[key]: { type: "delete", deletedItem: oldValue }
|
|
8264
8746
|
}
|
|
8265
8747
|
});
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
reverse,
|
|
8276
|
-
storageUpdates
|
|
8277
|
-
|
|
8748
|
+
return [ops, reverse, storageUpdates];
|
|
8749
|
+
}
|
|
8750
|
+
/**
|
|
8751
|
+
* Deletes a key from the LiveObject
|
|
8752
|
+
* @param key The key of the property to delete
|
|
8753
|
+
*/
|
|
8754
|
+
delete(key) {
|
|
8755
|
+
const result = this.#prepareDelete(key);
|
|
8756
|
+
if (result) {
|
|
8757
|
+
const [ops, reverse, storageUpdates] = result;
|
|
8758
|
+
_optionalChain([this, 'access', _214 => _214._pool, 'optionalAccess', _215 => _215.dispatch, 'call', _216 => _216(ops, reverse, storageUpdates)]);
|
|
8759
|
+
}
|
|
8278
8760
|
}
|
|
8279
8761
|
/**
|
|
8280
8762
|
* Adds or updates multiple properties at once with an object.
|
|
8281
8763
|
* @param patch The object used to overrides properties
|
|
8282
8764
|
*/
|
|
8283
8765
|
update(patch) {
|
|
8284
|
-
_optionalChain([this, 'access',
|
|
8766
|
+
_optionalChain([this, 'access', _217 => _217._pool, 'optionalAccess', _218 => _218.assertStorageIsWritable, 'call', _219 => _219()]);
|
|
8285
8767
|
if (_LiveObject.detectLargeObjects) {
|
|
8286
8768
|
const data = {};
|
|
8287
|
-
for (const [key, value] of this.#
|
|
8769
|
+
for (const [key, value] of this.#synced) {
|
|
8288
8770
|
if (!isLiveNode(value)) {
|
|
8289
8771
|
data[key] = value;
|
|
8290
8772
|
}
|
|
@@ -8313,14 +8795,15 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8313
8795
|
if (newValue === void 0) {
|
|
8314
8796
|
continue;
|
|
8315
8797
|
}
|
|
8316
|
-
const oldValue = this.#
|
|
8798
|
+
const oldValue = this.#synced.get(key);
|
|
8317
8799
|
if (isLiveNode(oldValue)) {
|
|
8318
8800
|
oldValue._detach();
|
|
8319
8801
|
}
|
|
8320
8802
|
if (isLiveNode(newValue)) {
|
|
8321
8803
|
newValue._setParentLink(this, key);
|
|
8322
8804
|
}
|
|
8323
|
-
this.#
|
|
8805
|
+
this.#local.delete(key);
|
|
8806
|
+
this.#synced.set(key, newValue);
|
|
8324
8807
|
this.invalidate();
|
|
8325
8808
|
}
|
|
8326
8809
|
return;
|
|
@@ -8340,7 +8823,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8340
8823
|
if (newValue === void 0) {
|
|
8341
8824
|
continue;
|
|
8342
8825
|
}
|
|
8343
|
-
const oldValue = this.#
|
|
8826
|
+
const oldValue = this.#synced.get(key);
|
|
8344
8827
|
if (isLiveNode(oldValue)) {
|
|
8345
8828
|
for (const childOp of oldValue._toOps(this._id, key)) {
|
|
8346
8829
|
reverseOps.push(childOp);
|
|
@@ -8372,7 +8855,8 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8372
8855
|
updatedProps[key] = newValue;
|
|
8373
8856
|
this.#unackedOpsByKey.set(key, opId);
|
|
8374
8857
|
}
|
|
8375
|
-
this.#
|
|
8858
|
+
this.#local.delete(key);
|
|
8859
|
+
this.#synced.set(key, newValue);
|
|
8376
8860
|
this.invalidate();
|
|
8377
8861
|
updateDelta[key] = { type: "update" };
|
|
8378
8862
|
}
|
|
@@ -8395,6 +8879,34 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8395
8879
|
});
|
|
8396
8880
|
this._pool.dispatch(ops, reverseOps, storageUpdates);
|
|
8397
8881
|
}
|
|
8882
|
+
/**
|
|
8883
|
+
* Creates a new LiveObject from a plain JSON object, recursively converting
|
|
8884
|
+
* nested objects to LiveObjects and arrays to LiveLists. An optional
|
|
8885
|
+
* SyncConfig controls per-key behavior (local-only, atomic, or deep).
|
|
8886
|
+
*
|
|
8887
|
+
* @private
|
|
8888
|
+
*/
|
|
8889
|
+
static from(obj, config) {
|
|
8890
|
+
if (!isPlainObject(obj)) throw new Error("Expected a JSON object");
|
|
8891
|
+
const liveObj = new _LiveObject({});
|
|
8892
|
+
liveObj.reconcile(obj, config);
|
|
8893
|
+
return liveObj;
|
|
8894
|
+
}
|
|
8895
|
+
/**
|
|
8896
|
+
* Reconciles a LiveObject tree to match the given JSON object and sync
|
|
8897
|
+
* config. Only mutates keys that actually changed. Recursively reconciles
|
|
8898
|
+
* the entire Live tree below it.
|
|
8899
|
+
*
|
|
8900
|
+
* @private
|
|
8901
|
+
*/
|
|
8902
|
+
reconcile(jsonObj, config) {
|
|
8903
|
+
if (this.immutableIs(jsonObj)) return;
|
|
8904
|
+
if (!isPlainObject(jsonObj))
|
|
8905
|
+
throw new Error(
|
|
8906
|
+
"Reconciling the document root expects a plain object value"
|
|
8907
|
+
);
|
|
8908
|
+
reconcileLiveObject(this, jsonObj, config);
|
|
8909
|
+
}
|
|
8398
8910
|
toImmutable() {
|
|
8399
8911
|
return super.toImmutable();
|
|
8400
8912
|
}
|
|
@@ -8409,7 +8921,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8409
8921
|
type: "LiveObject",
|
|
8410
8922
|
id: nodeId,
|
|
8411
8923
|
key,
|
|
8412
|
-
payload: Array.from(this.#
|
|
8924
|
+
payload: Array.from(this.#synced.entries()).map(
|
|
8413
8925
|
([key2, value]) => isLiveNode(value) ? value.toTreeNode(key2) : { type: "Json", id: `${nodeId}:${key2}`, key: key2, payload: value }
|
|
8414
8926
|
)
|
|
8415
8927
|
};
|
|
@@ -8417,20 +8929,27 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8417
8929
|
/** @internal */
|
|
8418
8930
|
_toImmutable() {
|
|
8419
8931
|
const result = {};
|
|
8420
|
-
for (const [key, val] of this.#
|
|
8932
|
+
for (const [key, val] of this.#synced) {
|
|
8421
8933
|
result[key] = isLiveStructure(val) ? val.toImmutable() : val;
|
|
8422
8934
|
}
|
|
8935
|
+
for (const [key, val] of this.#local) {
|
|
8936
|
+
result[key] = val;
|
|
8937
|
+
}
|
|
8423
8938
|
return process.env.NODE_ENV === "production" ? result : Object.freeze(result);
|
|
8424
8939
|
}
|
|
8425
8940
|
clone() {
|
|
8426
|
-
|
|
8941
|
+
const cloned = new _LiveObject(
|
|
8427
8942
|
Object.fromEntries(
|
|
8428
|
-
Array.from(this.#
|
|
8943
|
+
Array.from(this.#synced).map(([key, value]) => [
|
|
8429
8944
|
key,
|
|
8430
8945
|
isLiveStructure(value) ? value.clone() : deepClone(value)
|
|
8431
8946
|
])
|
|
8432
8947
|
)
|
|
8433
8948
|
);
|
|
8949
|
+
for (const [key, value] of this.#local) {
|
|
8950
|
+
cloned.#local.set(key, deepClone(value));
|
|
8951
|
+
}
|
|
8952
|
+
return cloned;
|
|
8434
8953
|
}
|
|
8435
8954
|
}, _class2.__initStatic(), _class2);
|
|
8436
8955
|
|
|
@@ -8730,17 +9249,6 @@ var Deque = class {
|
|
|
8730
9249
|
}
|
|
8731
9250
|
};
|
|
8732
9251
|
|
|
8733
|
-
// src/lib/Json.ts
|
|
8734
|
-
function isJsonScalar(data) {
|
|
8735
|
-
return data === null || typeof data === "string" || typeof data === "number" || typeof data === "boolean";
|
|
8736
|
-
}
|
|
8737
|
-
function isJsonArray(data) {
|
|
8738
|
-
return Array.isArray(data);
|
|
8739
|
-
}
|
|
8740
|
-
function isJsonObject(data) {
|
|
8741
|
-
return !isJsonScalar(data) && !isJsonArray(data);
|
|
8742
|
-
}
|
|
8743
|
-
|
|
8744
9252
|
// src/lib/stopwatch.ts
|
|
8745
9253
|
function makeStopWatch() {
|
|
8746
9254
|
let startTime = 0;
|
|
@@ -9038,15 +9546,15 @@ function installBackgroundTabSpy() {
|
|
|
9038
9546
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
9039
9547
|
const inBackgroundSince = { current: null };
|
|
9040
9548
|
function onVisibilityChange() {
|
|
9041
|
-
if (_optionalChain([doc, 'optionalAccess',
|
|
9549
|
+
if (_optionalChain([doc, 'optionalAccess', _220 => _220.visibilityState]) === "hidden") {
|
|
9042
9550
|
inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
|
|
9043
9551
|
} else {
|
|
9044
9552
|
inBackgroundSince.current = null;
|
|
9045
9553
|
}
|
|
9046
9554
|
}
|
|
9047
|
-
_optionalChain([doc, 'optionalAccess',
|
|
9555
|
+
_optionalChain([doc, 'optionalAccess', _221 => _221.addEventListener, 'call', _222 => _222("visibilitychange", onVisibilityChange)]);
|
|
9048
9556
|
const unsub = () => {
|
|
9049
|
-
_optionalChain([doc, 'optionalAccess',
|
|
9557
|
+
_optionalChain([doc, 'optionalAccess', _223 => _223.removeEventListener, 'call', _224 => _224("visibilitychange", onVisibilityChange)]);
|
|
9050
9558
|
};
|
|
9051
9559
|
return [inBackgroundSince, unsub];
|
|
9052
9560
|
}
|
|
@@ -9226,14 +9734,18 @@ function createRoom(options, config) {
|
|
|
9226
9734
|
}
|
|
9227
9735
|
context.activeBatch.reverseOps.pushLeft(reverse);
|
|
9228
9736
|
} else {
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9737
|
+
if (reverse.length > 0) {
|
|
9738
|
+
addToUndoStack(reverse);
|
|
9739
|
+
}
|
|
9740
|
+
if (ops.length > 0) {
|
|
9741
|
+
context.redoStack.length = 0;
|
|
9742
|
+
dispatchOps(ops);
|
|
9743
|
+
}
|
|
9232
9744
|
notify({ storageUpdates });
|
|
9233
9745
|
}
|
|
9234
9746
|
}
|
|
9235
9747
|
function isStorageWritable() {
|
|
9236
|
-
const scopes = _optionalChain([context, 'access',
|
|
9748
|
+
const scopes = _optionalChain([context, 'access', _225 => _225.dynamicSessionInfoSig, 'access', _226 => _226.get, 'call', _227 => _227(), 'optionalAccess', _228 => _228.scopes]);
|
|
9237
9749
|
return scopes !== void 0 ? canWriteStorage(scopes) : true;
|
|
9238
9750
|
}
|
|
9239
9751
|
const eventHub = {
|
|
@@ -9336,20 +9848,21 @@ function createRoom(options, config) {
|
|
|
9336
9848
|
context.pool
|
|
9337
9849
|
);
|
|
9338
9850
|
}
|
|
9339
|
-
const canWrite = _nullishCoalesce(_optionalChain([self, 'access',
|
|
9340
|
-
const
|
|
9341
|
-
|
|
9342
|
-
|
|
9343
|
-
if (
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9851
|
+
const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _229 => _229.get, 'call', _230 => _230(), 'optionalAccess', _231 => _231.canWrite]), () => ( true));
|
|
9852
|
+
const root = context.root;
|
|
9853
|
+
withoutHistory(() => {
|
|
9854
|
+
for (const key in context.initialStorage) {
|
|
9855
|
+
if (root.get(key) === void 0) {
|
|
9856
|
+
if (canWrite) {
|
|
9857
|
+
root.set(key, cloneLson(context.initialStorage[key]));
|
|
9858
|
+
} else {
|
|
9859
|
+
warn(
|
|
9860
|
+
`Attempted to populate missing storage key '${key}', but current user has no write access`
|
|
9861
|
+
);
|
|
9862
|
+
}
|
|
9349
9863
|
}
|
|
9350
9864
|
}
|
|
9351
|
-
}
|
|
9352
|
-
context.undoStack.length = stackSizeBefore;
|
|
9865
|
+
});
|
|
9353
9866
|
}
|
|
9354
9867
|
function _addToRealUndoStack(frames) {
|
|
9355
9868
|
if (context.undoStack.length >= 50) {
|
|
@@ -9540,7 +10053,7 @@ function createRoom(options, config) {
|
|
|
9540
10053
|
}
|
|
9541
10054
|
context.myPresence.patch(patch);
|
|
9542
10055
|
if (context.activeBatch) {
|
|
9543
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10056
|
+
if (_optionalChain([options2, 'optionalAccess', _232 => _232.addToHistory])) {
|
|
9544
10057
|
context.activeBatch.reverseOps.pushLeft({
|
|
9545
10058
|
type: "presence",
|
|
9546
10059
|
data: oldValues
|
|
@@ -9549,7 +10062,7 @@ function createRoom(options, config) {
|
|
|
9549
10062
|
context.activeBatch.updates.presence = true;
|
|
9550
10063
|
} else {
|
|
9551
10064
|
flushNowOrSoon();
|
|
9552
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10065
|
+
if (_optionalChain([options2, 'optionalAccess', _233 => _233.addToHistory])) {
|
|
9553
10066
|
addToUndoStack([{ type: "presence", data: oldValues }]);
|
|
9554
10067
|
}
|
|
9555
10068
|
notify({ presence: true });
|
|
@@ -9723,11 +10236,11 @@ function createRoom(options, config) {
|
|
|
9723
10236
|
break;
|
|
9724
10237
|
}
|
|
9725
10238
|
case ServerMsgCode.STORAGE_CHUNK:
|
|
9726
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
10239
|
+
_optionalChain([stopwatch, 'optionalAccess', _234 => _234.lap, 'call', _235 => _235()]);
|
|
9727
10240
|
nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
|
|
9728
10241
|
break;
|
|
9729
10242
|
case ServerMsgCode.STORAGE_STREAM_END: {
|
|
9730
|
-
const timing = _optionalChain([stopwatch, 'optionalAccess',
|
|
10243
|
+
const timing = _optionalChain([stopwatch, 'optionalAccess', _236 => _236.stop, 'call', _237 => _237()]);
|
|
9731
10244
|
if (timing) {
|
|
9732
10245
|
const ms = (v) => `${v.toFixed(1)}ms`;
|
|
9733
10246
|
const rest = timing.laps.slice(1);
|
|
@@ -9890,7 +10403,7 @@ function createRoom(options, config) {
|
|
|
9890
10403
|
const unacknowledgedOps = new Map(context.unacknowledgedOps);
|
|
9891
10404
|
createOrUpdateRootFromMessage(nodes);
|
|
9892
10405
|
applyAndSendOfflineOps(unacknowledgedOps);
|
|
9893
|
-
_optionalChain([_resolveStoragePromise, 'optionalCall',
|
|
10406
|
+
_optionalChain([_resolveStoragePromise, 'optionalCall', _238 => _238()]);
|
|
9894
10407
|
notifyStorageStatus();
|
|
9895
10408
|
eventHub.storageDidLoad.notify();
|
|
9896
10409
|
}
|
|
@@ -9908,7 +10421,7 @@ function createRoom(options, config) {
|
|
|
9908
10421
|
} else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
|
|
9909
10422
|
messages.push({ type: ClientMsgCode.FETCH_STORAGE });
|
|
9910
10423
|
nodeMapBuffer.take();
|
|
9911
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
10424
|
+
_optionalChain([stopwatch, 'optionalAccess', _239 => _239.start, 'call', _240 => _240()]);
|
|
9912
10425
|
}
|
|
9913
10426
|
if (options2.flush) {
|
|
9914
10427
|
flushNowOrSoon();
|
|
@@ -10042,6 +10555,16 @@ function createRoom(options, config) {
|
|
|
10042
10555
|
_addToRealUndoStack(Array.from(frames));
|
|
10043
10556
|
}
|
|
10044
10557
|
}
|
|
10558
|
+
function withoutHistory(fn) {
|
|
10559
|
+
const undoBefore = context.undoStack.length;
|
|
10560
|
+
const redoBefore = context.redoStack.length;
|
|
10561
|
+
try {
|
|
10562
|
+
return fn();
|
|
10563
|
+
} finally {
|
|
10564
|
+
context.undoStack.length = undoBefore;
|
|
10565
|
+
context.redoStack.length = redoBefore;
|
|
10566
|
+
}
|
|
10567
|
+
}
|
|
10045
10568
|
const syncSourceForStorage = config.createSyncSource();
|
|
10046
10569
|
function getStorageStatus() {
|
|
10047
10570
|
if (context.root === void 0) {
|
|
@@ -10111,8 +10634,8 @@ function createRoom(options, config) {
|
|
|
10111
10634
|
async function getThreads(options2) {
|
|
10112
10635
|
return httpClient.getThreads({
|
|
10113
10636
|
roomId,
|
|
10114
|
-
query: _optionalChain([options2, 'optionalAccess',
|
|
10115
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
10637
|
+
query: _optionalChain([options2, 'optionalAccess', _241 => _241.query]),
|
|
10638
|
+
cursor: _optionalChain([options2, 'optionalAccess', _242 => _242.cursor])
|
|
10116
10639
|
});
|
|
10117
10640
|
}
|
|
10118
10641
|
async function getThread(threadId) {
|
|
@@ -10234,7 +10757,7 @@ function createRoom(options, config) {
|
|
|
10234
10757
|
function getSubscriptionSettings(options2) {
|
|
10235
10758
|
return httpClient.getSubscriptionSettings({
|
|
10236
10759
|
roomId,
|
|
10237
|
-
signal: _optionalChain([options2, 'optionalAccess',
|
|
10760
|
+
signal: _optionalChain([options2, 'optionalAccess', _243 => _243.signal])
|
|
10238
10761
|
});
|
|
10239
10762
|
}
|
|
10240
10763
|
function updateSubscriptionSettings(settings) {
|
|
@@ -10256,7 +10779,7 @@ function createRoom(options, config) {
|
|
|
10256
10779
|
{
|
|
10257
10780
|
[kInternal]: {
|
|
10258
10781
|
get presenceBuffer() {
|
|
10259
|
-
return deepClone(_nullishCoalesce(_optionalChain([context, 'access',
|
|
10782
|
+
return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _244 => _244.buffer, 'access', _245 => _245.presenceUpdates, 'optionalAccess', _246 => _246.data]), () => ( null)));
|
|
10260
10783
|
},
|
|
10261
10784
|
// prettier-ignore
|
|
10262
10785
|
get undoStack() {
|
|
@@ -10271,9 +10794,9 @@ function createRoom(options, config) {
|
|
|
10271
10794
|
return context.yjsProvider;
|
|
10272
10795
|
},
|
|
10273
10796
|
setYjsProvider(newProvider) {
|
|
10274
|
-
_optionalChain([context, 'access',
|
|
10797
|
+
_optionalChain([context, 'access', _247 => _247.yjsProvider, 'optionalAccess', _248 => _248.off, 'call', _249 => _249("status", yjsStatusDidChange)]);
|
|
10275
10798
|
context.yjsProvider = newProvider;
|
|
10276
|
-
_optionalChain([newProvider, 'optionalAccess',
|
|
10799
|
+
_optionalChain([newProvider, 'optionalAccess', _250 => _250.on, 'call', _251 => _251("status", yjsStatusDidChange)]);
|
|
10277
10800
|
context.yjsProviderDidChange.notify();
|
|
10278
10801
|
},
|
|
10279
10802
|
yjsProviderDidChange: context.yjsProviderDidChange.observable,
|
|
@@ -10320,7 +10843,7 @@ function createRoom(options, config) {
|
|
|
10320
10843
|
source.dispose();
|
|
10321
10844
|
}
|
|
10322
10845
|
eventHub.roomWillDestroy.notify();
|
|
10323
|
-
_optionalChain([context, 'access',
|
|
10846
|
+
_optionalChain([context, 'access', _252 => _252.yjsProvider, 'optionalAccess', _253 => _253.off, 'call', _254 => _254("status", yjsStatusDidChange)]);
|
|
10324
10847
|
syncSourceForStorage.destroy();
|
|
10325
10848
|
syncSourceForYjs.destroy();
|
|
10326
10849
|
uninstallBgTabSpy();
|
|
@@ -10340,7 +10863,10 @@ function createRoom(options, config) {
|
|
|
10340
10863
|
canRedo,
|
|
10341
10864
|
clear,
|
|
10342
10865
|
pause: pauseHistory,
|
|
10343
|
-
resume: resumeHistory
|
|
10866
|
+
resume: resumeHistory,
|
|
10867
|
+
[kInternal]: {
|
|
10868
|
+
withoutHistory
|
|
10869
|
+
}
|
|
10344
10870
|
},
|
|
10345
10871
|
fetchYDoc,
|
|
10346
10872
|
getStorage,
|
|
@@ -10471,7 +10997,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
|
|
|
10471
10997
|
}
|
|
10472
10998
|
if (isLiveNode(first)) {
|
|
10473
10999
|
const node = first;
|
|
10474
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
11000
|
+
if (_optionalChain([options, 'optionalAccess', _255 => _255.isDeep])) {
|
|
10475
11001
|
const storageCallback = second;
|
|
10476
11002
|
return subscribeToLiveStructureDeeply(node, storageCallback);
|
|
10477
11003
|
} else {
|
|
@@ -10557,8 +11083,8 @@ function createClient(options) {
|
|
|
10557
11083
|
const authManager = createAuthManager(options, (token) => {
|
|
10558
11084
|
currentUserId.set(() => token.uid);
|
|
10559
11085
|
});
|
|
10560
|
-
const fetchPolyfill = _optionalChain([clientOptions, 'access',
|
|
10561
|
-
_optionalChain([globalThis, 'access',
|
|
11086
|
+
const fetchPolyfill = _optionalChain([clientOptions, 'access', _256 => _256.polyfills, 'optionalAccess', _257 => _257.fetch]) || /* istanbul ignore next */
|
|
11087
|
+
_optionalChain([globalThis, 'access', _258 => _258.fetch, 'optionalAccess', _259 => _259.bind, 'call', _260 => _260(globalThis)]);
|
|
10562
11088
|
const httpClient = createApiClient({
|
|
10563
11089
|
baseUrl,
|
|
10564
11090
|
fetchPolyfill,
|
|
@@ -10576,7 +11102,7 @@ function createClient(options) {
|
|
|
10576
11102
|
delegates: {
|
|
10577
11103
|
createSocket: makeCreateSocketDelegateForAi(
|
|
10578
11104
|
baseUrl,
|
|
10579
|
-
_optionalChain([clientOptions, 'access',
|
|
11105
|
+
_optionalChain([clientOptions, 'access', _261 => _261.polyfills, 'optionalAccess', _262 => _262.WebSocket])
|
|
10580
11106
|
),
|
|
10581
11107
|
authenticate: async () => {
|
|
10582
11108
|
const resp = await authManager.getAuthValue({
|
|
@@ -10636,7 +11162,7 @@ function createClient(options) {
|
|
|
10636
11162
|
createSocket: makeCreateSocketDelegateForRoom(
|
|
10637
11163
|
roomId,
|
|
10638
11164
|
baseUrl,
|
|
10639
|
-
_optionalChain([clientOptions, 'access',
|
|
11165
|
+
_optionalChain([clientOptions, 'access', _263 => _263.polyfills, 'optionalAccess', _264 => _264.WebSocket])
|
|
10640
11166
|
),
|
|
10641
11167
|
authenticate: makeAuthDelegateForRoom(roomId, authManager)
|
|
10642
11168
|
})),
|
|
@@ -10659,7 +11185,7 @@ function createClient(options) {
|
|
|
10659
11185
|
const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
|
|
10660
11186
|
if (shouldConnect) {
|
|
10661
11187
|
if (typeof atob === "undefined") {
|
|
10662
|
-
if (_optionalChain([clientOptions, 'access',
|
|
11188
|
+
if (_optionalChain([clientOptions, 'access', _265 => _265.polyfills, 'optionalAccess', _266 => _266.atob]) === void 0) {
|
|
10663
11189
|
throw new Error(
|
|
10664
11190
|
"You need to polyfill atob to use the client in your environment. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/atob-polyfill"
|
|
10665
11191
|
);
|
|
@@ -10671,7 +11197,7 @@ function createClient(options) {
|
|
|
10671
11197
|
return leaseRoom(newRoomDetails);
|
|
10672
11198
|
}
|
|
10673
11199
|
function getRoom(roomId) {
|
|
10674
|
-
const room = _optionalChain([roomsById, 'access',
|
|
11200
|
+
const room = _optionalChain([roomsById, 'access', _267 => _267.get, 'call', _268 => _268(roomId), 'optionalAccess', _269 => _269.room]);
|
|
10675
11201
|
return room ? room : null;
|
|
10676
11202
|
}
|
|
10677
11203
|
function logout() {
|
|
@@ -10687,7 +11213,7 @@ function createClient(options) {
|
|
|
10687
11213
|
const batchedResolveUsers = new Batch(
|
|
10688
11214
|
async (batchedUserIds) => {
|
|
10689
11215
|
const userIds = batchedUserIds.flat();
|
|
10690
|
-
const users = await _optionalChain([resolveUsers, 'optionalCall',
|
|
11216
|
+
const users = await _optionalChain([resolveUsers, 'optionalCall', _270 => _270({ userIds })]);
|
|
10691
11217
|
warnOnceIf(
|
|
10692
11218
|
!resolveUsers,
|
|
10693
11219
|
"Set the resolveUsers option in createClient to specify user info."
|
|
@@ -10704,7 +11230,7 @@ function createClient(options) {
|
|
|
10704
11230
|
const batchedResolveRoomsInfo = new Batch(
|
|
10705
11231
|
async (batchedRoomIds) => {
|
|
10706
11232
|
const roomIds = batchedRoomIds.flat();
|
|
10707
|
-
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall',
|
|
11233
|
+
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _271 => _271({ roomIds })]);
|
|
10708
11234
|
warnOnceIf(
|
|
10709
11235
|
!resolveRoomsInfo,
|
|
10710
11236
|
"Set the resolveRoomsInfo option in createClient to specify room info."
|
|
@@ -10721,7 +11247,7 @@ function createClient(options) {
|
|
|
10721
11247
|
const batchedResolveGroupsInfo = new Batch(
|
|
10722
11248
|
async (batchedGroupIds) => {
|
|
10723
11249
|
const groupIds = batchedGroupIds.flat();
|
|
10724
|
-
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall',
|
|
11250
|
+
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _272 => _272({ groupIds })]);
|
|
10725
11251
|
warnOnceIf(
|
|
10726
11252
|
!resolveGroupsInfo,
|
|
10727
11253
|
"Set the resolveGroupsInfo option in createClient to specify group info."
|
|
@@ -10777,7 +11303,7 @@ function createClient(options) {
|
|
|
10777
11303
|
}
|
|
10778
11304
|
};
|
|
10779
11305
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
10780
|
-
_optionalChain([win, 'optionalAccess',
|
|
11306
|
+
_optionalChain([win, 'optionalAccess', _273 => _273.addEventListener, 'call', _274 => _274("beforeunload", maybePreventClose)]);
|
|
10781
11307
|
}
|
|
10782
11308
|
async function getNotificationSettings(options2) {
|
|
10783
11309
|
const plainSettings = await httpClient.getNotificationSettings(options2);
|
|
@@ -10904,7 +11430,7 @@ var commentBodyElementsTypes = {
|
|
|
10904
11430
|
mention: "inline"
|
|
10905
11431
|
};
|
|
10906
11432
|
function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
10907
|
-
if (!body || !_optionalChain([body, 'optionalAccess',
|
|
11433
|
+
if (!body || !_optionalChain([body, 'optionalAccess', _275 => _275.content])) {
|
|
10908
11434
|
return;
|
|
10909
11435
|
}
|
|
10910
11436
|
const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
|
|
@@ -10914,13 +11440,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
|
10914
11440
|
for (const block of body.content) {
|
|
10915
11441
|
if (type === "all" || type === "block") {
|
|
10916
11442
|
if (guard(block)) {
|
|
10917
|
-
_optionalChain([visitor, 'optionalCall',
|
|
11443
|
+
_optionalChain([visitor, 'optionalCall', _276 => _276(block)]);
|
|
10918
11444
|
}
|
|
10919
11445
|
}
|
|
10920
11446
|
if (type === "all" || type === "inline") {
|
|
10921
11447
|
for (const inline of block.children) {
|
|
10922
11448
|
if (guard(inline)) {
|
|
10923
|
-
_optionalChain([visitor, 'optionalCall',
|
|
11449
|
+
_optionalChain([visitor, 'optionalCall', _277 => _277(inline)]);
|
|
10924
11450
|
}
|
|
10925
11451
|
}
|
|
10926
11452
|
}
|
|
@@ -11090,7 +11616,7 @@ var stringifyCommentBodyPlainElements = {
|
|
|
11090
11616
|
text: ({ element }) => element.text,
|
|
11091
11617
|
link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
|
|
11092
11618
|
mention: ({ element, user, group }) => {
|
|
11093
|
-
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
11619
|
+
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _278 => _278.name]), () => ( _optionalChain([group, 'optionalAccess', _279 => _279.name]))), () => ( element.id))}`;
|
|
11094
11620
|
}
|
|
11095
11621
|
};
|
|
11096
11622
|
var stringifyCommentBodyHtmlElements = {
|
|
@@ -11120,7 +11646,7 @@ var stringifyCommentBodyHtmlElements = {
|
|
|
11120
11646
|
return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
|
|
11121
11647
|
},
|
|
11122
11648
|
mention: ({ element, user, group }) => {
|
|
11123
|
-
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess',
|
|
11649
|
+
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _280 => _280.name]) ? html`${_optionalChain([user, 'optionalAccess', _281 => _281.name])}` : _optionalChain([group, 'optionalAccess', _282 => _282.name]) ? html`${_optionalChain([group, 'optionalAccess', _283 => _283.name])}` : element.id}</span>`;
|
|
11124
11650
|
}
|
|
11125
11651
|
};
|
|
11126
11652
|
var stringifyCommentBodyMarkdownElements = {
|
|
@@ -11130,426 +11656,123 @@ var stringifyCommentBodyMarkdownElements = {
|
|
|
11130
11656
|
text: ({ element }) => {
|
|
11131
11657
|
let children = element.text;
|
|
11132
11658
|
if (!children) {
|
|
11133
|
-
return children;
|
|
11134
|
-
}
|
|
11135
|
-
if (element.bold) {
|
|
11136
|
-
children = markdown`**${children}**`;
|
|
11137
|
-
}
|
|
11138
|
-
if (element.italic) {
|
|
11139
|
-
children = markdown`_${children}_`;
|
|
11140
|
-
}
|
|
11141
|
-
if (element.strikethrough) {
|
|
11142
|
-
children = markdown`~~${children}~~`;
|
|
11143
|
-
}
|
|
11144
|
-
if (element.code) {
|
|
11145
|
-
children = markdown`\`${children}\``;
|
|
11146
|
-
}
|
|
11147
|
-
return children;
|
|
11148
|
-
},
|
|
11149
|
-
link: ({ element, href }) => {
|
|
11150
|
-
return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
|
|
11151
|
-
},
|
|
11152
|
-
mention: ({ element, user, group }) => {
|
|
11153
|
-
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _265 => _265.name]), () => ( _optionalChain([group, 'optionalAccess', _266 => _266.name]))), () => ( element.id))}`;
|
|
11154
|
-
}
|
|
11155
|
-
};
|
|
11156
|
-
async function stringifyCommentBody(body, options) {
|
|
11157
|
-
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _267 => _267.format]), () => ( "plain"));
|
|
11158
|
-
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _268 => _268.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
|
|
11159
|
-
const elements = {
|
|
11160
|
-
...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
|
|
11161
|
-
..._optionalChain([options, 'optionalAccess', _269 => _269.elements])
|
|
11162
|
-
};
|
|
11163
|
-
const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
|
|
11164
|
-
body,
|
|
11165
|
-
_optionalChain([options, 'optionalAccess', _270 => _270.resolveUsers]),
|
|
11166
|
-
_optionalChain([options, 'optionalAccess', _271 => _271.resolveGroupsInfo])
|
|
11167
|
-
);
|
|
11168
|
-
const blocks = body.content.flatMap((block, blockIndex) => {
|
|
11169
|
-
switch (block.type) {
|
|
11170
|
-
case "paragraph": {
|
|
11171
|
-
const inlines = block.children.flatMap((inline, inlineIndex) => {
|
|
11172
|
-
if (isCommentBodyMention(inline)) {
|
|
11173
|
-
return inline.id ? [
|
|
11174
|
-
elements.mention(
|
|
11175
|
-
{
|
|
11176
|
-
element: inline,
|
|
11177
|
-
user: inline.kind === "user" ? resolvedUsers.get(inline.id) : void 0,
|
|
11178
|
-
group: inline.kind === "group" ? resolvedGroupsInfo.get(inline.id) : void 0
|
|
11179
|
-
},
|
|
11180
|
-
inlineIndex
|
|
11181
|
-
)
|
|
11182
|
-
] : [];
|
|
11183
|
-
}
|
|
11184
|
-
if (isCommentBodyLink(inline)) {
|
|
11185
|
-
const href = sanitizeUrl(inline.url);
|
|
11186
|
-
if (href === null) {
|
|
11187
|
-
return [
|
|
11188
|
-
elements.text(
|
|
11189
|
-
{
|
|
11190
|
-
element: { text: _nullishCoalesce(inline.text, () => ( inline.url)) }
|
|
11191
|
-
},
|
|
11192
|
-
inlineIndex
|
|
11193
|
-
)
|
|
11194
|
-
];
|
|
11195
|
-
}
|
|
11196
|
-
return [
|
|
11197
|
-
elements.link(
|
|
11198
|
-
{
|
|
11199
|
-
element: inline,
|
|
11200
|
-
href
|
|
11201
|
-
},
|
|
11202
|
-
inlineIndex
|
|
11203
|
-
)
|
|
11204
|
-
];
|
|
11205
|
-
}
|
|
11206
|
-
if (isCommentBodyText(inline)) {
|
|
11207
|
-
return [elements.text({ element: inline }, inlineIndex)];
|
|
11208
|
-
}
|
|
11209
|
-
return [];
|
|
11210
|
-
});
|
|
11211
|
-
return [
|
|
11212
|
-
elements.paragraph(
|
|
11213
|
-
{ element: block, children: inlines.join("") },
|
|
11214
|
-
blockIndex
|
|
11215
|
-
)
|
|
11216
|
-
];
|
|
11217
|
-
}
|
|
11218
|
-
default:
|
|
11219
|
-
return [];
|
|
11220
|
-
}
|
|
11221
|
-
});
|
|
11222
|
-
return blocks.join(separator);
|
|
11223
|
-
}
|
|
11224
|
-
|
|
11225
|
-
// src/crdts/utils.ts
|
|
11226
|
-
function toPlainLson(lson) {
|
|
11227
|
-
if (lson instanceof LiveObject) {
|
|
11228
|
-
return {
|
|
11229
|
-
liveblocksType: "LiveObject",
|
|
11230
|
-
data: Object.fromEntries(
|
|
11231
|
-
Object.entries(lson.toObject()).flatMap(
|
|
11232
|
-
([key, value]) => value !== void 0 ? [[key, toPlainLson(value)]] : []
|
|
11233
|
-
)
|
|
11234
|
-
)
|
|
11235
|
-
};
|
|
11236
|
-
} else if (lson instanceof LiveMap) {
|
|
11237
|
-
return {
|
|
11238
|
-
liveblocksType: "LiveMap",
|
|
11239
|
-
data: Object.fromEntries(
|
|
11240
|
-
[...lson].map(([key, value]) => [key, toPlainLson(value)])
|
|
11241
|
-
)
|
|
11242
|
-
};
|
|
11243
|
-
} else if (lson instanceof LiveList) {
|
|
11244
|
-
return {
|
|
11245
|
-
liveblocksType: "LiveList",
|
|
11246
|
-
data: [...lson].map((item) => toPlainLson(item))
|
|
11247
|
-
};
|
|
11248
|
-
} else {
|
|
11249
|
-
return lson;
|
|
11250
|
-
}
|
|
11251
|
-
}
|
|
11252
|
-
|
|
11253
|
-
// src/immutable.ts
|
|
11254
|
-
function lsonObjectToJson(obj) {
|
|
11255
|
-
const result = {};
|
|
11256
|
-
for (const key in obj) {
|
|
11257
|
-
const val = obj[key];
|
|
11258
|
-
if (val !== void 0) {
|
|
11259
|
-
result[key] = lsonToJson(val);
|
|
11260
|
-
}
|
|
11261
|
-
}
|
|
11262
|
-
return result;
|
|
11263
|
-
}
|
|
11264
|
-
function liveObjectToJson(liveObject) {
|
|
11265
|
-
return lsonObjectToJson(liveObject.toObject());
|
|
11266
|
-
}
|
|
11267
|
-
function liveMapToJson(map) {
|
|
11268
|
-
const result = {};
|
|
11269
|
-
for (const [key, value] of map.entries()) {
|
|
11270
|
-
result[key] = lsonToJson(value);
|
|
11271
|
-
}
|
|
11272
|
-
return result;
|
|
11273
|
-
}
|
|
11274
|
-
function lsonListToJson(value) {
|
|
11275
|
-
return value.map(lsonToJson);
|
|
11276
|
-
}
|
|
11277
|
-
function liveListToJson(value) {
|
|
11278
|
-
return lsonListToJson(value.toArray());
|
|
11279
|
-
}
|
|
11280
|
-
function lsonToJson(value) {
|
|
11281
|
-
if (value instanceof LiveObject) {
|
|
11282
|
-
return liveObjectToJson(value);
|
|
11283
|
-
} else if (value instanceof LiveList) {
|
|
11284
|
-
return liveListToJson(value);
|
|
11285
|
-
} else if (value instanceof LiveMap) {
|
|
11286
|
-
return liveMapToJson(value);
|
|
11287
|
-
} else if (value instanceof LiveRegister) {
|
|
11288
|
-
return value.data;
|
|
11289
|
-
}
|
|
11290
|
-
if (Array.isArray(value)) {
|
|
11291
|
-
return lsonListToJson(value);
|
|
11292
|
-
} else if (isPlainObject(value)) {
|
|
11293
|
-
return lsonObjectToJson(value);
|
|
11294
|
-
}
|
|
11295
|
-
return value;
|
|
11296
|
-
}
|
|
11297
|
-
function deepLiveify(value) {
|
|
11298
|
-
if (Array.isArray(value)) {
|
|
11299
|
-
return new LiveList(value.map(deepLiveify));
|
|
11300
|
-
} else if (isPlainObject(value)) {
|
|
11301
|
-
const init = {};
|
|
11302
|
-
for (const key in value) {
|
|
11303
|
-
const val = value[key];
|
|
11304
|
-
if (val === void 0) {
|
|
11305
|
-
continue;
|
|
11306
|
-
}
|
|
11307
|
-
init[key] = deepLiveify(val);
|
|
11308
|
-
}
|
|
11309
|
-
return new LiveObject(init);
|
|
11310
|
-
} else {
|
|
11311
|
-
return value;
|
|
11312
|
-
}
|
|
11313
|
-
}
|
|
11314
|
-
function patchLiveList(liveList, prev, next) {
|
|
11315
|
-
let i = 0;
|
|
11316
|
-
let prevEnd = prev.length - 1;
|
|
11317
|
-
let nextEnd = next.length - 1;
|
|
11318
|
-
let prevNode = prev[0];
|
|
11319
|
-
let nextNode = next[0];
|
|
11320
|
-
outer: {
|
|
11321
|
-
while (prevNode === nextNode) {
|
|
11322
|
-
++i;
|
|
11323
|
-
if (i > prevEnd || i > nextEnd) {
|
|
11324
|
-
break outer;
|
|
11325
|
-
}
|
|
11326
|
-
prevNode = prev[i];
|
|
11327
|
-
nextNode = next[i];
|
|
11328
|
-
}
|
|
11329
|
-
prevNode = prev[prevEnd];
|
|
11330
|
-
nextNode = next[nextEnd];
|
|
11331
|
-
while (prevNode === nextNode) {
|
|
11332
|
-
prevEnd--;
|
|
11333
|
-
nextEnd--;
|
|
11334
|
-
if (i > prevEnd || i > nextEnd) {
|
|
11335
|
-
break outer;
|
|
11336
|
-
}
|
|
11337
|
-
prevNode = prev[prevEnd];
|
|
11338
|
-
nextNode = next[nextEnd];
|
|
11339
|
-
}
|
|
11340
|
-
}
|
|
11341
|
-
if (i > prevEnd) {
|
|
11342
|
-
if (i <= nextEnd) {
|
|
11343
|
-
while (i <= nextEnd) {
|
|
11344
|
-
liveList.insert(deepLiveify(next[i]), i);
|
|
11345
|
-
i++;
|
|
11346
|
-
}
|
|
11347
|
-
}
|
|
11348
|
-
} else if (i > nextEnd) {
|
|
11349
|
-
let localI = i;
|
|
11350
|
-
while (localI <= prevEnd) {
|
|
11351
|
-
liveList.delete(i);
|
|
11352
|
-
localI++;
|
|
11353
|
-
}
|
|
11354
|
-
} else {
|
|
11355
|
-
while (i <= prevEnd && i <= nextEnd) {
|
|
11356
|
-
prevNode = prev[i];
|
|
11357
|
-
nextNode = next[i];
|
|
11358
|
-
const liveListNode = liveList.get(i);
|
|
11359
|
-
if (isLiveObject(liveListNode) && isPlainObject(prevNode) && isPlainObject(nextNode)) {
|
|
11360
|
-
patchLiveObject(liveListNode, prevNode, nextNode);
|
|
11361
|
-
} else {
|
|
11362
|
-
liveList.set(i, deepLiveify(nextNode));
|
|
11363
|
-
}
|
|
11364
|
-
i++;
|
|
11365
|
-
}
|
|
11366
|
-
while (i <= nextEnd) {
|
|
11367
|
-
liveList.insert(deepLiveify(next[i]), i);
|
|
11368
|
-
i++;
|
|
11659
|
+
return children;
|
|
11369
11660
|
}
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
liveList.delete(i);
|
|
11373
|
-
localI++;
|
|
11661
|
+
if (element.bold) {
|
|
11662
|
+
children = markdown`**${children}**`;
|
|
11374
11663
|
}
|
|
11375
|
-
|
|
11376
|
-
}
|
|
11377
|
-
function patchLiveObjectKey(liveObject, key, prev, next) {
|
|
11378
|
-
if (process.env.NODE_ENV !== "production") {
|
|
11379
|
-
const nonSerializableValue = findNonSerializableValue(next);
|
|
11380
|
-
if (nonSerializableValue) {
|
|
11381
|
-
error2(
|
|
11382
|
-
`New state path: '${nonSerializableValue.path}' value: '${String(
|
|
11383
|
-
nonSerializableValue.value
|
|
11384
|
-
)}' is not serializable.
|
|
11385
|
-
Only serializable value can be synced with Liveblocks.`
|
|
11386
|
-
);
|
|
11387
|
-
return;
|
|
11664
|
+
if (element.italic) {
|
|
11665
|
+
children = markdown`_${children}_`;
|
|
11388
11666
|
}
|
|
11389
|
-
|
|
11390
|
-
|
|
11391
|
-
if (next === void 0) {
|
|
11392
|
-
liveObject.delete(key);
|
|
11393
|
-
} else if (value === void 0) {
|
|
11394
|
-
liveObject.set(key, deepLiveify(next));
|
|
11395
|
-
} else if (prev === next) {
|
|
11396
|
-
return;
|
|
11397
|
-
} else if (isLiveList(value) && Array.isArray(prev) && Array.isArray(next)) {
|
|
11398
|
-
patchLiveList(value, prev, next);
|
|
11399
|
-
} else if (isLiveObject(value) && isPlainObject(prev) && isPlainObject(next)) {
|
|
11400
|
-
patchLiveObject(value, prev, next);
|
|
11401
|
-
} else {
|
|
11402
|
-
liveObject.set(key, deepLiveify(next));
|
|
11403
|
-
}
|
|
11404
|
-
}
|
|
11405
|
-
function patchLiveObject(root, prev, next) {
|
|
11406
|
-
const updates = {};
|
|
11407
|
-
for (const key in next) {
|
|
11408
|
-
patchLiveObjectKey(root, key, prev[key], next[key]);
|
|
11409
|
-
}
|
|
11410
|
-
for (const key in prev) {
|
|
11411
|
-
if (next[key] === void 0) {
|
|
11412
|
-
root.delete(key);
|
|
11667
|
+
if (element.strikethrough) {
|
|
11668
|
+
children = markdown`~~${children}~~`;
|
|
11413
11669
|
}
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
root.update(updates);
|
|
11417
|
-
}
|
|
11418
|
-
}
|
|
11419
|
-
function getParentsPath(node) {
|
|
11420
|
-
const path = [];
|
|
11421
|
-
while (node.parent.type === "HasParent") {
|
|
11422
|
-
if (isLiveList(node.parent.node)) {
|
|
11423
|
-
path.push(node.parent.node._indexOfPosition(node.parent.key));
|
|
11424
|
-
} else {
|
|
11425
|
-
path.push(node.parent.key);
|
|
11670
|
+
if (element.code) {
|
|
11671
|
+
children = markdown`\`${children}\``;
|
|
11426
11672
|
}
|
|
11427
|
-
|
|
11673
|
+
return children;
|
|
11674
|
+
},
|
|
11675
|
+
link: ({ element, href }) => {
|
|
11676
|
+
return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
|
|
11677
|
+
},
|
|
11678
|
+
mention: ({ element, user, group }) => {
|
|
11679
|
+
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _284 => _284.name]), () => ( _optionalChain([group, 'optionalAccess', _285 => _285.name]))), () => ( element.id))}`;
|
|
11428
11680
|
}
|
|
11429
|
-
|
|
11430
|
-
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11681
|
+
};
|
|
11682
|
+
async function stringifyCommentBody(body, options) {
|
|
11683
|
+
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _286 => _286.format]), () => ( "plain"));
|
|
11684
|
+
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _287 => _287.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
|
|
11685
|
+
const elements = {
|
|
11686
|
+
...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
|
|
11687
|
+
..._optionalChain([options, 'optionalAccess', _288 => _288.elements])
|
|
11688
|
+
};
|
|
11689
|
+
const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
|
|
11690
|
+
body,
|
|
11691
|
+
_optionalChain([options, 'optionalAccess', _289 => _289.resolveUsers]),
|
|
11692
|
+
_optionalChain([options, 'optionalAccess', _290 => _290.resolveGroupsInfo])
|
|
11435
11693
|
);
|
|
11436
|
-
|
|
11437
|
-
|
|
11438
|
-
|
|
11439
|
-
|
|
11440
|
-
|
|
11441
|
-
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11448
|
-
|
|
11449
|
-
|
|
11450
|
-
|
|
11451
|
-
const newState = Object.assign({}, state);
|
|
11452
|
-
for (const key in update.updates) {
|
|
11453
|
-
if (_optionalChain([update, 'access', _272 => _272.updates, 'access', _273 => _273[key], 'optionalAccess', _274 => _274.type]) === "update") {
|
|
11454
|
-
const val = update.node.get(key);
|
|
11455
|
-
if (val !== void 0) {
|
|
11456
|
-
newState[key] = lsonToJson(val);
|
|
11457
|
-
}
|
|
11458
|
-
} else if (_optionalChain([update, 'access', _275 => _275.updates, 'access', _276 => _276[key], 'optionalAccess', _277 => _277.type]) === "delete") {
|
|
11459
|
-
delete newState[key];
|
|
11694
|
+
const blocks = body.content.flatMap((block, blockIndex) => {
|
|
11695
|
+
switch (block.type) {
|
|
11696
|
+
case "paragraph": {
|
|
11697
|
+
const inlines = block.children.flatMap((inline, inlineIndex) => {
|
|
11698
|
+
if (isCommentBodyMention(inline)) {
|
|
11699
|
+
return inline.id ? [
|
|
11700
|
+
elements.mention(
|
|
11701
|
+
{
|
|
11702
|
+
element: inline,
|
|
11703
|
+
user: inline.kind === "user" ? resolvedUsers.get(inline.id) : void 0,
|
|
11704
|
+
group: inline.kind === "group" ? resolvedGroupsInfo.get(inline.id) : void 0
|
|
11705
|
+
},
|
|
11706
|
+
inlineIndex
|
|
11707
|
+
)
|
|
11708
|
+
] : [];
|
|
11460
11709
|
}
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
for (const listUpdate of update.updates) {
|
|
11472
|
-
if (listUpdate.type === "set") {
|
|
11473
|
-
newState = newState.map(
|
|
11474
|
-
(item, index) => index === listUpdate.index ? lsonToJson(listUpdate.item) : item
|
|
11475
|
-
);
|
|
11476
|
-
} else if (listUpdate.type === "insert") {
|
|
11477
|
-
if (listUpdate.index === newState.length) {
|
|
11478
|
-
newState.push(lsonToJson(listUpdate.item));
|
|
11479
|
-
} else {
|
|
11480
|
-
newState = [
|
|
11481
|
-
...newState.slice(0, listUpdate.index),
|
|
11482
|
-
lsonToJson(listUpdate.item),
|
|
11483
|
-
...newState.slice(listUpdate.index)
|
|
11484
|
-
];
|
|
11485
|
-
}
|
|
11486
|
-
} else if (listUpdate.type === "delete") {
|
|
11487
|
-
newState.splice(listUpdate.index, 1);
|
|
11488
|
-
} else if (listUpdate.type === "move") {
|
|
11489
|
-
if (listUpdate.previousIndex > listUpdate.index) {
|
|
11490
|
-
newState = [
|
|
11491
|
-
...newState.slice(0, listUpdate.index),
|
|
11492
|
-
lsonToJson(listUpdate.item),
|
|
11493
|
-
...newState.slice(listUpdate.index, listUpdate.previousIndex),
|
|
11494
|
-
...newState.slice(listUpdate.previousIndex + 1)
|
|
11495
|
-
];
|
|
11496
|
-
} else {
|
|
11497
|
-
newState = [
|
|
11498
|
-
...newState.slice(0, listUpdate.previousIndex),
|
|
11499
|
-
...newState.slice(
|
|
11500
|
-
listUpdate.previousIndex + 1,
|
|
11501
|
-
listUpdate.index + 1
|
|
11502
|
-
),
|
|
11503
|
-
lsonToJson(listUpdate.item),
|
|
11504
|
-
...newState.slice(listUpdate.index + 1)
|
|
11710
|
+
if (isCommentBodyLink(inline)) {
|
|
11711
|
+
const href = sanitizeUrl(inline.url);
|
|
11712
|
+
if (href === null) {
|
|
11713
|
+
return [
|
|
11714
|
+
elements.text(
|
|
11715
|
+
{
|
|
11716
|
+
element: { text: _nullishCoalesce(inline.text, () => ( inline.url)) }
|
|
11717
|
+
},
|
|
11718
|
+
inlineIndex
|
|
11719
|
+
)
|
|
11505
11720
|
];
|
|
11506
11721
|
}
|
|
11722
|
+
return [
|
|
11723
|
+
elements.link(
|
|
11724
|
+
{
|
|
11725
|
+
element: inline,
|
|
11726
|
+
href
|
|
11727
|
+
},
|
|
11728
|
+
inlineIndex
|
|
11729
|
+
)
|
|
11730
|
+
];
|
|
11507
11731
|
}
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
}
|
|
11511
|
-
case "LiveMap": {
|
|
11512
|
-
if (!isJsonObject(state)) {
|
|
11513
|
-
throw new Error(
|
|
11514
|
-
"Internal: received update on LiveMap but state was not an object"
|
|
11515
|
-
);
|
|
11516
|
-
}
|
|
11517
|
-
const newState = Object.assign({}, state);
|
|
11518
|
-
for (const key in update.updates) {
|
|
11519
|
-
if (_optionalChain([update, 'access', _278 => _278.updates, 'access', _279 => _279[key], 'optionalAccess', _280 => _280.type]) === "update") {
|
|
11520
|
-
const value = update.node.get(key);
|
|
11521
|
-
if (value !== void 0) {
|
|
11522
|
-
newState[key] = lsonToJson(value);
|
|
11523
|
-
}
|
|
11524
|
-
} else if (_optionalChain([update, 'access', _281 => _281.updates, 'access', _282 => _282[key], 'optionalAccess', _283 => _283.type]) === "delete") {
|
|
11525
|
-
delete newState[key];
|
|
11732
|
+
if (isCommentBodyText(inline)) {
|
|
11733
|
+
return [elements.text({ element: inline }, inlineIndex)];
|
|
11526
11734
|
}
|
|
11527
|
-
|
|
11528
|
-
|
|
11735
|
+
return [];
|
|
11736
|
+
});
|
|
11737
|
+
return [
|
|
11738
|
+
elements.paragraph(
|
|
11739
|
+
{ element: block, children: inlines.join("") },
|
|
11740
|
+
blockIndex
|
|
11741
|
+
)
|
|
11742
|
+
];
|
|
11529
11743
|
}
|
|
11744
|
+
default:
|
|
11745
|
+
return [];
|
|
11530
11746
|
}
|
|
11531
|
-
}
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11747
|
+
});
|
|
11748
|
+
return blocks.join(separator);
|
|
11749
|
+
}
|
|
11750
|
+
|
|
11751
|
+
// src/crdts/utils.ts
|
|
11752
|
+
function toPlainLson(lson) {
|
|
11753
|
+
if (lson instanceof LiveObject) {
|
|
11754
|
+
return {
|
|
11755
|
+
liveblocksType: "LiveObject",
|
|
11756
|
+
data: Object.fromEntries(
|
|
11757
|
+
Object.entries(lson.toObject()).flatMap(
|
|
11758
|
+
([key, value]) => value !== void 0 ? [[key, toPlainLson(value)]] : []
|
|
11759
|
+
)
|
|
11760
|
+
)
|
|
11761
|
+
};
|
|
11762
|
+
} else if (lson instanceof LiveMap) {
|
|
11763
|
+
return {
|
|
11764
|
+
liveblocksType: "LiveMap",
|
|
11765
|
+
data: Object.fromEntries(
|
|
11766
|
+
[...lson].map(([key, value]) => [key, toPlainLson(value)])
|
|
11767
|
+
)
|
|
11768
|
+
};
|
|
11769
|
+
} else if (lson instanceof LiveList) {
|
|
11770
|
+
return {
|
|
11771
|
+
liveblocksType: "LiveList",
|
|
11772
|
+
data: [...lson].map((item) => toPlainLson(item))
|
|
11773
|
+
};
|
|
11551
11774
|
} else {
|
|
11552
|
-
return
|
|
11775
|
+
return lson;
|
|
11553
11776
|
}
|
|
11554
11777
|
}
|
|
11555
11778
|
|
|
@@ -11601,9 +11824,9 @@ function makePoller(callback, intervalMs, options) {
|
|
|
11601
11824
|
const startTime = performance.now();
|
|
11602
11825
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
11603
11826
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
11604
|
-
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
11827
|
+
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _291 => _291.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
|
|
11605
11828
|
const context = {
|
|
11606
|
-
inForeground: _optionalChain([doc, 'optionalAccess',
|
|
11829
|
+
inForeground: _optionalChain([doc, 'optionalAccess', _292 => _292.visibilityState]) !== "hidden",
|
|
11607
11830
|
lastSuccessfulPollAt: startTime,
|
|
11608
11831
|
count: 0,
|
|
11609
11832
|
backoff: 0
|
|
@@ -11684,11 +11907,11 @@ function makePoller(callback, intervalMs, options) {
|
|
|
11684
11907
|
pollNowIfStale();
|
|
11685
11908
|
}
|
|
11686
11909
|
function onVisibilityChange() {
|
|
11687
|
-
setInForeground(_optionalChain([doc, 'optionalAccess',
|
|
11910
|
+
setInForeground(_optionalChain([doc, 'optionalAccess', _293 => _293.visibilityState]) !== "hidden");
|
|
11688
11911
|
}
|
|
11689
|
-
_optionalChain([doc, 'optionalAccess',
|
|
11690
|
-
_optionalChain([win, 'optionalAccess',
|
|
11691
|
-
_optionalChain([win, 'optionalAccess',
|
|
11912
|
+
_optionalChain([doc, 'optionalAccess', _294 => _294.addEventListener, 'call', _295 => _295("visibilitychange", onVisibilityChange)]);
|
|
11913
|
+
_optionalChain([win, 'optionalAccess', _296 => _296.addEventListener, 'call', _297 => _297("online", onVisibilityChange)]);
|
|
11914
|
+
_optionalChain([win, 'optionalAccess', _298 => _298.addEventListener, 'call', _299 => _299("focus", pollNowIfStale)]);
|
|
11692
11915
|
fsm.start();
|
|
11693
11916
|
return {
|
|
11694
11917
|
inc,
|
|
@@ -11827,5 +12050,5 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
|
11827
12050
|
|
|
11828
12051
|
|
|
11829
12052
|
|
|
11830
|
-
exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.lsonToJson = lsonToJson; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.objectToQuery = objectToQuery; exports.
|
|
12053
|
+
exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.legacy_patchLiveObjectKey = legacy_patchLiveObjectKey; exports.lsonToJson = lsonToJson; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
|
|
11831
12054
|
//# sourceMappingURL=index.cjs.map
|