@liveblocks/core 3.8.1 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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.8.1";
9
+ var PKG_VERSION = "3.9.0";
10
10
  var PKG_FORMAT = "esm";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -2387,6 +2387,14 @@ function createApiClient({
2387
2387
  function getGroup(groupId) {
2388
2388
  return batchedGetGroups.get(groupId);
2389
2389
  }
2390
+ async function getUrlMetadata(_url) {
2391
+ const { metadata } = await httpClient.get(
2392
+ url`/v2/c/urls/metadata`,
2393
+ await authManager.getAuthValue({ requestedScope: "comments:read" }),
2394
+ { url: _url }
2395
+ );
2396
+ return metadata;
2397
+ }
2390
2398
  return {
2391
2399
  // Room threads
2392
2400
  getThreads,
@@ -2444,7 +2452,9 @@ function createApiClient({
2444
2452
  groupsStore,
2445
2453
  getGroup,
2446
2454
  // AI
2447
- executeContextualPrompt
2455
+ executeContextualPrompt,
2456
+ // URL metadata
2457
+ getUrlMetadata
2448
2458
  };
2449
2459
  }
2450
2460
  function getBearerTokenFromAuthValue(authValue) {
@@ -3059,7 +3069,6 @@ var ServerMsgCode = /* @__PURE__ */ ((ServerMsgCode2) => {
3059
3069
  ServerMsgCode2[ServerMsgCode2["ROOM_STATE"] = 104] = "ROOM_STATE";
3060
3070
  ServerMsgCode2[ServerMsgCode2["INITIAL_STORAGE_STATE"] = 200] = "INITIAL_STORAGE_STATE";
3061
3071
  ServerMsgCode2[ServerMsgCode2["UPDATE_STORAGE"] = 201] = "UPDATE_STORAGE";
3062
- ServerMsgCode2[ServerMsgCode2["REJECT_STORAGE_OP"] = 299] = "REJECT_STORAGE_OP";
3063
3072
  ServerMsgCode2[ServerMsgCode2["UPDATE_YDOC"] = 300] = "UPDATE_YDOC";
3064
3073
  ServerMsgCode2[ServerMsgCode2["THREAD_CREATED"] = 400] = "THREAD_CREATED";
3065
3074
  ServerMsgCode2[ServerMsgCode2["THREAD_DELETED"] = 407] = "THREAD_DELETED";
@@ -3070,6 +3079,7 @@ var ServerMsgCode = /* @__PURE__ */ ((ServerMsgCode2) => {
3070
3079
  ServerMsgCode2[ServerMsgCode2["COMMENT_DELETED"] = 404] = "COMMENT_DELETED";
3071
3080
  ServerMsgCode2[ServerMsgCode2["COMMENT_REACTION_ADDED"] = 405] = "COMMENT_REACTION_ADDED";
3072
3081
  ServerMsgCode2[ServerMsgCode2["COMMENT_REACTION_REMOVED"] = 406] = "COMMENT_REACTION_REMOVED";
3082
+ ServerMsgCode2[ServerMsgCode2["REJECT_STORAGE_OP"] = 299] = "REJECT_STORAGE_OP";
3073
3083
  return ServerMsgCode2;
3074
3084
  })(ServerMsgCode || {});
3075
3085
 
@@ -3697,240 +3707,6 @@ var ManagedSocket = class {
3697
3707
  // src/internal.ts
3698
3708
  var kInternal = Symbol();
3699
3709
 
3700
- // src/lib/shallow.ts
3701
- function shallowArray(xs, ys) {
3702
- if (xs.length !== ys.length) {
3703
- return false;
3704
- }
3705
- for (let i = 0; i < xs.length; i++) {
3706
- if (!Object.is(xs[i], ys[i])) {
3707
- return false;
3708
- }
3709
- }
3710
- return true;
3711
- }
3712
- function shallowObj(objA, objB) {
3713
- if (!isPlainObject(objA) || !isPlainObject(objB)) {
3714
- return false;
3715
- }
3716
- const keysA = Object.keys(objA);
3717
- if (keysA.length !== Object.keys(objB).length) {
3718
- return false;
3719
- }
3720
- return keysA.every(
3721
- (key) => Object.prototype.hasOwnProperty.call(objB, key) && Object.is(objA[key], objB[key])
3722
- );
3723
- }
3724
- function shallow(a, b) {
3725
- if (Object.is(a, b)) {
3726
- return true;
3727
- }
3728
- const isArrayA = Array.isArray(a);
3729
- const isArrayB = Array.isArray(b);
3730
- if (isArrayA || isArrayB) {
3731
- if (!isArrayA || !isArrayB) {
3732
- return false;
3733
- }
3734
- return shallowArray(a, b);
3735
- }
3736
- return shallowObj(a, b);
3737
- }
3738
- function shallow2(a, b) {
3739
- if (!isPlainObject(a) || !isPlainObject(b)) {
3740
- return shallow(a, b);
3741
- }
3742
- const keysA = Object.keys(a);
3743
- if (keysA.length !== Object.keys(b).length) {
3744
- return false;
3745
- }
3746
- return keysA.every(
3747
- (key) => Object.prototype.hasOwnProperty.call(b, key) && shallow(a[key], b[key])
3748
- );
3749
- }
3750
-
3751
- // src/lib/TreePool.ts
3752
- var TreePool = class {
3753
- #_items;
3754
- #_childrenOf;
3755
- #_sorted;
3756
- #_primaryKey;
3757
- #_parentKeyFn;
3758
- #_lt;
3759
- constructor(primaryKey, parentKey, lt) {
3760
- this.#_primaryKey = primaryKey;
3761
- this.#_parentKeyFn = parentKey;
3762
- this.#_lt = lt;
3763
- this.#_items = /* @__PURE__ */ new Map();
3764
- this.#_childrenOf = new DefaultMap(() => /* @__PURE__ */ new Set());
3765
- this.#_sorted = SortedList.with(lt);
3766
- }
3767
- get(id) {
3768
- return this.#_items.get(id);
3769
- }
3770
- getOrThrow(id) {
3771
- return this.get(id) ?? raise(`Item with id ${id} not found`);
3772
- }
3773
- get sorted() {
3774
- return this.#_sorted;
3775
- }
3776
- getParentId(id) {
3777
- const item = this.getOrThrow(id);
3778
- return this.#_parentKeyFn(item);
3779
- }
3780
- getParent(id) {
3781
- const parentId = this.getParentId(id);
3782
- return parentId ? this.getOrThrow(parentId) : null;
3783
- }
3784
- getChildren(id) {
3785
- const childIds = this.#_childrenOf.get(id);
3786
- if (!childIds) return [];
3787
- return Array.from(childIds).map(
3788
- (id2) => this.#_items.get(id2)
3789
- // eslint-disable-line no-restricted-syntax
3790
- );
3791
- }
3792
- *walkUp(id, predicate) {
3793
- const includeSelf = true;
3794
- let nodeId = id;
3795
- do {
3796
- const item = this.getOrThrow(nodeId);
3797
- if (includeSelf || nodeId !== id) {
3798
- if (!predicate || predicate(item)) {
3799
- yield item;
3800
- }
3801
- }
3802
- nodeId = this.#_parentKeyFn(item);
3803
- } while (nodeId !== null);
3804
- }
3805
- // XXXX Generalize
3806
- *walkLeft(id, predicate) {
3807
- const self = this.getOrThrow(id);
3808
- const siblings = SortedList.from(this.getSiblings(id), this.#_lt);
3809
- for (const sibling of siblings.iterReversed()) {
3810
- if (this.#_lt(self, sibling)) continue;
3811
- if (!predicate || predicate(sibling)) {
3812
- yield sibling;
3813
- }
3814
- }
3815
- }
3816
- // XXXX Generalize
3817
- *walkRight(id, predicate) {
3818
- const self = this.getOrThrow(id);
3819
- const siblings = SortedList.from(this.getSiblings(id), this.#_lt);
3820
- for (const sibling of siblings) {
3821
- if (this.#_lt(sibling, self)) continue;
3822
- if (!predicate || predicate(sibling)) {
3823
- yield sibling;
3824
- }
3825
- }
3826
- }
3827
- // XXXX Generalize
3828
- *walkDown(id, predicate) {
3829
- const children = SortedList.from(this.getChildren(id), this.#_lt).rawArray;
3830
- for (let i = children.length - 1; i >= 0; i--) {
3831
- const child = children[i];
3832
- yield* this.walkDown(
3833
- this.#_primaryKey(child),
3834
- predicate
3835
- // "depth-first",
3836
- // true
3837
- );
3838
- if (!predicate || predicate(child)) {
3839
- yield child;
3840
- }
3841
- }
3842
- }
3843
- /** Returns all siblings, not including the item itself. */
3844
- getSiblings(id) {
3845
- const self = this.getOrThrow(id);
3846
- const parentId = this.getParentId(id);
3847
- return this.getChildren(parentId).filter((item) => item !== self);
3848
- }
3849
- [Symbol.iterator]() {
3850
- return this.#_sorted[Symbol.iterator]();
3851
- }
3852
- upsert(item) {
3853
- const pk = this.#_primaryKey(item);
3854
- const existing = this.#_items.get(pk);
3855
- if (existing) {
3856
- if (this.#_parentKeyFn(existing) !== this.#_parentKeyFn(item)) {
3857
- throw new Error(
3858
- "Cannot upsert parent ID changes that change the tree structure. Remove the entry first, and recreate it"
3859
- );
3860
- }
3861
- this.#_sorted.remove(existing);
3862
- }
3863
- this.#_items.set(pk, item);
3864
- this.#_sorted.add(item);
3865
- const parentId = this.#_parentKeyFn(item);
3866
- this.#_childrenOf.getOrCreate(parentId).add(pk);
3867
- }
3868
- remove(pk) {
3869
- const item = this.#_items.get(pk);
3870
- if (!item) return false;
3871
- const childIds = this.#_childrenOf.get(pk);
3872
- if (childIds) {
3873
- throw new Error(
3874
- `Cannot remove item '${pk}' while it still has children. Remove children first.`
3875
- );
3876
- }
3877
- const parentId = this.#_parentKeyFn(item);
3878
- const siblings = this.#_childrenOf.get(parentId);
3879
- if (siblings) {
3880
- siblings.delete(pk);
3881
- if (siblings.size === 0) {
3882
- this.#_childrenOf.delete(parentId);
3883
- }
3884
- }
3885
- this.#_sorted.remove(item);
3886
- this.#_childrenOf.delete(pk);
3887
- this.#_items.delete(pk);
3888
- return true;
3889
- }
3890
- clear() {
3891
- if (this.#_items.size === 0) return false;
3892
- this.#_childrenOf.clear();
3893
- this.#_items.clear();
3894
- this.#_sorted.clear();
3895
- return true;
3896
- }
3897
- };
3898
-
3899
- // src/protocol/AuthToken.ts
3900
- var Permission = /* @__PURE__ */ ((Permission2) => {
3901
- Permission2["Read"] = "room:read";
3902
- Permission2["Write"] = "room:write";
3903
- Permission2["PresenceWrite"] = "room:presence:write";
3904
- Permission2["CommentsWrite"] = "comments:write";
3905
- Permission2["CommentsRead"] = "comments:read";
3906
- return Permission2;
3907
- })(Permission || {});
3908
- function canWriteStorage(scopes) {
3909
- return scopes.includes("room:write" /* Write */);
3910
- }
3911
- function canComment(scopes) {
3912
- return scopes.includes("comments:write" /* CommentsWrite */) || scopes.includes("room:write" /* Write */);
3913
- }
3914
- function isValidAuthTokenPayload(data) {
3915
- return isPlainObject(data) && (data.k === "acc" /* ACCESS_TOKEN */ || data.k === "id" /* ID_TOKEN */ || data.k === "sec-legacy" /* SECRET_LEGACY */);
3916
- }
3917
- function parseAuthToken(rawTokenString) {
3918
- const tokenParts = rawTokenString.split(".");
3919
- if (tokenParts.length !== 3) {
3920
- throw new Error("Authentication error: invalid JWT token");
3921
- }
3922
- const payload = tryParseJson(b64decode(tokenParts[1]));
3923
- if (!(payload && isValidAuthTokenPayload(payload))) {
3924
- throw new Error(
3925
- "Authentication error: expected a valid token but did not get one. Hint: if you are using a callback, ensure the room is passed when creating the token. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClientCallback"
3926
- );
3927
- }
3928
- return {
3929
- raw: rawTokenString,
3930
- parsed: payload
3931
- };
3932
- }
3933
-
3934
3710
  // src/lib/IncrementalJsonParser.ts
3935
3711
  var EMPTY_OBJECT = Object.freeze({});
3936
3712
  var NULL_KEYWORD_CHARS = Array.from(new Set("null"));
@@ -4100,95 +3876,237 @@ var IncrementalJsonParser = class {
4100
3876
  }
4101
3877
  };
4102
3878
 
4103
- // src/types/ai.ts
4104
- function replaceOrAppend(content, newItem, keyFn, now2) {
4105
- const existingIndex = findLastIndex(
4106
- content,
4107
- (item) => item.type === newItem.type && keyFn(item) === keyFn(newItem)
3879
+ // src/lib/shallow.ts
3880
+ function shallowArray(xs, ys) {
3881
+ if (xs.length !== ys.length) {
3882
+ return false;
3883
+ }
3884
+ for (let i = 0; i < xs.length; i++) {
3885
+ if (!Object.is(xs[i], ys[i])) {
3886
+ return false;
3887
+ }
3888
+ }
3889
+ return true;
3890
+ }
3891
+ function shallowObj(objA, objB) {
3892
+ if (!isPlainObject(objA) || !isPlainObject(objB)) {
3893
+ return false;
3894
+ }
3895
+ const keysA = Object.keys(objA);
3896
+ if (keysA.length !== Object.keys(objB).length) {
3897
+ return false;
3898
+ }
3899
+ return keysA.every(
3900
+ (key) => Object.prototype.hasOwnProperty.call(objB, key) && Object.is(objA[key], objB[key])
4108
3901
  );
4109
- if (existingIndex > -1) {
4110
- content[existingIndex] = newItem;
4111
- } else {
4112
- closePart(content[content.length - 1], now2);
4113
- content.push(newItem);
3902
+ }
3903
+ function shallow(a, b) {
3904
+ if (Object.is(a, b)) {
3905
+ return true;
3906
+ }
3907
+ const isArrayA = Array.isArray(a);
3908
+ const isArrayB = Array.isArray(b);
3909
+ if (isArrayA || isArrayB) {
3910
+ if (!isArrayA || !isArrayB) {
3911
+ return false;
3912
+ }
3913
+ return shallowArray(a, b);
3914
+ }
3915
+ return shallowObj(a, b);
3916
+ }
3917
+ function shallow2(a, b) {
3918
+ if (!isPlainObject(a) || !isPlainObject(b)) {
3919
+ return shallow(a, b);
3920
+ }
3921
+ const keysA = Object.keys(a);
3922
+ if (keysA.length !== Object.keys(b).length) {
3923
+ return false;
3924
+ }
3925
+ return keysA.every(
3926
+ (key) => Object.prototype.hasOwnProperty.call(b, key) && shallow(a[key], b[key])
3927
+ );
3928
+ }
3929
+
3930
+ // src/lib/TreePool.ts
3931
+ var TreePool = class {
3932
+ #_items;
3933
+ #_childrenOf;
3934
+ #_sorted;
3935
+ #_primaryKey;
3936
+ #_parentKeyFn;
3937
+ #_lt;
3938
+ constructor(primaryKey, parentKey, lt) {
3939
+ this.#_primaryKey = primaryKey;
3940
+ this.#_parentKeyFn = parentKey;
3941
+ this.#_lt = lt;
3942
+ this.#_items = /* @__PURE__ */ new Map();
3943
+ this.#_childrenOf = new DefaultMap(() => /* @__PURE__ */ new Set());
3944
+ this.#_sorted = SortedList.with(lt);
3945
+ }
3946
+ get(id) {
3947
+ return this.#_items.get(id);
3948
+ }
3949
+ getOrThrow(id) {
3950
+ return this.get(id) ?? raise(`Item with id ${id} not found`);
3951
+ }
3952
+ get sorted() {
3953
+ return this.#_sorted;
3954
+ }
3955
+ getParentId(id) {
3956
+ const item = this.getOrThrow(id);
3957
+ return this.#_parentKeyFn(item);
3958
+ }
3959
+ getParent(id) {
3960
+ const parentId = this.getParentId(id);
3961
+ return parentId ? this.getOrThrow(parentId) : null;
3962
+ }
3963
+ getChildren(id) {
3964
+ const childIds = this.#_childrenOf.get(id);
3965
+ if (!childIds) return [];
3966
+ return Array.from(childIds).map(
3967
+ (id2) => this.#_items.get(id2)
3968
+ // eslint-disable-line no-restricted-syntax
3969
+ );
3970
+ }
3971
+ *walkUp(id, predicate) {
3972
+ const includeSelf = true;
3973
+ let nodeId = id;
3974
+ do {
3975
+ const item = this.getOrThrow(nodeId);
3976
+ if (includeSelf || nodeId !== id) {
3977
+ if (!predicate || predicate(item)) {
3978
+ yield item;
3979
+ }
3980
+ }
3981
+ nodeId = this.#_parentKeyFn(item);
3982
+ } while (nodeId !== null);
3983
+ }
3984
+ // XXXX Generalize
3985
+ *walkLeft(id, predicate) {
3986
+ const self = this.getOrThrow(id);
3987
+ const siblings = SortedList.from(this.getSiblings(id), this.#_lt);
3988
+ for (const sibling of siblings.iterReversed()) {
3989
+ if (this.#_lt(self, sibling)) continue;
3990
+ if (!predicate || predicate(sibling)) {
3991
+ yield sibling;
3992
+ }
3993
+ }
3994
+ }
3995
+ // XXXX Generalize
3996
+ *walkRight(id, predicate) {
3997
+ const self = this.getOrThrow(id);
3998
+ const siblings = SortedList.from(this.getSiblings(id), this.#_lt);
3999
+ for (const sibling of siblings) {
4000
+ if (this.#_lt(sibling, self)) continue;
4001
+ if (!predicate || predicate(sibling)) {
4002
+ yield sibling;
4003
+ }
4004
+ }
4005
+ }
4006
+ // XXXX Generalize
4007
+ *walkDown(id, predicate) {
4008
+ const children = SortedList.from(this.getChildren(id), this.#_lt).rawArray;
4009
+ for (let i = children.length - 1; i >= 0; i--) {
4010
+ const child = children[i];
4011
+ yield* this.walkDown(
4012
+ this.#_primaryKey(child),
4013
+ predicate
4014
+ // "depth-first",
4015
+ // true
4016
+ );
4017
+ if (!predicate || predicate(child)) {
4018
+ yield child;
4019
+ }
4020
+ }
4114
4021
  }
4115
- }
4116
- function closePart(prevPart, endedAt) {
4117
- if (prevPart?.type === "reasoning") {
4118
- prevPart.endedAt ??= endedAt;
4022
+ /** Returns all siblings, not including the item itself. */
4023
+ getSiblings(id) {
4024
+ const self = this.getOrThrow(id);
4025
+ const parentId = this.getParentId(id);
4026
+ return this.getChildren(parentId).filter((item) => item !== self);
4119
4027
  }
4120
- }
4121
- function patchContentWithDelta(content, delta) {
4122
- if (delta === null)
4123
- return;
4124
- const now2 = (/* @__PURE__ */ new Date()).toISOString();
4125
- const lastPart = content[content.length - 1];
4126
- switch (delta.type) {
4127
- case "text-delta":
4128
- if (lastPart?.type === "text") {
4129
- lastPart.text += delta.textDelta;
4130
- } else {
4131
- closePart(lastPart, now2);
4132
- content.push({ type: "text", text: delta.textDelta });
4133
- }
4134
- break;
4135
- case "reasoning-delta":
4136
- if (lastPart?.type === "reasoning") {
4137
- lastPart.text += delta.textDelta;
4138
- } else {
4139
- closePart(lastPart, now2);
4140
- content.push({
4141
- type: "reasoning",
4142
- text: delta.textDelta,
4143
- startedAt: now2
4144
- });
4028
+ [Symbol.iterator]() {
4029
+ return this.#_sorted[Symbol.iterator]();
4030
+ }
4031
+ upsert(item) {
4032
+ const pk = this.#_primaryKey(item);
4033
+ const existing = this.#_items.get(pk);
4034
+ if (existing) {
4035
+ if (this.#_parentKeyFn(existing) !== this.#_parentKeyFn(item)) {
4036
+ throw new Error(
4037
+ "Cannot upsert parent ID changes that change the tree structure. Remove the entry first, and recreate it"
4038
+ );
4145
4039
  }
4146
- break;
4147
- case "tool-stream": {
4148
- const toolInvocation = createReceivingToolInvocation(
4149
- delta.invocationId,
4150
- delta.name
4040
+ this.#_sorted.remove(existing);
4041
+ }
4042
+ this.#_items.set(pk, item);
4043
+ this.#_sorted.add(item);
4044
+ const parentId = this.#_parentKeyFn(item);
4045
+ this.#_childrenOf.getOrCreate(parentId).add(pk);
4046
+ }
4047
+ remove(pk) {
4048
+ const item = this.#_items.get(pk);
4049
+ if (!item) return false;
4050
+ const childIds = this.#_childrenOf.get(pk);
4051
+ if (childIds) {
4052
+ throw new Error(
4053
+ `Cannot remove item '${pk}' while it still has children. Remove children first.`
4151
4054
  );
4152
- content.push(toolInvocation);
4153
- break;
4154
4055
  }
4155
- case "tool-delta": {
4156
- if (lastPart?.type === "tool-invocation" && lastPart.stage === "receiving") {
4157
- lastPart.__appendDelta?.(delta.delta);
4056
+ const parentId = this.#_parentKeyFn(item);
4057
+ const siblings = this.#_childrenOf.get(parentId);
4058
+ if (siblings) {
4059
+ siblings.delete(pk);
4060
+ if (siblings.size === 0) {
4061
+ this.#_childrenOf.delete(parentId);
4158
4062
  }
4159
- break;
4160
4063
  }
4161
- case "tool-invocation":
4162
- replaceOrAppend(content, delta, (x) => x.invocationId, now2);
4163
- break;
4164
- case "retrieval":
4165
- replaceOrAppend(content, delta, (x) => x.id, now2);
4166
- break;
4167
- default:
4168
- return assertNever(delta, "Unhandled case");
4064
+ this.#_sorted.remove(item);
4065
+ this.#_childrenOf.delete(pk);
4066
+ this.#_items.delete(pk);
4067
+ return true;
4068
+ }
4069
+ clear() {
4070
+ if (this.#_items.size === 0) return false;
4071
+ this.#_childrenOf.clear();
4072
+ this.#_items.clear();
4073
+ this.#_sorted.clear();
4074
+ return true;
4169
4075
  }
4076
+ };
4077
+
4078
+ // src/protocol/AuthToken.ts
4079
+ var Permission = /* @__PURE__ */ ((Permission2) => {
4080
+ Permission2["Read"] = "room:read";
4081
+ Permission2["Write"] = "room:write";
4082
+ Permission2["PresenceWrite"] = "room:presence:write";
4083
+ Permission2["CommentsWrite"] = "comments:write";
4084
+ Permission2["CommentsRead"] = "comments:read";
4085
+ return Permission2;
4086
+ })(Permission || {});
4087
+ function canWriteStorage(scopes) {
4088
+ return scopes.includes("room:write" /* Write */);
4170
4089
  }
4171
- function createReceivingToolInvocation(invocationId, name, partialArgsText = "") {
4172
- const parser = new IncrementalJsonParser(partialArgsText);
4090
+ function canComment(scopes) {
4091
+ return scopes.includes("comments:write" /* CommentsWrite */) || scopes.includes("room:write" /* Write */);
4092
+ }
4093
+ function isValidAuthTokenPayload(data) {
4094
+ return isPlainObject(data) && (data.k === "acc" /* ACCESS_TOKEN */ || data.k === "id" /* ID_TOKEN */ || data.k === "sec-legacy" /* SECRET_LEGACY */);
4095
+ }
4096
+ function parseAuthToken(rawTokenString) {
4097
+ const tokenParts = rawTokenString.split(".");
4098
+ if (tokenParts.length !== 3) {
4099
+ throw new Error("Authentication error: invalid JWT token");
4100
+ }
4101
+ const payload = tryParseJson(b64decode(tokenParts[1]));
4102
+ if (!(payload && isValidAuthTokenPayload(payload))) {
4103
+ throw new Error(
4104
+ "Authentication error: expected a valid token but did not get one. Hint: if you are using a callback, ensure the room is passed when creating the token. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClientCallback"
4105
+ );
4106
+ }
4173
4107
  return {
4174
- type: "tool-invocation",
4175
- stage: "receiving",
4176
- invocationId,
4177
- name,
4178
- // --- Alternative implementation for FRONTEND only ------------------------
4179
- get partialArgsText() {
4180
- return parser.source;
4181
- },
4182
- // prettier-ignore
4183
- get partialArgs() {
4184
- return parser.json;
4185
- },
4186
- // prettier-ignore
4187
- __appendDelta(delta) {
4188
- parser.append(delta);
4189
- }
4190
- // prettier-ignore
4191
- // ------------------------------------------------------------------------
4108
+ raw: rawTokenString,
4109
+ parsed: payload
4192
4110
  };
4193
4111
  }
4194
4112
 
@@ -4687,6 +4605,7 @@ function createAi(config) {
4687
4605
  toolsStore,
4688
4606
  knowledgeStore
4689
4607
  };
4608
+ const status\u03A3 = new Signal("initial");
4690
4609
  const DELTA_THROTTLE = 25;
4691
4610
  let pendingDeltas = [];
4692
4611
  let deltaBatchTimer = null;
@@ -4710,7 +4629,7 @@ function createAi(config) {
4710
4629
  }
4711
4630
  }
4712
4631
  let lastTokenKey;
4713
- function onStatusDidChange(_newStatus) {
4632
+ function onStatusDidChange(newStatus) {
4714
4633
  const authValue = managedSocket.authValue;
4715
4634
  if (authValue !== null) {
4716
4635
  const tokenKey = getBearerTokenFromAuthValue(authValue);
@@ -4730,6 +4649,7 @@ function createAi(config) {
4730
4649
  }
4731
4650
  }
4732
4651
  }
4652
+ status\u03A3.set(newStatus);
4733
4653
  }
4734
4654
  let _connectionLossTimerId;
4735
4655
  let _hasLostConnection = false;
@@ -4988,7 +4908,8 @@ function createAi(config) {
4988
4908
  getStatus: () => managedSocket.getStatus(),
4989
4909
  signals: {
4990
4910
  getChatMessagesForBranch\u03A3: context.messagesStore.getChatMessagesForBranch\u03A3,
4991
- getTool\u03A3: context.toolsStore.getTool\u03A3
4911
+ getTool\u03A3: context.toolsStore.getTool\u03A3,
4912
+ status\u03A3
4992
4913
  },
4993
4914
  getChatById: context.chatsStore.getChatById,
4994
4915
  queryChats: context.chatsStore.findMany,
@@ -5021,7 +4942,7 @@ function makeCreateSocketDelegateForAi(baseUrl, WebSocketPolyfill) {
5021
4942
  }
5022
4943
  const url2 = new URL(baseUrl);
5023
4944
  url2.protocol = url2.protocol === "http:" ? "ws" : "wss";
5024
- url2.pathname = "/ai/v6";
4945
+ url2.pathname = "/ai/v7";
5025
4946
  if (authValue.type === "secret") {
5026
4947
  url2.searchParams.set("tok", authValue.token.raw);
5027
4948
  } else if (authValue.type === "public") {
@@ -5033,6 +4954,112 @@ function makeCreateSocketDelegateForAi(baseUrl, WebSocketPolyfill) {
5033
4954
  return new ws(url2.toString());
5034
4955
  };
5035
4956
  }
4957
+ function replaceOrAppend(content, newItem, keyFn, now2) {
4958
+ const existingIndex = findLastIndex(
4959
+ content,
4960
+ (item) => item.type === newItem.type && keyFn(item) === keyFn(newItem)
4961
+ );
4962
+ if (existingIndex > -1) {
4963
+ content[existingIndex] = newItem;
4964
+ } else {
4965
+ closePart(content[content.length - 1], now2);
4966
+ content.push(newItem);
4967
+ }
4968
+ }
4969
+ function closePart(prevPart, endedAt) {
4970
+ if (prevPart?.type === "reasoning") {
4971
+ prevPart.endedAt ??= endedAt;
4972
+ }
4973
+ }
4974
+ function patchContentWithDelta(content, delta) {
4975
+ if (delta === null)
4976
+ return;
4977
+ const parts = content.filter(
4978
+ (part) => part.type !== "sources"
4979
+ );
4980
+ const sources = content.filter((part) => part.type === "sources").flatMap((part) => part.sources);
4981
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
4982
+ const lastPart = parts[parts.length - 1];
4983
+ switch (delta.type) {
4984
+ case "text-delta":
4985
+ if (lastPart?.type === "text") {
4986
+ lastPart.text += delta.textDelta;
4987
+ } else {
4988
+ closePart(lastPart, now2);
4989
+ parts.push({ type: "text", text: delta.textDelta });
4990
+ }
4991
+ break;
4992
+ case "reasoning-delta":
4993
+ if (lastPart?.type === "reasoning") {
4994
+ lastPart.text += delta.textDelta;
4995
+ } else {
4996
+ closePart(lastPart, now2);
4997
+ parts.push({
4998
+ type: "reasoning",
4999
+ text: delta.textDelta,
5000
+ startedAt: now2
5001
+ });
5002
+ }
5003
+ break;
5004
+ case "tool-stream": {
5005
+ const toolInvocation = createReceivingToolInvocation(
5006
+ delta.invocationId,
5007
+ delta.name
5008
+ );
5009
+ parts.push(toolInvocation);
5010
+ break;
5011
+ }
5012
+ case "tool-delta": {
5013
+ if (lastPart?.type === "tool-invocation" && lastPart.stage === "receiving") {
5014
+ lastPart.__appendDelta?.(delta.delta);
5015
+ }
5016
+ break;
5017
+ }
5018
+ case "tool-invocation":
5019
+ replaceOrAppend(parts, delta, (x) => x.invocationId, now2);
5020
+ break;
5021
+ case "retrieval":
5022
+ replaceOrAppend(parts, delta, (x) => x.id, now2);
5023
+ break;
5024
+ case "source": {
5025
+ sources.push(delta);
5026
+ break;
5027
+ }
5028
+ default:
5029
+ return assertNever(delta, "Unhandled case");
5030
+ }
5031
+ if (sources.length > 0) {
5032
+ parts.push({
5033
+ type: "sources",
5034
+ sources
5035
+ });
5036
+ }
5037
+ content.length = 0;
5038
+ content.push(...parts);
5039
+ }
5040
+ function createReceivingToolInvocation(invocationId, name, partialArgsText = "") {
5041
+ const parser = new IncrementalJsonParser(partialArgsText);
5042
+ return {
5043
+ type: "tool-invocation",
5044
+ stage: "receiving",
5045
+ invocationId,
5046
+ name,
5047
+ // --- Alternative implementation for FRONTEND only ------------------------
5048
+ get partialArgsText() {
5049
+ return parser.source;
5050
+ },
5051
+ // prettier-ignore
5052
+ get partialArgs() {
5053
+ return parser.json;
5054
+ },
5055
+ // prettier-ignore
5056
+ __appendDelta(delta) {
5057
+ parser.append(delta);
5058
+ }
5059
+ // prettier-ignore
5060
+ // ------------------------------------------------------------------------
5061
+ };
5062
+ }
5036
5063
 
5037
5064
  // src/auth-manager.ts
5038
5065
  function createAuthManager(authOptions, onAuthenticate) {
@@ -8161,16 +8188,6 @@ function findNonSerializableValue(value, path = "") {
8161
8188
  return false;
8162
8189
  }
8163
8190
 
8164
- // src/lib/debug.ts
8165
- function captureStackTrace(msg, traceRoot) {
8166
- const errorLike = { name: msg };
8167
- if (typeof Error.captureStackTrace !== "function") {
8168
- return void 0;
8169
- }
8170
- Error.captureStackTrace(errorLike, traceRoot);
8171
- return errorLike.stack;
8172
- }
8173
-
8174
8191
  // src/lib/Deque.ts
8175
8192
  var Deque = class {
8176
8193
  #data;
@@ -8581,9 +8598,7 @@ function createRoom(options, config) {
8581
8598
  redoStack: [],
8582
8599
  pausedHistory: null,
8583
8600
  activeBatch: null,
8584
- unacknowledgedOps: /* @__PURE__ */ new Map(),
8585
- // Debug
8586
- opStackTraces: process.env.NODE_ENV !== "production" ? /* @__PURE__ */ new Map() : void 0
8601
+ unacknowledgedOps: /* @__PURE__ */ new Map()
8587
8602
  };
8588
8603
  let lastTokenKey;
8589
8604
  function onStatusDidChange(newStatus) {
@@ -8667,16 +8682,6 @@ function createRoom(options, config) {
8667
8682
  }
8668
8683
  });
8669
8684
  function onDispatch(ops, reverse, storageUpdates) {
8670
- if (process.env.NODE_ENV !== "production") {
8671
- const stackTrace = captureStackTrace("Storage mutation", onDispatch);
8672
- if (stackTrace) {
8673
- for (const op of ops) {
8674
- if (op.opId) {
8675
- nn(context.opStackTraces).set(op.opId, stackTrace);
8676
- }
8677
- }
8678
- }
8679
- }
8680
8685
  if (context.activeBatch) {
8681
8686
  for (const op of ops) {
8682
8687
  context.activeBatch.ops.push(op);
@@ -8993,9 +8998,6 @@ function createRoom(options, config) {
8993
8998
  source = 0 /* UNDOREDO_RECONNECT */;
8994
8999
  } else {
8995
9000
  const opId = nn(op.opId);
8996
- if (process.env.NODE_ENV !== "production") {
8997
- nn(context.opStackTraces).delete(opId);
8998
- }
8999
9001
  const deleted = context.unacknowledgedOps.delete(opId);
9000
9002
  source = deleted ? 2 /* ACK */ : 1 /* REMOTE */;
9001
9003
  }
@@ -9281,38 +9283,6 @@ function createRoom(options, config) {
9281
9283
  }
9282
9284
  break;
9283
9285
  }
9284
- // Receiving a RejectedOps message in the client means that the server is no
9285
- // longer in sync with the client. Trying to synchronize the client again by
9286
- // rolling back particular Ops may be hard/impossible. It's fine to not try and
9287
- // accept the out-of-sync reality and throw an error. We look at this kind of bug
9288
- // as a developer-owned bug. In production, these errors are not expected to happen.
9289
- case 299 /* REJECT_STORAGE_OP */: {
9290
- errorWithTitle(
9291
- "Storage mutation rejection error",
9292
- message.reason
9293
- );
9294
- if (process.env.NODE_ENV !== "production") {
9295
- const traces = /* @__PURE__ */ new Set();
9296
- for (const opId of message.opIds) {
9297
- const trace = context.opStackTraces?.get(opId);
9298
- if (trace) {
9299
- traces.add(trace);
9300
- }
9301
- }
9302
- if (traces.size > 0) {
9303
- warnWithTitle(
9304
- "The following function calls caused the rejected storage mutations:",
9305
- `
9306
-
9307
- ${Array.from(traces).join("\n\n")}`
9308
- );
9309
- }
9310
- throw new Error(
9311
- `Storage mutations rejected by server: ${message.reason}`
9312
- );
9313
- }
9314
- break;
9315
- }
9316
9286
  case 400 /* THREAD_CREATED */:
9317
9287
  case 407 /* THREAD_DELETED */:
9318
9288
  case 401 /* THREAD_METADATA_UPDATED */:
@@ -9325,6 +9295,8 @@ ${Array.from(traces).join("\n\n")}`
9325
9295
  eventHub.comments.notify(message);
9326
9296
  break;
9327
9297
  }
9298
+ default:
9299
+ break;
9328
9300
  }
9329
9301
  }
9330
9302
  notify(updates);