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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // package.json
2
2
  var package_default = {
3
- version: "1.0.0"};
3
+ version: "1.0.2"};
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,21 @@ 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 && !isPlainObject(v["data"])) return false;
457
+ if (v["fieldSchemaJSON"] !== void 0 && !Array.isArray(v["fieldSchemaJSON"])) return false;
458
+ if (v["globalSlug"] !== void 0 && typeof v["globalSlug"] !== "string") return false;
459
+ if (v["collectionSlug"] !== void 0 && typeof v["collectionSlug"] !== "string") return false;
460
+ if (v["locale"] !== void 0 && typeof v["locale"] !== "string") return false;
461
+ if (v["ready"] !== void 0 && typeof v["ready"] !== "boolean") return false;
462
+ if (v["previewToken"] !== void 0 && typeof v["previewToken"] !== "string") return false;
463
+ if (v["protocolVersion"] !== void 0 && typeof v["protocolVersion"] !== "number") return false;
464
+ return true;
465
+ }
466
+ function isPlainObject(value) {
467
+ return typeof value === "object" && value !== null && !Array.isArray(value);
468
+ }
442
469
 
443
470
  // src/core/state.ts
444
471
  var DEFAULT_TIMEOUT_MS = 0;
@@ -3170,10 +3197,12 @@ async function runWithTransition(callback) {
3170
3197
  var KEY_ATTRIBUTE = "data-payload-key";
3171
3198
  var NESTED_KEY_ATTRIBUTE = "data-payload-nested-key";
3172
3199
  var NESTED_TEMPLATE_ATTRIBUTE = "data-payload-nested-template";
3173
- var previousItemValues = /* @__PURE__ */ new WeakMap();
3200
+ function createStructuralStore() {
3201
+ return /* @__PURE__ */ new WeakMap();
3202
+ }
3174
3203
  function applyStructuralPatches(options) {
3175
- const { template, container, patches } = options;
3176
- const memory = getMemory(container);
3204
+ const { template, container, patches, store } = options;
3205
+ const memory = getMemory(container, store);
3177
3206
  const removes = [];
3178
3207
  const inserts = [];
3179
3208
  const moves = [];
@@ -3198,7 +3227,7 @@ function applyStructuralPatches(options) {
3198
3227
  const node = container.children[patch.index];
3199
3228
  const replacement = renderItem(template, patch.value, patch.index);
3200
3229
  if (!node || !replacement) continue;
3201
- populateNestedSlots(replacement, patch.value);
3230
+ populateNestedSlots(replacement, patch.value, store);
3202
3231
  container.replaceChild(replacement, node);
3203
3232
  rememberItem(memory, patch.value);
3204
3233
  }
@@ -3207,7 +3236,7 @@ function applyStructuralPatches(options) {
3207
3236
  const oldNode = container.children[patch.index];
3208
3237
  const newNode = renderItem(template, patch.value, patch.index);
3209
3238
  if (!oldNode || !newNode) continue;
3210
- reconcileNestedSlots(oldNode, newNode, patch.value, memory);
3239
+ reconcileNestedSlots(oldNode, newNode, patch.value, memory, store);
3211
3240
  container.replaceChild(newNode, oldNode);
3212
3241
  rememberItem(memory, patch.value);
3213
3242
  }
@@ -3217,7 +3246,7 @@ function applyStructuralPatches(options) {
3217
3246
  const before = container.children[patch.index] ?? null;
3218
3247
  const node = renderItem(template, patch.value, patch.index);
3219
3248
  if (!node) continue;
3220
- populateNestedSlots(node, patch.value);
3249
+ populateNestedSlots(node, patch.value, store);
3221
3250
  container.insertBefore(node, before);
3222
3251
  rememberItem(memory, patch.value);
3223
3252
  }
@@ -3231,7 +3260,7 @@ function applyStructuralPatches(options) {
3231
3260
  container.insertBefore(node, before);
3232
3261
  }
3233
3262
  }
3234
- function populateNestedSlots(item, value) {
3263
+ function populateNestedSlots(item, value, store) {
3235
3264
  const slots = item.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`);
3236
3265
  for (const slot of Array.from(slots)) {
3237
3266
  const key = slot.getAttribute(NESTED_KEY_ATTRIBUTE);
@@ -3245,10 +3274,12 @@ function populateNestedSlots(item, value) {
3245
3274
  applyStructuralPatches({
3246
3275
  template: nestedTemplate,
3247
3276
  container: slot,
3248
- patches});
3277
+ patches,
3278
+ store
3279
+ });
3249
3280
  }
3250
3281
  }
3251
- function reconcileNestedSlots(oldItem, newItem, nextValue, memory) {
3282
+ function reconcileNestedSlots(oldItem, newItem, nextValue, memory, store) {
3252
3283
  const oldSlots = oldItem.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`);
3253
3284
  if (oldSlots.length === 0) return;
3254
3285
  const itemKey = readKey(nextValue);
@@ -3268,7 +3299,9 @@ function reconcileNestedSlots(oldItem, newItem, nextValue, memory) {
3268
3299
  applyStructuralPatches({
3269
3300
  template: nestedTemplate,
3270
3301
  container: oldSlot,
3271
- patches});
3302
+ patches,
3303
+ store
3304
+ });
3272
3305
  }
3273
3306
  }
3274
3307
  function readNestedArray(value, key) {
@@ -3277,11 +3310,11 @@ function readNestedArray(value, key) {
3277
3310
  if (!Array.isArray(nested)) return void 0;
3278
3311
  return nested;
3279
3312
  }
3280
- function getMemory(container) {
3281
- let map = previousItemValues.get(container);
3313
+ function getMemory(container, store) {
3314
+ let map = store.get(container);
3282
3315
  if (!map) {
3283
3316
  map = /* @__PURE__ */ new Map();
3284
- previousItemValues.set(container, map);
3317
+ store.set(container, map);
3285
3318
  }
3286
3319
  return map;
3287
3320
  }
@@ -3352,44 +3385,48 @@ function escapeRegex2(value) {
3352
3385
  }
3353
3386
 
3354
3387
  // 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) {
3388
+ function createStructuralArrayRenderer() {
3389
+ const previousValues = /* @__PURE__ */ new WeakMap();
3390
+ const warnedContainers = /* @__PURE__ */ new WeakSet();
3391
+ const store = createStructuralStore();
3392
+ return {
3393
+ name: "structural-array",
3394
+ render(target, value) {
3395
+ if (!Array.isArray(value)) return;
3396
+ const container = target.element;
3397
+ const template = target.arrayTemplate;
3398
+ if (template === void 0 || template.length === 0) {
3399
+ warnMissingTemplate(warnedContainers, container, target.fieldName);
3400
+ return;
3401
+ }
3402
+ const previous = previousValues.get(container) ?? [];
3403
+ const patches = diffArray(previous, value);
3404
+ if (patches.length === 0) {
3405
+ previousValues.set(container, value.slice());
3406
+ return;
3407
+ }
3408
+ void runWithTransition(() => {
3409
+ applyStructuralPatches({
3410
+ template,
3411
+ container,
3412
+ patches,
3413
+ store
3414
+ });
3415
+ });
3370
3416
  previousValues.set(container, value.slice());
3371
- return;
3372
3417
  }
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) {
3418
+ };
3419
+ }
3420
+ function warnMissingTemplate(warnedContainers, container, fieldName) {
3383
3421
  if (warnedContainers.has(container)) return;
3384
3422
  warnedContainers.add(container);
3385
3423
  console.warn(
3386
3424
  `[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
3425
  );
3388
3426
  }
3389
- registerBuiltinRenderer(structuralArrayRenderer);
3390
3427
 
3391
3428
  // src/field-types/index.ts
3392
- var BUILTIN = [
3429
+ var STATELESS_BUILTIN = [
3393
3430
  textRenderer2,
3394
3431
  textareaRenderer,
3395
3432
  richTextRenderer,
@@ -3405,11 +3442,10 @@ var BUILTIN = [
3405
3442
  dateRenderer,
3406
3443
  numberRenderer,
3407
3444
  arrayRenderer,
3408
- { ...arrayRenderer, name: "blocks" },
3409
- structuralArrayRenderer
3445
+ { ...arrayRenderer, name: "blocks" }
3410
3446
  ];
3411
3447
  function buildBuiltinRenderers2() {
3412
- return buildBuiltinRenderers(BUILTIN);
3448
+ return buildBuiltinRenderers([...STATELESS_BUILTIN, createStructuralArrayRenderer()]);
3413
3449
  }
3414
3450
 
3415
3451
  // src/client/index.ts