@tinycloud/sdk-services 3.1.0-beta.13 → 3.1.0-beta.14

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
@@ -1863,6 +1863,18 @@ var MAX_KV_BATCH_READ_ITEMS = 100;
1863
1863
  function isJsonObject(value) {
1864
1864
  return typeof value === "object" && value !== null && !Array.isArray(value);
1865
1865
  }
1866
+ var pathByteEncoder = new TextEncoder();
1867
+ function comparePathsByBytes(a, b) {
1868
+ const left = pathByteEncoder.encode(a);
1869
+ const right = pathByteEncoder.encode(b);
1870
+ const length = Math.min(left.length, right.length);
1871
+ for (let index = 0; index < length; index++) {
1872
+ if (left[index] !== right[index]) {
1873
+ return left[index] - right[index];
1874
+ }
1875
+ }
1876
+ return left.length - right.length;
1877
+ }
1866
1878
  var REVOKED_BODY = /^(?:Invalid invocation: )?delegation-(?:(revoked): [A-Za-z0-9]+|(ancestor-revoked): ancestor=[A-Za-z0-9]+ invoked=[A-Za-z0-9]+)$/;
1867
1879
  function revocationCodeOf(body) {
1868
1880
  const match = REVOKED_BODY.exec(body.trim());
@@ -2096,15 +2108,25 @@ var KVService = class extends BaseService {
2096
2108
  )?.[1];
2097
2109
  return contentType?.includes("application/json") ? JSON.parse(text) : text;
2098
2110
  }
2111
+ /**
2112
+ * Validate a batch read response and return its items in the caller's
2113
+ * request order. The node flattens invocation abilities from a `BTreeMap`,
2114
+ * so results arrive sorted by UTF-8 byte order of the path, not in request
2115
+ * order. Items that carry their path in `key` are matched by path; if no
2116
+ * item carries a key, items are assumed to be in the node's byte-sorted
2117
+ * order and the request is aligned the same way. Any mix of keyed and
2118
+ * keyless items, a missing requested path, an unrequested path, or a
2119
+ * malformed item fails closed (returns undefined).
2120
+ */
2099
2121
  normalizeBatchReadResponse(data, paths, requireData) {
2100
2122
  if (!data || typeof data !== "object") return void 0;
2101
2123
  const response = data;
2102
- if (!Array.isArray(response.results) || response.results.length !== paths.length) {
2124
+ const items = response.results;
2125
+ if (!Array.isArray(items) || items.length !== paths.length) {
2103
2126
  return void 0;
2104
2127
  }
2105
- for (let index = 0; index < response.results.length; index++) {
2106
- const item = response.results[index];
2107
- if (!item || typeof item !== "object" || item.key !== paths[index] || typeof item.ok !== "boolean") {
2128
+ for (const item of items) {
2129
+ if (!item || typeof item !== "object" || typeof item.ok !== "boolean") {
2108
2130
  return void 0;
2109
2131
  }
2110
2132
  if (item.ok && (!item.headers || typeof item.headers !== "object" || Object.values(item.headers).some((value) => typeof value !== "string") || requireData && typeof item.dataBase64 !== "string")) {
@@ -2114,7 +2136,24 @@ var KVService = class extends BaseService {
2114
2136
  return void 0;
2115
2137
  }
2116
2138
  }
2117
- return response;
2139
+ if (items.every((item) => typeof item.key === "string")) {
2140
+ const byPath = new Map(items.map((item) => [item.key, item]));
2141
+ if (byPath.size !== items.length) return void 0;
2142
+ const aligned2 = [];
2143
+ for (const path of paths) {
2144
+ const item = byPath.get(path);
2145
+ if (!item) return void 0;
2146
+ aligned2.push(item);
2147
+ }
2148
+ return aligned2;
2149
+ }
2150
+ if (items.some((item) => item.key !== void 0)) return void 0;
2151
+ const requestOrder = paths.map((_, index) => index).sort((a, b) => comparePathsByBytes(paths[a], paths[b]));
2152
+ const aligned = new Array(items.length);
2153
+ for (let position = 0; position < requestOrder.length; position++) {
2154
+ aligned[requestOrder[position]] = items[position];
2155
+ }
2156
+ return aligned;
2118
2157
  }
2119
2158
  async batchRead(keys, action, options) {
2120
2159
  if (!this.requireAuth()) return err(authRequiredError("kv"));
@@ -2207,19 +2246,19 @@ var KVService = class extends BaseService {
2207
2246
  { meta: { status: response.status, statusText: response.statusText } }
2208
2247
  ));
2209
2248
  }
2210
- const payload = this.normalizeBatchReadResponse(
2249
+ const items = this.normalizeBatchReadResponse(
2211
2250
  await response.json(),
2212
2251
  paths,
2213
2252
  action === KVAction.GET
2214
2253
  );
2215
- if (!payload) {
2254
+ if (!items) {
2216
2255
  return err(serviceError(
2217
2256
  ErrorCodes.NETWORK_ERROR,
2218
2257
  "KV batch read response did not match the requested keys",
2219
2258
  "kv"
2220
2259
  ));
2221
2260
  }
2222
- const results = payload.results.map((item, index) => {
2261
+ const results = items.map((item, index) => {
2223
2262
  if (!item.ok) {
2224
2263
  return {
2225
2264
  key: keys[index],