@preprio/toolkit 0.5.0-rc.2 → 0.5.0-rc.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.
Files changed (50) hide show
  1. package/README.md +209 -10
  2. package/dist/astro/index.cjs +1194 -1
  3. package/dist/astro/index.d.cts +47 -1
  4. package/dist/astro/index.d.ts +47 -1
  5. package/dist/astro/index.js +1197 -1
  6. package/dist/chunk-46ISDRHT.js +26 -0
  7. package/dist/chunk-74KY5EAM.js +1219 -0
  8. package/dist/chunk-AHBN6FQP.js +184 -0
  9. package/dist/{chunk-FLPNN3CV.js → chunk-PDNCNTDB.js} +1370 -623
  10. package/dist/chunk-S3VT4UWM.js +75 -0
  11. package/dist/chunk-TG6N3C22.js +246 -0
  12. package/dist/chunk-URXSDJOU.js +356 -0
  13. package/dist/index.cjs +3166 -392
  14. package/dist/index.d.cts +238 -4
  15. package/dist/index.d.ts +238 -4
  16. package/dist/index.js +189 -149
  17. package/dist/live-preview-H4643QYF.js +18 -0
  18. package/dist/nextjs/components.cjs +1522 -359
  19. package/dist/nextjs/components.d.cts +1 -1
  20. package/dist/nextjs/components.d.ts +1 -1
  21. package/dist/nextjs/components.js +4 -1
  22. package/dist/nextjs/index.cjs +1085 -6
  23. package/dist/nextjs/index.d.cts +73 -1
  24. package/dist/nextjs/index.d.ts +73 -1
  25. package/dist/nextjs/index.js +1079 -7
  26. package/dist/nextjs/live-action.cjs +285 -0
  27. package/dist/nextjs/live-action.d.cts +12 -0
  28. package/dist/nextjs/live-action.d.ts +12 -0
  29. package/dist/nextjs/live-action.js +68 -0
  30. package/dist/nextjs/live.cjs +1896 -0
  31. package/dist/nextjs/live.d.cts +52 -0
  32. package/dist/nextjs/live.d.ts +52 -0
  33. package/dist/nextjs/live.js +265 -0
  34. package/dist/nuxt/index.cjs +1 -1
  35. package/dist/nuxt/index.js +1 -1
  36. package/dist/nuxt/live-preview-O2ZTJNW4.js +1520 -0
  37. package/dist/nuxt/live.cjs +1720 -0
  38. package/dist/nuxt/live.d.cts +43 -0
  39. package/dist/nuxt/live.d.ts +43 -0
  40. package/dist/nuxt/live.js +94 -0
  41. package/dist/{pixel-B3oQNbZ3.d.cts → pixel-CX422dCO.d.cts} +10 -1
  42. package/dist/{pixel-B3oQNbZ3.d.ts → pixel-CX422dCO.d.ts} +10 -1
  43. package/dist/react/components.cjs +1522 -359
  44. package/dist/react/components.d.cts +9 -0
  45. package/dist/react/components.d.ts +9 -0
  46. package/dist/react/components.js +1522 -359
  47. package/dist/sveltekit/index.cjs +1 -1
  48. package/dist/sveltekit/index.js +1 -1
  49. package/package.json +12 -1
  50. package/src/astro/PreprToolbar.astro +7 -1
@@ -0,0 +1,1720 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res, err) => function __init() {
7
+ if (err) throw err[0];
8
+ try {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ } catch (e) {
11
+ throw err = [e], e;
12
+ }
13
+ };
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+
28
+ // src/core/utils.ts
29
+ function getTrustedParentOrigin() {
30
+ return trustedParentOrigin;
31
+ }
32
+ function sendPreprEvent(event, data, options) {
33
+ if (typeof window !== "undefined") {
34
+ const message = {
35
+ name: "prepr_preview_bar",
36
+ event,
37
+ ...data
38
+ };
39
+ window.dispatchEvent(
40
+ new CustomEvent("prepr_preview_bar", { detail: message })
41
+ );
42
+ if (window.parent && window.parent !== window) {
43
+ if (trustedParentOrigin) {
44
+ window.parent.postMessage(message, trustedParentOrigin);
45
+ } else if (options?.allowUntrustedTarget) {
46
+ window.parent.postMessage(message, "*");
47
+ }
48
+ }
49
+ }
50
+ }
51
+ function createScopedLogger(scopeName) {
52
+ return new DebugLogger({
53
+ prefix: `[Prepr][${scopeName}]`
54
+ });
55
+ }
56
+ var trustedParentOrigin, DebugLogger, globalDebugLogger;
57
+ var init_utils = __esm({
58
+ "src/core/utils.ts"() {
59
+ "use strict";
60
+ trustedParentOrigin = null;
61
+ DebugLogger = class {
62
+ constructor(options) {
63
+ this.options = {
64
+ prefix: "[Prepr]",
65
+ ...options
66
+ };
67
+ }
68
+ // A local `enabled` wins; otherwise defer to the global logger so scoped
69
+ // loggers created before initDebugLogger() still pick up the setting.
70
+ isEnabled() {
71
+ if (this.options.enabled !== void 0) {
72
+ return this.options.enabled;
73
+ }
74
+ return globalDebugLogger?.options?.enabled ?? false;
75
+ }
76
+ log(message, ...args) {
77
+ if (!this.isEnabled()) return;
78
+ const prefix = this.options.prefix;
79
+ console.log(`${prefix} ${message}`, ...args);
80
+ }
81
+ warn(message, ...args) {
82
+ if (!this.isEnabled()) return;
83
+ const prefix = this.options.prefix;
84
+ console.warn(`${prefix} ${message}`, ...args);
85
+ }
86
+ error(message, ...args) {
87
+ if (!this.isEnabled()) return;
88
+ const prefix = this.options.prefix;
89
+ console.error(`${prefix} ${message}`, ...args);
90
+ }
91
+ };
92
+ globalDebugLogger = null;
93
+ }
94
+ });
95
+
96
+ // src/core/live-preview/index-snapshot.ts
97
+ function indexSnapshot(data) {
98
+ const index = /* @__PURE__ */ new Map();
99
+ const visited = /* @__PURE__ */ new WeakSet();
100
+ const path = [];
101
+ function walk(node) {
102
+ if (node === null || typeof node !== "object") return;
103
+ if (visited.has(node)) return;
104
+ visited.add(node);
105
+ if (Array.isArray(node)) {
106
+ for (let i = 0; i < node.length; i++) {
107
+ path.push(i);
108
+ walk(node[i]);
109
+ path.pop();
110
+ }
111
+ return;
112
+ }
113
+ const record = node;
114
+ if (typeof record._id === "string") {
115
+ const paths = index.get(record._id);
116
+ if (paths) paths.push([...path]);
117
+ else index.set(record._id, [[...path]]);
118
+ } else if (typeof record.__typename === "string") {
119
+ debug.log("item without _id will not live-update", {
120
+ __typename: record.__typename
121
+ });
122
+ }
123
+ for (const key in record) {
124
+ if (!Object.prototype.hasOwnProperty.call(record, key)) continue;
125
+ path.push(key);
126
+ walk(record[key]);
127
+ path.pop();
128
+ }
129
+ }
130
+ walk(data);
131
+ return index;
132
+ }
133
+ var debug;
134
+ var init_index_snapshot = __esm({
135
+ "src/core/live-preview/index-snapshot.ts"() {
136
+ "use strict";
137
+ init_utils();
138
+ debug = createScopedLogger("live-preview");
139
+ }
140
+ });
141
+
142
+ // src/core/live-preview/field-name.ts
143
+ function graphqlFieldName(apiId) {
144
+ return apiId.replace(UPPERCASE_BOUNDARY, "$1_").toLowerCase();
145
+ }
146
+ function fieldKeyIn(record, apiId) {
147
+ if (Object.prototype.hasOwnProperty.call(record, apiId)) return apiId;
148
+ const name = graphqlFieldName(apiId);
149
+ return Object.prototype.hasOwnProperty.call(record, name) ? name : void 0;
150
+ }
151
+ function plainTextFromHtml(html) {
152
+ return html.replace(TAG_PATTERN, "");
153
+ }
154
+ function isTextEntry(record) {
155
+ const typename = record.__typename;
156
+ if (typeof typename === "string") return typename === "Text";
157
+ return "html" in record || "text" in record && "format" in record;
158
+ }
159
+ var UPPERCASE_BOUNDARY, TEXT_BODY_FIELDS, TAG_PATTERN;
160
+ var init_field_name = __esm({
161
+ "src/core/live-preview/field-name.ts"() {
162
+ "use strict";
163
+ UPPERCASE_BOUNDARY = /(.)(?=[A-Z])/g;
164
+ TEXT_BODY_FIELDS = [
165
+ { name: "body", plain: false },
166
+ { name: "html", plain: false },
167
+ { name: "text", plain: true }
168
+ ];
169
+ TAG_PATTERN = /<[^>]+>/g;
170
+ }
171
+ });
172
+
173
+ // src/core/live-preview/patch.ts
174
+ function isPlainObject(value) {
175
+ return value !== null && typeof value === "object" && !Array.isArray(value);
176
+ }
177
+ function mergeObject(current, incoming) {
178
+ let changed = false;
179
+ const next = { ...current };
180
+ for (const key of Object.keys(current)) {
181
+ if (!(key in incoming) || incoming[key] === void 0) continue;
182
+ const value = isPlainObject(current[key]) && isPlainObject(incoming[key]) ? mergeObject(current[key], incoming[key]) : incoming[key];
183
+ if (value !== current[key]) {
184
+ next[key] = value;
185
+ changed = true;
186
+ }
187
+ }
188
+ return changed ? next : current;
189
+ }
190
+ function shapeLike(template, incoming) {
191
+ const out = {};
192
+ for (const key of Object.keys(template)) {
193
+ const value = incoming[key];
194
+ out[key] = value === void 0 ? null : isPlainObject(template[key]) && isPlainObject(value) ? shapeLike(template[key], value) : value;
195
+ }
196
+ return out;
197
+ }
198
+ function mergeStructured(current, incoming) {
199
+ if (incoming === null || Array.isArray(incoming) && !incoming.length) {
200
+ if (Array.isArray(current)) return current.length ? [] : current;
201
+ return null;
202
+ }
203
+ const list = Array.isArray(incoming) ? incoming : [incoming];
204
+ if (current === null || current === void 0) return incoming;
205
+ if (Array.isArray(current)) {
206
+ const template = current.find(isPlainObject);
207
+ return list.map((entry) => {
208
+ const match = current.find(
209
+ (c) => isPlainObject(c) && c._id !== void 0 && c._id === entry._id
210
+ );
211
+ if (isPlainObject(match)) return mergeObject(match, entry);
212
+ return isPlainObject(template) ? shapeLike(template, entry) : entry;
213
+ });
214
+ }
215
+ if (isPlainObject(current)) return mergeObject(current, list[0]);
216
+ return current;
217
+ }
218
+ function isPatchable(current) {
219
+ return current === null || typeof current === "string" || typeof current === "number" || typeof current === "boolean";
220
+ }
221
+ function cloneNode(node) {
222
+ return Array.isArray(node) ? [...node] : { ...node };
223
+ }
224
+ function patchSnapshot(snapshot, index, itemId, field, value) {
225
+ const paths = index.get(itemId);
226
+ if (!paths?.length) return snapshot;
227
+ let root = snapshot;
228
+ let changed = false;
229
+ const markChanged = () => {
230
+ changed = true;
231
+ };
232
+ for (const path of paths) {
233
+ for (const [target, targetValue] of expandTextBody(
234
+ root,
235
+ path,
236
+ field,
237
+ value
238
+ )) {
239
+ root = patchAtPath(root, path, target, targetValue, markChanged);
240
+ }
241
+ }
242
+ return changed ? root : snapshot;
243
+ }
244
+ function expandTextBody(root, path, field, value) {
245
+ const segments = field.split(".");
246
+ if (segments[segments.length - 1] !== "body" || typeof value !== "string") {
247
+ return [[field, value]];
248
+ }
249
+ let node = root;
250
+ for (const step of path) {
251
+ node = node[step];
252
+ }
253
+ for (const segment of segments.slice(0, -1)) {
254
+ if (node === null || typeof node !== "object") return [[field, value]];
255
+ const record2 = node;
256
+ node = INDEX_SEGMENT.test(segment) ? record2[Number(segment)] : record2[fieldKeyIn(record2, segment) ?? segment];
257
+ }
258
+ if (node === null || typeof node !== "object" || Array.isArray(node)) {
259
+ return [[field, value]];
260
+ }
261
+ const record = node;
262
+ if (!isTextEntry(record)) return [[field, value]];
263
+ const prefix = segments.slice(0, -1);
264
+ const writes = [];
265
+ for (const { name, plain } of TEXT_BODY_FIELDS) {
266
+ if (!(name in record)) continue;
267
+ writes.push([
268
+ [...prefix, name].join("."),
269
+ plain ? plainTextFromHtml(value) : value
270
+ ]);
271
+ }
272
+ return writes.length ? writes : [[field, value]];
273
+ }
274
+ function patchAtPath(root, path, field, value, markChanged) {
275
+ const segments = field.split(".");
276
+ if (segments.some((s) => FORBIDDEN_SEGMENTS.has(s))) return root;
277
+ let node = root;
278
+ for (const step of path) {
279
+ node = node[step];
280
+ }
281
+ const fullPath = [...path];
282
+ for (const segment of segments) {
283
+ let step = segment;
284
+ if (INDEX_SEGMENT.test(segment)) {
285
+ step = Number(segment);
286
+ } else if (node !== null && typeof node === "object") {
287
+ step = fieldKeyIn(node, segment) ?? segment;
288
+ }
289
+ fullPath.push(step);
290
+ node = node !== null && typeof node === "object" ? node[step] : void 0;
291
+ }
292
+ return writeAtPath(root, fullPath, value, markChanged);
293
+ }
294
+ function writeAtPath(root, fullPath, value, markChanged = () => {
295
+ }) {
296
+ if (!fullPath.length) return root;
297
+ if (fullPath.some((s) => FORBIDDEN_SEGMENTS.has(String(s)))) return root;
298
+ const last = fullPath.length - 1;
299
+ let node = root;
300
+ for (let i = 0; i < last; i++) {
301
+ if (node === null || typeof node !== "object") return root;
302
+ node = node[fullPath[i]];
303
+ }
304
+ if (node === null || typeof node !== "object") return root;
305
+ const container = node;
306
+ const key = fullPath[last];
307
+ if (!(key in container)) return root;
308
+ let next;
309
+ if (value === null || typeof value === "object") {
310
+ next = mergeStructured(container[key], value);
311
+ } else if (!isPatchable(container[key])) {
312
+ return root;
313
+ } else {
314
+ next = keepEditLink(container[key], value);
315
+ }
316
+ if (container[key] === next) return root;
317
+ const newRoot = cloneNode(root);
318
+ let cursor = newRoot;
319
+ for (let i = 0; i < last; i++) {
320
+ const child = cloneNode(cursor[fullPath[i]]);
321
+ cursor[fullPath[i]] = child;
322
+ cursor = child;
323
+ }
324
+ cursor[key] = next;
325
+ markChanged();
326
+ return newRoot;
327
+ }
328
+ function listKeysOf(entry) {
329
+ if (!isPlainObject(entry)) return [];
330
+ const keys = [];
331
+ if (typeof entry._id === "string") keys.push(entry._id);
332
+ const first = Array.isArray(entry.items) ? entry.items[0] : null;
333
+ if (isPlainObject(first) && typeof first._id === "string") {
334
+ keys.push(first._id);
335
+ }
336
+ return keys;
337
+ }
338
+ function buildText(entry, template) {
339
+ const body = typeof entry.body === "string" ? entry.body : "";
340
+ const full = {
341
+ __typename: "Text",
342
+ _id: entry._id,
343
+ body,
344
+ html: body,
345
+ text: plainTextFromHtml(body),
346
+ format: entry.format ?? null
347
+ };
348
+ if (!template) return full;
349
+ const out = {};
350
+ for (const key of Object.keys(template)) {
351
+ out[key] = key in full ? full[key] : null;
352
+ }
353
+ return out;
354
+ }
355
+ function syncList(current, entries, build) {
356
+ if (current === null || current === void 0) {
357
+ const built = syncList([], entries, build);
358
+ return built.length ? built : current;
359
+ }
360
+ if (!Array.isArray(current)) return current;
361
+ const byKey = /* @__PURE__ */ new Map();
362
+ const templates = /* @__PURE__ */ new Map();
363
+ for (const c of current) {
364
+ for (const key of listKeysOf(c)) byKey.set(key, c);
365
+ if (isPlainObject(c) && typeof c.__typename === "string") {
366
+ if (!templates.has(c.__typename)) templates.set(c.__typename, c);
367
+ }
368
+ }
369
+ if (!entries.length) return current.length ? [] : current;
370
+ if (current.length && !byKey.size) return current;
371
+ if (current.length && !entries.some((e) => byKey.has(e._id))) return current;
372
+ const next = [];
373
+ for (const entry of entries) {
374
+ const existing = byKey.get(entry._id);
375
+ const built = existing === void 0 && entry.fields ? build?.(entry) : void 0;
376
+ if (existing !== void 0) {
377
+ next.push(existing);
378
+ } else if (built) {
379
+ next.push(built);
380
+ } else if (entry.__typename === "Text") {
381
+ next.push(buildText(entry, templates.get("Text")));
382
+ }
383
+ }
384
+ const same = next.length === current.length && next.every((n, i) => n === current[i]);
385
+ return same ? current : next;
386
+ }
387
+ function syncListSnapshot(snapshot, index, itemId, field, entries) {
388
+ const paths = index.get(itemId);
389
+ if (!paths?.length) return snapshot;
390
+ const fieldPath = field.split(".");
391
+ if (fieldPath.some((s) => FORBIDDEN_SEGMENTS.has(s))) return snapshot;
392
+ let root = snapshot;
393
+ for (const path of paths) {
394
+ root = syncListAtPath(root, [...path, ...fieldPath], entries);
395
+ }
396
+ return root;
397
+ }
398
+ function syncListAtPath(root, fullPath, entries, build) {
399
+ if (!fullPath.length) return root;
400
+ if (fullPath.some((s) => FORBIDDEN_SEGMENTS.has(String(s)))) return root;
401
+ let node = root;
402
+ for (const key of fullPath) {
403
+ node = node !== null && typeof node === "object" ? node[key] : void 0;
404
+ }
405
+ const next = syncList(node, entries, build);
406
+ if (next === node) return root;
407
+ const newRoot = cloneNode(root);
408
+ let cursor = newRoot;
409
+ for (let i = 0; i < fullPath.length - 1; i++) {
410
+ const child = cloneNode(cursor[fullPath[i]]);
411
+ cursor[fullPath[i]] = child;
412
+ cursor = child;
413
+ }
414
+ cursor[fullPath[fullPath.length - 1]] = next;
415
+ return newRoot;
416
+ }
417
+ function keepEditLink(current, value) {
418
+ if (typeof current !== "string" || typeof value !== "string") return value;
419
+ const { encoded } = (0, import_stega.vercelStegaSplit)(current);
420
+ if (!encoded || (0, import_stega.vercelStegaSplit)(value).encoded) return value;
421
+ return value + encoded;
422
+ }
423
+ var import_stega, INDEX_SEGMENT, FORBIDDEN_SEGMENTS;
424
+ var init_patch = __esm({
425
+ "src/core/live-preview/patch.ts"() {
426
+ "use strict";
427
+ import_stega = require("@vercel/stega");
428
+ init_field_name();
429
+ INDEX_SEGMENT = /^\d+$/;
430
+ FORBIDDEN_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
431
+ }
432
+ });
433
+
434
+ // src/core/live-preview/live-store.ts
435
+ function withPatch(log2, patch) {
436
+ let previous = -1;
437
+ for (let i = log2.length - 1; i >= 0; i--) {
438
+ const p = log2[i];
439
+ if (p.type === patch.type && p.itemId === patch.itemId && p.field === patch.field) {
440
+ previous = i;
441
+ break;
442
+ }
443
+ }
444
+ if (previous === -1) return [...log2, patch];
445
+ const since = log2.slice(previous + 1);
446
+ const listPrefix = `${patch.field}.`;
447
+ const dependsOnPosition = since.some(
448
+ (p) => p.type === "list" || patch.type === "list" && p.itemId === patch.itemId && p.field.startsWith(listPrefix)
449
+ );
450
+ if (dependsOnPosition) return [...log2, patch];
451
+ return [...log2.slice(0, previous), ...since, patch];
452
+ }
453
+ function createLiveStore(options = {}) {
454
+ const accepts = (patch) => options.accept ? options.accept(patch) : true;
455
+ const entries = /* @__PURE__ */ new Set();
456
+ const invalidateListeners = /* @__PURE__ */ new Set();
457
+ const pendingInvalidates = /* @__PURE__ */ new Map();
458
+ let defaultFetcher = null;
459
+ let log2 = [];
460
+ const logListeners = /* @__PURE__ */ new Set();
461
+ function record(patch) {
462
+ log2 = withPatch(log2, patch).slice(-MAX_LOG_ENTRIES);
463
+ logListeners.forEach((fn) => fn(log2));
464
+ }
465
+ function notify(entry) {
466
+ entry.listeners.forEach((fn) => fn());
467
+ }
468
+ async function refetch(entry) {
469
+ const fetcher = entry.opts.fetcher ?? defaultFetcher;
470
+ if (!fetcher || entry.opts.query == null) return;
471
+ const token = ++entry.fetchToken;
472
+ try {
473
+ const result = await fetcher(entry.opts.query, entry.opts.variables);
474
+ if (token !== entry.fetchToken || !entries.has(entry)) return;
475
+ entry.snapshot = result;
476
+ entry.index = indexSnapshot(result);
477
+ notify(entry);
478
+ } catch (error) {
479
+ debug2.log("refetch failed, keeping previous snapshot", error);
480
+ }
481
+ }
482
+ function runInvalidate(itemId) {
483
+ pendingInvalidates.delete(itemId);
484
+ invalidateListeners.forEach((fn) => fn(itemId));
485
+ for (const entry of entries) {
486
+ if (entry.index.has(itemId)) void refetch(entry);
487
+ }
488
+ }
489
+ return {
490
+ register(data, opts = {}) {
491
+ const entry = {
492
+ snapshot: data,
493
+ index: indexSnapshot(data),
494
+ opts,
495
+ listeners: /* @__PURE__ */ new Set(),
496
+ fetchToken: 0
497
+ };
498
+ for (const patch of log2) {
499
+ if (patch.type === "field") {
500
+ entry.snapshot = patchSnapshot(
501
+ entry.snapshot,
502
+ entry.index,
503
+ patch.itemId,
504
+ patch.field,
505
+ patch.value
506
+ );
507
+ } else {
508
+ const next = syncListSnapshot(
509
+ entry.snapshot,
510
+ entry.index,
511
+ patch.itemId,
512
+ patch.field,
513
+ patch.entries
514
+ );
515
+ if (next !== entry.snapshot) {
516
+ entry.snapshot = next;
517
+ entry.index = indexSnapshot(next);
518
+ }
519
+ }
520
+ }
521
+ entries.add(entry);
522
+ return {
523
+ getSnapshot: () => entry.snapshot,
524
+ subscribe(fn) {
525
+ entry.listeners.add(fn);
526
+ return () => entry.listeners.delete(fn);
527
+ },
528
+ unregister() {
529
+ entry.listeners.clear();
530
+ entries.delete(entry);
531
+ }
532
+ };
533
+ },
534
+ pushPatch(itemId, field, value, edit) {
535
+ const patch = edit ? { type: "field", itemId, field, value, edit } : { type: "field", itemId, field, value };
536
+ if (!accepts(patch)) return;
537
+ record(patch);
538
+ for (const entry of entries) {
539
+ const next = patchSnapshot(
540
+ entry.snapshot,
541
+ entry.index,
542
+ itemId,
543
+ field,
544
+ value
545
+ );
546
+ if (next !== entry.snapshot) {
547
+ entry.snapshot = next;
548
+ notify(entry);
549
+ }
550
+ }
551
+ },
552
+ pushList(itemId, field, list) {
553
+ const patch = { type: "list", itemId, field, entries: list };
554
+ if (!accepts(patch)) return;
555
+ record(patch);
556
+ for (const entry of entries) {
557
+ const next = syncListSnapshot(
558
+ entry.snapshot,
559
+ entry.index,
560
+ itemId,
561
+ field,
562
+ list
563
+ );
564
+ if (next !== entry.snapshot) {
565
+ entry.snapshot = next;
566
+ entry.index = indexSnapshot(next);
567
+ notify(entry);
568
+ }
569
+ }
570
+ },
571
+ invalidate(itemId) {
572
+ if (log2.length) {
573
+ log2 = [];
574
+ logListeners.forEach((fn) => fn(log2));
575
+ }
576
+ const pending = pendingInvalidates.get(itemId);
577
+ if (pending) clearTimeout(pending);
578
+ pendingInvalidates.set(
579
+ itemId,
580
+ setTimeout(() => runInvalidate(itemId), INVALIDATE_DEBOUNCE_MS)
581
+ );
582
+ },
583
+ setFetcher(fetcher) {
584
+ defaultFetcher = fetcher;
585
+ },
586
+ onInvalidate(fn) {
587
+ invalidateListeners.add(fn);
588
+ return () => invalidateListeners.delete(fn);
589
+ },
590
+ getLog: () => log2,
591
+ onLogChange(fn) {
592
+ logListeners.add(fn);
593
+ return () => logListeners.delete(fn);
594
+ }
595
+ };
596
+ }
597
+ var debug2, INVALIDATE_DEBOUNCE_MS, MAX_LOG_ENTRIES;
598
+ var init_live_store = __esm({
599
+ "src/core/live-preview/live-store.ts"() {
600
+ "use strict";
601
+ init_utils();
602
+ init_index_snapshot();
603
+ init_patch();
604
+ debug2 = createScopedLogger("live-preview");
605
+ INVALIDATE_DEBOUNCE_MS = 150;
606
+ MAX_LOG_ENTRIES = 500;
607
+ }
608
+ });
609
+
610
+ // src/core/iframe-bridge.ts
611
+ function isAllowedEditorOrigin(origin, allowed) {
612
+ if (allowed) {
613
+ if (allowed.includes("*")) return origin !== "null";
614
+ return allowed.includes(origin);
615
+ }
616
+ let url;
617
+ try {
618
+ url = new URL(origin);
619
+ } catch {
620
+ return false;
621
+ }
622
+ if (url.protocol !== "https:" || url.port !== "") return false;
623
+ const suffix = `.${EDITOR_BASE_DOMAIN}`;
624
+ if (!url.hostname.endsWith(suffix)) return false;
625
+ const label = url.hostname.slice(0, -suffix.length);
626
+ return label.length > 0 && !label.includes(".");
627
+ }
628
+ var debug3, EDITOR_BASE_DOMAIN;
629
+ var init_iframe_bridge = __esm({
630
+ "src/core/iframe-bridge.ts"() {
631
+ "use strict";
632
+ init_utils();
633
+ debug3 = createScopedLogger("iframe-bridge");
634
+ EDITOR_BASE_DOMAIN = "prepr.io";
635
+ }
636
+ });
637
+
638
+ // src/core/live-preview/validate.ts
639
+ function isScalar(v) {
640
+ return typeof v === "string" || typeof v === "number" || typeof v === "boolean";
641
+ }
642
+ function isSafeLinkValue(value) {
643
+ const stripped = value.replace(URL_IGNORED_ANYWHERE, "");
644
+ let start = 0;
645
+ while (start < stripped.length && stripped.charCodeAt(start) <= 32) start++;
646
+ return !SCRIPT_SCHEME.test(stripped.slice(start));
647
+ }
648
+ function isUrlKey(key) {
649
+ return URL_KEY.test(key);
650
+ }
651
+ function isSafeKeyValue(key, value) {
652
+ if (typeof value !== "string") return true;
653
+ if (key === "url") return SAFE_URL.test(value);
654
+ return !isUrlKey(key) || isSafeLinkValue(value);
655
+ }
656
+ function isLiveValue(v, depth = 0) {
657
+ if (v === null || isScalar(v)) return true;
658
+ if (depth >= MAX_DEPTH) return false;
659
+ if (Array.isArray(v)) {
660
+ return depth === 0 && v.length <= MAX_ENTRIES && v.every((entry) => isPlainRecord(entry) && isLiveValue(entry, depth + 1));
661
+ }
662
+ if (!isPlainRecord(v)) return false;
663
+ const keys = Object.keys(v);
664
+ if (keys.length > MAX_ENTRIES) return false;
665
+ return keys.every((key) => {
666
+ if (FORBIDDEN_KEYS.has(key)) return false;
667
+ const value = v[key];
668
+ if (!isSafeKeyValue(key, value)) return false;
669
+ return !Array.isArray(value) && isLiveValue(value, depth + 1);
670
+ });
671
+ }
672
+ function isLiveFieldChange(field, value) {
673
+ if (!isLiveValue(value)) return false;
674
+ const name = field.slice(field.lastIndexOf(".") + 1);
675
+ return typeof value !== "string" || !isUrlKey(name) || isSafeLinkValue(value);
676
+ }
677
+ function parseListEntries(value) {
678
+ if (!Array.isArray(value) || value.length > MAX_LIST_ENTRIES) return null;
679
+ const list = [];
680
+ for (const raw of value) {
681
+ if (!isPlainRecord(raw) || typeof raw._id !== "string" || !raw._id) {
682
+ return null;
683
+ }
684
+ const entry = { _id: raw._id };
685
+ if (typeof raw.__typename === "string") entry.__typename = raw.__typename;
686
+ if (typeof raw.body === "string") entry.body = raw.body;
687
+ if (typeof raw.format === "string" || raw.format === null) {
688
+ entry.format = raw.format;
689
+ }
690
+ if (typeof raw.typeName === "string" && raw.typeName.length <= 200) {
691
+ entry.typeName = raw.typeName;
692
+ }
693
+ if (raw.fields !== void 0) {
694
+ if (!isPlainRecord(raw.fields) || !isFieldValue(raw.fields, 0)) {
695
+ return null;
696
+ }
697
+ entry.fields = raw.fields;
698
+ }
699
+ list.push(entry);
700
+ }
701
+ return list;
702
+ }
703
+ function isPlainRecord(v) {
704
+ return v !== null && typeof v === "object" && Object.getPrototypeOf(v) === Object.prototype;
705
+ }
706
+ function isFieldValue(v, depth) {
707
+ if (v === null || isScalar(v)) return true;
708
+ if (depth >= MAX_FIELD_DEPTH) return false;
709
+ if (Array.isArray(v)) {
710
+ return v.length <= MAX_ENTRIES && v.every(
711
+ (entry) => isScalar(entry) || isPlainRecord(entry) && isFieldValue(entry, depth + 1)
712
+ );
713
+ }
714
+ if (!isPlainRecord(v)) return false;
715
+ const keys = Object.keys(v);
716
+ if (keys.length > MAX_FIELD_KEYS) return false;
717
+ return keys.every((key) => {
718
+ if (FORBIDDEN_KEYS.has(key)) return false;
719
+ const value = v[key];
720
+ if (!isSafeKeyValue(key, value)) return false;
721
+ return isFieldValue(value, depth + 1);
722
+ });
723
+ }
724
+ function parseEditTarget(raw) {
725
+ if (!isPlainRecord(raw)) return void 0;
726
+ const { item, field } = raw;
727
+ if (typeof item !== "string" || !item || item.length > MAX_EDIT_LENGTH) {
728
+ return void 0;
729
+ }
730
+ if (typeof field !== "string" || !field || field.length > MAX_EDIT_LENGTH) {
731
+ return void 0;
732
+ }
733
+ return { item, field };
734
+ }
735
+ var MAX_DEPTH, MAX_ENTRIES, FORBIDDEN_KEYS, SAFE_URL, URL_KEY, URL_IGNORED_ANYWHERE, SCRIPT_SCHEME, MAX_LIST_ENTRIES, MAX_FIELD_DEPTH, MAX_FIELD_KEYS, MAX_EDIT_LENGTH;
736
+ var init_validate = __esm({
737
+ "src/core/live-preview/validate.ts"() {
738
+ "use strict";
739
+ MAX_DEPTH = 3;
740
+ MAX_ENTRIES = 50;
741
+ FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
742
+ SAFE_URL = /^https?:\/\//i;
743
+ URL_KEY = /^(?:url|href|src|link)$|(?:_url|Url)$/;
744
+ URL_IGNORED_ANYWHERE = /[\t\n\r]/g;
745
+ SCRIPT_SCHEME = /^(?:javascript|vbscript|data):/i;
746
+ MAX_LIST_ENTRIES = 200;
747
+ MAX_FIELD_DEPTH = 6;
748
+ MAX_FIELD_KEYS = 100;
749
+ MAX_EDIT_LENGTH = 1e3;
750
+ }
751
+ });
752
+
753
+ // src/core/live-preview/bridge-events.ts
754
+ function createLiveBridge(store2, options = {}) {
755
+ let parentOrigin = null;
756
+ const onMessage = (evt) => {
757
+ const data = evt?.data;
758
+ if (data?.event === "prepr:initVE" && !parentOrigin) {
759
+ if (isAllowedEditorOrigin(evt.origin, options.allowedEditorOrigins?.())) {
760
+ parentOrigin = evt.origin;
761
+ } else {
762
+ debug4.warn("ignored live preview handshake from origin", evt.origin);
763
+ }
764
+ return;
765
+ }
766
+ const trusted = parentOrigin ?? getTrustedParentOrigin();
767
+ if (!trusted || evt.origin !== trusted) return;
768
+ if (data?.event === "prepr:fieldChange") {
769
+ if (typeof data.itemId === "string" && typeof data.field === "string" && data.field && isLiveFieldChange(data.field, data.value)) {
770
+ const edit = parseEditTarget(data.edit);
771
+ if (edit) store2.pushPatch(data.itemId, data.field, data.value, edit);
772
+ else store2.pushPatch(data.itemId, data.field, data.value);
773
+ } else {
774
+ debug4.log("dropped malformed fieldChange", data);
775
+ }
776
+ return;
777
+ }
778
+ if (data?.event === "prepr:listChange") {
779
+ const list = parseListEntries(data.entries);
780
+ if (typeof data.itemId === "string" && typeof data.field === "string" && data.field && list) {
781
+ store2.pushList(data.itemId, data.field, list);
782
+ } else {
783
+ debug4.log("dropped malformed listChange", data);
784
+ }
785
+ return;
786
+ }
787
+ if (data?.event === "prepr:itemChanged") {
788
+ if (typeof data.itemId === "string") {
789
+ store2.invalidate(data.itemId);
790
+ } else {
791
+ debug4.log("dropped malformed itemChanged", data);
792
+ }
793
+ }
794
+ };
795
+ return {
796
+ start() {
797
+ window.addEventListener("message", onMessage);
798
+ sendPreprEvent(
799
+ "live_ready",
800
+ options.strictMode?.() ? { strictMode: true } : void 0,
801
+ { allowUntrustedTarget: true }
802
+ );
803
+ },
804
+ stop() {
805
+ window.removeEventListener("message", onMessage);
806
+ }
807
+ };
808
+ }
809
+ var debug4;
810
+ var init_bridge_events = __esm({
811
+ "src/core/live-preview/bridge-events.ts"() {
812
+ "use strict";
813
+ init_utils();
814
+ init_iframe_bridge();
815
+ init_validate();
816
+ debug4 = createScopedLogger("live-preview:bridge");
817
+ }
818
+ });
819
+
820
+ // src/core/live-preview/query-document.ts
821
+ function tokenize(source) {
822
+ const tokens = [];
823
+ let i = 0;
824
+ const n = source.length;
825
+ while (i < n) {
826
+ const ch = source[i];
827
+ if (ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === "," || ch === "\uFEFF") {
828
+ i++;
829
+ } else if (ch === "#") {
830
+ while (i < n && source[i] !== "\n" && source[i] !== "\r") i++;
831
+ } else if (ch === "." && source.startsWith("...", i)) {
832
+ tokens.push({ type: "punct", value: "..." });
833
+ i += 3;
834
+ } else if (PUNCT.has(ch)) {
835
+ tokens.push({ type: "punct", value: ch });
836
+ i++;
837
+ } else if (NAME_START.test(ch)) {
838
+ const start = i;
839
+ while (i < n && NAME_CONTINUE.test(source[i])) i++;
840
+ tokens.push({ type: "name", value: source.slice(start, i) });
841
+ } else if (ch === '"') {
842
+ if (source.startsWith('"""', i)) {
843
+ i += 3;
844
+ while (i < n && !source.startsWith('"""', i)) {
845
+ i += source.startsWith('\\"""', i) ? 4 : 1;
846
+ }
847
+ if (i >= n) throw new SyntaxError("Unterminated block string");
848
+ i += 3;
849
+ } else {
850
+ i++;
851
+ while (i < n && source[i] !== '"') {
852
+ if (source[i] === "\n" || source[i] === "\r") {
853
+ throw new SyntaxError("Unterminated string");
854
+ }
855
+ i += source[i] === "\\" ? 2 : 1;
856
+ }
857
+ if (i >= n) throw new SyntaxError("Unterminated string");
858
+ i++;
859
+ }
860
+ tokens.push({ type: "value" });
861
+ } else if (ch === "-" || ch >= "0" && ch <= "9") {
862
+ i++;
863
+ while (i < n && /[0-9.eE+-]/.test(source[i])) i++;
864
+ tokens.push({ type: "value" });
865
+ } else {
866
+ throw new SyntaxError(`Unexpected character "${ch}"`);
867
+ }
868
+ }
869
+ return tokens;
870
+ }
871
+ function parseSource(source, operationName) {
872
+ const tokens = tokenize(source);
873
+ let pos = 0;
874
+ const peek = () => tokens[pos];
875
+ const isPunct = (value) => {
876
+ const t = tokens[pos];
877
+ return t?.type === "punct" && t.value === value;
878
+ };
879
+ const expectPunct = (value) => {
880
+ if (!isPunct(value)) throw new SyntaxError(`Expected "${value}"`);
881
+ pos++;
882
+ };
883
+ const expectName = () => {
884
+ const t = tokens[pos];
885
+ if (t?.type !== "name") throw new SyntaxError("Expected a name");
886
+ pos++;
887
+ return t.value;
888
+ };
889
+ const skipParens = () => {
890
+ expectPunct("(");
891
+ let depth = 1;
892
+ while (depth > 0) {
893
+ const t = tokens[pos++];
894
+ if (!t) throw new SyntaxError("Unbalanced parentheses");
895
+ if (t.type === "punct" && t.value === "(") depth++;
896
+ else if (t.type === "punct" && t.value === ")") depth--;
897
+ }
898
+ };
899
+ const skipDirectives = () => {
900
+ while (isPunct("@")) {
901
+ pos++;
902
+ expectName();
903
+ if (isPunct("(")) skipParens();
904
+ }
905
+ };
906
+ const parseSelectionSet = () => {
907
+ expectPunct("{");
908
+ const selections = [];
909
+ while (!isPunct("}")) {
910
+ if (!peek()) throw new SyntaxError("Unterminated selection set");
911
+ selections.push(parseSelection());
912
+ }
913
+ pos++;
914
+ return selections;
915
+ };
916
+ const parseSelection = () => {
917
+ if (isPunct("...")) {
918
+ pos++;
919
+ const t = peek();
920
+ if (t?.type === "name" && t.value !== "on") {
921
+ pos++;
922
+ skipDirectives();
923
+ return { kind: "spread", name: t.value };
924
+ }
925
+ let on = null;
926
+ if (t?.type === "name") {
927
+ pos++;
928
+ on = expectName();
929
+ }
930
+ skipDirectives();
931
+ return { kind: "inline", on, selections: parseSelectionSet() };
932
+ }
933
+ let name = expectName();
934
+ const key = name;
935
+ if (isPunct(":")) {
936
+ pos++;
937
+ name = expectName();
938
+ }
939
+ let hasArgs = false;
940
+ if (isPunct("(")) {
941
+ hasArgs = true;
942
+ skipParens();
943
+ }
944
+ skipDirectives();
945
+ const selections = isPunct("{") ? parseSelectionSet() : null;
946
+ return { kind: "field", name, key, hasArgs, selections };
947
+ };
948
+ const fragments = /* @__PURE__ */ new Map();
949
+ const operations = [];
950
+ while (pos < tokens.length) {
951
+ if (isPunct("{")) {
952
+ operations.push({ name: null, selections: parseSelectionSet() });
953
+ continue;
954
+ }
955
+ const keyword = expectName();
956
+ if (keyword === "fragment") {
957
+ const name = expectName();
958
+ if (expectName() !== "on") throw new SyntaxError('Expected "on"');
959
+ const on = expectName();
960
+ skipDirectives();
961
+ fragments.set(name, { on, selections: parseSelectionSet() });
962
+ } else if (keyword === "query" || keyword === "mutation" || keyword === "subscription") {
963
+ const t = peek();
964
+ let name = null;
965
+ if (t?.type === "name") name = expectName();
966
+ if (isPunct("(")) skipParens();
967
+ skipDirectives();
968
+ operations.push({ name, selections: parseSelectionSet() });
969
+ } else {
970
+ throw new SyntaxError(`Unexpected "${keyword}"`);
971
+ }
972
+ }
973
+ return { operation: pickOperation(operations, operationName), fragments };
974
+ }
975
+ function pickOperation(operations, operationName) {
976
+ const op = operationName ? operations.find((o) => o.name === operationName) : operations[0];
977
+ if (!op) throw new SyntaxError("The document has no operation");
978
+ return op.selections;
979
+ }
980
+ function fromAstSelections(set) {
981
+ return set.selections.map((s) => {
982
+ if (s.kind === "FragmentSpread")
983
+ return { kind: "spread", name: s.name.value };
984
+ if (s.kind === "InlineFragment") {
985
+ return {
986
+ kind: "inline",
987
+ on: s.typeCondition?.name.value ?? null,
988
+ selections: fromAstSelections(s.selectionSet)
989
+ };
990
+ }
991
+ const name = s.name.value;
992
+ return {
993
+ kind: "field",
994
+ name,
995
+ key: s.alias?.value ?? name,
996
+ hasArgs: Boolean(s.arguments?.length),
997
+ selections: s.selectionSet ? fromAstSelections(s.selectionSet) : null
998
+ };
999
+ });
1000
+ }
1001
+ function fromAst(doc, operationName) {
1002
+ const fragments = /* @__PURE__ */ new Map();
1003
+ const operations = [];
1004
+ for (const def of doc.definitions ?? []) {
1005
+ if (def.kind === "FragmentDefinition" && def.name && def.typeCondition && def.selectionSet) {
1006
+ fragments.set(def.name.value, {
1007
+ on: def.typeCondition.name.value,
1008
+ selections: fromAstSelections(def.selectionSet)
1009
+ });
1010
+ } else if (def.kind === "OperationDefinition" && def.selectionSet) {
1011
+ operations.push({
1012
+ name: def.name?.value ?? null,
1013
+ selections: fromAstSelections(def.selectionSet)
1014
+ });
1015
+ }
1016
+ }
1017
+ return { operation: pickOperation(operations, operationName), fragments };
1018
+ }
1019
+ function readQueryDocument(query, operationName) {
1020
+ const cacheKey = operationName ?? "";
1021
+ if (typeof query === "object" && query !== null && query.kind === "Document") {
1022
+ let byName = astCache.get(query);
1023
+ if (!byName) astCache.set(query, byName = /* @__PURE__ */ new Map());
1024
+ let parsed2 = byName.get(cacheKey);
1025
+ if (!parsed2) {
1026
+ parsed2 = fromAst(
1027
+ query,
1028
+ operationName
1029
+ );
1030
+ byName.set(cacheKey, parsed2);
1031
+ }
1032
+ return parsed2;
1033
+ }
1034
+ const source = String(query);
1035
+ const sourceKey = `${cacheKey}
1036
+ ${source}`;
1037
+ let parsed = sourceCache.get(sourceKey);
1038
+ if (!parsed) {
1039
+ parsed = parseSource(source, operationName);
1040
+ if (sourceCache.size >= SOURCE_CACHE_LIMIT) {
1041
+ sourceCache.delete(sourceCache.keys().next().value);
1042
+ }
1043
+ sourceCache.set(sourceKey, parsed);
1044
+ }
1045
+ return parsed;
1046
+ }
1047
+ function collectFields(selections, typename, doc, options = {}) {
1048
+ const cacheKey = `${options.strict ? "s" : "l"}:${typename ?? ""}`;
1049
+ let cached = fieldsCache.get(selections);
1050
+ if (!cached) {
1051
+ cached = /* @__PURE__ */ new Map();
1052
+ fieldsCache.set(selections, cached);
1053
+ }
1054
+ const hit = cached.get(cacheKey);
1055
+ if (hit) return hit;
1056
+ const fields = resolveFields(selections, typename, doc, options);
1057
+ cached.set(cacheKey, fields);
1058
+ return fields;
1059
+ }
1060
+ function resolveFields(selections, typename, doc, options) {
1061
+ const exact = /* @__PURE__ */ new Map();
1062
+ const loose = /* @__PURE__ */ new Map();
1063
+ const merged = /* @__PURE__ */ new Map();
1064
+ const walkedMatched = /* @__PURE__ */ new Set();
1065
+ const walkedLoose = /* @__PURE__ */ new Set();
1066
+ const add = (target, s) => {
1067
+ let field = target.get(s.key);
1068
+ if (!field) {
1069
+ field = { name: s.name, key: s.key, hasArgs: s.hasArgs, selections: [] };
1070
+ target.set(s.key, field);
1071
+ merged.set(field, /* @__PURE__ */ new Set());
1072
+ }
1073
+ const done = merged.get(field);
1074
+ if (s.selections && !done.has(s.selections)) {
1075
+ done.add(s.selections);
1076
+ field.selections = [...field.selections, ...s.selections];
1077
+ }
1078
+ };
1079
+ const applies = (on, list) => conditionMatches(on, typename) || typename !== void 0 && typeConditions(list, doc).includes(typename);
1080
+ const walk = (list, matched) => {
1081
+ for (const s of list) {
1082
+ if (s.kind === "field") {
1083
+ add(matched ? exact : loose, s);
1084
+ } else if (s.kind === "inline") {
1085
+ walk(s.selections, matched && applies(s.on, s.selections));
1086
+ } else {
1087
+ const fragment = doc.fragments.get(s.name);
1088
+ if (!fragment) continue;
1089
+ const asMatched = matched && applies(fragment.on, fragment.selections);
1090
+ if (walkedMatched.has(fragment)) continue;
1091
+ if (!asMatched && walkedLoose.has(fragment)) continue;
1092
+ (asMatched ? walkedMatched : walkedLoose).add(fragment);
1093
+ walk(fragment.selections, asMatched);
1094
+ }
1095
+ }
1096
+ };
1097
+ walk(selections, true);
1098
+ if (!options.strict) {
1099
+ for (const [key, field] of loose) {
1100
+ if (!exact.has(key)) exact.set(key, field);
1101
+ }
1102
+ }
1103
+ return exact;
1104
+ }
1105
+ function conditionMatches(on, typename) {
1106
+ return on === null || typename === void 0 || on === typename;
1107
+ }
1108
+ function typeConditions(selections, doc) {
1109
+ const hit = conditionsCache.get(selections);
1110
+ if (hit) return hit;
1111
+ const names = /* @__PURE__ */ new Set();
1112
+ const seen = /* @__PURE__ */ new Set();
1113
+ const walk = (list) => {
1114
+ for (const s of list) {
1115
+ if (s.kind === "inline") {
1116
+ if (s.on) names.add(s.on);
1117
+ walk(s.selections);
1118
+ } else if (s.kind === "spread") {
1119
+ const fragment = doc.fragments.get(s.name);
1120
+ if (!fragment || seen.has(fragment)) continue;
1121
+ seen.add(fragment);
1122
+ names.add(fragment.on);
1123
+ walk(fragment.selections);
1124
+ }
1125
+ }
1126
+ };
1127
+ walk(selections);
1128
+ const conditions = [...names];
1129
+ conditionsCache.set(selections, conditions);
1130
+ return conditions;
1131
+ }
1132
+ var NAME_START, NAME_CONTINUE, PUNCT, astCache, sourceCache, SOURCE_CACHE_LIMIT, fieldsCache, conditionsCache;
1133
+ var init_query_document = __esm({
1134
+ "src/core/live-preview/query-document.ts"() {
1135
+ "use strict";
1136
+ NAME_START = /[_A-Za-z]/;
1137
+ NAME_CONTINUE = /[_0-9A-Za-z]/;
1138
+ PUNCT = /* @__PURE__ */ new Set([
1139
+ "!",
1140
+ "$",
1141
+ "&",
1142
+ "(",
1143
+ ")",
1144
+ ":",
1145
+ "=",
1146
+ "@",
1147
+ "[",
1148
+ "]",
1149
+ "{",
1150
+ "|",
1151
+ "}"
1152
+ ]);
1153
+ astCache = /* @__PURE__ */ new WeakMap();
1154
+ sourceCache = /* @__PURE__ */ new Map();
1155
+ SOURCE_CACHE_LIMIT = 200;
1156
+ fieldsCache = /* @__PURE__ */ new WeakMap();
1157
+ conditionsCache = /* @__PURE__ */ new WeakMap();
1158
+ }
1159
+ });
1160
+
1161
+ // src/core/live-preview/normalize-query.ts
1162
+ function parsePatchLog(raw) {
1163
+ let value = raw;
1164
+ if (typeof value === "string") {
1165
+ if (!value || value.length > MAX_LOG_SOURCE_LENGTH) return [];
1166
+ try {
1167
+ value = JSON.parse(value);
1168
+ } catch {
1169
+ return [];
1170
+ }
1171
+ }
1172
+ if (!Array.isArray(value)) return [];
1173
+ const log2 = [];
1174
+ for (const entry of value.slice(-MAX_LOG_ENTRIES2)) {
1175
+ if (!isPlainRecord(entry)) continue;
1176
+ const { type, itemId, field } = entry;
1177
+ if (typeof itemId !== "string" || !itemId) continue;
1178
+ if (typeof field !== "string" || !field) continue;
1179
+ if (type === "field" && isLiveFieldChange(field, entry.value)) {
1180
+ const edit = parseEditTarget(entry.edit);
1181
+ log2.push(
1182
+ edit ? { type, itemId, field, value: entry.value, edit } : { type, itemId, field, value: entry.value }
1183
+ );
1184
+ } else if (type === "list") {
1185
+ const entries = parseListEntries(entry.entries);
1186
+ if (entries) log2.push({ type, itemId, field, entries });
1187
+ }
1188
+ }
1189
+ return log2;
1190
+ }
1191
+ function normalizeQuery(query, result, options = {}) {
1192
+ return applyPatchLog(
1193
+ query,
1194
+ result,
1195
+ parsePatchLog(options.log),
1196
+ options.operationName
1197
+ );
1198
+ }
1199
+ function applyPatchLog(query, result, log2, operationName) {
1200
+ if (!log2.length || result === null || typeof result !== "object") {
1201
+ return result;
1202
+ }
1203
+ if (isEnvelope(result)) {
1204
+ const data = applyPatchLog(query, result.data, log2, operationName);
1205
+ return data === result.data ? result : { ...result, data };
1206
+ }
1207
+ let doc = null;
1208
+ try {
1209
+ doc = readQueryDocument(query, operationName);
1210
+ } catch (error) {
1211
+ debug5.log("could not read the query; applying fields by literal path", {
1212
+ error: String(error)
1213
+ });
1214
+ }
1215
+ let root = result;
1216
+ let index = null;
1217
+ for (const patch of log2) {
1218
+ try {
1219
+ index ?? (index = indexSnapshot(root));
1220
+ const next = applyPatch(root, index, patch, doc, result);
1221
+ if (next !== root) {
1222
+ root = next;
1223
+ if (patch.type === "list" || !isScalarValue(patch.value)) {
1224
+ index = null;
1225
+ }
1226
+ }
1227
+ } catch (error) {
1228
+ debug5.log("could not apply a change", {
1229
+ itemId: patch.itemId,
1230
+ field: patch.field,
1231
+ error: String(error)
1232
+ });
1233
+ }
1234
+ }
1235
+ return root;
1236
+ }
1237
+ function isScalarValue(value) {
1238
+ return value === null || typeof value !== "object";
1239
+ }
1240
+ function applyPatch(root, index, patch, doc, result) {
1241
+ const ownerPaths = index.get(patch.itemId);
1242
+ if (!ownerPaths?.length) return root;
1243
+ const segments = patch.field.split(".");
1244
+ if (segments.some((s) => !s || FORBIDDEN_SEGMENTS2.has(s))) return root;
1245
+ const targets = [];
1246
+ const plain = /* @__PURE__ */ new Set();
1247
+ for (const ownerPath of ownerPaths) {
1248
+ if (doc) {
1249
+ const resolved = resolveTargets(root, doc, ownerPath, segments);
1250
+ root = resolved.root;
1251
+ targets.push(...resolved.targets);
1252
+ resolved.plain.forEach((target) => plain.add(target));
1253
+ } else {
1254
+ targets.push([...ownerPath, ...segments.map(toPathSegment)]);
1255
+ }
1256
+ }
1257
+ if (!targets.length) {
1258
+ debug5.log("no field in the query matches", {
1259
+ itemId: patch.itemId,
1260
+ field: patch.field
1261
+ });
1262
+ return root;
1263
+ }
1264
+ if (patch.type === "field") {
1265
+ for (const target of targets) {
1266
+ const pushed = plain.has(target) && typeof patch.value === "string" ? plainTextFromHtml(patch.value) : patch.value;
1267
+ let value = keepEditLink(readAtPath(root, target), pushed);
1268
+ if (patch.edit && typeof value === "string" && !(0, import_stega2.vercelStegaSplit)(value).encoded) {
1269
+ value = editLinksFor(result, patch.edit.item)?.encode(
1270
+ value,
1271
+ patch.edit.field
1272
+ ) ?? value;
1273
+ }
1274
+ root = writeAtPath(root, target, value);
1275
+ }
1276
+ } else {
1277
+ for (const target of targets) {
1278
+ const selections = doc ? selectionsAt(root, doc, target) : null;
1279
+ const build = doc && selections ? (entry) => buildEntry(doc, selections, entry, {
1280
+ links: editLinks(result, entry),
1281
+ lists: listKeysIn(result)
1282
+ }) : void 0;
1283
+ root = syncListAtPath(root, target, patch.entries, build);
1284
+ }
1285
+ }
1286
+ return root;
1287
+ }
1288
+ function readAtPath(root, path) {
1289
+ let node = root;
1290
+ for (const step of path) {
1291
+ if (node === null || typeof node !== "object") return void 0;
1292
+ node = node[step];
1293
+ }
1294
+ return node;
1295
+ }
1296
+ function isEnvelope(value) {
1297
+ if (Array.isArray(value) || !("data" in value)) return false;
1298
+ return Object.keys(value).every((key) => ENVELOPE_KEYS.has(key));
1299
+ }
1300
+ function toPathSegment(segment) {
1301
+ return INDEX_SEGMENT2.test(segment) ? Number(segment) : segment;
1302
+ }
1303
+ function typenameOf(node) {
1304
+ const typename = node.__typename;
1305
+ return typeof typename === "string" ? typename : void 0;
1306
+ }
1307
+ function selectionsAt(root, doc, path) {
1308
+ let node = root;
1309
+ let selections = doc.operation;
1310
+ for (const step of path) {
1311
+ if (Array.isArray(node)) {
1312
+ node = node[step];
1313
+ continue;
1314
+ }
1315
+ if (node === null || typeof node !== "object") return null;
1316
+ const field = collectFields(selections, typenameOf(node), doc).get(
1317
+ String(step)
1318
+ );
1319
+ if (!field) return null;
1320
+ selections = field.selections;
1321
+ node = node[String(step)];
1322
+ }
1323
+ return selections;
1324
+ }
1325
+ function resolveTargets(root, doc, ownerPath, segments) {
1326
+ let owner = root;
1327
+ for (const step of ownerPath) {
1328
+ owner = owner[step];
1329
+ }
1330
+ const selections = selectionsAt(root, doc, ownerPath);
1331
+ if (!selections) return { root, targets: [], plain: /* @__PURE__ */ new Set() };
1332
+ let current = root;
1333
+ const out = [];
1334
+ const plain = /* @__PURE__ */ new Set();
1335
+ const walk = (node, sel, i, path) => {
1336
+ if (i === segments.length) {
1337
+ out.push(path);
1338
+ return;
1339
+ }
1340
+ const segment = segments[i];
1341
+ if (Array.isArray(node)) {
1342
+ if (INDEX_SEGMENT2.test(segment)) {
1343
+ const position = Number(segment);
1344
+ if (position < node.length) {
1345
+ walk(node[position], sel, i + 1, [...path, position]);
1346
+ }
1347
+ } else if (segment === "items") {
1348
+ walk(node, sel, i + 1, path);
1349
+ }
1350
+ return;
1351
+ }
1352
+ if (node === null || typeof node !== "object") return;
1353
+ const record = node;
1354
+ const wanted = graphqlFieldName(segment);
1355
+ const textBody = i === segments.length - 1 && segment === "body" && isTextEntry(record) ? TEXT_BODY_FIELDS : null;
1356
+ let matched = false;
1357
+ for (const field of collectFields(sel, typenameOf(node), doc).values()) {
1358
+ const alias = textBody?.find((f) => f.name === field.name);
1359
+ if (field.name !== segment && field.name !== wanted && !alias) continue;
1360
+ if (!Object.prototype.hasOwnProperty.call(record, field.key)) continue;
1361
+ matched = true;
1362
+ const fieldPath = [...path, field.key];
1363
+ if (alias?.plain) plain.add(fieldPath);
1364
+ let value = record[field.key];
1365
+ const next = segments[i + 1];
1366
+ if (value === null && field.selections.length && next !== void 0 && next !== "items" && !INDEX_SEGMENT2.test(next)) {
1367
+ const typename = resolveTypename(
1368
+ doc,
1369
+ field.selections,
1370
+ void 0,
1371
+ void 0
1372
+ );
1373
+ if (typename !== void 0) {
1374
+ value = fillObject(doc, field.selections, typename, {}, void 0, {
1375
+ links: null,
1376
+ lists: listKeysIn(root)
1377
+ });
1378
+ current = writeAtPath(current, fieldPath, value);
1379
+ }
1380
+ }
1381
+ walk(value, field.selections, i + 1, fieldPath);
1382
+ }
1383
+ if (!matched && segment === "items") walk(node, sel, i + 1, path);
1384
+ };
1385
+ walk(owner, selections, 0, ownerPath);
1386
+ return { root: current, targets: out, plain };
1387
+ }
1388
+ function resolveTypename(doc, selections, typename, typeName) {
1389
+ const known = typeConditions(selections, doc);
1390
+ const explicit = typeof typename === "string" ? typename : void 0;
1391
+ if (!known.length) return explicit ?? null;
1392
+ if (explicit && known.includes(explicit)) return explicit;
1393
+ for (const candidate of [explicit, typeName]) {
1394
+ if (typeof candidate !== "string" || !candidate) continue;
1395
+ const match = known.find((name) => typeKey(name) === typeKey(candidate));
1396
+ if (match) return match;
1397
+ }
1398
+ const named = explicit !== void 0 || typeof typeName === "string";
1399
+ return known.length === 1 && !named ? known[0] : void 0;
1400
+ }
1401
+ function buildEntry(doc, selections, entry, ctx) {
1402
+ const typename = resolveTypename(
1403
+ doc,
1404
+ selections,
1405
+ entry.__typename,
1406
+ entry.typeName
1407
+ );
1408
+ if (typename === void 0) return void 0;
1409
+ return fillObject(
1410
+ doc,
1411
+ selections,
1412
+ typename,
1413
+ entry.fields ?? {},
1414
+ entry._id,
1415
+ ctx
1416
+ );
1417
+ }
1418
+ function fillObject(doc, selections, typename, values, id, ctx) {
1419
+ const out = {};
1420
+ const { links } = ctx;
1421
+ const lists = ctx.lists(typename);
1422
+ const edit = isPlainRecord(values.__edit) ? values.__edit : null;
1423
+ const apiIdOf = /* @__PURE__ */ new Map();
1424
+ for (const key of Object.keys(values)) {
1425
+ apiIdOf.set(key, key);
1426
+ const name = graphqlFieldName(key);
1427
+ if (!apiIdOf.has(name)) apiIdOf.set(name, key);
1428
+ }
1429
+ if (edit && isPlainRecord(edit.apiIds)) {
1430
+ for (const [name, apiId] of Object.entries(edit.apiIds)) {
1431
+ if (typeof apiId === "string") apiIdOf.set(name, apiId);
1432
+ }
1433
+ }
1434
+ const valueOf = (name) => {
1435
+ if (Object.prototype.hasOwnProperty.call(values, name)) return values[name];
1436
+ const key = apiIdOf.get(name);
1437
+ return key !== void 0 && key in values ? values[key] : void 0;
1438
+ };
1439
+ const editField = (name) => {
1440
+ if (!edit) return null;
1441
+ if (typeof edit.field === "string")
1442
+ return name === "body" ? edit.field : null;
1443
+ if (typeof edit.path !== "string") return null;
1444
+ const apiId = apiIdOf.get(name) ?? name;
1445
+ const text = Array.isArray(edit.text) ? edit.text : [];
1446
+ if (!text.includes(apiId) && !text.includes(name)) return null;
1447
+ return `${edit.path}.items.${apiId}`;
1448
+ };
1449
+ const fields = collectFields(selections, typename ?? void 0, doc, {
1450
+ strict: true
1451
+ });
1452
+ for (const field of fields.values()) {
1453
+ if (field.name === "__typename") {
1454
+ out[field.key] = typename;
1455
+ } else if (field.name === "_id") {
1456
+ out[field.key] = typeof id === "string" ? id : values._id ?? null;
1457
+ } else if (field.selections.length) {
1458
+ const value = valueOf(field.name);
1459
+ out[field.key] = value == null && lists.has(field.key) ? [] : fillNested(doc, field.selections, value, ctx);
1460
+ } else {
1461
+ const value = valueOf(field.name);
1462
+ if (Array.isArray(value) && value.every(isScalarItem)) {
1463
+ out[field.key] = value;
1464
+ continue;
1465
+ }
1466
+ if (value == null && lists.has(field.key)) {
1467
+ out[field.key] = [];
1468
+ continue;
1469
+ }
1470
+ const scalar = value === void 0 || value !== null && typeof value === "object" ? null : value;
1471
+ const target = typeof scalar === "string" ? editField(field.name) : null;
1472
+ out[field.key] = target && links ? links.encode(scalar, target) : scalar;
1473
+ }
1474
+ }
1475
+ return out;
1476
+ }
1477
+ function fillNested(doc, selections, value, ctx) {
1478
+ const one = (item) => {
1479
+ if (!isPlainRecord(item)) return null;
1480
+ const typename = resolveTypename(
1481
+ doc,
1482
+ selections,
1483
+ item.__typename,
1484
+ item.typeName
1485
+ );
1486
+ if (typename === void 0) return null;
1487
+ return fillObject(doc, selections, typename, item, item._id, ctx);
1488
+ };
1489
+ if (Array.isArray(value)) return value.map(one).filter((v) => v !== null);
1490
+ return value === void 0 ? null : one(value);
1491
+ }
1492
+ function isScalarItem(value) {
1493
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1494
+ }
1495
+ function listKeysIn(result) {
1496
+ return (typename) => {
1497
+ if (!typename || result === null || typeof result !== "object") {
1498
+ return NO_KEYS;
1499
+ }
1500
+ let byType = listKeysCache.get(result);
1501
+ if (!byType) {
1502
+ byType = /* @__PURE__ */ new Map();
1503
+ const seen = /* @__PURE__ */ new WeakSet();
1504
+ const walk = (node) => {
1505
+ if (node === null || typeof node !== "object" || seen.has(node)) return;
1506
+ seen.add(node);
1507
+ if (Array.isArray(node)) {
1508
+ node.forEach(walk);
1509
+ return;
1510
+ }
1511
+ const record = node;
1512
+ const type = typeof record.__typename === "string" ? record.__typename : null;
1513
+ for (const [key, value] of Object.entries(record)) {
1514
+ if (type && Array.isArray(value)) {
1515
+ let keys = byType.get(type);
1516
+ if (!keys) byType.set(type, keys = /* @__PURE__ */ new Set());
1517
+ keys.add(key);
1518
+ }
1519
+ walk(value);
1520
+ }
1521
+ };
1522
+ walk(result);
1523
+ listKeysCache.set(result, byType);
1524
+ }
1525
+ return byType.get(typename) ?? NO_KEYS;
1526
+ };
1527
+ }
1528
+ function editLinks(result, entry) {
1529
+ const edit = entry.fields?.__edit;
1530
+ if (!isPlainRecord(edit) || typeof edit.item !== "string") return null;
1531
+ return editLinksFor(result, edit.item);
1532
+ }
1533
+ function editLinksFor(result, item) {
1534
+ if (!ITEM_ID.test(item)) return null;
1535
+ const template = findEditLink(result);
1536
+ if (!template) return null;
1537
+ return {
1538
+ encode(text, field) {
1539
+ if ((0, import_stega2.vercelStegaSplit)(text).encoded) return text;
1540
+ let href;
1541
+ try {
1542
+ href = new URL(template.href);
1543
+ } catch {
1544
+ return text;
1545
+ }
1546
+ href.pathname = href.pathname.replace(
1547
+ EDIT_PATH,
1548
+ () => `/content/edit/${item}`
1549
+ );
1550
+ href.searchParams.set("field", field);
1551
+ const link = href.toString().replace(/%2E/gi, ".").replace(/%2F/gi, "/");
1552
+ return (0, import_stega2.vercelStegaCombine)(text, { origin: template.origin, href: link });
1553
+ }
1554
+ };
1555
+ }
1556
+ function findEditLink(root) {
1557
+ if (root === null || typeof root !== "object") return null;
1558
+ if (linkCache.has(root)) return linkCache.get(root) ?? null;
1559
+ let found = null;
1560
+ const seen = /* @__PURE__ */ new WeakSet();
1561
+ const walk = (node) => {
1562
+ if (found) return;
1563
+ if (typeof node === "string") {
1564
+ if (!(0, import_stega2.vercelStegaSplit)(node).encoded) return;
1565
+ try {
1566
+ const decoded = (0, import_stega2.vercelStegaDecode)(node);
1567
+ if (typeof decoded?.origin === "string" && typeof decoded.href === "string" && EDIT_PATH.test(decoded.href)) {
1568
+ found = { origin: decoded.origin, href: decoded.href };
1569
+ }
1570
+ } catch {
1571
+ }
1572
+ return;
1573
+ }
1574
+ if (node === null || typeof node !== "object" || seen.has(node)) return;
1575
+ seen.add(node);
1576
+ for (const value of Object.values(node)) walk(value);
1577
+ };
1578
+ walk(root);
1579
+ linkCache.set(root, found);
1580
+ return found;
1581
+ }
1582
+ var import_stega2, debug5, MAX_LOG_ENTRIES2, MAX_LOG_SOURCE_LENGTH, INDEX_SEGMENT2, FORBIDDEN_SEGMENTS2, ENVELOPE_KEYS, NON_ALPHANUMERIC, typeKey, NO_KEYS, listKeysCache, EDIT_PATH, ITEM_ID, linkCache;
1583
+ var init_normalize_query = __esm({
1584
+ "src/core/live-preview/normalize-query.ts"() {
1585
+ "use strict";
1586
+ import_stega2 = require("@vercel/stega");
1587
+ init_utils();
1588
+ init_field_name();
1589
+ init_index_snapshot();
1590
+ init_patch();
1591
+ init_query_document();
1592
+ init_validate();
1593
+ debug5 = createScopedLogger("live-preview:normalize");
1594
+ MAX_LOG_ENTRIES2 = 500;
1595
+ MAX_LOG_SOURCE_LENGTH = 1e6;
1596
+ INDEX_SEGMENT2 = /^\d+$/;
1597
+ FORBIDDEN_SEGMENTS2 = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
1598
+ ENVELOPE_KEYS = /* @__PURE__ */ new Set(["data", "errors", "extensions"]);
1599
+ NON_ALPHANUMERIC = /[^a-z0-9]/gi;
1600
+ typeKey = (name) => name.replace(NON_ALPHANUMERIC, "").toLowerCase();
1601
+ NO_KEYS = /* @__PURE__ */ new Set();
1602
+ listKeysCache = /* @__PURE__ */ new WeakMap();
1603
+ EDIT_PATH = /\/content\/edit\/[^/?#]+/;
1604
+ ITEM_ID = /^[A-Za-z0-9_-]+$/;
1605
+ linkCache = /* @__PURE__ */ new WeakMap();
1606
+ }
1607
+ });
1608
+
1609
+ // src/core/live-preview/index.ts
1610
+ var live_preview_exports = {};
1611
+ __export(live_preview_exports, {
1612
+ applyPatchLog: () => applyPatchLog,
1613
+ createLiveBridge: () => createLiveBridge,
1614
+ createLiveStore: () => createLiveStore,
1615
+ normalizeQuery: () => normalizeQuery,
1616
+ parsePatchLog: () => parsePatchLog
1617
+ });
1618
+ var init_live_preview = __esm({
1619
+ "src/core/live-preview/index.ts"() {
1620
+ "use strict";
1621
+ init_live_store();
1622
+ init_bridge_events();
1623
+ init_normalize_query();
1624
+ }
1625
+ });
1626
+
1627
+ // src/nuxt/live.ts
1628
+ var live_exports = {};
1629
+ __export(live_exports, {
1630
+ useNormalizedQuery: () => useNormalizedQuery
1631
+ });
1632
+ module.exports = __toCommonJS(live_exports);
1633
+ var import_vue = require("vue");
1634
+
1635
+ // src/core/live-preview/test-reset.ts
1636
+ var resets = /* @__PURE__ */ new Set();
1637
+ function onTestReset(reset) {
1638
+ resets.add(reset);
1639
+ }
1640
+
1641
+ // src/nuxt/live.ts
1642
+ var starting = null;
1643
+ var store = null;
1644
+ var bridge = null;
1645
+ var applyLog = null;
1646
+ var log = (0, import_vue.shallowRef)([]);
1647
+ var allowedEditorOrigins;
1648
+ var strictMode;
1649
+ var startListeners = /* @__PURE__ */ new Set();
1650
+ function isFramed() {
1651
+ return typeof window !== "undefined" && window.self !== window.top;
1652
+ }
1653
+ function startLive() {
1654
+ starting ?? (starting = Promise.resolve().then(() => (init_live_preview(), live_preview_exports)).then(
1655
+ ({ applyPatchLog: applyPatchLog2, createLiveBridge: createLiveBridge2, createLiveStore: createLiveStore2 }) => {
1656
+ applyLog = applyPatchLog2;
1657
+ const started = createLiveStore2();
1658
+ bridge = createLiveBridge2(started, {
1659
+ allowedEditorOrigins: () => allowedEditorOrigins,
1660
+ strictMode: () => strictMode
1661
+ });
1662
+ bridge.start();
1663
+ started.onLogChange((next) => {
1664
+ log.value = next;
1665
+ });
1666
+ store = started;
1667
+ startListeners.forEach((listener) => listener(started));
1668
+ startListeners.clear();
1669
+ }
1670
+ ));
1671
+ }
1672
+ function whenLive(listener) {
1673
+ if (store) {
1674
+ listener(store);
1675
+ return () => {
1676
+ };
1677
+ }
1678
+ startListeners.add(listener);
1679
+ return () => startListeners.delete(listener);
1680
+ }
1681
+ function useNormalizedQuery(query, data, options = {}) {
1682
+ if (!options.enabled || !isFramed()) {
1683
+ return (0, import_vue.computed)(() => (0, import_vue.unref)(data));
1684
+ }
1685
+ if (options.strictMode) strictMode = true;
1686
+ if (options.allowedEditorOrigins) {
1687
+ allowedEditorOrigins = [...options.allowedEditorOrigins];
1688
+ }
1689
+ startLive();
1690
+ if (options.onSave && (0, import_vue.getCurrentScope)()) {
1691
+ const onSave = options.onSave;
1692
+ let offInvalidate = null;
1693
+ const stopWaiting = whenLive((started) => {
1694
+ offInvalidate = started.onInvalidate(() => onSave());
1695
+ });
1696
+ (0, import_vue.onScopeDispose)(() => {
1697
+ stopWaiting();
1698
+ offInvalidate?.();
1699
+ });
1700
+ }
1701
+ return (0, import_vue.computed)(() => {
1702
+ const value = (0, import_vue.unref)(data);
1703
+ return log.value.length && applyLog ? applyLog(query, value, log.value) : value;
1704
+ });
1705
+ }
1706
+ onTestReset(() => {
1707
+ bridge?.stop();
1708
+ bridge = null;
1709
+ store = null;
1710
+ starting = null;
1711
+ applyLog = null;
1712
+ startListeners.clear();
1713
+ log.value = [];
1714
+ allowedEditorOrigins = void 0;
1715
+ strictMode = void 0;
1716
+ });
1717
+ // Annotate the CommonJS export names for ESM import in node:
1718
+ 0 && (module.exports = {
1719
+ useNormalizedQuery
1720
+ });