@tinycloud/sdk-services 3.1.0-beta.11 → 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/kv/index.cjs CHANGED
@@ -830,6 +830,18 @@ var MAX_KV_BATCH_READ_ITEMS = 100;
830
830
  function isJsonObject(value) {
831
831
  return typeof value === "object" && value !== null && !Array.isArray(value);
832
832
  }
833
+ var pathByteEncoder = new TextEncoder();
834
+ function comparePathsByBytes(a, b) {
835
+ const left = pathByteEncoder.encode(a);
836
+ const right = pathByteEncoder.encode(b);
837
+ const length = Math.min(left.length, right.length);
838
+ for (let index = 0; index < length; index++) {
839
+ if (left[index] !== right[index]) {
840
+ return left[index] - right[index];
841
+ }
842
+ }
843
+ return left.length - right.length;
844
+ }
833
845
  var REVOKED_BODY = /^(?:Invalid invocation: )?delegation-(?:(revoked): [A-Za-z0-9]+|(ancestor-revoked): ancestor=[A-Za-z0-9]+ invoked=[A-Za-z0-9]+)$/;
834
846
  function revocationCodeOf(body) {
835
847
  const match = REVOKED_BODY.exec(body.trim());
@@ -1063,15 +1075,25 @@ var KVService = class extends BaseService {
1063
1075
  )?.[1];
1064
1076
  return contentType?.includes("application/json") ? JSON.parse(text) : text;
1065
1077
  }
1078
+ /**
1079
+ * Validate a batch read response and return its items in the caller's
1080
+ * request order. The node flattens invocation abilities from a `BTreeMap`,
1081
+ * so results arrive sorted by UTF-8 byte order of the path, not in request
1082
+ * order. Items that carry their path in `key` are matched by path; if no
1083
+ * item carries a key, items are assumed to be in the node's byte-sorted
1084
+ * order and the request is aligned the same way. Any mix of keyed and
1085
+ * keyless items, a missing requested path, an unrequested path, or a
1086
+ * malformed item fails closed (returns undefined).
1087
+ */
1066
1088
  normalizeBatchReadResponse(data, paths, requireData) {
1067
1089
  if (!data || typeof data !== "object") return void 0;
1068
1090
  const response = data;
1069
- if (!Array.isArray(response.results) || response.results.length !== paths.length) {
1091
+ const items = response.results;
1092
+ if (!Array.isArray(items) || items.length !== paths.length) {
1070
1093
  return void 0;
1071
1094
  }
1072
- for (let index = 0; index < response.results.length; index++) {
1073
- const item = response.results[index];
1074
- if (!item || typeof item !== "object" || item.key !== paths[index] || typeof item.ok !== "boolean") {
1095
+ for (const item of items) {
1096
+ if (!item || typeof item !== "object" || typeof item.ok !== "boolean") {
1075
1097
  return void 0;
1076
1098
  }
1077
1099
  if (item.ok && (!item.headers || typeof item.headers !== "object" || Object.values(item.headers).some((value) => typeof value !== "string") || requireData && typeof item.dataBase64 !== "string")) {
@@ -1081,7 +1103,24 @@ var KVService = class extends BaseService {
1081
1103
  return void 0;
1082
1104
  }
1083
1105
  }
1084
- return response;
1106
+ if (items.every((item) => typeof item.key === "string")) {
1107
+ const byPath = new Map(items.map((item) => [item.key, item]));
1108
+ if (byPath.size !== items.length) return void 0;
1109
+ const aligned2 = [];
1110
+ for (const path of paths) {
1111
+ const item = byPath.get(path);
1112
+ if (!item) return void 0;
1113
+ aligned2.push(item);
1114
+ }
1115
+ return aligned2;
1116
+ }
1117
+ if (items.some((item) => item.key !== void 0)) return void 0;
1118
+ const requestOrder = paths.map((_, index) => index).sort((a, b) => comparePathsByBytes(paths[a], paths[b]));
1119
+ const aligned = new Array(items.length);
1120
+ for (let position = 0; position < requestOrder.length; position++) {
1121
+ aligned[requestOrder[position]] = items[position];
1122
+ }
1123
+ return aligned;
1085
1124
  }
1086
1125
  async batchRead(keys, action, options) {
1087
1126
  if (!this.requireAuth()) return err(authRequiredError("kv"));
@@ -1174,19 +1213,19 @@ var KVService = class extends BaseService {
1174
1213
  { meta: { status: response.status, statusText: response.statusText } }
1175
1214
  ));
1176
1215
  }
1177
- const payload = this.normalizeBatchReadResponse(
1216
+ const items = this.normalizeBatchReadResponse(
1178
1217
  await response.json(),
1179
1218
  paths,
1180
1219
  action === KVAction.GET
1181
1220
  );
1182
- if (!payload) {
1221
+ if (!items) {
1183
1222
  return err(serviceError(
1184
1223
  ErrorCodes.NETWORK_ERROR,
1185
1224
  "KV batch read response did not match the requested keys",
1186
1225
  "kv"
1187
1226
  ));
1188
1227
  }
1189
- const results = payload.results.map((item, index) => {
1228
+ const results = items.map((item, index) => {
1190
1229
  if (!item.ok) {
1191
1230
  return {
1192
1231
  key: keys[index],