@axiom-lattice/client-sdk 4.3.4 → 4.3.6

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.
Files changed (37) hide show
  1. package/dist/__tests__/project-rooms.test.js +0 -66
  2. package/dist/__tests__/project-rooms.test.js.map +1 -1
  3. package/dist/__tests__/room-events.test.d.ts +2 -0
  4. package/dist/__tests__/room-events.test.d.ts.map +1 -0
  5. package/dist/__tests__/room-events.test.js +144 -0
  6. package/dist/__tests__/room-events.test.js.map +1 -0
  7. package/dist/__tests__/workspace-rooms.test.d.ts +2 -0
  8. package/dist/__tests__/workspace-rooms.test.d.ts.map +1 -0
  9. package/dist/__tests__/workspace-rooms.test.js +116 -0
  10. package/dist/__tests__/workspace-rooms.test.js.map +1 -0
  11. package/dist/client.d.ts +4 -0
  12. package/dist/client.d.ts.map +1 -1
  13. package/dist/client.js +4 -0
  14. package/dist/client.js.map +1 -1
  15. package/dist/index.d.ts +137 -46
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +300 -181
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +298 -181
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/project-room-hydrators.d.ts +18 -0
  22. package/dist/project-room-hydrators.d.ts.map +1 -0
  23. package/dist/project-room-hydrators.js +95 -0
  24. package/dist/project-room-hydrators.js.map +1 -0
  25. package/dist/project-rooms.d.ts +3 -51
  26. package/dist/project-rooms.d.ts.map +1 -1
  27. package/dist/project-rooms.js +5 -178
  28. package/dist/project-rooms.js.map +1 -1
  29. package/dist/room-events.d.ts +108 -0
  30. package/dist/room-events.d.ts.map +1 -0
  31. package/dist/room-events.js +127 -0
  32. package/dist/room-events.js.map +1 -0
  33. package/dist/workspace-rooms.d.ts +26 -0
  34. package/dist/workspace-rooms.d.ts.map +1 -0
  35. package/dist/workspace-rooms.js +67 -0
  36. package/dist/workspace-rooms.js.map +1 -0
  37. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -2336,7 +2336,7 @@ var AbstractClient = class {
2336
2336
  const query = searchParams.toString();
2337
2337
  const response = await this.makeRequest(`/api/web-apps${query ? `?${query}` : ""}`);
2338
2338
  return {
2339
- records: response.data.records.map((record2) => this.hydrateAgentWebApp(record2)),
2339
+ records: response.data.records.map((record3) => this.hydrateAgentWebApp(record3)),
2340
2340
  total: response.data.total
2341
2341
  };
2342
2342
  },
@@ -2977,19 +2977,19 @@ var AbstractClient = class {
2977
2977
  if (!value || typeof value !== "object" || Array.isArray(value)) {
2978
2978
  throw new ApiError("Invalid Agent Web App response", 500, value);
2979
2979
  }
2980
- const record2 = value;
2980
+ const record3 = value;
2981
2981
  const hydrateDate = (field) => {
2982
- const raw = record2[field];
2983
- const date2 = raw instanceof Date ? new Date(raw.getTime()) : new Date(
2982
+ const raw = record3[field];
2983
+ const date3 = raw instanceof Date ? new Date(raw.getTime()) : new Date(
2984
2984
  typeof raw === "string" || typeof raw === "number" ? raw : Number.NaN
2985
2985
  );
2986
- if (Number.isNaN(date2.getTime())) {
2986
+ if (Number.isNaN(date3.getTime())) {
2987
2987
  throw new ApiError(`Invalid Agent Web App ${field}`, 500, value);
2988
2988
  }
2989
- return date2;
2989
+ return date3;
2990
2990
  };
2991
2991
  return {
2992
- ...record2,
2992
+ ...record3,
2993
2993
  createdAt: hydrateDate("createdAt"),
2994
2994
  updatedAt: hydrateDate("updatedAt")
2995
2995
  };
@@ -3429,115 +3429,7 @@ var ExportImportClient = class {
3429
3429
  }
3430
3430
  };
3431
3431
 
3432
- // src/sse-parser.ts
3433
- var SseParseError = class extends Error {
3434
- constructor(message) {
3435
- super(message);
3436
- this.code = "INVALID_EVENT";
3437
- this.name = "SseParseError";
3438
- }
3439
- };
3440
- async function* parseSseBody(body, options = {}) {
3441
- const reader = body.getReader();
3442
- const decoder = new TextDecoder();
3443
- let buffer = "";
3444
- let event = "";
3445
- let id;
3446
- let retry;
3447
- let data = [];
3448
- const dispatch = () => {
3449
- if (data.length === 0) {
3450
- event = "";
3451
- id = void 0;
3452
- retry = void 0;
3453
- return void 0;
3454
- }
3455
- let parsed;
3456
- try {
3457
- parsed = JSON.parse(data.join("\n"));
3458
- } catch {
3459
- throw new SseParseError("Invalid SSE JSON");
3460
- }
3461
- if (options.strictJsonObject && (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)))
3462
- throw new SseParseError("SSE data must be an object");
3463
- const result = { event, data: parsed, ...id === void 0 ? {} : { id }, ...retry === void 0 ? {} : { retry } };
3464
- event = "";
3465
- id = void 0;
3466
- retry = void 0;
3467
- data = [];
3468
- return result;
3469
- };
3470
- const processLine = (raw) => {
3471
- const line = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
3472
- if (line === "")
3473
- return dispatch();
3474
- if (line.startsWith(":"))
3475
- return void 0;
3476
- const separator = line.indexOf(":");
3477
- const field = separator < 0 ? line : line.slice(0, separator);
3478
- let value = separator < 0 ? "" : line.slice(separator + 1);
3479
- if (value.startsWith(" "))
3480
- value = value.slice(1);
3481
- if (field === "event")
3482
- event = value;
3483
- else if (field === "data")
3484
- data.push(value);
3485
- else if (field === "id")
3486
- id = value;
3487
- else if (field === "retry") {
3488
- const parsed = Number(value);
3489
- if (!Number.isInteger(parsed) || parsed < 0 || !Number.isFinite(parsed))
3490
- throw new SseParseError("Invalid SSE retry");
3491
- retry = parsed;
3492
- }
3493
- return void 0;
3494
- };
3495
- try {
3496
- while (true) {
3497
- const chunk = await reader.read();
3498
- if (chunk.done) {
3499
- buffer += decoder.decode();
3500
- break;
3501
- }
3502
- buffer += decoder.decode(chunk.value, { stream: true });
3503
- let index = findLineBreak(buffer);
3504
- while (index >= 0) {
3505
- if (buffer[index] === "\r" && index === buffer.length - 1)
3506
- break;
3507
- const frame2 = processLine(buffer.slice(0, index));
3508
- buffer = buffer.slice(index + lineBreakLength(buffer, index));
3509
- if (frame2)
3510
- yield frame2;
3511
- index = findLineBreak(buffer);
3512
- }
3513
- }
3514
- if (buffer) {
3515
- const frame2 = processLine(buffer);
3516
- if (frame2)
3517
- yield frame2;
3518
- }
3519
- const frame = processLine("");
3520
- if (frame)
3521
- yield frame;
3522
- } finally {
3523
- await reader.cancel().catch(() => void 0);
3524
- reader.releaseLock();
3525
- }
3526
- }
3527
- function findLineBreak(value) {
3528
- const lf = value.indexOf("\n");
3529
- const cr = value.indexOf("\r");
3530
- if (lf < 0)
3531
- return cr;
3532
- if (cr < 0)
3533
- return lf;
3534
- return Math.min(lf, cr);
3535
- }
3536
- function lineBreakLength(value, index) {
3537
- return value[index] === "\r" && value[index + 1] === "\n" ? 2 : 1;
3538
- }
3539
-
3540
- // src/project-rooms.ts
3432
+ // src/project-room-hydrators.ts
3541
3433
  var ProjectRoomClientError = class extends Error {
3542
3434
  constructor(message, status, code, retryable, details) {
3543
3435
  super(message);
@@ -3555,10 +3447,10 @@ var date = (value, field) => {
3555
3447
  throw new ProjectRoomClientError(`Invalid ${field}`, 500, "INVALID_RESPONSE", false);
3556
3448
  return result;
3557
3449
  };
3558
- var requiredString = (record2, field) => {
3559
- if (typeof record2[field] !== "string")
3450
+ var requiredString = (record3, field) => {
3451
+ if (typeof record3[field] !== "string")
3560
3452
  throw new ProjectRoomClientError(`Invalid ${field}`, 500, "INVALID_RESPONSE", false);
3561
- return record2[field];
3453
+ return record3[field];
3562
3454
  };
3563
3455
  var oneOf = (value, values, field) => {
3564
3456
  if (typeof value !== "string" || !values.includes(value))
@@ -3629,13 +3521,23 @@ var hydrateBot = (value) => {
3629
3521
  exactKeys(row, ["id", "tenantId", "workspaceId", "projectId", "roomId", "assistantId", "role", "title", "mentionName", "status", "roomThreadId", "joinedAt", "updatedAt"], ["responsibility"]);
3630
3522
  return { id: requiredString(row, "id"), tenantId: requiredString(row, "tenantId"), workspaceId: requiredString(row, "workspaceId"), projectId: requiredString(row, "projectId"), roomId: requiredString(row, "roomId"), assistantId: requiredString(row, "assistantId"), role: oneOf(row.role, botRoles, "role"), title: requiredString(row, "title"), ...row.responsibility === void 0 ? {} : { responsibility: requiredString(row, "responsibility") }, mentionName: requiredString(row, "mentionName"), status: oneOf(row.status, botStatuses, "status"), roomThreadId: requiredString(row, "roomThreadId"), joinedAt: date(row.joinedAt, "joinedAt"), updatedAt: date(row.updatedAt, "updatedAt") };
3631
3523
  };
3632
- var iso = (value) => date(value, "date").toISOString();
3633
3524
  var hydrateDispatch = (value) => {
3634
3525
  const row = record(value);
3635
3526
  if (typeof row.success !== "boolean" || row.membershipId !== void 0 && typeof row.membershipId !== "string" || row.errorCode !== void 0 && typeof row.errorCode !== "string")
3636
3527
  throw new ProjectRoomClientError("Invalid dispatch response", 500, "INVALID_RESPONSE", false);
3637
3528
  return { success: row.success, ...row.membershipId === void 0 ? {} : { membershipId: row.membershipId }, ...row.errorCode === void 0 ? {} : { errorCode: row.errorCode } };
3638
3529
  };
3530
+ function hydratePublicMember(value) {
3531
+ const row = record(value);
3532
+ return { id: requiredString(row, "id"), userId: requiredString(row, "userId"), role: row.role, status: row.status, joinedAt: date(row.joinedAt, "joinedAt"), updatedAt: date(row.updatedAt, "updatedAt") };
3533
+ }
3534
+ function hydratePublicBot(value) {
3535
+ const row = record(value);
3536
+ return { id: requiredString(row, "id"), role: row.role, title: requiredString(row, "title"), ...row.responsibility === void 0 ? {} : { responsibility: row.responsibility }, mentionName: requiredString(row, "mentionName"), status: row.status, joinedAt: date(row.joinedAt, "joinedAt"), updatedAt: date(row.updatedAt, "updatedAt") };
3537
+ }
3538
+
3539
+ // src/project-rooms.ts
3540
+ var iso = (value) => date(value, "date").toISOString();
3639
3541
  var encode = encodeURIComponent;
3640
3542
  var ProjectRoomsClient = class {
3641
3543
  constructor(baseURL, getHeaders) {
@@ -3666,6 +3568,9 @@ var ProjectRoomsClient = class {
3666
3568
  if (!Array.isArray(result))
3667
3569
  throw new ProjectRoomClientError("Invalid retry response", 500, "INVALID_RESPONSE", false);
3668
3570
  return result.map(hydrateDispatch);
3571
+ },
3572
+ markRead: async (projectId) => {
3573
+ await this.request(`/api/projects/${encode(projectId)}/room/read-state`, { method: "POST", body: {} });
3669
3574
  }
3670
3575
  };
3671
3576
  this.members = {
@@ -3682,14 +3587,10 @@ var ProjectRoomsClient = class {
3682
3587
  resume: async (projectId, membershipId, input) => hydrateBot(await this.request(`/api/projects/${encode(projectId)}/bots/${encode(membershipId)}/resume`, { method: "POST", body: { expectedUpdatedAt: iso(input.expectedUpdatedAt) } })),
3683
3588
  remove: async (projectId, membershipId, input) => this.request(`/api/projects/${encode(projectId)}/bots/${encode(membershipId)}?expectedUpdatedAt=${encode(iso(input.expectedUpdatedAt))}`, { method: "DELETE" })
3684
3589
  };
3685
- this.events = { connect: (projectId, options) => this.connect(projectId, options) };
3686
3590
  }
3687
3591
  async getRoom(projectId) {
3688
3592
  return hydrateRoom(await this.request(`/api/projects/${encode(projectId)}/room`));
3689
3593
  }
3690
- async getRealtimeMode(projectId) {
3691
- return this.request(`/api/projects/${encode(projectId)}/room/realtime-mode`);
3692
- }
3693
3594
  async records(path, hydrate) {
3694
3595
  const result = await this.request(path);
3695
3596
  if (!Array.isArray(result))
@@ -3709,25 +3610,285 @@ var ProjectRoomsClient = class {
3709
3610
  throw new ProjectRoomClientError("Missing response data", 500, "INVALID_RESPONSE", false);
3710
3611
  return payload.data;
3711
3612
  }
3712
- connect(projectId, options) {
3713
- const headers = { ...this.getHeaders(), Accept: "text/event-stream", ...options.lastEventId ? { "Last-Event-ID": options.lastEventId } : {} };
3613
+ };
3614
+
3615
+ // src/workspace-rooms.ts
3616
+ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3617
+ var record2 = (value) => {
3618
+ if (!isRecord2(value))
3619
+ throw new ProjectRoomClientError("Invalid workspace rooms response", 500, "INVALID_RESPONSE", false);
3620
+ return value;
3621
+ };
3622
+ var requiredString2 = (row, field) => {
3623
+ if (typeof row[field] !== "string")
3624
+ throw new ProjectRoomClientError(`Invalid ${field}`, 500, "INVALID_RESPONSE", false);
3625
+ return row[field];
3626
+ };
3627
+ var date2 = (value, field) => {
3628
+ const result = value instanceof Date ? new Date(value.getTime()) : new Date(typeof value === "string" ? value : Number.NaN);
3629
+ if (!Number.isFinite(result.getTime()))
3630
+ throw new ProjectRoomClientError(`Invalid ${field}`, 500, "INVALID_RESPONSE", false);
3631
+ return result;
3632
+ };
3633
+ var hydrateProject = (value) => {
3634
+ const row = record2(value);
3635
+ return {
3636
+ id: requiredString2(row, "id"),
3637
+ tenantId: requiredString2(row, "tenantId"),
3638
+ workspaceId: requiredString2(row, "workspaceId"),
3639
+ name: requiredString2(row, "name"),
3640
+ ...row.description === void 0 ? {} : { description: requiredString2(row, "description") },
3641
+ ...row.config === void 0 ? {} : { config: row.config },
3642
+ ...row.kind === void 0 ? {} : { kind: requiredString2(row, "kind") },
3643
+ createdAt: date2(row.createdAt, "createdAt"),
3644
+ updatedAt: date2(row.updatedAt, "updatedAt")
3645
+ };
3646
+ };
3647
+ var hydrateEntry = (value) => {
3648
+ const row = record2(value);
3649
+ const names = row.participantNames;
3650
+ if (!Array.isArray(names) || names.some((n) => typeof n !== "string"))
3651
+ throw new ProjectRoomClientError("Invalid participantNames", 500, "INVALID_RESPONSE", false);
3652
+ if (typeof row.participantCount !== "number" || typeof row.unreadCount !== "number")
3653
+ throw new ProjectRoomClientError("Invalid room entry counts", 500, "INVALID_RESPONSE", false);
3654
+ return {
3655
+ project: hydrateProject(row.project),
3656
+ room: hydrateRoom(row.room),
3657
+ ...row.lastMessage === void 0 ? {} : { lastMessage: hydrateMessage(row.lastMessage) },
3658
+ participantCount: row.participantCount,
3659
+ participantNames: names,
3660
+ ...row.isPublic === void 0 ? {} : { isPublic: row.isPublic === true },
3661
+ unreadCount: row.unreadCount
3662
+ };
3663
+ };
3664
+ var WorkspaceRoomsClient = class {
3665
+ constructor(baseURL, getHeaders) {
3666
+ this.baseURL = baseURL;
3667
+ this.getHeaders = getHeaders;
3668
+ }
3669
+ /** Lists the user's rooms in a workspace with last message and unread count. */
3670
+ async list(workspaceId) {
3671
+ const response = await fetch(`${this.baseURL}/api/workspaces/${encodeURIComponent(workspaceId)}/rooms`, { headers: this.getHeaders() });
3672
+ const payload = await response.json().catch(() => void 0);
3673
+ if (!response.ok || !payload?.success) {
3674
+ const error = payload?.error;
3675
+ throw new ProjectRoomClientError(typeof error?.message === "string" ? error.message : "Workspace rooms request failed", response.status, typeof error?.code === "string" ? error.code : response.ok ? "INVALID_RESPONSE" : "HTTP_ERROR", error?.retryable === true, error?.details);
3676
+ }
3677
+ if (!payload.data || !Array.isArray(payload.data.rooms))
3678
+ throw new ProjectRoomClientError("Invalid workspace rooms response", 500, "INVALID_RESPONSE", false);
3679
+ return payload.data.rooms.map(hydrateEntry);
3680
+ }
3681
+ };
3682
+
3683
+ // src/sse-parser.ts
3684
+ var SseParseError = class extends Error {
3685
+ constructor(message) {
3686
+ super(message);
3687
+ this.code = "INVALID_EVENT";
3688
+ this.name = "SseParseError";
3689
+ }
3690
+ };
3691
+ async function* parseSseBody(body, options = {}) {
3692
+ const reader = body.getReader();
3693
+ const decoder = new TextDecoder();
3694
+ let buffer = "";
3695
+ let event = "";
3696
+ let id;
3697
+ let retry;
3698
+ let data = [];
3699
+ const dispatch = () => {
3700
+ if (data.length === 0) {
3701
+ event = "";
3702
+ id = void 0;
3703
+ retry = void 0;
3704
+ return void 0;
3705
+ }
3706
+ let parsed;
3707
+ try {
3708
+ parsed = JSON.parse(data.join("\n"));
3709
+ } catch {
3710
+ throw new SseParseError("Invalid SSE JSON");
3711
+ }
3712
+ if (options.strictJsonObject && (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)))
3713
+ throw new SseParseError("SSE data must be an object");
3714
+ const result = { event, data: parsed, ...id === void 0 ? {} : { id }, ...retry === void 0 ? {} : { retry } };
3715
+ event = "";
3716
+ id = void 0;
3717
+ retry = void 0;
3718
+ data = [];
3719
+ return result;
3720
+ };
3721
+ const processLine = (raw) => {
3722
+ const line = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
3723
+ if (line === "")
3724
+ return dispatch();
3725
+ if (line.startsWith(":"))
3726
+ return void 0;
3727
+ const separator = line.indexOf(":");
3728
+ const field = separator < 0 ? line : line.slice(0, separator);
3729
+ let value = separator < 0 ? "" : line.slice(separator + 1);
3730
+ if (value.startsWith(" "))
3731
+ value = value.slice(1);
3732
+ if (field === "event")
3733
+ event = value;
3734
+ else if (field === "data")
3735
+ data.push(value);
3736
+ else if (field === "id")
3737
+ id = value;
3738
+ else if (field === "retry") {
3739
+ const parsed = Number(value);
3740
+ if (!Number.isInteger(parsed) || parsed < 0 || !Number.isFinite(parsed))
3741
+ throw new SseParseError("Invalid SSE retry");
3742
+ retry = parsed;
3743
+ }
3744
+ return void 0;
3745
+ };
3746
+ try {
3747
+ while (true) {
3748
+ const chunk = await reader.read();
3749
+ if (chunk.done) {
3750
+ buffer += decoder.decode();
3751
+ break;
3752
+ }
3753
+ buffer += decoder.decode(chunk.value, { stream: true });
3754
+ let index = findLineBreak(buffer);
3755
+ while (index >= 0) {
3756
+ if (buffer[index] === "\r" && index === buffer.length - 1)
3757
+ break;
3758
+ const frame2 = processLine(buffer.slice(0, index));
3759
+ buffer = buffer.slice(index + lineBreakLength(buffer, index));
3760
+ if (frame2)
3761
+ yield frame2;
3762
+ index = findLineBreak(buffer);
3763
+ }
3764
+ }
3765
+ if (buffer) {
3766
+ const frame2 = processLine(buffer);
3767
+ if (frame2)
3768
+ yield frame2;
3769
+ }
3770
+ const frame = processLine("");
3771
+ if (frame)
3772
+ yield frame;
3773
+ } finally {
3774
+ await reader.cancel().catch(() => void 0);
3775
+ reader.releaseLock();
3776
+ }
3777
+ }
3778
+ function findLineBreak(value) {
3779
+ const lf = value.indexOf("\n");
3780
+ const cr = value.indexOf("\r");
3781
+ if (lf < 0)
3782
+ return cr;
3783
+ if (cr < 0)
3784
+ return lf;
3785
+ return Math.min(lf, cr);
3786
+ }
3787
+ function lineBreakLength(value, index) {
3788
+ return value[index] === "\r" && value[index + 1] === "\n" ? 2 : 1;
3789
+ }
3790
+
3791
+ // src/room-events.ts
3792
+ var invalidFrame = (message) => new ProjectRoomClientError(message, 200, "INVALID_EVENT", false);
3793
+ var requiredString3 = (row, field) => {
3794
+ if (typeof row[field] !== "string")
3795
+ throw invalidFrame(`Invalid ${field}`);
3796
+ return row[field];
3797
+ };
3798
+ var oneOf2 = (value, values, field) => {
3799
+ if (typeof value !== "string" || !values.includes(value))
3800
+ throw invalidFrame(`Invalid ${field}`);
3801
+ return value;
3802
+ };
3803
+ var hydrateScope = (value) => {
3804
+ if (!isRecord(value))
3805
+ throw invalidFrame("Invalid scope");
3806
+ return { tenantId: requiredString3(value, "tenantId"), roomId: requiredString3(value, "roomId"), projectId: requiredString3(value, "projectId") };
3807
+ };
3808
+ var hydrateControl = (event, payload) => {
3809
+ if (event === "ready") {
3810
+ if (typeof payload.epoch !== "string" || payload.headEventId !== null && typeof payload.headEventId !== "string" || Object.keys(payload).some((key) => key !== "epoch" && key !== "headEventId"))
3811
+ throw invalidFrame("Invalid SSE control");
3812
+ return { type: "ready", data: { epoch: payload.epoch, headEventId: payload.headEventId } };
3813
+ }
3814
+ if (Object.keys(payload).some((key) => key !== "reason"))
3815
+ throw invalidFrame("Invalid SSE control");
3816
+ if (event === "resync")
3817
+ return { type: "resync", data: { reason: oneOf2(payload.reason, ["SERVER_RESTART", "CURSOR_EXPIRED", "SLOW_CONSUMER"], "reason") } };
3818
+ return { type: "access.revoked", data: { reason: oneOf2(payload.reason, ["PROJECT_ACCESS_REVOKED", "TOKEN_EXPIRED", "CONNECTION_SUPERSEDED"], "reason") } };
3819
+ };
3820
+ var ROOM_SCOPED_TYPES = ["message.created", "roster.changed", "membership.changed", "task.changed"];
3821
+ function hydrateWorkspaceFrame(raw) {
3822
+ const payload = isRecord(raw.data) ? raw.data : void 0;
3823
+ if (raw.event === "ready" || raw.event === "resync" || raw.event === "access.revoked") {
3824
+ if (!payload || Object.prototype.hasOwnProperty.call(payload, "type"))
3825
+ throw invalidFrame("Invalid SSE control");
3826
+ return hydrateControl(raw.event, payload);
3827
+ }
3828
+ if (typeof payload?.type !== "string" || payload.type !== raw.event || typeof payload.id !== "string" || raw.id !== payload.id)
3829
+ throw invalidFrame("Invalid SSE business event");
3830
+ const occurredAt = date(payload.occurredAt, "occurredAt");
3831
+ const scope = payload.scope === void 0 ? void 0 : hydrateScope(payload.scope);
3832
+ const roomScoped = ROOM_SCOPED_TYPES.includes(payload.type);
3833
+ if (roomScoped && scope === void 0)
3834
+ throw invalidFrame("Invalid SSE business event scope");
3835
+ const data = payload.data;
3836
+ if (payload.type === "message.created") {
3837
+ if (!isRecord(data))
3838
+ throw invalidFrame("Invalid SSE business event data");
3839
+ return { type: payload.type, id: payload.id, occurredAt, scope, data: { message: hydrateMessage(data.message) } };
3840
+ }
3841
+ if (payload.type === "roster.changed") {
3842
+ if (!isRecord(data))
3843
+ throw invalidFrame("Invalid SSE business event data");
3844
+ return { type: payload.type, id: payload.id, occurredAt, scope, data: { change: requiredString3(data, "change"), membership: hydratePublicBot(data.membership) } };
3845
+ }
3846
+ if (payload.type === "membership.changed") {
3847
+ if (!isRecord(data))
3848
+ throw invalidFrame("Invalid SSE business event data");
3849
+ return { type: payload.type, id: payload.id, occurredAt, scope, data: { change: requiredString3(data, "change"), membership: hydratePublicMember(data.membership) } };
3850
+ }
3851
+ if (payload.type === "task.changed") {
3852
+ if (!isRecord(data))
3853
+ throw invalidFrame("Invalid SSE business event data");
3854
+ return { type: payload.type, id: payload.id, occurredAt, scope, data: { taskId: requiredString3(data, "taskId"), status: requiredString3(data, "status"), ownerMembershipId: requiredString3(data, "ownerMembershipId"), updatedAt: date(data.updatedAt, "updatedAt") } };
3855
+ }
3856
+ if (payload.type === "read.changed") {
3857
+ if (!isRecord(data))
3858
+ throw invalidFrame("Invalid SSE business event data");
3859
+ return { type: payload.type, id: payload.id, occurredAt, data: { projectId: requiredString3(data, "projectId"), roomId: requiredString3(data, "roomId"), lastReadAt: date(data.lastReadAt, "lastReadAt") } };
3860
+ }
3861
+ if (payload.type === "membership.affected") {
3862
+ if (!isRecord(data))
3863
+ throw invalidFrame("Invalid SSE business event data");
3864
+ return { type: payload.type, id: payload.id, occurredAt, data: { change: oneOf2(data.change, ["added", "removed", "role_changed"], "change"), projectId: requiredString3(data, "projectId"), roomId: requiredString3(data, "roomId") } };
3865
+ }
3866
+ return { type: payload.type, id: payload.id, occurredAt, data: payload.data, ...scope === void 0 ? {} : { scope } };
3867
+ }
3868
+ var RoomEventsClient = class {
3869
+ constructor(baseURL, getHeaders) {
3870
+ this.baseURL = baseURL;
3871
+ this.getHeaders = getHeaders;
3872
+ }
3873
+ connect(workspaceId, options) {
3874
+ const headers = { ...this.getHeaders(), Accept: "text/event-stream" };
3714
3875
  let resolveOpen;
3715
3876
  let rejectOpen;
3716
3877
  const opened = new Promise((resolve, reject) => {
3717
3878
  resolveOpen = resolve;
3718
3879
  rejectOpen = reject;
3719
3880
  });
3720
- const responsePromise = fetch(`${this.baseURL}/api/projects/${encode(projectId)}/room/events`, { headers, signal: options.signal }).then(async (response) => {
3881
+ const responsePromise = fetch(`${this.baseURL}/api/workspaces/${encodeURIComponent(workspaceId)}/room-events`, { headers, signal: options.signal }).then(async (response) => {
3721
3882
  if (!response.ok) {
3722
3883
  const payload = await response.json().catch(() => void 0);
3723
3884
  const error = payload?.error;
3724
- throw new ProjectRoomClientError(typeof error?.message === "string" ? error.message : "Project Room stream failed", response.status, typeof error?.code === "string" ? error.code : "HTTP_ERROR", error?.retryable === true, error?.details);
3885
+ throw new ProjectRoomClientError(typeof error?.message === "string" ? error.message : "Workspace room events stream failed", response.status, typeof error?.code === "string" ? error.code : "HTTP_ERROR", error?.retryable === true, error?.details);
3725
3886
  }
3726
3887
  if (response.headers?.get && response.headers.get("content-type")?.split(";")[0].trim() !== "text/event-stream")
3727
- throw new ProjectRoomClientError("Project Room stream has invalid content type", response.status, "INVALID_RESPONSE", false);
3888
+ throw new ProjectRoomClientError("Workspace room events stream has invalid content type", response.status, "INVALID_RESPONSE", false);
3728
3889
  if (!response.body)
3729
- throw new ProjectRoomClientError("Project Room stream has no body", 500, "INVALID_RESPONSE", false);
3730
- resolveOpen({ status: 200, ...options.lastEventId === void 0 ? {} : { lastEventId: options.lastEventId } });
3890
+ throw new ProjectRoomClientError("Workspace room events stream has no body", 500, "INVALID_RESPONSE", false);
3891
+ resolveOpen({ status: 200 });
3731
3892
  return response;
3732
3893
  }).catch((error) => {
3733
3894
  rejectOpen(error);
@@ -3737,22 +3898,10 @@ var ProjectRoomsClient = class {
3737
3898
  const response = await responsePromise;
3738
3899
  const body = response.body;
3739
3900
  if (!body)
3740
- throw new ProjectRoomClientError("Project Room stream has no body", 500, "INVALID_RESPONSE", false);
3901
+ throw new ProjectRoomClientError("Workspace room events stream has no body", 500, "INVALID_RESPONSE", false);
3741
3902
  for await (const raw of parseSseBody(body, { strictJsonObject: true })) {
3742
3903
  try {
3743
- const event = raw.event;
3744
- const payload = isRecord(raw.data) ? raw.data : void 0;
3745
- let value = payload;
3746
- if (event === "ready" || event === "resync" || event === "access.revoked") {
3747
- if (!payload || Object.prototype.hasOwnProperty.call(payload, "type"))
3748
- throw new ProjectRoomClientError("Invalid SSE control", 200, "INVALID_EVENT", false);
3749
- value = { type: event, data: payload };
3750
- } else {
3751
- if (typeof payload?.type !== "string" || payload.type !== event || typeof payload.id !== "string" || raw.id !== payload.id)
3752
- throw new ProjectRoomClientError("Invalid SSE business event", 200, "INVALID_EVENT", false);
3753
- value = payload;
3754
- }
3755
- yield { event: hydrateEvent(value), ...raw.id === void 0 ? {} : { id: raw.id }, ...raw.retry === void 0 ? {} : { retry: raw.retry } };
3904
+ yield { event: hydrateWorkspaceFrame(raw), ...raw.id === void 0 ? {} : { id: raw.id }, ...raw.retry === void 0 ? {} : { retry: raw.retry } };
3756
3905
  } catch (error) {
3757
3906
  if (error instanceof ProjectRoomClientError && error.code === "INVALID_EVENT")
3758
3907
  throw new ProjectRoomClientError(error.message, 400, "INVALID_EVENT", false, error.details);
@@ -3767,42 +3916,6 @@ var ProjectRoomsClient = class {
3767
3916
  return { opened, [Symbol.asyncIterator]: () => stream };
3768
3917
  }
3769
3918
  };
3770
- function hydrateEvent(value) {
3771
- const row = record(value);
3772
- if (row.type === "ready") {
3773
- exactKeys(row, ["type", "data"]);
3774
- const data2 = record(row.data);
3775
- exactKeys(data2, ["epoch", "headEventId"]);
3776
- if (typeof data2.epoch !== "string" || data2.headEventId !== null && typeof data2.headEventId !== "string")
3777
- throw new ProjectRoomClientError("Invalid SSE control", 200, "INVALID_EVENT", false);
3778
- return { type: "ready", data: { epoch: data2.epoch, headEventId: data2.headEventId } };
3779
- }
3780
- if (row.type === "resync" || row.type === "access.revoked") {
3781
- exactKeys(row, ["type", "data"]);
3782
- const data2 = record(row.data);
3783
- exactKeys(data2, ["reason"]);
3784
- const reasons = row.type === "resync" ? ["SERVER_RESTART", "CURSOR_EXPIRED", "SLOW_CONSUMER"] : ["PROJECT_ACCESS_REVOKED", "TOKEN_EXPIRED"];
3785
- return { type: row.type, data: { reason: oneOf(data2.reason, reasons, "reason") } };
3786
- }
3787
- const data = record(row.data);
3788
- if (row.type === "message.created")
3789
- return { ...row, occurredAt: date(row.occurredAt, "occurredAt"), data: { message: hydrateMessage(data.message) } };
3790
- if (row.type === "roster.changed")
3791
- return { ...row, occurredAt: date(row.occurredAt, "occurredAt"), data: { change: data.change, membership: hydratePublicBot(data.membership) } };
3792
- if (row.type === "membership.changed")
3793
- return { ...row, occurredAt: date(row.occurredAt, "occurredAt"), data: { change: data.change, membership: hydratePublicMember(data.membership) } };
3794
- if (row.type === "task.changed")
3795
- return { ...row, occurredAt: date(row.occurredAt, "occurredAt"), data: { taskId: requiredString(data, "taskId"), status: data.status, ownerMembershipId: requiredString(data, "ownerMembershipId"), updatedAt: date(data.updatedAt, "updatedAt") } };
3796
- throw new ProjectRoomClientError("Invalid SSE event", 200, "INVALID_EVENT", false);
3797
- }
3798
- function hydratePublicMember(value) {
3799
- const row = record(value);
3800
- return { id: requiredString(row, "id"), userId: requiredString(row, "userId"), role: row.role, status: row.status, joinedAt: date(row.joinedAt, "joinedAt"), updatedAt: date(row.updatedAt, "updatedAt") };
3801
- }
3802
- function hydratePublicBot(value) {
3803
- const row = record(value);
3804
- return { id: requiredString(row, "id"), role: row.role, title: requiredString(row, "title"), ...row.responsibility === void 0 ? {} : { responsibility: row.responsibility }, mentionName: requiredString(row, "mentionName"), status: row.status, joinedAt: date(row.joinedAt, "joinedAt"), updatedAt: date(row.updatedAt, "updatedAt") };
3805
- }
3806
3919
 
3807
3920
  // src/client.ts
3808
3921
  var _Client = class extends AbstractClient {
@@ -3820,6 +3933,8 @@ var _Client = class extends AbstractClient {
3820
3933
  this.resources = new ResourcesClient(this.config.baseURL, () => this.getAllHeaders());
3821
3934
  this.exportImport = new ExportImportClient(this.config, () => this.getAllHeaders());
3822
3935
  this.projectRooms = new ProjectRoomsClient(this.config.baseURL, () => this.getAllHeaders());
3936
+ this.workspaceRooms = new WorkspaceRoomsClient(this.config.baseURL, () => this.getAllHeaders());
3937
+ this.roomEvents = new RoomEventsClient(this.config.baseURL, () => this.getAllHeaders());
3823
3938
  }
3824
3939
  /**
3825
3940
  * Helper method to handle fetch responses and errors
@@ -5016,11 +5131,13 @@ export {
5016
5131
  ProjectRoomClientError,
5017
5132
  ProjectRoomsClient,
5018
5133
  ResourcesClient,
5134
+ RoomEventsClient,
5019
5135
  RuntimeAxiomClient,
5020
5136
  ScheduleExecutionType,
5021
5137
  ScheduledTaskStatus,
5022
5138
  WeChatClient,
5023
5139
  WorkspaceClient,
5140
+ WorkspaceRoomsClient,
5024
5141
  createSimpleMessageMerger
5025
5142
  };
5026
5143
  //# sourceMappingURL=index.mjs.map