@liveblocks/core 3.5.1 → 3.5.2
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 +347 -241
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +253 -147
- 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.2";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -3817,99 +3817,174 @@ 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
|
|
3915
3990
|
function patchContentWithDelta(content, delta) {
|
|
@@ -3933,28 +4008,16 @@ function patchContentWithDelta(content, delta) {
|
|
|
3933
4008
|
}
|
|
3934
4009
|
break;
|
|
3935
4010
|
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
|
-
};
|
|
4011
|
+
const toolInvocation = createReceivingToolInvocation(
|
|
4012
|
+
delta.invocationId,
|
|
4013
|
+
delta.name
|
|
4014
|
+
);
|
|
3952
4015
|
content.push(toolInvocation);
|
|
3953
4016
|
break;
|
|
3954
4017
|
}
|
|
3955
4018
|
case "tool-delta": {
|
|
3956
4019
|
if (lastPart?.type === "tool-invocation" && lastPart.stage === "receiving") {
|
|
3957
|
-
lastPart.
|
|
4020
|
+
lastPart.__appendDelta?.(delta.delta);
|
|
3958
4021
|
}
|
|
3959
4022
|
break;
|
|
3960
4023
|
}
|
|
@@ -3974,6 +4037,25 @@ function patchContentWithDelta(content, delta) {
|
|
|
3974
4037
|
return assertNever(delta, "Unhandled case");
|
|
3975
4038
|
}
|
|
3976
4039
|
}
|
|
4040
|
+
function createReceivingToolInvocation(invocationId, name, partialArgsText = "") {
|
|
4041
|
+
const parser = new IncrementalJsonParser(partialArgsText);
|
|
4042
|
+
return {
|
|
4043
|
+
type: "tool-invocation",
|
|
4044
|
+
stage: "receiving",
|
|
4045
|
+
invocationId,
|
|
4046
|
+
name,
|
|
4047
|
+
get partialArgsText() {
|
|
4048
|
+
return parser.source;
|
|
4049
|
+
},
|
|
4050
|
+
get partialArgs() {
|
|
4051
|
+
return parser.json;
|
|
4052
|
+
},
|
|
4053
|
+
// Internal method to append deltas
|
|
4054
|
+
__appendDelta(delta) {
|
|
4055
|
+
parser.append(delta);
|
|
4056
|
+
}
|
|
4057
|
+
};
|
|
4058
|
+
}
|
|
3977
4059
|
|
|
3978
4060
|
// src/ai.ts
|
|
3979
4061
|
var DEFAULT_REQUEST_TIMEOUT = 4e3;
|
|
@@ -4425,6 +4507,28 @@ function createAi(config) {
|
|
|
4425
4507
|
toolsStore,
|
|
4426
4508
|
knowledge: new KnowledgeStack()
|
|
4427
4509
|
};
|
|
4510
|
+
const DELTA_THROTTLE = 25;
|
|
4511
|
+
let pendingDeltas = [];
|
|
4512
|
+
let deltaBatchTimer = null;
|
|
4513
|
+
function flushPendingDeltas() {
|
|
4514
|
+
const currentQueue = pendingDeltas;
|
|
4515
|
+
pendingDeltas = [];
|
|
4516
|
+
if (deltaBatchTimer !== null) {
|
|
4517
|
+
clearTimeout(deltaBatchTimer);
|
|
4518
|
+
deltaBatchTimer = null;
|
|
4519
|
+
}
|
|
4520
|
+
batch(() => {
|
|
4521
|
+
for (const { id, delta } of currentQueue) {
|
|
4522
|
+
context.messagesStore.addDelta(id, delta);
|
|
4523
|
+
}
|
|
4524
|
+
});
|
|
4525
|
+
}
|
|
4526
|
+
function enqueueDelta(id, delta) {
|
|
4527
|
+
pendingDeltas.push({ id, delta });
|
|
4528
|
+
if (deltaBatchTimer === null) {
|
|
4529
|
+
deltaBatchTimer = setTimeout(flushPendingDeltas, DELTA_THROTTLE);
|
|
4530
|
+
}
|
|
4531
|
+
}
|
|
4428
4532
|
let lastTokenKey;
|
|
4429
4533
|
function onStatusDidChange(_newStatus) {
|
|
4430
4534
|
const authValue = managedSocket.authValue;
|
|
@@ -4464,6 +4568,7 @@ function createAi(config) {
|
|
|
4464
4568
|
function onDidConnect() {
|
|
4465
4569
|
}
|
|
4466
4570
|
function onDidDisconnect() {
|
|
4571
|
+
flushPendingDeltas();
|
|
4467
4572
|
}
|
|
4468
4573
|
function handleServerMessage(event) {
|
|
4469
4574
|
if (typeof event.data !== "string")
|
|
@@ -4478,50 +4583,51 @@ function createAi(config) {
|
|
|
4478
4583
|
return;
|
|
4479
4584
|
}
|
|
4480
4585
|
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);
|
|
4586
|
+
if (msg.event === "delta") {
|
|
4587
|
+
const { id, delta } = msg;
|
|
4588
|
+
enqueueDelta(id, delta);
|
|
4589
|
+
} else {
|
|
4590
|
+
batch(() => {
|
|
4591
|
+
flushPendingDeltas();
|
|
4592
|
+
switch (msg.event) {
|
|
4593
|
+
case "cmd-failed":
|
|
4594
|
+
pendingCmd?.reject(new Error(msg.error));
|
|
4595
|
+
break;
|
|
4596
|
+
case "settle": {
|
|
4597
|
+
context.messagesStore.upsert(msg.message);
|
|
4598
|
+
break;
|
|
4520
4599
|
}
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4600
|
+
case "warning":
|
|
4601
|
+
warn(msg.message);
|
|
4602
|
+
break;
|
|
4603
|
+
case "error":
|
|
4604
|
+
error2(msg.error);
|
|
4605
|
+
break;
|
|
4606
|
+
case "rebooted":
|
|
4607
|
+
context.messagesStore.failAllPending();
|
|
4608
|
+
break;
|
|
4609
|
+
case "sync":
|
|
4610
|
+
for (const m of msg["-messages"] ?? []) {
|
|
4611
|
+
context.messagesStore.remove(m.chatId, m.id);
|
|
4612
|
+
}
|
|
4613
|
+
for (const chatId of msg["-chats"] ?? []) {
|
|
4614
|
+
context.chatsStore.markDeleted(chatId);
|
|
4615
|
+
context.messagesStore.removeByChatId(chatId);
|
|
4616
|
+
}
|
|
4617
|
+
for (const chatId of msg.clear ?? []) {
|
|
4618
|
+
context.messagesStore.removeByChatId(chatId);
|
|
4619
|
+
}
|
|
4620
|
+
if (msg.chats) {
|
|
4621
|
+
context.chatsStore.upsertMany(msg.chats);
|
|
4622
|
+
}
|
|
4623
|
+
if (msg.messages) {
|
|
4624
|
+
context.messagesStore.upsertMany(msg.messages);
|
|
4625
|
+
}
|
|
4626
|
+
break;
|
|
4627
|
+
default:
|
|
4628
|
+
return assertNever(msg, "Unhandled case");
|
|
4629
|
+
}
|
|
4630
|
+
});
|
|
4525
4631
|
}
|
|
4526
4632
|
} else {
|
|
4527
4633
|
switch (msg.cmd) {
|