@pmate/chat-sdk 0.12.0-next.7 → 0.12.0-next.70

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 (96) hide show
  1. package/README.md +152 -81
  2. package/lib/advanced.d.ts +10 -0
  3. package/lib/advanced.js +10 -0
  4. package/lib/chat.d.ts +5 -0
  5. package/lib/chat.js +11 -0
  6. package/lib/chatContract.d.ts +148 -0
  7. package/lib/chatContract.js +1 -0
  8. package/lib/chatError.d.ts +11 -0
  9. package/lib/chatError.js +13 -0
  10. package/lib/chatTypes.d.ts +121 -0
  11. package/lib/chatTypes.js +1 -0
  12. package/lib/credentials.d.ts +26 -0
  13. package/lib/credentials.js +110 -0
  14. package/lib/fileMetadata.d.ts +9 -0
  15. package/lib/fileMetadata.js +18 -0
  16. package/lib/framework.d.ts +11 -0
  17. package/lib/framework.js +12 -0
  18. package/lib/history.d.ts +4 -0
  19. package/lib/history.js +8 -0
  20. package/lib/hooks/useChatSnapshot.d.ts +4 -0
  21. package/lib/hooks/useChatSnapshot.js +9 -0
  22. package/lib/index.d.ts +2 -0
  23. package/lib/index.js +2 -0
  24. package/lib/internal/chatEngine.d.ts +131 -0
  25. package/lib/internal/chatEngine.js +280 -0
  26. package/lib/internal/chatRegistry.d.ts +4 -0
  27. package/lib/internal/chatRegistry.js +4 -0
  28. package/lib/internal/createPublicChat.d.ts +4 -0
  29. package/lib/internal/createPublicChat.js +52 -0
  30. package/lib/messageView.d.ts +6 -0
  31. package/lib/messageView.js +103 -0
  32. package/lib/runtime/batchedReadIndex.d.ts +16 -3
  33. package/lib/runtime/batchedReadIndex.js +50 -4
  34. package/lib/runtime/cachedMessage.d.ts +12 -0
  35. package/lib/runtime/cachedMessage.js +18 -0
  36. package/lib/runtime/chatClient.d.ts +2 -0
  37. package/lib/runtime/chatClient.js +8 -3
  38. package/lib/runtime/chatError.d.ts +3 -0
  39. package/lib/runtime/chatError.js +15 -0
  40. package/lib/runtime/chatSession.d.ts +127 -13
  41. package/lib/runtime/chatSession.js +727 -40
  42. package/lib/runtime/connectivity.d.ts +4 -0
  43. package/lib/runtime/connectivity.js +8 -0
  44. package/lib/runtime/conversationDirectory.d.ts +37 -0
  45. package/lib/runtime/conversationDirectory.js +116 -0
  46. package/lib/runtime/conversationRead.d.ts +13 -0
  47. package/lib/runtime/conversationRead.js +34 -0
  48. package/lib/runtime/conversationReading.d.ts +28 -0
  49. package/lib/runtime/conversationReading.js +47 -0
  50. package/lib/runtime/createChat.d.ts +11 -7
  51. package/lib/runtime/createChat.js +46 -23
  52. package/lib/runtime/durableSender.d.ts +97 -14
  53. package/lib/runtime/durableSender.js +786 -71
  54. package/lib/runtime/groupClient.d.ts +76 -0
  55. package/lib/runtime/groupClient.js +325 -0
  56. package/lib/runtime/index.d.ts +7 -0
  57. package/lib/runtime/index.js +5 -0
  58. package/lib/runtime/messageClient.d.ts +35 -8
  59. package/lib/runtime/messageClient.js +364 -66
  60. package/lib/runtime/messageControls.d.ts +19 -0
  61. package/lib/runtime/messageControls.js +44 -0
  62. package/lib/runtime/messageLaunch.d.ts +44 -0
  63. package/lib/runtime/messageLaunch.js +137 -0
  64. package/lib/runtime/messageQuotes.d.ts +3 -0
  65. package/lib/runtime/messageQuotes.js +17 -0
  66. package/lib/runtime/messageReaders.d.ts +12 -1
  67. package/lib/runtime/messageReaders.js +67 -3
  68. package/lib/runtime/messageStore.d.ts +40 -2
  69. package/lib/runtime/messageStore.js +227 -11
  70. package/lib/runtime/messageTimeline.d.ts +50 -0
  71. package/lib/runtime/messageTimeline.js +120 -0
  72. package/lib/runtime/outboxSchema.d.ts +5 -0
  73. package/lib/runtime/outboxSchema.js +59 -0
  74. package/lib/runtime/outgoingContent.d.ts +89 -0
  75. package/lib/runtime/outgoingContent.js +113 -0
  76. package/lib/runtime/readBatchJournal.d.ts +35 -0
  77. package/lib/runtime/readBatchJournal.js +210 -0
  78. package/lib/runtime/readCounts.d.ts +15 -1
  79. package/lib/runtime/readCounts.js +97 -9
  80. package/lib/runtime/readIndex.d.ts +68 -7
  81. package/lib/runtime/readIndex.js +460 -22
  82. package/lib/runtime/readSchema.d.ts +2 -0
  83. package/lib/runtime/readSchema.js +58 -0
  84. package/lib/runtime/readSync.d.ts +1 -0
  85. package/lib/runtime/readSync.js +26 -9
  86. package/lib/runtime/readingClient.d.ts +19 -0
  87. package/lib/runtime/readingClient.js +131 -19
  88. package/lib/runtime/readingContent.d.ts +5 -0
  89. package/lib/runtime/readingContent.js +23 -0
  90. package/lib/runtime/responseCache.d.ts +59 -0
  91. package/lib/runtime/responseCache.js +232 -0
  92. package/lib/runtime/socialReadClient.d.ts +4 -2
  93. package/lib/runtime/socialReadClient.js +12 -8
  94. package/lib/runtime/voiceUpload.d.ts +2 -0
  95. package/lib/runtime/voiceUpload.js +27 -0
  96. package/package.json +27 -2
@@ -22,6 +22,7 @@ export type SocialGroup = {
22
22
  title: string;
23
23
  avatar?: string | null;
24
24
  revision: string;
25
+ versionNumber?: number;
25
26
  };
26
27
  export type SocialRelationship = {
27
28
  appId: string;
@@ -45,7 +46,7 @@ export declare class SocialReadClient {
45
46
  private readonly options;
46
47
  constructor(options: SocialReadClientOptions);
47
48
  /** Without teamId includes current Teams and unassigned contact metadata for migration. */
48
- contacts(teamId?: string): Promise<ChatReaderContact[]>;
49
+ contacts(teamId?: string, signal?: AbortSignal): Promise<ChatReaderContact[]>;
49
50
  unread(teamId?: string): Promise<ChatReaderUnread[]>;
50
51
  messages(input: {
51
52
  threadId: string;
@@ -57,11 +58,12 @@ export declare class SocialReadClient {
57
58
  limit?: number;
58
59
  before?: string;
59
60
  after?: string;
61
+ messageId?: string;
60
62
  }, signal?: AbortSignal): Promise<SocialMessagePage>;
61
63
  group(input: {
62
64
  groupId: string;
63
65
  teamId?: string;
64
- }): Promise<SocialGroup>;
66
+ }, signal?: AbortSignal): Promise<SocialGroup>;
65
67
  relationship(input: {
66
68
  peerId: string;
67
69
  teamId?: string;
@@ -14,8 +14,8 @@ export class SocialReadClient {
14
14
  options;
15
15
  constructor(options) { this.options = { ...options }; }
16
16
  /** Without teamId includes current Teams and unassigned contact metadata for migration. */
17
- contacts(teamId) {
18
- return this.list("contacts", this.teamQuery(teamId));
17
+ contacts(teamId, signal) {
18
+ return this.list("contacts", this.teamQuery(teamId), signal);
19
19
  }
20
20
  unread(teamId) {
21
21
  return this.list("unread", this.teamQuery(teamId));
@@ -26,22 +26,26 @@ export class SocialReadClient {
26
26
  }
27
27
  async messagePage(input, signal) {
28
28
  this.requireTeam(input.teamId);
29
- const limit = input.limit ?? 100;
29
+ const limit = input.limit ?? (input.messageId === undefined ? 100 : 1);
30
30
  if (!Number.isSafeInteger(limit) || limit < 1 || limit > 500 || (input.before !== undefined && input.after !== undefined))
31
31
  throw new SocialReadError(400, "INVALID_MESSAGE_PAGE");
32
+ if (input.messageId !== undefined && (!input.messageId || input.messageId.length > 256 || /[\u0000-\u001f\u007f]/.test(input.messageId) || limit !== 1 || input.before !== undefined || input.after !== undefined))
33
+ throw new SocialReadError(400, "INVALID_MESSAGE_LOOKUP");
32
34
  const value = await this.request("messages", { threadId: input.threadId, ...this.teamQuery(input.teamId), limit: String(limit),
33
- ...(input.before === undefined ? {} : { before: input.before }), ...(input.after === undefined ? {} : { after: input.after }) }, signal);
35
+ ...(input.before === undefined ? {} : { before: input.before }), ...(input.after === undefined ? {} : { after: input.after }), ...(input.messageId === undefined ? {} : { messageId: input.messageId }) }, signal);
34
36
  const cursor = (token) => typeof token === "string" && /^mp1:\d+:[0-9a-f]{64}$/.test(token);
35
37
  if (!value || !Array.isArray(value.messages) || value.messages.length > limit || !cursor(value.checkpoint)
36
38
  || (value.nextBefore !== null && !cursor(value.nextBefore)) || typeof value.hasMoreChanges !== "boolean" || typeof value.resetRequired !== "boolean"
37
39
  || value.messages.some(row => row.appId !== this.options.appId || row.threadId !== input.threadId || row.teamId !== input.teamId || !row.messageId || !Number.isFinite(row.serverCreatedAt))
38
40
  || (value.resetRequired && (value.messages.length || value.hasMoreChanges || value.nextBefore !== null)))
39
41
  throw new SocialReadError(502, "INVALID_MESSAGE_PAGE_RESPONSE");
42
+ if (input.messageId !== undefined && (value.messages.some(row => row.messageId !== input.messageId) || value.nextBefore !== null || value.hasMoreChanges || value.resetRequired))
43
+ throw new SocialReadError(502, "INVALID_MESSAGE_LOOKUP_RESPONSE");
40
44
  return value;
41
45
  }
42
- group(input) {
46
+ group(input, signal) {
43
47
  this.requireTeam(input.teamId);
44
- return this.request("group", { groupId: input.groupId, ...this.teamQuery(input.teamId) });
48
+ return this.request("group", { groupId: input.groupId, ...this.teamQuery(input.teamId) }, signal);
45
49
  }
46
50
  relationship(input) {
47
51
  this.requireTeam(input.teamId);
@@ -54,8 +58,8 @@ export class SocialReadClient {
54
58
  if (this.options.appId === "pmate:merry" && !teamId)
55
59
  throw new SocialReadError(400, "TEAM_ID_REQUIRED");
56
60
  }
57
- async list(action, query) {
58
- const value = await this.request(action, query);
61
+ async list(action, query, signal) {
62
+ const value = await this.request(action, query, signal);
59
63
  if (!Array.isArray(value))
60
64
  throw new SocialReadError(502, "INVALID_SOCIAL_READ_RESPONSE");
61
65
  return value;
@@ -0,0 +1,2 @@
1
+ /** The SDK owns upload I/O; hosts configure only their service endpoint. */
2
+ export declare function voiceUploader(profileId: string, endpoint?: string, fetcher?: typeof fetch): (blob: Blob, signal: AbortSignal) => Promise<string>;
@@ -0,0 +1,27 @@
1
+ import { isOffline } from "./connectivity.js";
2
+ /** The SDK owns upload I/O; hosts configure only their service endpoint. */
3
+ export function voiceUploader(profileId, endpoint = "https://upload-fc.pmate.chat", fetcher = globalThis.fetch) {
4
+ return async (blob, signal) => {
5
+ if (signal.aborted)
6
+ throw new DOMException("Upload aborted", "AbortError");
7
+ if (isOffline())
8
+ throw new Error("VOICE_UPLOAD_OFFLINE");
9
+ const bytes = new Uint8Array(await blob.arrayBuffer());
10
+ if (signal.aborted)
11
+ throw new DOMException("Upload aborted", "AbortError");
12
+ let binary = "";
13
+ for (let offset = 0; offset < bytes.length; offset += 32768)
14
+ binary += String.fromCharCode(...bytes.subarray(offset, offset + 32768));
15
+ const extension = blob.type.includes("mp4") ? "m4a" : blob.type.includes("mpeg") ? "mp3" : "webm";
16
+ const type = extension === "m4a" ? "audio/mp4" : extension === "mp3" ? "audio/mpeg" : "audio/webm";
17
+ if (isOffline())
18
+ throw new Error("VOICE_UPLOAD_OFFLINE");
19
+ const response = await fetcher(`${endpoint.replace(/\/+$/, "")}/file`, { method: "POST", signal, headers: { "Content-Type": "application/json", "x-file-content-type": type }, body: JSON.stringify({ user: profileId, base64: btoa(binary), filename: `voice-${Date.now()}.${extension}` }) });
20
+ if (!response.ok)
21
+ throw new Error("VOICE_UPLOAD_FAILED");
22
+ const result = await response.json();
23
+ if (typeof result.data !== "string" || !result.data)
24
+ throw new Error("VOICE_UPLOAD_FAILED");
25
+ return result.data;
26
+ };
27
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pmate/chat-sdk",
3
- "version": "0.12.0-next.7",
4
- "description": "Cross-platform PMate chat input components, voice input primitives, and ASR helpers",
3
+ "version": "0.12.0-next.70",
4
+ "description": "Local-first chat SDK, message subscriptions, reading state, and shared chat UI primitives",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
7
7
  "types": "./lib/index.d.ts",
@@ -19,10 +19,35 @@
19
19
  "import": "./lib/index.js",
20
20
  "default": "./lib/index.js"
21
21
  },
22
+ "./bootstrap": {
23
+ "types": "./lib/runtime/messageLaunch.d.ts",
24
+ "import": "./lib/runtime/messageLaunch.js",
25
+ "default": "./lib/runtime/messageLaunch.js"
26
+ },
22
27
  "./runtime": {
23
28
  "types": "./lib/runtime/index.d.ts",
24
29
  "import": "./lib/runtime/index.js",
25
30
  "default": "./lib/runtime/index.js"
31
+ },
32
+ "./chat": {
33
+ "types": "./lib/chat.d.ts",
34
+ "import": "./lib/chat.js",
35
+ "default": "./lib/chat.js"
36
+ },
37
+ "./advanced": {
38
+ "types": "./lib/advanced.d.ts",
39
+ "import": "./lib/advanced.js",
40
+ "default": "./lib/advanced.js"
41
+ },
42
+ "./framework": {
43
+ "types": "./lib/framework.d.ts",
44
+ "import": "./lib/framework.js",
45
+ "default": "./lib/framework.js"
46
+ },
47
+ "./history": {
48
+ "types": "./lib/history.d.ts",
49
+ "import": "./lib/history.js",
50
+ "default": "./lib/history.js"
26
51
  }
27
52
  },
28
53
  "publishConfig": {