payload-live-preview 1.0.1 → 1.0.3

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/core.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // package.json
2
2
  var package_default = {
3
- version: "1.0.1"};
3
+ version: "1.0.3"};
4
4
 
5
5
  // src/version.ts
6
6
  var VERSION = package_default.version;
@@ -336,6 +336,12 @@ var MessageBus = class {
336
336
  #handlers;
337
337
  #boundListener;
338
338
  #attached = false;
339
+ /**
340
+ * Tail of the async token-validation chain. Each gated update appends
341
+ * its validation to this promise, guaranteeing validations resolve —
342
+ * and updates dispatch — in the order the messages arrived.
343
+ */
344
+ #validationChain = Promise.resolve();
339
345
  constructor(matcher, handlers) {
340
346
  this.#matcher = matcher;
341
347
  this.#handlers = handlers;
@@ -392,6 +398,10 @@ var MessageBus = class {
392
398
  }
393
399
  switch (data.type) {
394
400
  case "payload-live-preview":
401
+ if (!isLivePreviewMessage(data)) {
402
+ this.#handlers.onInvalid?.("shape", origin);
403
+ return;
404
+ }
395
405
  this.#dispatchUpdate(data, origin);
396
406
  return;
397
407
  case "payload-document-event":
@@ -423,15 +433,17 @@ var MessageBus = class {
423
433
  else this.#handlers.onInvalid?.("token", origin);
424
434
  return;
425
435
  }
426
- void approved.then(
427
- (ok) => {
428
- if (ok) this.#handlers.onUpdate(message, origin);
429
- else this.#handlers.onInvalid?.("token", origin);
430
- },
431
- () => {
436
+ this.#validationChain = this.#validationChain.then(async () => {
437
+ let ok;
438
+ try {
439
+ ok = await approved;
440
+ } catch {
432
441
  this.#handlers.onInvalid?.("token", origin);
442
+ return;
433
443
  }
434
- );
444
+ if (ok) this.#handlers.onUpdate(message, origin);
445
+ else this.#handlers.onInvalid?.("token", origin);
446
+ });
435
447
  }
436
448
  };
437
449
  function isObjectMessage(value) {
@@ -439,6 +451,25 @@ function isObjectMessage(value) {
439
451
  if (!("type" in value)) return false;
440
452
  return typeof value.type === "string";
441
453
  }
454
+ function isLivePreviewMessage(value) {
455
+ const v = value;
456
+ if (v["data"] !== void 0 && v["data"] !== null && !isPlainObject(v["data"])) return false;
457
+ if (!optionalTypeOk(v["fieldSchemaJSON"], (x) => Array.isArray(x))) return false;
458
+ if (!optionalTypeOk(v["globalSlug"], (x) => typeof x === "string")) return false;
459
+ if (!optionalTypeOk(v["collectionSlug"], (x) => typeof x === "string")) return false;
460
+ if (!optionalTypeOk(v["locale"], (x) => typeof x === "string")) return false;
461
+ if (!optionalTypeOk(v["ready"], (x) => typeof x === "boolean")) return false;
462
+ if (!optionalTypeOk(v["previewToken"], (x) => typeof x === "string")) return false;
463
+ if (!optionalTypeOk(v["protocolVersion"], (x) => typeof x === "number")) return false;
464
+ return true;
465
+ }
466
+ function optionalTypeOk(value, check) {
467
+ if (value === void 0 || value === null) return true;
468
+ return check(value);
469
+ }
470
+ function isPlainObject(value) {
471
+ return typeof value === "object" && value !== null && !Array.isArray(value);
472
+ }
442
473
 
443
474
  // src/core/state.ts
444
475
  var DEFAULT_TIMEOUT_MS = 0;
@@ -3170,10 +3201,12 @@ async function runWithTransition(callback) {
3170
3201
  var KEY_ATTRIBUTE = "data-payload-key";
3171
3202
  var NESTED_KEY_ATTRIBUTE = "data-payload-nested-key";
3172
3203
  var NESTED_TEMPLATE_ATTRIBUTE = "data-payload-nested-template";
3173
- var previousItemValues = /* @__PURE__ */ new WeakMap();
3204
+ function createStructuralStore() {
3205
+ return /* @__PURE__ */ new WeakMap();
3206
+ }
3174
3207
  function applyStructuralPatches(options) {
3175
- const { template, container, patches } = options;
3176
- const memory = getMemory(container);
3208
+ const { template, container, patches, store } = options;
3209
+ const memory = getMemory(container, store);
3177
3210
  const removes = [];
3178
3211
  const inserts = [];
3179
3212
  const moves = [];
@@ -3198,7 +3231,7 @@ function applyStructuralPatches(options) {
3198
3231
  const node = container.children[patch.index];
3199
3232
  const replacement = renderItem(template, patch.value, patch.index);
3200
3233
  if (!node || !replacement) continue;
3201
- populateNestedSlots(replacement, patch.value);
3234
+ populateNestedSlots(replacement, patch.value, store);
3202
3235
  container.replaceChild(replacement, node);
3203
3236
  rememberItem(memory, patch.value);
3204
3237
  }
@@ -3207,7 +3240,7 @@ function applyStructuralPatches(options) {
3207
3240
  const oldNode = container.children[patch.index];
3208
3241
  const newNode = renderItem(template, patch.value, patch.index);
3209
3242
  if (!oldNode || !newNode) continue;
3210
- reconcileNestedSlots(oldNode, newNode, patch.value, memory);
3243
+ reconcileNestedSlots(oldNode, newNode, patch.value, memory, store);
3211
3244
  container.replaceChild(newNode, oldNode);
3212
3245
  rememberItem(memory, patch.value);
3213
3246
  }
@@ -3217,7 +3250,7 @@ function applyStructuralPatches(options) {
3217
3250
  const before = container.children[patch.index] ?? null;
3218
3251
  const node = renderItem(template, patch.value, patch.index);
3219
3252
  if (!node) continue;
3220
- populateNestedSlots(node, patch.value);
3253
+ populateNestedSlots(node, patch.value, store);
3221
3254
  container.insertBefore(node, before);
3222
3255
  rememberItem(memory, patch.value);
3223
3256
  }
@@ -3231,7 +3264,7 @@ function applyStructuralPatches(options) {
3231
3264
  container.insertBefore(node, before);
3232
3265
  }
3233
3266
  }
3234
- function populateNestedSlots(item, value) {
3267
+ function populateNestedSlots(item, value, store) {
3235
3268
  const slots = item.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`);
3236
3269
  for (const slot of Array.from(slots)) {
3237
3270
  const key = slot.getAttribute(NESTED_KEY_ATTRIBUTE);
@@ -3245,10 +3278,12 @@ function populateNestedSlots(item, value) {
3245
3278
  applyStructuralPatches({
3246
3279
  template: nestedTemplate,
3247
3280
  container: slot,
3248
- patches});
3281
+ patches,
3282
+ store
3283
+ });
3249
3284
  }
3250
3285
  }
3251
- function reconcileNestedSlots(oldItem, newItem, nextValue, memory) {
3286
+ function reconcileNestedSlots(oldItem, newItem, nextValue, memory, store) {
3252
3287
  const oldSlots = oldItem.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`);
3253
3288
  if (oldSlots.length === 0) return;
3254
3289
  const itemKey = readKey(nextValue);
@@ -3268,7 +3303,9 @@ function reconcileNestedSlots(oldItem, newItem, nextValue, memory) {
3268
3303
  applyStructuralPatches({
3269
3304
  template: nestedTemplate,
3270
3305
  container: oldSlot,
3271
- patches});
3306
+ patches,
3307
+ store
3308
+ });
3272
3309
  }
3273
3310
  }
3274
3311
  function readNestedArray(value, key) {
@@ -3277,11 +3314,11 @@ function readNestedArray(value, key) {
3277
3314
  if (!Array.isArray(nested)) return void 0;
3278
3315
  return nested;
3279
3316
  }
3280
- function getMemory(container) {
3281
- let map = previousItemValues.get(container);
3317
+ function getMemory(container, store) {
3318
+ let map = store.get(container);
3282
3319
  if (!map) {
3283
3320
  map = /* @__PURE__ */ new Map();
3284
- previousItemValues.set(container, map);
3321
+ store.set(container, map);
3285
3322
  }
3286
3323
  return map;
3287
3324
  }
@@ -3352,44 +3389,48 @@ function escapeRegex2(value) {
3352
3389
  }
3353
3390
 
3354
3391
  // src/field-types/structural-array.ts
3355
- var previousValues = /* @__PURE__ */ new WeakMap();
3356
- var warnedContainers = /* @__PURE__ */ new WeakSet();
3357
- var structuralArrayRenderer = {
3358
- name: "structural-array",
3359
- render(target, value) {
3360
- if (!Array.isArray(value)) return;
3361
- const container = target.element;
3362
- const template = target.arrayTemplate;
3363
- if (template === void 0 || template.length === 0) {
3364
- warnMissingTemplate(container, target.fieldName);
3365
- return;
3366
- }
3367
- const previous = previousValues.get(container) ?? [];
3368
- const patches = diffArray(previous, value);
3369
- if (patches.length === 0) {
3392
+ function createStructuralArrayRenderer() {
3393
+ const previousValues = /* @__PURE__ */ new WeakMap();
3394
+ const warnedContainers = /* @__PURE__ */ new WeakSet();
3395
+ const store = createStructuralStore();
3396
+ return {
3397
+ name: "structural-array",
3398
+ render(target, value) {
3399
+ if (!Array.isArray(value)) return;
3400
+ const container = target.element;
3401
+ const template = target.arrayTemplate;
3402
+ if (template === void 0 || template.length === 0) {
3403
+ warnMissingTemplate(warnedContainers, container, target.fieldName);
3404
+ return;
3405
+ }
3406
+ const previous = previousValues.get(container) ?? [];
3407
+ const patches = diffArray(previous, value);
3408
+ if (patches.length === 0) {
3409
+ previousValues.set(container, value.slice());
3410
+ return;
3411
+ }
3412
+ void runWithTransition(() => {
3413
+ applyStructuralPatches({
3414
+ template,
3415
+ container,
3416
+ patches,
3417
+ store
3418
+ });
3419
+ });
3370
3420
  previousValues.set(container, value.slice());
3371
- return;
3372
3421
  }
3373
- void runWithTransition(() => {
3374
- applyStructuralPatches({
3375
- template,
3376
- container,
3377
- patches});
3378
- });
3379
- previousValues.set(container, value.slice());
3380
- }
3381
- };
3382
- function warnMissingTemplate(container, fieldName) {
3422
+ };
3423
+ }
3424
+ function warnMissingTemplate(warnedContainers, container, fieldName) {
3383
3425
  if (warnedContainers.has(container)) return;
3384
3426
  warnedContainers.add(container);
3385
3427
  console.warn(
3386
3428
  `[live-preview] Skipping structural update for "${fieldName}" \u2014 the <${container.tagName.toLowerCase()}> with data-payload-structural is missing data-payload-array-template. Add an inline template (e.g., data-payload-array-template="<li>{{label}}</li>") so the renderer can materialise new items.`
3387
3429
  );
3388
3430
  }
3389
- registerBuiltinRenderer(structuralArrayRenderer);
3390
3431
 
3391
3432
  // src/field-types/index.ts
3392
- var BUILTIN = [
3433
+ var STATELESS_BUILTIN = [
3393
3434
  textRenderer2,
3394
3435
  textareaRenderer,
3395
3436
  richTextRenderer,
@@ -3405,11 +3446,10 @@ var BUILTIN = [
3405
3446
  dateRenderer,
3406
3447
  numberRenderer,
3407
3448
  arrayRenderer,
3408
- { ...arrayRenderer, name: "blocks" },
3409
- structuralArrayRenderer
3449
+ { ...arrayRenderer, name: "blocks" }
3410
3450
  ];
3411
3451
  function buildBuiltinRenderers2() {
3412
- return buildBuiltinRenderers(BUILTIN);
3452
+ return buildBuiltinRenderers([...STATELESS_BUILTIN, createStructuralArrayRenderer()]);
3413
3453
  }
3414
3454
 
3415
3455
  // src/client/index.ts