@pmate/chat-sdk 0.11.7 → 0.11.9
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.
|
@@ -28,9 +28,13 @@ export declare class ReadCountsClient {
|
|
|
28
28
|
private revision;
|
|
29
29
|
private running;
|
|
30
30
|
private dirty;
|
|
31
|
+
private subscribed;
|
|
32
|
+
private subscriptionDenied;
|
|
33
|
+
private subscriptionPending?;
|
|
31
34
|
constructor(options: ReadCountsOptions);
|
|
32
35
|
private post;
|
|
33
36
|
private subscription;
|
|
37
|
+
private renew;
|
|
34
38
|
watch(threadId: string | undefined, messageIds: string[]): void;
|
|
35
39
|
changed(threadId: string, revision: number): void;
|
|
36
40
|
reconnect(): void;
|
|
@@ -14,6 +14,9 @@ export class ReadCountsClient {
|
|
|
14
14
|
revision = -1;
|
|
15
15
|
running = false;
|
|
16
16
|
dirty = false;
|
|
17
|
+
subscribed = false;
|
|
18
|
+
subscriptionDenied = false;
|
|
19
|
+
subscriptionPending;
|
|
17
20
|
constructor(options) {
|
|
18
21
|
this.options = options;
|
|
19
22
|
}
|
|
@@ -29,6 +32,38 @@ export class ReadCountsClient {
|
|
|
29
32
|
subscription(threadId, release) {
|
|
30
33
|
return this.post("/api/social/reading/subscription", { appId: this.options.appId, profileId: this.options.profileId, threadId, clientInstanceId: this.options.clientInstanceId, sequence: nextSubscriptionSequence(), release });
|
|
31
34
|
}
|
|
35
|
+
renew() {
|
|
36
|
+
if (!this.thread || this.closed || this.subscriptionDenied)
|
|
37
|
+
return;
|
|
38
|
+
const threadId = this.thread, generation = this.generation;
|
|
39
|
+
if (this.subscriptionPending?.generation === generation)
|
|
40
|
+
return;
|
|
41
|
+
const pending = { generation, promise: undefined };
|
|
42
|
+
pending.promise = this.subscription(threadId, false).then(() => {
|
|
43
|
+
if (this.closed || generation !== this.generation || this.thread !== threadId)
|
|
44
|
+
return;
|
|
45
|
+
const recovered = !this.subscribed;
|
|
46
|
+
this.subscribed = true;
|
|
47
|
+
if (this.heartbeat === undefined)
|
|
48
|
+
this.heartbeat = setInterval(() => { if (!this.closed && this.thread === threadId)
|
|
49
|
+
this.renew(); }, 20_000);
|
|
50
|
+
// Recover changes that occurred before a receiver/subscription became ready.
|
|
51
|
+
if (recovered && this.revision >= 0)
|
|
52
|
+
this.schedule(0);
|
|
53
|
+
}).catch(error => {
|
|
54
|
+
if (this.closed || generation !== this.generation)
|
|
55
|
+
return;
|
|
56
|
+
this.subscribed = false;
|
|
57
|
+
if (/READ_COUNTS_HTTP_(401|403)/.test(String(error))) {
|
|
58
|
+
this.subscriptionDenied = true;
|
|
59
|
+
clearInterval(this.heartbeat);
|
|
60
|
+
this.heartbeat = undefined;
|
|
61
|
+
}
|
|
62
|
+
this.options.onError?.(error);
|
|
63
|
+
}).finally(() => { if (this.subscriptionPending === pending)
|
|
64
|
+
this.subscriptionPending = undefined; });
|
|
65
|
+
this.subscriptionPending = pending;
|
|
66
|
+
}
|
|
32
67
|
watch(threadId, messageIds) {
|
|
33
68
|
if (this.closed)
|
|
34
69
|
return;
|
|
@@ -36,6 +71,8 @@ export class ReadCountsClient {
|
|
|
36
71
|
if (this.thread === threadId) {
|
|
37
72
|
if (JSON.stringify(ids) !== JSON.stringify(this.ids)) {
|
|
38
73
|
this.ids = ids;
|
|
74
|
+
if (!this.subscribed)
|
|
75
|
+
this.renew();
|
|
39
76
|
this.schedule(0);
|
|
40
77
|
}
|
|
41
78
|
return;
|
|
@@ -51,13 +88,15 @@ export class ReadCountsClient {
|
|
|
51
88
|
this.revision = -1;
|
|
52
89
|
this.dirty = false;
|
|
53
90
|
this.retries = 0;
|
|
91
|
+
this.subscribed = false;
|
|
92
|
+
this.subscriptionDenied = false;
|
|
54
93
|
if (old)
|
|
55
94
|
void this.subscription(old, true).catch(error => this.options.onError?.(error));
|
|
56
95
|
if (!threadId)
|
|
57
96
|
return;
|
|
58
|
-
|
|
97
|
+
this.renew();
|
|
59
98
|
this.heartbeat = setInterval(() => { if (!this.closed && this.thread === threadId)
|
|
60
|
-
|
|
99
|
+
this.renew(); }, 20_000);
|
|
61
100
|
this.schedule(0);
|
|
62
101
|
}
|
|
63
102
|
changed(threadId, revision) {
|
|
@@ -70,7 +109,9 @@ export class ReadCountsClient {
|
|
|
70
109
|
reconnect() {
|
|
71
110
|
if (!this.thread || this.closed)
|
|
72
111
|
return;
|
|
73
|
-
|
|
112
|
+
this.subscribed = false;
|
|
113
|
+
this.subscriptionDenied = false;
|
|
114
|
+
this.renew();
|
|
74
115
|
this.schedule(0);
|
|
75
116
|
}
|
|
76
117
|
schedule(delay) {
|
|
@@ -105,6 +146,8 @@ export class ReadCountsClient {
|
|
|
105
146
|
this.retries = 0;
|
|
106
147
|
this.revision = value.revision;
|
|
107
148
|
this.options.onChange(value);
|
|
149
|
+
if (!this.subscribed)
|
|
150
|
+
this.renew();
|
|
108
151
|
}
|
|
109
152
|
catch (error) {
|
|
110
153
|
if (!controller.signal.aborted && generation === this.generation && !this.closed) {
|
|
@@ -36,7 +36,7 @@ export class SocialReadClient {
|
|
|
36
36
|
return teamId === undefined ? {} : { teamId };
|
|
37
37
|
}
|
|
38
38
|
requireTeam(teamId) {
|
|
39
|
-
if (this.options.appId === "pmate:
|
|
39
|
+
if (this.options.appId === "pmate:merry" && !teamId)
|
|
40
40
|
throw new SocialReadError(400, "TEAM_ID_REQUIRED");
|
|
41
41
|
}
|
|
42
42
|
async list(action, query) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pmate/chat-sdk",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.9",
|
|
4
4
|
"description": "Cross-platform PMate chat input components, voice input primitives, and ASR helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -28,6 +28,15 @@
|
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"clean": "rimraf lib",
|
|
33
|
+
"build": "pnpm run clean && tsc -p tsconfig.build.json && cp src/voice/recorder-processor.js lib/voice/recorder-processor.js",
|
|
34
|
+
"prepack": "pnpm run build",
|
|
35
|
+
"npm:publish": "pnpm run build && npm publish --access public --registry https://registry.npmjs.org/",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"storybook": "storybook dev -p 6009",
|
|
38
|
+
"build-storybook": "storybook build --output-dir dist"
|
|
39
|
+
},
|
|
31
40
|
"dependencies": {
|
|
32
41
|
"@emoji-mart/data": "^1.2.1",
|
|
33
42
|
"@emoji-mart/react": "^1.1.1",
|
|
@@ -43,24 +52,16 @@
|
|
|
43
52
|
"devDependencies": {
|
|
44
53
|
"@storybook/addon-docs": "^9.0.17",
|
|
45
54
|
"@storybook/react-vite": "9.0.17",
|
|
46
|
-
"@tailwindcss/vite": "
|
|
47
|
-
"@types/react": "
|
|
48
|
-
"@types/react-dom": "
|
|
55
|
+
"@tailwindcss/vite": "catalog:",
|
|
56
|
+
"@types/react": "catalog:",
|
|
57
|
+
"@types/react-dom": "catalog:",
|
|
49
58
|
"fake-indexeddb": "^6.2.5",
|
|
50
|
-
"react": "
|
|
51
|
-
"react-dom": "
|
|
59
|
+
"react": "catalog:",
|
|
60
|
+
"react-dom": "catalog:",
|
|
52
61
|
"rimraf": "^6.1.2",
|
|
53
62
|
"storybook": "^9.0.17",
|
|
54
|
-
"tailwindcss": "
|
|
63
|
+
"tailwindcss": "catalog:",
|
|
55
64
|
"typescript": "5.9.2",
|
|
56
65
|
"vitest": "^4.0.17"
|
|
57
|
-
},
|
|
58
|
-
"scripts": {
|
|
59
|
-
"clean": "rimraf lib",
|
|
60
|
-
"build": "pnpm run clean && tsc -p tsconfig.build.json && cp src/voice/recorder-processor.js lib/voice/recorder-processor.js",
|
|
61
|
-
"npm:publish": "pnpm run build && npm publish --access public --registry https://registry.npmjs.org/",
|
|
62
|
-
"test": "vitest run",
|
|
63
|
-
"storybook": "storybook dev -p 6009",
|
|
64
|
-
"build-storybook": "storybook build --output-dir dist"
|
|
65
66
|
}
|
|
66
|
-
}
|
|
67
|
+
}
|