deepspace 0.17.0 → 0.18.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/CHANGELOG.md +145 -1
- package/README.md +18 -41
- package/dist/cli.js +1176 -1327
- package/dist/cli.js.map +1 -1
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/worker.js.map +1 -1
- package/features/documents/src/LibrarySidebar.tsx +6 -8
- package/features/documents/src/editor/useDocEditor.ts +3 -8
- package/features/landing/feature.json +1 -1
- package/features/messaging/src/components/chat/MessageItem.tsx +83 -34
- package/features/messaging/src/hooks/useChatChannel.ts +2 -8
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1786,6 +1786,8 @@ function parseServerError(error) {
|
|
|
1786
1786
|
// src/client/storage/record-socket.ts
|
|
1787
1787
|
var WS_CONNECTING = 0;
|
|
1788
1788
|
var WS_OPEN = 1;
|
|
1789
|
+
var PING_EVERY_MS = 15e3;
|
|
1790
|
+
var PONG_TIMEOUT_MS = 3e4;
|
|
1789
1791
|
var RecordSocket = class {
|
|
1790
1792
|
constructor(config) {
|
|
1791
1793
|
this.config = config;
|
|
@@ -1801,6 +1803,14 @@ var RecordSocket = class {
|
|
|
1801
1803
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
1802
1804
|
reconnectAttempt = 0;
|
|
1803
1805
|
reconnectTimeout = null;
|
|
1806
|
+
heartbeat = null;
|
|
1807
|
+
/** Any inbound frame proves the peer is answering. */
|
|
1808
|
+
lastInboundAt = 0;
|
|
1809
|
+
/** Monotonic time of the one probe awaiting an inbound answer. */
|
|
1810
|
+
outstandingPingAt = null;
|
|
1811
|
+
/** Monotonic time of the prior heartbeat callback. A long gap means the
|
|
1812
|
+
* scheduler was suspended, so a pre-suspension probe cannot be judged. */
|
|
1813
|
+
lastHeartbeatCheckAt = 0;
|
|
1804
1814
|
// Bumped by connect() (on entry) and disconnect()/destroy(). connect()
|
|
1805
1815
|
// captures it before awaiting the auth token and re-checks after; a
|
|
1806
1816
|
// mismatch means a teardown (or a newer connect) raced in during the
|
|
@@ -1849,10 +1859,12 @@ var RecordSocket = class {
|
|
|
1849
1859
|
ws.onopen = () => {
|
|
1850
1860
|
config.log?.("connected", config.roomId);
|
|
1851
1861
|
config.listeners.onStatus("connected");
|
|
1862
|
+
this.startHeartbeat(ws);
|
|
1852
1863
|
this.resubscribeAll(ws);
|
|
1853
1864
|
};
|
|
1854
1865
|
ws.onmessage = (event) => this.handleMessage(event);
|
|
1855
1866
|
ws.onclose = () => {
|
|
1867
|
+
this.stopHeartbeat();
|
|
1856
1868
|
config.log?.("disconnected", config.roomId);
|
|
1857
1869
|
config.listeners.onStatus("disconnected");
|
|
1858
1870
|
config.listeners.onReady(false);
|
|
@@ -1907,8 +1919,48 @@ var RecordSocket = class {
|
|
|
1907
1919
|
this.reconnectTimeout = null;
|
|
1908
1920
|
}
|
|
1909
1921
|
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Turn a peer that stopped answering into a `close` event. That is the whole
|
|
1924
|
+
* job — `onclose` already reports 'disconnected', marks every query stale,
|
|
1925
|
+
* and reconnects with backoff. Without this it is never called, because
|
|
1926
|
+
* nothing about the connection is actually broken.
|
|
1927
|
+
*/
|
|
1928
|
+
startHeartbeat(ws) {
|
|
1929
|
+
this.stopHeartbeat();
|
|
1930
|
+
this.lastInboundAt = performance.now();
|
|
1931
|
+
this.lastHeartbeatCheckAt = this.lastInboundAt;
|
|
1932
|
+
this.outstandingPingAt = null;
|
|
1933
|
+
this.heartbeat = setInterval(() => {
|
|
1934
|
+
if (ws.readyState !== WS_OPEN) return;
|
|
1935
|
+
const now = performance.now();
|
|
1936
|
+
const callbackGap = now - this.lastHeartbeatCheckAt;
|
|
1937
|
+
this.lastHeartbeatCheckAt = now;
|
|
1938
|
+
if (this.outstandingPingAt !== null) {
|
|
1939
|
+
if (now - this.outstandingPingAt >= PONG_TIMEOUT_MS) {
|
|
1940
|
+
if (callbackGap >= PONG_TIMEOUT_MS) {
|
|
1941
|
+
ws.send("ping");
|
|
1942
|
+
this.outstandingPingAt = now;
|
|
1943
|
+
} else {
|
|
1944
|
+
ws.close();
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
if (now - this.lastInboundAt >= PING_EVERY_MS) {
|
|
1950
|
+
ws.send("ping");
|
|
1951
|
+
this.outstandingPingAt = now;
|
|
1952
|
+
}
|
|
1953
|
+
}, PING_EVERY_MS);
|
|
1954
|
+
}
|
|
1955
|
+
stopHeartbeat() {
|
|
1956
|
+
if (this.heartbeat) clearInterval(this.heartbeat);
|
|
1957
|
+
this.heartbeat = null;
|
|
1958
|
+
this.outstandingPingAt = null;
|
|
1959
|
+
this.lastHeartbeatCheckAt = 0;
|
|
1960
|
+
}
|
|
1910
1961
|
/** Close without firing onclose — prevents the zombie-reconnect. */
|
|
1911
1962
|
teardownSocket() {
|
|
1963
|
+
this.stopHeartbeat();
|
|
1912
1964
|
const ws = this.ws;
|
|
1913
1965
|
if (!ws) return;
|
|
1914
1966
|
this.config.log?.("closing", this.config.roomId);
|
|
@@ -1977,6 +2029,9 @@ var RecordSocket = class {
|
|
|
1977
2029
|
}
|
|
1978
2030
|
}
|
|
1979
2031
|
handleMessage(event) {
|
|
2032
|
+
this.lastInboundAt = performance.now();
|
|
2033
|
+
this.outstandingPingAt = null;
|
|
2034
|
+
if (event.data === "pong") return;
|
|
1980
2035
|
if (event.data instanceof ArrayBuffer) {
|
|
1981
2036
|
this.binaryHandlers.forEach((h) => h(event.data));
|
|
1982
2037
|
return;
|