@liveblocks/core 3.5.1 → 3.5.3
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 +419 -257
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -4
- package/dist/index.d.ts +29 -4
- package/dist/index.js +322 -160
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
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.5.
|
|
9
|
+
var PKG_VERSION = "3.5.3";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -3817,108 +3817,204 @@ function parseAuthToken(rawTokenString) {
|
|
|
3817
3817
|
};
|
|
3818
3818
|
}
|
|
3819
3819
|
|
|
3820
|
-
// src/lib/
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
}
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3820
|
+
// src/lib/IncrementalJsonParser.ts
|
|
3821
|
+
var EMPTY_OBJECT = Object.freeze({});
|
|
3822
|
+
var NULL_KEYWORD_CHARS = Array.from(new Set("null"));
|
|
3823
|
+
var TRUE_KEYWORD_CHARS = Array.from(new Set("true"));
|
|
3824
|
+
var FALSE_KEYWORD_CHARS = Array.from(new Set("false"));
|
|
3825
|
+
var ALL_KEYWORD_CHARS = Array.from(new Set("nulltruefalse"));
|
|
3826
|
+
function stripChar(str, chars) {
|
|
3827
|
+
const lastChar = str[str.length - 1];
|
|
3828
|
+
if (chars.includes(lastChar)) {
|
|
3829
|
+
return str.slice(0, -1);
|
|
3830
|
+
}
|
|
3831
|
+
return str;
|
|
3832
|
+
}
|
|
3833
|
+
var IncrementalJsonParser = class {
|
|
3834
|
+
// Input
|
|
3835
|
+
#sourceText = "";
|
|
3836
|
+
// Output
|
|
3837
|
+
#cachedJson;
|
|
3838
|
+
/** How much we've already parsed */
|
|
3839
|
+
#scanIndex = 0;
|
|
3840
|
+
/** Whether the last char processed was a backslash */
|
|
3841
|
+
#escaped = false;
|
|
3842
|
+
/**
|
|
3843
|
+
* Start position of the last unterminated string, -1 if we're not inside
|
|
3844
|
+
* a string currently.
|
|
3845
|
+
*
|
|
3846
|
+
* Example: '{"a": "foo'
|
|
3847
|
+
* ^
|
|
3848
|
+
*/
|
|
3849
|
+
#lastUnterminatedString = -1;
|
|
3850
|
+
/**
|
|
3851
|
+
* Start position of the last fully terminated string we've seen.
|
|
3852
|
+
*
|
|
3853
|
+
* Example: '{"a": "foo'
|
|
3854
|
+
* ^
|
|
3855
|
+
*/
|
|
3856
|
+
#lastTerminatedString = -1;
|
|
3857
|
+
/** The bracket stack of expected closing chars. For input '{"a": ["foo', the stack would be ['}', ']']. */
|
|
3858
|
+
#stack = [];
|
|
3859
|
+
constructor(text = "") {
|
|
3860
|
+
this.append(text);
|
|
3861
|
+
}
|
|
3862
|
+
get source() {
|
|
3863
|
+
return this.#sourceText;
|
|
3864
|
+
}
|
|
3865
|
+
get json() {
|
|
3866
|
+
if (this.#cachedJson === void 0) {
|
|
3867
|
+
this.#cachedJson = this.#parse();
|
|
3868
|
+
}
|
|
3869
|
+
return this.#cachedJson;
|
|
3870
|
+
}
|
|
3871
|
+
/** Whether we're currently inside an unterminated string, e.g. '{"hello' */
|
|
3872
|
+
get #inString() {
|
|
3873
|
+
return this.#lastUnterminatedString >= 0;
|
|
3874
|
+
}
|
|
3875
|
+
append(delta) {
|
|
3876
|
+
if (delta) {
|
|
3877
|
+
if (this.#sourceText === "") {
|
|
3878
|
+
delta = delta.trimStart();
|
|
3879
3879
|
}
|
|
3880
|
+
this.#sourceText += delta;
|
|
3881
|
+
this.#cachedJson = void 0;
|
|
3880
3882
|
}
|
|
3881
3883
|
}
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3884
|
+
#autocompleteTail(output) {
|
|
3885
|
+
if (this.#inString) {
|
|
3886
|
+
return "";
|
|
3887
|
+
}
|
|
3888
|
+
const lastChar = output.charAt(output.length - 1);
|
|
3889
|
+
if (lastChar === "") return "";
|
|
3890
|
+
if (lastChar === "-") {
|
|
3891
|
+
return "0";
|
|
3892
|
+
}
|
|
3893
|
+
if (!ALL_KEYWORD_CHARS.includes(lastChar)) return "";
|
|
3894
|
+
if (NULL_KEYWORD_CHARS.includes(lastChar)) {
|
|
3895
|
+
if (output.endsWith("nul")) return "l";
|
|
3896
|
+
if (output.endsWith("nu")) return "ll";
|
|
3897
|
+
if (output.endsWith("n")) return "ull";
|
|
3898
|
+
}
|
|
3899
|
+
if (TRUE_KEYWORD_CHARS.includes(lastChar)) {
|
|
3900
|
+
if (output.endsWith("tru")) return "e";
|
|
3901
|
+
if (output.endsWith("tr")) return "ue";
|
|
3902
|
+
if (output.endsWith("t")) return "rue";
|
|
3903
|
+
}
|
|
3904
|
+
if (FALSE_KEYWORD_CHARS.includes(lastChar)) {
|
|
3905
|
+
if (output.endsWith("fals")) return "e";
|
|
3906
|
+
if (output.endsWith("fal")) return "se";
|
|
3907
|
+
if (output.endsWith("fa")) return "lse";
|
|
3908
|
+
if (output.endsWith("f")) return "alse";
|
|
3909
|
+
}
|
|
3910
|
+
return "";
|
|
3911
|
+
}
|
|
3912
|
+
/**
|
|
3913
|
+
* Updates the internal parsing state by processing any new content
|
|
3914
|
+
* that has been appended since the last parse. This updates the state with
|
|
3915
|
+
* facts only. Any interpretation is left to the #parse() method.
|
|
3916
|
+
*/
|
|
3917
|
+
#catchup() {
|
|
3918
|
+
const newContent = this.#sourceText.slice(this.#scanIndex);
|
|
3919
|
+
for (let i = 0; i < newContent.length; i++) {
|
|
3920
|
+
const ch = newContent[i];
|
|
3921
|
+
const absolutePos = this.#scanIndex + i;
|
|
3922
|
+
if (this.#inString) {
|
|
3923
|
+
if (this.#escaped) {
|
|
3924
|
+
this.#escaped = false;
|
|
3925
|
+
} else if (ch === "\\") {
|
|
3926
|
+
this.#escaped = true;
|
|
3927
|
+
} else if (ch === '"') {
|
|
3928
|
+
this.#lastTerminatedString = this.#lastUnterminatedString;
|
|
3929
|
+
this.#lastUnterminatedString = -1;
|
|
3930
|
+
}
|
|
3931
|
+
} else {
|
|
3932
|
+
if (ch === '"') {
|
|
3933
|
+
this.#lastUnterminatedString = absolutePos;
|
|
3934
|
+
} else if (ch === "{") {
|
|
3935
|
+
this.#stack.push("}");
|
|
3936
|
+
} else if (ch === "[") {
|
|
3937
|
+
this.#stack.push("]");
|
|
3938
|
+
} else if (ch === "}" && this.#stack.length > 0 && this.#stack[this.#stack.length - 1] === "}") {
|
|
3939
|
+
this.#stack.pop();
|
|
3940
|
+
} else if (ch === "]" && this.#stack.length > 0 && this.#stack[this.#stack.length - 1] === "]") {
|
|
3941
|
+
this.#stack.pop();
|
|
3942
|
+
}
|
|
3903
3943
|
}
|
|
3904
|
-
pos--;
|
|
3905
3944
|
}
|
|
3945
|
+
this.#scanIndex = this.#sourceText.length;
|
|
3906
3946
|
}
|
|
3907
|
-
|
|
3908
|
-
|
|
3947
|
+
#parse() {
|
|
3948
|
+
this.#catchup();
|
|
3949
|
+
let result = this.#sourceText;
|
|
3950
|
+
if (result.charAt(0) !== "{") {
|
|
3951
|
+
return EMPTY_OBJECT;
|
|
3952
|
+
}
|
|
3953
|
+
if (result.endsWith("}")) {
|
|
3954
|
+
const quickCheck = tryParseJson(result);
|
|
3955
|
+
if (quickCheck) {
|
|
3956
|
+
return quickCheck;
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
if (this.#inString) {
|
|
3960
|
+
if (this.#escaped) {
|
|
3961
|
+
result = result.slice(0, -1);
|
|
3962
|
+
}
|
|
3963
|
+
result += '"';
|
|
3964
|
+
}
|
|
3965
|
+
result = result.trimEnd();
|
|
3966
|
+
result = stripChar(result, ",.");
|
|
3967
|
+
result = result + this.#autocompleteTail(result);
|
|
3968
|
+
const suffix = this.#stack.reduceRight((acc, ch) => acc + ch, "");
|
|
3969
|
+
{
|
|
3970
|
+
const attempt = tryParseJson(result + suffix);
|
|
3971
|
+
if (attempt) {
|
|
3972
|
+
return attempt;
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
if (this.#inString) {
|
|
3976
|
+
result = result.slice(0, this.#lastUnterminatedString);
|
|
3977
|
+
} else {
|
|
3978
|
+
result = stripChar(result, ":");
|
|
3979
|
+
if (result.endsWith('"')) {
|
|
3980
|
+
result = result.slice(0, this.#lastTerminatedString);
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
result = stripChar(result, ",");
|
|
3984
|
+
result += suffix;
|
|
3985
|
+
return tryParseJson(result) ?? EMPTY_OBJECT;
|
|
3909
3986
|
}
|
|
3910
|
-
|
|
3911
|
-
return tryParseJson(result) ?? {};
|
|
3912
|
-
}
|
|
3987
|
+
};
|
|
3913
3988
|
|
|
3914
3989
|
// src/types/ai.ts
|
|
3990
|
+
function replaceOrAppend(content, newItem, keyFn, now2) {
|
|
3991
|
+
const existingIndex = findLastIndex(
|
|
3992
|
+
content,
|
|
3993
|
+
(item) => item.type === newItem.type && keyFn(item) === keyFn(newItem)
|
|
3994
|
+
);
|
|
3995
|
+
if (existingIndex > -1) {
|
|
3996
|
+
content[existingIndex] = newItem;
|
|
3997
|
+
} else {
|
|
3998
|
+
closePart(content[content.length - 1], now2);
|
|
3999
|
+
content.push(newItem);
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
4002
|
+
function closePart(prevPart, endedAt) {
|
|
4003
|
+
if (prevPart?.type === "reasoning") {
|
|
4004
|
+
prevPart.endedAt ??= endedAt;
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
3915
4007
|
function patchContentWithDelta(content, delta) {
|
|
4008
|
+
if (delta === null)
|
|
4009
|
+
return;
|
|
4010
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
3916
4011
|
const lastPart = content[content.length - 1];
|
|
3917
4012
|
switch (delta.type) {
|
|
3918
4013
|
case "text-delta":
|
|
3919
4014
|
if (lastPart?.type === "text") {
|
|
3920
4015
|
lastPart.text += delta.textDelta;
|
|
3921
4016
|
} else {
|
|
4017
|
+
closePart(lastPart, now2);
|
|
3922
4018
|
content.push({ type: "text", text: delta.textDelta });
|
|
3923
4019
|
}
|
|
3924
4020
|
break;
|
|
@@ -3926,54 +4022,61 @@ function patchContentWithDelta(content, delta) {
|
|
|
3926
4022
|
if (lastPart?.type === "reasoning") {
|
|
3927
4023
|
lastPart.text += delta.textDelta;
|
|
3928
4024
|
} else {
|
|
4025
|
+
closePart(lastPart, now2);
|
|
3929
4026
|
content.push({
|
|
3930
4027
|
type: "reasoning",
|
|
3931
|
-
text: delta.textDelta ?? ""
|
|
4028
|
+
text: delta.textDelta ?? "",
|
|
4029
|
+
startedAt: now2
|
|
3932
4030
|
});
|
|
3933
4031
|
}
|
|
3934
4032
|
break;
|
|
3935
4033
|
case "tool-stream": {
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
stage: "receiving",
|
|
3941
|
-
invocationId: delta.invocationId,
|
|
3942
|
-
name: delta.name,
|
|
3943
|
-
partialArgsText: "",
|
|
3944
|
-
get partialArgs() {
|
|
3945
|
-
if (this.partialArgsText !== _cacheKey) {
|
|
3946
|
-
_cachedArgs = parsePartialJsonObject(this.partialArgsText);
|
|
3947
|
-
_cacheKey = this.partialArgsText;
|
|
3948
|
-
}
|
|
3949
|
-
return _cachedArgs;
|
|
3950
|
-
}
|
|
3951
|
-
};
|
|
4034
|
+
const toolInvocation = createReceivingToolInvocation(
|
|
4035
|
+
delta.invocationId,
|
|
4036
|
+
delta.name
|
|
4037
|
+
);
|
|
3952
4038
|
content.push(toolInvocation);
|
|
3953
4039
|
break;
|
|
3954
4040
|
}
|
|
3955
4041
|
case "tool-delta": {
|
|
3956
4042
|
if (lastPart?.type === "tool-invocation" && lastPart.stage === "receiving") {
|
|
3957
|
-
lastPart.
|
|
4043
|
+
lastPart.__appendDelta?.(delta.delta);
|
|
3958
4044
|
}
|
|
3959
4045
|
break;
|
|
3960
4046
|
}
|
|
3961
|
-
case "tool-invocation":
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
);
|
|
3966
|
-
if (existingIndex > -1) {
|
|
3967
|
-
content[existingIndex] = delta;
|
|
3968
|
-
} else {
|
|
3969
|
-
content.push(delta);
|
|
3970
|
-
}
|
|
4047
|
+
case "tool-invocation":
|
|
4048
|
+
replaceOrAppend(content, delta, (x) => x.invocationId, now2);
|
|
4049
|
+
break;
|
|
4050
|
+
case "retrieval":
|
|
4051
|
+
replaceOrAppend(content, delta, (x) => x.id, now2);
|
|
3971
4052
|
break;
|
|
3972
|
-
}
|
|
3973
4053
|
default:
|
|
3974
4054
|
return assertNever(delta, "Unhandled case");
|
|
3975
4055
|
}
|
|
3976
4056
|
}
|
|
4057
|
+
function createReceivingToolInvocation(invocationId, name, partialArgsText = "") {
|
|
4058
|
+
const parser = new IncrementalJsonParser(partialArgsText);
|
|
4059
|
+
return {
|
|
4060
|
+
type: "tool-invocation",
|
|
4061
|
+
stage: "receiving",
|
|
4062
|
+
invocationId,
|
|
4063
|
+
name,
|
|
4064
|
+
// --- Alternative implementation for FRONTEND only ------------------------
|
|
4065
|
+
get partialArgsText() {
|
|
4066
|
+
return parser.source;
|
|
4067
|
+
},
|
|
4068
|
+
// prettier-ignore
|
|
4069
|
+
get partialArgs() {
|
|
4070
|
+
return parser.json;
|
|
4071
|
+
},
|
|
4072
|
+
// prettier-ignore
|
|
4073
|
+
__appendDelta(delta) {
|
|
4074
|
+
parser.append(delta);
|
|
4075
|
+
}
|
|
4076
|
+
// prettier-ignore
|
|
4077
|
+
// ------------------------------------------------------------------------
|
|
4078
|
+
};
|
|
4079
|
+
}
|
|
3977
4080
|
|
|
3978
4081
|
// src/ai.ts
|
|
3979
4082
|
var DEFAULT_REQUEST_TIMEOUT = 4e3;
|
|
@@ -4373,6 +4476,33 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
|
|
|
4373
4476
|
failAllPending,
|
|
4374
4477
|
markMine(messageId) {
|
|
4375
4478
|
myMessages.add(messageId);
|
|
4479
|
+
},
|
|
4480
|
+
/**
|
|
4481
|
+
* Iterates over all my auto-executing messages.
|
|
4482
|
+
*
|
|
4483
|
+
* These are messages that match all these conditions:
|
|
4484
|
+
* - The message is an assistant message
|
|
4485
|
+
* - The message is owned by this client ("mine")
|
|
4486
|
+
* - The message is currently in "awaiting-tool" status
|
|
4487
|
+
* - The message has at least one tool invocation in "executing" stage
|
|
4488
|
+
* - The tool invocation has an execute() function defined
|
|
4489
|
+
*/
|
|
4490
|
+
*getAutoExecutingMessageIds() {
|
|
4491
|
+
for (const messageId of myMessages) {
|
|
4492
|
+
const message = getMessageById(messageId);
|
|
4493
|
+
if (message?.role === "assistant" && message.status === "awaiting-tool") {
|
|
4494
|
+
const isAutoExecuting = message.contentSoFar.some((part) => {
|
|
4495
|
+
if (part.type === "tool-invocation" && part.stage === "executing") {
|
|
4496
|
+
const tool = toolsStore.getTool\u03A3(part.name, message.chatId).get();
|
|
4497
|
+
return typeof tool?.execute === "function";
|
|
4498
|
+
}
|
|
4499
|
+
return false;
|
|
4500
|
+
});
|
|
4501
|
+
if (isAutoExecuting) {
|
|
4502
|
+
yield message.id;
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4505
|
+
}
|
|
4376
4506
|
}
|
|
4377
4507
|
};
|
|
4378
4508
|
}
|
|
@@ -4425,6 +4555,28 @@ function createAi(config) {
|
|
|
4425
4555
|
toolsStore,
|
|
4426
4556
|
knowledge: new KnowledgeStack()
|
|
4427
4557
|
};
|
|
4558
|
+
const DELTA_THROTTLE = 25;
|
|
4559
|
+
let pendingDeltas = [];
|
|
4560
|
+
let deltaBatchTimer = null;
|
|
4561
|
+
function flushPendingDeltas() {
|
|
4562
|
+
const currentQueue = pendingDeltas;
|
|
4563
|
+
pendingDeltas = [];
|
|
4564
|
+
if (deltaBatchTimer !== null) {
|
|
4565
|
+
clearTimeout(deltaBatchTimer);
|
|
4566
|
+
deltaBatchTimer = null;
|
|
4567
|
+
}
|
|
4568
|
+
batch(() => {
|
|
4569
|
+
for (const { id, delta } of currentQueue) {
|
|
4570
|
+
context.messagesStore.addDelta(id, delta);
|
|
4571
|
+
}
|
|
4572
|
+
});
|
|
4573
|
+
}
|
|
4574
|
+
function enqueueDelta(id, delta) {
|
|
4575
|
+
pendingDeltas.push({ id, delta });
|
|
4576
|
+
if (deltaBatchTimer === null) {
|
|
4577
|
+
deltaBatchTimer = setTimeout(flushPendingDeltas, DELTA_THROTTLE);
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4428
4580
|
let lastTokenKey;
|
|
4429
4581
|
function onStatusDidChange(_newStatus) {
|
|
4430
4582
|
const authValue = managedSocket.authValue;
|
|
@@ -4464,6 +4616,7 @@ function createAi(config) {
|
|
|
4464
4616
|
function onDidConnect() {
|
|
4465
4617
|
}
|
|
4466
4618
|
function onDidDisconnect() {
|
|
4619
|
+
flushPendingDeltas();
|
|
4467
4620
|
}
|
|
4468
4621
|
function handleServerMessage(event) {
|
|
4469
4622
|
if (typeof event.data !== "string")
|
|
@@ -4478,50 +4631,51 @@ function createAi(config) {
|
|
|
4478
4631
|
return;
|
|
4479
4632
|
}
|
|
4480
4633
|
if ("event" in msg) {
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
case "warning":
|
|
4495
|
-
warn(msg.message);
|
|
4496
|
-
break;
|
|
4497
|
-
case "error":
|
|
4498
|
-
error2(msg.error);
|
|
4499
|
-
break;
|
|
4500
|
-
case "rebooted":
|
|
4501
|
-
context.messagesStore.failAllPending();
|
|
4502
|
-
break;
|
|
4503
|
-
case "sync":
|
|
4504
|
-
batch(() => {
|
|
4505
|
-
for (const m of msg["-messages"] ?? []) {
|
|
4506
|
-
context.messagesStore.remove(m.chatId, m.id);
|
|
4507
|
-
}
|
|
4508
|
-
for (const chatId of msg["-chats"] ?? []) {
|
|
4509
|
-
context.chatsStore.markDeleted(chatId);
|
|
4510
|
-
context.messagesStore.removeByChatId(chatId);
|
|
4511
|
-
}
|
|
4512
|
-
for (const chatId of msg.clear ?? []) {
|
|
4513
|
-
context.messagesStore.removeByChatId(chatId);
|
|
4514
|
-
}
|
|
4515
|
-
if (msg.chats) {
|
|
4516
|
-
context.chatsStore.upsertMany(msg.chats);
|
|
4517
|
-
}
|
|
4518
|
-
if (msg.messages) {
|
|
4519
|
-
context.messagesStore.upsertMany(msg.messages);
|
|
4634
|
+
if (msg.event === "delta") {
|
|
4635
|
+
const { id, delta } = msg;
|
|
4636
|
+
enqueueDelta(id, delta);
|
|
4637
|
+
} else {
|
|
4638
|
+
batch(() => {
|
|
4639
|
+
flushPendingDeltas();
|
|
4640
|
+
switch (msg.event) {
|
|
4641
|
+
case "cmd-failed":
|
|
4642
|
+
pendingCmd?.reject(new Error(msg.error));
|
|
4643
|
+
break;
|
|
4644
|
+
case "settle": {
|
|
4645
|
+
context.messagesStore.upsert(msg.message);
|
|
4646
|
+
break;
|
|
4520
4647
|
}
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4648
|
+
case "warning":
|
|
4649
|
+
warn(msg.message);
|
|
4650
|
+
break;
|
|
4651
|
+
case "error":
|
|
4652
|
+
error2(msg.error);
|
|
4653
|
+
break;
|
|
4654
|
+
case "rebooted":
|
|
4655
|
+
context.messagesStore.failAllPending();
|
|
4656
|
+
break;
|
|
4657
|
+
case "sync":
|
|
4658
|
+
for (const m of msg["-messages"] ?? []) {
|
|
4659
|
+
context.messagesStore.remove(m.chatId, m.id);
|
|
4660
|
+
}
|
|
4661
|
+
for (const chatId of msg["-chats"] ?? []) {
|
|
4662
|
+
context.chatsStore.markDeleted(chatId);
|
|
4663
|
+
context.messagesStore.removeByChatId(chatId);
|
|
4664
|
+
}
|
|
4665
|
+
for (const chatId of msg.clear ?? []) {
|
|
4666
|
+
context.messagesStore.removeByChatId(chatId);
|
|
4667
|
+
}
|
|
4668
|
+
if (msg.chats) {
|
|
4669
|
+
context.chatsStore.upsertMany(msg.chats);
|
|
4670
|
+
}
|
|
4671
|
+
if (msg.messages) {
|
|
4672
|
+
context.messagesStore.upsertMany(msg.messages);
|
|
4673
|
+
}
|
|
4674
|
+
break;
|
|
4675
|
+
default:
|
|
4676
|
+
return assertNever(msg, "Unhandled case");
|
|
4677
|
+
}
|
|
4678
|
+
});
|
|
4525
4679
|
}
|
|
4526
4680
|
} else {
|
|
4527
4681
|
switch (msg.cmd) {
|
|
@@ -4660,6 +4814,14 @@ function createAi(config) {
|
|
|
4660
4814
|
messagesStore.markMine(resp.message.id);
|
|
4661
4815
|
}
|
|
4662
4816
|
}
|
|
4817
|
+
function handleBeforeUnload() {
|
|
4818
|
+
for (const messageId of context.messagesStore.getAutoExecutingMessageIds()) {
|
|
4819
|
+
sendClientMsgWithResponse({ cmd: "abort-ai", messageId }).catch(() => {
|
|
4820
|
+
});
|
|
4821
|
+
}
|
|
4822
|
+
}
|
|
4823
|
+
const win = typeof window !== "undefined" ? window : void 0;
|
|
4824
|
+
win?.addEventListener("beforeunload", handleBeforeUnload, { once: true });
|
|
4663
4825
|
return Object.defineProperty(
|
|
4664
4826
|
{
|
|
4665
4827
|
[kInternal]: {
|
|
@@ -4727,7 +4889,7 @@ function makeCreateSocketDelegateForAi(baseUrl, WebSocketPolyfill) {
|
|
|
4727
4889
|
}
|
|
4728
4890
|
const url2 = new URL(baseUrl);
|
|
4729
4891
|
url2.protocol = url2.protocol === "http:" ? "ws" : "wss";
|
|
4730
|
-
url2.pathname = "/ai/
|
|
4892
|
+
url2.pathname = "/ai/v6";
|
|
4731
4893
|
if (authValue.type === "secret") {
|
|
4732
4894
|
url2.searchParams.set("tok", authValue.token.raw);
|
|
4733
4895
|
} else if (authValue.type === "public") {
|