payload-live-preview 1.0.0 → 1.0.2

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