@preprio/toolkit 0.5.0-rc.5 → 0.5.0-rc.6

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 (38) hide show
  1. package/README.md +125 -26
  2. package/dist/astro/index.cjs +126 -30
  3. package/dist/astro/index.js +130 -30
  4. package/dist/{chunk-TG6N3C22.js → chunk-IPMB32AZ.js} +1 -1
  5. package/dist/{chunk-74KY5EAM.js → chunk-KD3GK6TO.js} +2 -0
  6. package/dist/{chunk-3X55JL52.js → chunk-KZIRM54F.js} +1 -1
  7. package/dist/{chunk-SBLZANL5.js → chunk-L3SDL6MP.js} +11 -3
  8. package/dist/{chunk-CMUFTCG3.js → chunk-WHZNCYUS.js} +1 -1
  9. package/dist/codegen/index.cjs +79 -0
  10. package/dist/codegen/index.d.cts +46 -0
  11. package/dist/codegen/index.d.ts +46 -0
  12. package/dist/codegen/index.js +62 -0
  13. package/dist/index.cjs +133 -28
  14. package/dist/index.d.cts +14 -2
  15. package/dist/index.d.ts +14 -2
  16. package/dist/index.js +108 -6
  17. package/dist/{live-preview-H4643QYF.js → live-preview-DLXGXRE5.js} +2 -2
  18. package/dist/nextjs/components.cjs +11 -3
  19. package/dist/nextjs/components.js +2 -2
  20. package/dist/nextjs/index.cjs +124 -28
  21. package/dist/nextjs/index.js +128 -28
  22. package/dist/nextjs/live-action.js +3 -3
  23. package/dist/nextjs/live.js +1 -1
  24. package/dist/nuxt/chunk-BWPGO25E.js +340 -0
  25. package/dist/nuxt/index.cjs +1 -1
  26. package/dist/nuxt/index.js +1 -1
  27. package/dist/nuxt/{live-preview-O2ZTJNW4.js → live-preview-2RCU35W5.js} +6 -337
  28. package/dist/nuxt/live.cjs +1007 -911
  29. package/dist/nuxt/live.js +109 -5
  30. package/dist/react/components.cjs +11 -3
  31. package/dist/react/components.js +11 -3
  32. package/dist/sveltekit/chunk-BWPGO25E.js +340 -0
  33. package/dist/sveltekit/index.cjs +1 -1
  34. package/dist/sveltekit/index.js +1 -1
  35. package/dist/sveltekit/{live-preview-O2ZTJNW4.js → live-preview-2RCU35W5.js} +6 -337
  36. package/dist/sveltekit/live.cjs +1008 -909
  37. package/dist/sveltekit/live.js +118 -11
  38. package/package.json +11 -1
@@ -49,7 +49,7 @@ module.exports = __toCommonJS(nextjs_exports);
49
49
  var import_server = require("next/server");
50
50
 
51
51
  // src/version.ts
52
- var VERSION = "0.5.0-rc.5";
52
+ var VERSION = "0.5.0-rc.6";
53
53
 
54
54
  // src/core/constants.ts
55
55
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -345,14 +345,14 @@ function indexSnapshot(data) {
345
345
  const index = /* @__PURE__ */ new Map();
346
346
  const visited = /* @__PURE__ */ new WeakSet();
347
347
  const path = [];
348
- function walk(node) {
348
+ function walk2(node) {
349
349
  if (node === null || typeof node !== "object") return;
350
350
  if (visited.has(node)) return;
351
351
  visited.add(node);
352
352
  if (Array.isArray(node)) {
353
353
  for (let i = 0; i < node.length; i++) {
354
354
  path.push(i);
355
- walk(node[i]);
355
+ walk2(node[i]);
356
356
  path.pop();
357
357
  }
358
358
  return;
@@ -370,11 +370,11 @@ function indexSnapshot(data) {
370
370
  for (const key in record) {
371
371
  if (!Object.prototype.hasOwnProperty.call(record, key)) continue;
372
372
  path.push(key);
373
- walk(record[key]);
373
+ walk2(record[key]);
374
374
  path.pop();
375
375
  }
376
376
  }
377
- walk(data);
377
+ walk2(data);
378
378
  return index;
379
379
  }
380
380
 
@@ -831,12 +831,12 @@ function resolveFields(selections, typename, doc, options) {
831
831
  }
832
832
  };
833
833
  const applies = (on, list) => conditionMatches(on, typename) || typename !== void 0 && typeConditions(list, doc).includes(typename);
834
- const walk = (list, matched) => {
834
+ const walk2 = (list, matched) => {
835
835
  for (const s of list) {
836
836
  if (s.kind === "field") {
837
837
  add(matched ? exact : loose, s);
838
838
  } else if (s.kind === "inline") {
839
- walk(s.selections, matched && applies(s.on, s.selections));
839
+ walk2(s.selections, matched && applies(s.on, s.selections));
840
840
  } else {
841
841
  const fragment = doc.fragments.get(s.name);
842
842
  if (!fragment) continue;
@@ -844,11 +844,11 @@ function resolveFields(selections, typename, doc, options) {
844
844
  if (walkedMatched.has(fragment)) continue;
845
845
  if (!asMatched && walkedLoose.has(fragment)) continue;
846
846
  (asMatched ? walkedMatched : walkedLoose).add(fragment);
847
- walk(fragment.selections, asMatched);
847
+ walk2(fragment.selections, asMatched);
848
848
  }
849
849
  }
850
850
  };
851
- walk(selections, true);
851
+ walk2(selections, true);
852
852
  if (!options.strict) {
853
853
  for (const [key, field] of loose) {
854
854
  if (!exact.has(key)) exact.set(key, field);
@@ -865,21 +865,21 @@ function typeConditions(selections, doc) {
865
865
  if (hit) return hit;
866
866
  const names = /* @__PURE__ */ new Set();
867
867
  const seen = /* @__PURE__ */ new Set();
868
- const walk = (list) => {
868
+ const walk2 = (list) => {
869
869
  for (const s of list) {
870
870
  if (s.kind === "inline") {
871
871
  if (s.on) names.add(s.on);
872
- walk(s.selections);
872
+ walk2(s.selections);
873
873
  } else if (s.kind === "spread") {
874
874
  const fragment = doc.fragments.get(s.name);
875
875
  if (!fragment || seen.has(fragment)) continue;
876
876
  seen.add(fragment);
877
877
  names.add(fragment.on);
878
- walk(fragment.selections);
878
+ walk2(fragment.selections);
879
879
  }
880
880
  }
881
881
  };
882
- walk(selections);
882
+ walk2(selections);
883
883
  const conditions = [...names];
884
884
  conditionsCache.set(selections, conditions);
885
885
  return conditions;
@@ -1031,7 +1031,7 @@ function resolveTargets(root, doc, ownerPath, segments) {
1031
1031
  let current = root;
1032
1032
  const out = [];
1033
1033
  const plain = /* @__PURE__ */ new Set();
1034
- const walk = (node, sel, i, path) => {
1034
+ const walk2 = (node, sel, i, path) => {
1035
1035
  if (i === segments.length) {
1036
1036
  out.push(path);
1037
1037
  return;
@@ -1041,10 +1041,10 @@ function resolveTargets(root, doc, ownerPath, segments) {
1041
1041
  if (INDEX_SEGMENT.test(segment)) {
1042
1042
  const position = Number(segment);
1043
1043
  if (position < node.length) {
1044
- walk(node[position], sel, i + 1, [...path, position]);
1044
+ walk2(node[position], sel, i + 1, [...path, position]);
1045
1045
  }
1046
1046
  } else if (segment === "items") {
1047
- walk(node, sel, i + 1, path);
1047
+ walk2(node, sel, i + 1, path);
1048
1048
  }
1049
1049
  return;
1050
1050
  }
@@ -1077,11 +1077,11 @@ function resolveTargets(root, doc, ownerPath, segments) {
1077
1077
  current = writeAtPath(current, fieldPath, value);
1078
1078
  }
1079
1079
  }
1080
- walk(value, field.selections, i + 1, fieldPath);
1080
+ walk2(value, field.selections, i + 1, fieldPath);
1081
1081
  }
1082
- if (!matched && segment === "items") walk(node, sel, i + 1, path);
1082
+ if (!matched && segment === "items") walk2(node, sel, i + 1, path);
1083
1083
  };
1084
- walk(owner, selections, 0, ownerPath);
1084
+ walk2(owner, selections, 0, ownerPath);
1085
1085
  return { root: current, targets: out, plain };
1086
1086
  }
1087
1087
  var NON_ALPHANUMERIC = /[^a-z0-9]/gi;
@@ -1204,11 +1204,11 @@ function listKeysIn(result) {
1204
1204
  if (!byType) {
1205
1205
  byType = /* @__PURE__ */ new Map();
1206
1206
  const seen = /* @__PURE__ */ new WeakSet();
1207
- const walk = (node) => {
1207
+ const walk2 = (node) => {
1208
1208
  if (node === null || typeof node !== "object" || seen.has(node)) return;
1209
1209
  seen.add(node);
1210
1210
  if (Array.isArray(node)) {
1211
- node.forEach(walk);
1211
+ node.forEach(walk2);
1212
1212
  return;
1213
1213
  }
1214
1214
  const record = node;
@@ -1219,10 +1219,10 @@ function listKeysIn(result) {
1219
1219
  if (!keys) byType.set(type, keys = /* @__PURE__ */ new Set());
1220
1220
  keys.add(key);
1221
1221
  }
1222
- walk(value);
1222
+ walk2(value);
1223
1223
  }
1224
1224
  };
1225
- walk(result);
1225
+ walk2(result);
1226
1226
  listKeysCache.set(result, byType);
1227
1227
  }
1228
1228
  return byType.get(typename) ?? NO_KEYS;
@@ -1264,7 +1264,7 @@ function findEditLink(root) {
1264
1264
  if (linkCache.has(root)) return linkCache.get(root) ?? null;
1265
1265
  let found = null;
1266
1266
  const seen = /* @__PURE__ */ new WeakSet();
1267
- const walk = (node) => {
1267
+ const walk2 = (node) => {
1268
1268
  if (found) return;
1269
1269
  if (typeof node === "string") {
1270
1270
  if (!(0, import_stega2.vercelStegaSplit)(node).encoded) return;
@@ -1279,13 +1279,108 @@ function findEditLink(root) {
1279
1279
  }
1280
1280
  if (node === null || typeof node !== "object" || seen.has(node)) return;
1281
1281
  seen.add(node);
1282
- for (const value of Object.values(node)) walk(value);
1282
+ for (const value of Object.values(node)) walk2(value);
1283
1283
  };
1284
- walk(root);
1284
+ walk2(root);
1285
1285
  linkCache.set(root, found);
1286
1286
  return found;
1287
1287
  }
1288
1288
 
1289
+ // src/core/live-preview/edit-links.ts
1290
+ var import_stega3 = require("@vercel/stega");
1291
+ var ENTRY_PARAM = "entry";
1292
+ var TOP_LEVEL_ENTRY = /^[A-Za-z0-9_]+\.\d+$/;
1293
+ function entryIdOf(element) {
1294
+ if (!isRecord(element)) return void 0;
1295
+ if (typeof element._id === "string") return element._id;
1296
+ if (element.__typename !== "Assets" || !Array.isArray(element.items)) {
1297
+ return void 0;
1298
+ }
1299
+ const first = element.items[0];
1300
+ return isRecord(first) && typeof first._id === "string" ? first._id : void 0;
1301
+ }
1302
+ function isRecord(value) {
1303
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1304
+ }
1305
+ function annotate(value, ctx) {
1306
+ if (!ctx.entryId) return value;
1307
+ const { cleaned, encoded } = (0, import_stega3.vercelStegaSplit)(value);
1308
+ if (!encoded) return value;
1309
+ let payload;
1310
+ try {
1311
+ payload = (0, import_stega3.vercelStegaDecode)(encoded);
1312
+ } catch {
1313
+ return value;
1314
+ }
1315
+ if (typeof payload?.href !== "string") return value;
1316
+ let url;
1317
+ try {
1318
+ url = new URL(payload.href);
1319
+ } catch {
1320
+ return value;
1321
+ }
1322
+ if (url.searchParams.has(ENTRY_PARAM)) return value;
1323
+ url.searchParams.set(ENTRY_PARAM, ctx.entryId);
1324
+ const itemId = decodeURIComponent(url.pathname.split("/").pop() ?? "");
1325
+ if (!url.searchParams.has("field") && ctx.entryField && TOP_LEVEL_ENTRY.test(ctx.entryField) && itemId === ctx.entryOwnerId) {
1326
+ url.searchParams.set("field", ctx.entryField);
1327
+ }
1328
+ return (0, import_stega3.vercelStegaCombine)(
1329
+ cleaned,
1330
+ { ...payload, href: url.toString() },
1331
+ false
1332
+ );
1333
+ }
1334
+ function walk(value, selections, ctx) {
1335
+ if (typeof value === "string") return annotate(value, ctx);
1336
+ if (Array.isArray(value)) {
1337
+ let changed2 = false;
1338
+ const next2 = value.map((element, index) => {
1339
+ const path = [...ctx.path, String(index)];
1340
+ const entryId = ctx.inAssets ? void 0 : entryIdOf(element);
1341
+ const entry = entryId ? {
1342
+ entryId,
1343
+ entryField: ctx.ownerId ? path.join(".") : void 0,
1344
+ entryOwnerId: ctx.ownerId,
1345
+ inAssets: isRecord(element) && element._id === void 0
1346
+ } : {};
1347
+ const out = walk(element, selections, { ...ctx, ...entry, path });
1348
+ if (out !== element) changed2 = true;
1349
+ return out;
1350
+ });
1351
+ return changed2 ? next2 : value;
1352
+ }
1353
+ if (!isRecord(value)) return value;
1354
+ const id = typeof value._id === "string" ? value._id : void 0;
1355
+ const typename = typeof value.__typename === "string" ? value.__typename : void 0;
1356
+ const fields = ctx.doc && selections ? collectFields(selections, typename, ctx.doc) : null;
1357
+ let changed = false;
1358
+ const next = {};
1359
+ for (const [key, child] of Object.entries(value)) {
1360
+ const field = fields?.get(key);
1361
+ const name = field?.name ?? key;
1362
+ const out = walk(child, field?.selections ?? null, {
1363
+ ...ctx,
1364
+ ownerId: id ?? ctx.ownerId,
1365
+ path: id ? [name] : [...ctx.path, name]
1366
+ });
1367
+ if (out !== child) changed = true;
1368
+ next[key] = out;
1369
+ }
1370
+ return changed ? next : value;
1371
+ }
1372
+ function annotateEditLinks(result, query, operationName) {
1373
+ let doc = null;
1374
+ if (query !== void 0) {
1375
+ try {
1376
+ doc = readQueryDocument(query, operationName);
1377
+ } catch {
1378
+ doc = null;
1379
+ }
1380
+ }
1381
+ return walk(result, doc?.operation ?? null, { doc, path: [] });
1382
+ }
1383
+
1289
1384
  // src/nextjs/server.ts
1290
1385
  var React = __toESM(require("react"), 1);
1291
1386
 
@@ -1526,9 +1621,10 @@ var getPreprLiveLog = cacheForRender(
1526
1621
  );
1527
1622
  async function normalizeQuery(query, result, options = {}) {
1528
1623
  if (!options.enabled) return result;
1624
+ const annotated = annotateEditLinks(result, query, options.operationName);
1529
1625
  const log = await getPreprLiveLog();
1530
- if (!log.length) return result;
1531
- return applyPatchLog(query, result, log, options.operationName);
1626
+ if (!log.length) return annotated;
1627
+ return applyPatchLog(query, annotated, log, options.operationName);
1532
1628
  }
1533
1629
 
1534
1630
  // src/nextjs/index.ts
@@ -2,7 +2,7 @@
2
2
  import { NextResponse } from "next/server";
3
3
 
4
4
  // src/version.ts
5
- var VERSION = "0.5.0-rc.5";
5
+ var VERSION = "0.5.0-rc.6";
6
6
 
7
7
  // src/core/constants.ts
8
8
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -302,14 +302,14 @@ function indexSnapshot(data) {
302
302
  const index = /* @__PURE__ */ new Map();
303
303
  const visited = /* @__PURE__ */ new WeakSet();
304
304
  const path = [];
305
- function walk(node) {
305
+ function walk2(node) {
306
306
  if (node === null || typeof node !== "object") return;
307
307
  if (visited.has(node)) return;
308
308
  visited.add(node);
309
309
  if (Array.isArray(node)) {
310
310
  for (let i = 0; i < node.length; i++) {
311
311
  path.push(i);
312
- walk(node[i]);
312
+ walk2(node[i]);
313
313
  path.pop();
314
314
  }
315
315
  return;
@@ -327,11 +327,11 @@ function indexSnapshot(data) {
327
327
  for (const key in record) {
328
328
  if (!Object.prototype.hasOwnProperty.call(record, key)) continue;
329
329
  path.push(key);
330
- walk(record[key]);
330
+ walk2(record[key]);
331
331
  path.pop();
332
332
  }
333
333
  }
334
- walk(data);
334
+ walk2(data);
335
335
  return index;
336
336
  }
337
337
 
@@ -788,12 +788,12 @@ function resolveFields(selections, typename, doc, options) {
788
788
  }
789
789
  };
790
790
  const applies = (on, list) => conditionMatches(on, typename) || typename !== void 0 && typeConditions(list, doc).includes(typename);
791
- const walk = (list, matched) => {
791
+ const walk2 = (list, matched) => {
792
792
  for (const s of list) {
793
793
  if (s.kind === "field") {
794
794
  add(matched ? exact : loose, s);
795
795
  } else if (s.kind === "inline") {
796
- walk(s.selections, matched && applies(s.on, s.selections));
796
+ walk2(s.selections, matched && applies(s.on, s.selections));
797
797
  } else {
798
798
  const fragment = doc.fragments.get(s.name);
799
799
  if (!fragment) continue;
@@ -801,11 +801,11 @@ function resolveFields(selections, typename, doc, options) {
801
801
  if (walkedMatched.has(fragment)) continue;
802
802
  if (!asMatched && walkedLoose.has(fragment)) continue;
803
803
  (asMatched ? walkedMatched : walkedLoose).add(fragment);
804
- walk(fragment.selections, asMatched);
804
+ walk2(fragment.selections, asMatched);
805
805
  }
806
806
  }
807
807
  };
808
- walk(selections, true);
808
+ walk2(selections, true);
809
809
  if (!options.strict) {
810
810
  for (const [key, field] of loose) {
811
811
  if (!exact.has(key)) exact.set(key, field);
@@ -822,21 +822,21 @@ function typeConditions(selections, doc) {
822
822
  if (hit) return hit;
823
823
  const names = /* @__PURE__ */ new Set();
824
824
  const seen = /* @__PURE__ */ new Set();
825
- const walk = (list) => {
825
+ const walk2 = (list) => {
826
826
  for (const s of list) {
827
827
  if (s.kind === "inline") {
828
828
  if (s.on) names.add(s.on);
829
- walk(s.selections);
829
+ walk2(s.selections);
830
830
  } else if (s.kind === "spread") {
831
831
  const fragment = doc.fragments.get(s.name);
832
832
  if (!fragment || seen.has(fragment)) continue;
833
833
  seen.add(fragment);
834
834
  names.add(fragment.on);
835
- walk(fragment.selections);
835
+ walk2(fragment.selections);
836
836
  }
837
837
  }
838
838
  };
839
- walk(selections);
839
+ walk2(selections);
840
840
  const conditions = [...names];
841
841
  conditionsCache.set(selections, conditions);
842
842
  return conditions;
@@ -988,7 +988,7 @@ function resolveTargets(root, doc, ownerPath, segments) {
988
988
  let current = root;
989
989
  const out = [];
990
990
  const plain = /* @__PURE__ */ new Set();
991
- const walk = (node, sel, i, path) => {
991
+ const walk2 = (node, sel, i, path) => {
992
992
  if (i === segments.length) {
993
993
  out.push(path);
994
994
  return;
@@ -998,10 +998,10 @@ function resolveTargets(root, doc, ownerPath, segments) {
998
998
  if (INDEX_SEGMENT.test(segment)) {
999
999
  const position = Number(segment);
1000
1000
  if (position < node.length) {
1001
- walk(node[position], sel, i + 1, [...path, position]);
1001
+ walk2(node[position], sel, i + 1, [...path, position]);
1002
1002
  }
1003
1003
  } else if (segment === "items") {
1004
- walk(node, sel, i + 1, path);
1004
+ walk2(node, sel, i + 1, path);
1005
1005
  }
1006
1006
  return;
1007
1007
  }
@@ -1034,11 +1034,11 @@ function resolveTargets(root, doc, ownerPath, segments) {
1034
1034
  current = writeAtPath(current, fieldPath, value);
1035
1035
  }
1036
1036
  }
1037
- walk(value, field.selections, i + 1, fieldPath);
1037
+ walk2(value, field.selections, i + 1, fieldPath);
1038
1038
  }
1039
- if (!matched && segment === "items") walk(node, sel, i + 1, path);
1039
+ if (!matched && segment === "items") walk2(node, sel, i + 1, path);
1040
1040
  };
1041
- walk(owner, selections, 0, ownerPath);
1041
+ walk2(owner, selections, 0, ownerPath);
1042
1042
  return { root: current, targets: out, plain };
1043
1043
  }
1044
1044
  var NON_ALPHANUMERIC = /[^a-z0-9]/gi;
@@ -1161,11 +1161,11 @@ function listKeysIn(result) {
1161
1161
  if (!byType) {
1162
1162
  byType = /* @__PURE__ */ new Map();
1163
1163
  const seen = /* @__PURE__ */ new WeakSet();
1164
- const walk = (node) => {
1164
+ const walk2 = (node) => {
1165
1165
  if (node === null || typeof node !== "object" || seen.has(node)) return;
1166
1166
  seen.add(node);
1167
1167
  if (Array.isArray(node)) {
1168
- node.forEach(walk);
1168
+ node.forEach(walk2);
1169
1169
  return;
1170
1170
  }
1171
1171
  const record = node;
@@ -1176,10 +1176,10 @@ function listKeysIn(result) {
1176
1176
  if (!keys) byType.set(type, keys = /* @__PURE__ */ new Set());
1177
1177
  keys.add(key);
1178
1178
  }
1179
- walk(value);
1179
+ walk2(value);
1180
1180
  }
1181
1181
  };
1182
- walk(result);
1182
+ walk2(result);
1183
1183
  listKeysCache.set(result, byType);
1184
1184
  }
1185
1185
  return byType.get(typename) ?? NO_KEYS;
@@ -1221,7 +1221,7 @@ function findEditLink(root) {
1221
1221
  if (linkCache.has(root)) return linkCache.get(root) ?? null;
1222
1222
  let found = null;
1223
1223
  const seen = /* @__PURE__ */ new WeakSet();
1224
- const walk = (node) => {
1224
+ const walk2 = (node) => {
1225
1225
  if (found) return;
1226
1226
  if (typeof node === "string") {
1227
1227
  if (!vercelStegaSplit2(node).encoded) return;
@@ -1236,13 +1236,112 @@ function findEditLink(root) {
1236
1236
  }
1237
1237
  if (node === null || typeof node !== "object" || seen.has(node)) return;
1238
1238
  seen.add(node);
1239
- for (const value of Object.values(node)) walk(value);
1239
+ for (const value of Object.values(node)) walk2(value);
1240
1240
  };
1241
- walk(root);
1241
+ walk2(root);
1242
1242
  linkCache.set(root, found);
1243
1243
  return found;
1244
1244
  }
1245
1245
 
1246
+ // src/core/live-preview/edit-links.ts
1247
+ import {
1248
+ vercelStegaCombine as vercelStegaCombine2,
1249
+ vercelStegaDecode as vercelStegaDecode2,
1250
+ vercelStegaSplit as vercelStegaSplit3
1251
+ } from "@vercel/stega";
1252
+ var ENTRY_PARAM = "entry";
1253
+ var TOP_LEVEL_ENTRY = /^[A-Za-z0-9_]+\.\d+$/;
1254
+ function entryIdOf(element) {
1255
+ if (!isRecord(element)) return void 0;
1256
+ if (typeof element._id === "string") return element._id;
1257
+ if (element.__typename !== "Assets" || !Array.isArray(element.items)) {
1258
+ return void 0;
1259
+ }
1260
+ const first = element.items[0];
1261
+ return isRecord(first) && typeof first._id === "string" ? first._id : void 0;
1262
+ }
1263
+ function isRecord(value) {
1264
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1265
+ }
1266
+ function annotate(value, ctx) {
1267
+ if (!ctx.entryId) return value;
1268
+ const { cleaned, encoded } = vercelStegaSplit3(value);
1269
+ if (!encoded) return value;
1270
+ let payload;
1271
+ try {
1272
+ payload = vercelStegaDecode2(encoded);
1273
+ } catch {
1274
+ return value;
1275
+ }
1276
+ if (typeof payload?.href !== "string") return value;
1277
+ let url;
1278
+ try {
1279
+ url = new URL(payload.href);
1280
+ } catch {
1281
+ return value;
1282
+ }
1283
+ if (url.searchParams.has(ENTRY_PARAM)) return value;
1284
+ url.searchParams.set(ENTRY_PARAM, ctx.entryId);
1285
+ const itemId = decodeURIComponent(url.pathname.split("/").pop() ?? "");
1286
+ if (!url.searchParams.has("field") && ctx.entryField && TOP_LEVEL_ENTRY.test(ctx.entryField) && itemId === ctx.entryOwnerId) {
1287
+ url.searchParams.set("field", ctx.entryField);
1288
+ }
1289
+ return vercelStegaCombine2(
1290
+ cleaned,
1291
+ { ...payload, href: url.toString() },
1292
+ false
1293
+ );
1294
+ }
1295
+ function walk(value, selections, ctx) {
1296
+ if (typeof value === "string") return annotate(value, ctx);
1297
+ if (Array.isArray(value)) {
1298
+ let changed2 = false;
1299
+ const next2 = value.map((element, index) => {
1300
+ const path = [...ctx.path, String(index)];
1301
+ const entryId = ctx.inAssets ? void 0 : entryIdOf(element);
1302
+ const entry = entryId ? {
1303
+ entryId,
1304
+ entryField: ctx.ownerId ? path.join(".") : void 0,
1305
+ entryOwnerId: ctx.ownerId,
1306
+ inAssets: isRecord(element) && element._id === void 0
1307
+ } : {};
1308
+ const out = walk(element, selections, { ...ctx, ...entry, path });
1309
+ if (out !== element) changed2 = true;
1310
+ return out;
1311
+ });
1312
+ return changed2 ? next2 : value;
1313
+ }
1314
+ if (!isRecord(value)) return value;
1315
+ const id = typeof value._id === "string" ? value._id : void 0;
1316
+ const typename = typeof value.__typename === "string" ? value.__typename : void 0;
1317
+ const fields = ctx.doc && selections ? collectFields(selections, typename, ctx.doc) : null;
1318
+ let changed = false;
1319
+ const next = {};
1320
+ for (const [key, child] of Object.entries(value)) {
1321
+ const field = fields?.get(key);
1322
+ const name = field?.name ?? key;
1323
+ const out = walk(child, field?.selections ?? null, {
1324
+ ...ctx,
1325
+ ownerId: id ?? ctx.ownerId,
1326
+ path: id ? [name] : [...ctx.path, name]
1327
+ });
1328
+ if (out !== child) changed = true;
1329
+ next[key] = out;
1330
+ }
1331
+ return changed ? next : value;
1332
+ }
1333
+ function annotateEditLinks(result, query, operationName) {
1334
+ let doc = null;
1335
+ if (query !== void 0) {
1336
+ try {
1337
+ doc = readQueryDocument(query, operationName);
1338
+ } catch {
1339
+ doc = null;
1340
+ }
1341
+ }
1342
+ return walk(result, doc?.operation ?? null, { doc, path: [] });
1343
+ }
1344
+
1246
1345
  // src/nextjs/server.ts
1247
1346
  import * as React from "react";
1248
1347
 
@@ -1483,9 +1582,10 @@ var getPreprLiveLog = cacheForRender(
1483
1582
  );
1484
1583
  async function normalizeQuery(query, result, options = {}) {
1485
1584
  if (!options.enabled) return result;
1585
+ const annotated = annotateEditLinks(result, query, options.operationName);
1486
1586
  const log = await getPreprLiveLog();
1487
- if (!log.length) return result;
1488
- return applyPatchLog(query, result, log, options.operationName);
1587
+ if (!log.length) return annotated;
1588
+ return applyPatchLog(query, annotated, log, options.operationName);
1489
1589
  }
1490
1590
 
1491
1591
  // src/nextjs/index.ts
@@ -1,11 +1,11 @@
1
1
  "use server";
2
2
  import {
3
3
  isPreviewFromHeaders
4
- } from "../chunk-3X55JL52.js";
5
- import "../chunk-CMUFTCG3.js";
4
+ } from "../chunk-KZIRM54F.js";
5
+ import "../chunk-WHZNCYUS.js";
6
6
  import {
7
7
  parsePatchLog
8
- } from "../chunk-74KY5EAM.js";
8
+ } from "../chunk-KD3GK6TO.js";
9
9
  import "../chunk-S3VT4UWM.js";
10
10
 
11
11
  // src/nextjs/live-action.ts
@@ -27,7 +27,7 @@ function isFramed() {
27
27
  return typeof window !== "undefined" && window.self !== window.top;
28
28
  }
29
29
  function startLive() {
30
- starting ?? (starting = import("../live-preview-H4643QYF.js").then(
30
+ starting ?? (starting = import("../live-preview-DLXGXRE5.js").then(
31
31
  ({ createLiveBridge, createLiveStore }) => {
32
32
  const skipped = new Set(quarantined());
33
33
  const started = createLiveStore({