@rei-standard/amsg-client 2.9.0-next.3 → 2.9.0-next.4

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 CHANGED
@@ -170,6 +170,41 @@ var ReiClient = class {
170
170
  if (!json.success) throw new Error(json.error?.message || "Failed to fetch VAPID public key");
171
171
  return json.publicKey;
172
172
  }
173
+ /**
174
+ * Fetch the worker's capability manifest (single-user amsg-server 2.7.0+,
175
+ * `GET /capabilities`).
176
+ *
177
+ * Feature detection for deploy drift: an outdated worker lacks newer
178
+ * endpoints/behaviors silently, so the frontend can call this once and
179
+ * show a "worker needs a redeploy" hint instead of leaving new features
180
+ * dead. Feature names are library-defined strings (e.g. `client-state`,
181
+ * `client-state-chunking`, `agentic-hooks`) that grow over time.
182
+ *
183
+ * Sends `X-Client-Token` when a `serverToken` is configured.
184
+ *
185
+ * @returns {Promise<{ serverVersion: string, features: string[] } | null>}
186
+ * `null` when the worker predates the endpoint (HTTP 404) or the
187
+ * response is not JSON (e.g. a proxy error page). Other failures
188
+ * (wrong token, 5xx with a JSON envelope) throw.
189
+ */
190
+ async getCapabilities() {
191
+ const res = await fetch(`${this._baseUrl}/capabilities`, {
192
+ method: "GET",
193
+ headers: this._withServerToken({})
194
+ });
195
+ if (res.status === 404) return null;
196
+ let json;
197
+ try {
198
+ json = await res.json();
199
+ } catch {
200
+ return null;
201
+ }
202
+ if (!json?.success) throw new Error(json?.error?.message || "Failed to fetch capabilities");
203
+ return {
204
+ serverVersion: typeof json.serverVersion === "string" ? json.serverVersion : "",
205
+ features: Array.isArray(json.features) ? json.features : []
206
+ };
207
+ }
173
208
  // ─── Public API ─────────────────────────────────────────────────
174
209
  /**
175
210
  * Schedule a message.
@@ -613,10 +648,23 @@ var ReiClient = class {
613
648
  * (requires `init()`); the worker re-encrypts each value at rest
614
649
  * under the per-user key.
615
650
  *
651
+ * Large values: on amsg-server 2.7.0+ a value over 200KB is stored
652
+ * chunked across rows by the worker itself — no client-side splitting
653
+ * needed, and reads return the original value reassembled. The default
654
+ * per-value ceiling is 5MB (worker factory config `maxStateValueBytes`).
655
+ * Older workers reject the whole batch for oversized values; probe with
656
+ * `getCapabilities()` (feature `client-state-chunking`) when you need
657
+ * to know which behavior you'll get.
658
+ *
659
+ * Partial failure: an invalid/oversized entry only rejects itself.
660
+ * When at least one entry is rejected the response carries
661
+ * `data.rejected: [{ index, namespace, key, code, message }]`; when all
662
+ * entries are accepted the response shape is unchanged (no `rejected`).
663
+ *
616
664
  * @param {Array<{ namespace: string, key: string, value: string, updatedAt: number }>} entries
617
665
  * - `value`: pre-serialized string (the SDK does not stringify it for you).
618
666
  * - `updatedAt`: epoch milliseconds.
619
- * @returns {Promise<Object>} `{ success, data?: { upserted, skipped }, error? }`
667
+ * @returns {Promise<Object>} `{ success, data?: { upserted, skipped, rejected? }, error? }`
620
668
  */
621
669
  async putClientState(entries) {
622
670
  if (!Array.isArray(entries) || entries.length === 0) {
package/dist/index.d.cts CHANGED
@@ -464,6 +464,43 @@ class ReiClient {
464
464
  return json.publicKey;
465
465
  }
466
466
 
467
+ /**
468
+ * Fetch the worker's capability manifest (single-user amsg-server 2.7.0+,
469
+ * `GET /capabilities`).
470
+ *
471
+ * Feature detection for deploy drift: an outdated worker lacks newer
472
+ * endpoints/behaviors silently, so the frontend can call this once and
473
+ * show a "worker needs a redeploy" hint instead of leaving new features
474
+ * dead. Feature names are library-defined strings (e.g. `client-state`,
475
+ * `client-state-chunking`, `agentic-hooks`) that grow over time.
476
+ *
477
+ * Sends `X-Client-Token` when a `serverToken` is configured.
478
+ *
479
+ * @returns {Promise<{ serverVersion: string, features: string[] } | null>}
480
+ * `null` when the worker predates the endpoint (HTTP 404) or the
481
+ * response is not JSON (e.g. a proxy error page). Other failures
482
+ * (wrong token, 5xx with a JSON envelope) throw.
483
+ */
484
+ async getCapabilities() {
485
+ const res = await fetch(`${this._baseUrl}/capabilities`, {
486
+ method: 'GET',
487
+ headers: this._withServerToken({})
488
+ });
489
+ if (res.status === 404) return null;
490
+
491
+ let json;
492
+ try {
493
+ json = await res.json();
494
+ } catch {
495
+ return null;
496
+ }
497
+ if (!json?.success) throw new Error(json?.error?.message || 'Failed to fetch capabilities');
498
+ return {
499
+ serverVersion: typeof json.serverVersion === 'string' ? json.serverVersion : '',
500
+ features: Array.isArray(json.features) ? json.features : []
501
+ };
502
+ }
503
+
467
504
  // ─── Public API ─────────────────────────────────────────────────
468
505
 
469
506
  /**
@@ -1009,10 +1046,23 @@ class ReiClient {
1009
1046
  * (requires `init()`); the worker re-encrypts each value at rest
1010
1047
  * under the per-user key.
1011
1048
  *
1049
+ * Large values: on amsg-server 2.7.0+ a value over 200KB is stored
1050
+ * chunked across rows by the worker itself — no client-side splitting
1051
+ * needed, and reads return the original value reassembled. The default
1052
+ * per-value ceiling is 5MB (worker factory config `maxStateValueBytes`).
1053
+ * Older workers reject the whole batch for oversized values; probe with
1054
+ * `getCapabilities()` (feature `client-state-chunking`) when you need
1055
+ * to know which behavior you'll get.
1056
+ *
1057
+ * Partial failure: an invalid/oversized entry only rejects itself.
1058
+ * When at least one entry is rejected the response carries
1059
+ * `data.rejected: [{ index, namespace, key, code, message }]`; when all
1060
+ * entries are accepted the response shape is unchanged (no `rejected`).
1061
+ *
1012
1062
  * @param {Array<{ namespace: string, key: string, value: string, updatedAt: number }>} entries
1013
1063
  * - `value`: pre-serialized string (the SDK does not stringify it for you).
1014
1064
  * - `updatedAt`: epoch milliseconds.
1015
- * @returns {Promise<Object>} `{ success, data?: { upserted, skipped }, error? }`
1065
+ * @returns {Promise<Object>} `{ success, data?: { upserted, skipped, rejected? }, error? }`
1016
1066
  */
1017
1067
  async putClientState(entries) {
1018
1068
  if (!Array.isArray(entries) || entries.length === 0) {
package/dist/index.d.ts CHANGED
@@ -464,6 +464,43 @@ class ReiClient {
464
464
  return json.publicKey;
465
465
  }
466
466
 
467
+ /**
468
+ * Fetch the worker's capability manifest (single-user amsg-server 2.7.0+,
469
+ * `GET /capabilities`).
470
+ *
471
+ * Feature detection for deploy drift: an outdated worker lacks newer
472
+ * endpoints/behaviors silently, so the frontend can call this once and
473
+ * show a "worker needs a redeploy" hint instead of leaving new features
474
+ * dead. Feature names are library-defined strings (e.g. `client-state`,
475
+ * `client-state-chunking`, `agentic-hooks`) that grow over time.
476
+ *
477
+ * Sends `X-Client-Token` when a `serverToken` is configured.
478
+ *
479
+ * @returns {Promise<{ serverVersion: string, features: string[] } | null>}
480
+ * `null` when the worker predates the endpoint (HTTP 404) or the
481
+ * response is not JSON (e.g. a proxy error page). Other failures
482
+ * (wrong token, 5xx with a JSON envelope) throw.
483
+ */
484
+ async getCapabilities() {
485
+ const res = await fetch(`${this._baseUrl}/capabilities`, {
486
+ method: 'GET',
487
+ headers: this._withServerToken({})
488
+ });
489
+ if (res.status === 404) return null;
490
+
491
+ let json;
492
+ try {
493
+ json = await res.json();
494
+ } catch {
495
+ return null;
496
+ }
497
+ if (!json?.success) throw new Error(json?.error?.message || 'Failed to fetch capabilities');
498
+ return {
499
+ serverVersion: typeof json.serverVersion === 'string' ? json.serverVersion : '',
500
+ features: Array.isArray(json.features) ? json.features : []
501
+ };
502
+ }
503
+
467
504
  // ─── Public API ─────────────────────────────────────────────────
468
505
 
469
506
  /**
@@ -1009,10 +1046,23 @@ class ReiClient {
1009
1046
  * (requires `init()`); the worker re-encrypts each value at rest
1010
1047
  * under the per-user key.
1011
1048
  *
1049
+ * Large values: on amsg-server 2.7.0+ a value over 200KB is stored
1050
+ * chunked across rows by the worker itself — no client-side splitting
1051
+ * needed, and reads return the original value reassembled. The default
1052
+ * per-value ceiling is 5MB (worker factory config `maxStateValueBytes`).
1053
+ * Older workers reject the whole batch for oversized values; probe with
1054
+ * `getCapabilities()` (feature `client-state-chunking`) when you need
1055
+ * to know which behavior you'll get.
1056
+ *
1057
+ * Partial failure: an invalid/oversized entry only rejects itself.
1058
+ * When at least one entry is rejected the response carries
1059
+ * `data.rejected: [{ index, namespace, key, code, message }]`; when all
1060
+ * entries are accepted the response shape is unchanged (no `rejected`).
1061
+ *
1012
1062
  * @param {Array<{ namespace: string, key: string, value: string, updatedAt: number }>} entries
1013
1063
  * - `value`: pre-serialized string (the SDK does not stringify it for you).
1014
1064
  * - `updatedAt`: epoch milliseconds.
1015
- * @returns {Promise<Object>} `{ success, data?: { upserted, skipped }, error? }`
1065
+ * @returns {Promise<Object>} `{ success, data?: { upserted, skipped, rejected? }, error? }`
1016
1066
  */
1017
1067
  async putClientState(entries) {
1018
1068
  if (!Array.isArray(entries) || entries.length === 0) {
package/dist/index.mjs CHANGED
@@ -148,6 +148,41 @@ var ReiClient = class {
148
148
  if (!json.success) throw new Error(json.error?.message || "Failed to fetch VAPID public key");
149
149
  return json.publicKey;
150
150
  }
151
+ /**
152
+ * Fetch the worker's capability manifest (single-user amsg-server 2.7.0+,
153
+ * `GET /capabilities`).
154
+ *
155
+ * Feature detection for deploy drift: an outdated worker lacks newer
156
+ * endpoints/behaviors silently, so the frontend can call this once and
157
+ * show a "worker needs a redeploy" hint instead of leaving new features
158
+ * dead. Feature names are library-defined strings (e.g. `client-state`,
159
+ * `client-state-chunking`, `agentic-hooks`) that grow over time.
160
+ *
161
+ * Sends `X-Client-Token` when a `serverToken` is configured.
162
+ *
163
+ * @returns {Promise<{ serverVersion: string, features: string[] } | null>}
164
+ * `null` when the worker predates the endpoint (HTTP 404) or the
165
+ * response is not JSON (e.g. a proxy error page). Other failures
166
+ * (wrong token, 5xx with a JSON envelope) throw.
167
+ */
168
+ async getCapabilities() {
169
+ const res = await fetch(`${this._baseUrl}/capabilities`, {
170
+ method: "GET",
171
+ headers: this._withServerToken({})
172
+ });
173
+ if (res.status === 404) return null;
174
+ let json;
175
+ try {
176
+ json = await res.json();
177
+ } catch {
178
+ return null;
179
+ }
180
+ if (!json?.success) throw new Error(json?.error?.message || "Failed to fetch capabilities");
181
+ return {
182
+ serverVersion: typeof json.serverVersion === "string" ? json.serverVersion : "",
183
+ features: Array.isArray(json.features) ? json.features : []
184
+ };
185
+ }
151
186
  // ─── Public API ─────────────────────────────────────────────────
152
187
  /**
153
188
  * Schedule a message.
@@ -591,10 +626,23 @@ var ReiClient = class {
591
626
  * (requires `init()`); the worker re-encrypts each value at rest
592
627
  * under the per-user key.
593
628
  *
629
+ * Large values: on amsg-server 2.7.0+ a value over 200KB is stored
630
+ * chunked across rows by the worker itself — no client-side splitting
631
+ * needed, and reads return the original value reassembled. The default
632
+ * per-value ceiling is 5MB (worker factory config `maxStateValueBytes`).
633
+ * Older workers reject the whole batch for oversized values; probe with
634
+ * `getCapabilities()` (feature `client-state-chunking`) when you need
635
+ * to know which behavior you'll get.
636
+ *
637
+ * Partial failure: an invalid/oversized entry only rejects itself.
638
+ * When at least one entry is rejected the response carries
639
+ * `data.rejected: [{ index, namespace, key, code, message }]`; when all
640
+ * entries are accepted the response shape is unchanged (no `rejected`).
641
+ *
594
642
  * @param {Array<{ namespace: string, key: string, value: string, updatedAt: number }>} entries
595
643
  * - `value`: pre-serialized string (the SDK does not stringify it for you).
596
644
  * - `updatedAt`: epoch milliseconds.
597
- * @returns {Promise<Object>} `{ success, data?: { upserted, skipped }, error? }`
645
+ * @returns {Promise<Object>} `{ success, data?: { upserted, skipped, rejected? }, error? }`
598
646
  */
599
647
  async putClientState(entries) {
600
648
  if (!Array.isArray(entries) || entries.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rei-standard/amsg-client",
3
- "version": "2.9.0-next.3",
3
+ "version": "2.9.0-next.4",
4
4
  "description": "ReiStandard Active Messaging browser client SDK — also re-exports shared push types, builders, and guards from @rei-standard/amsg-shared",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "node": ">=20"
34
34
  },
35
35
  "dependencies": {
36
- "@rei-standard/amsg-shared": "^0.4.0-next.0"
36
+ "@rei-standard/amsg-shared": "^0.4.0-next.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "tsup": "^8.0.0",