@phtngyn/cms 0.2.0-beta.6 → 0.2.0-beta.8
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/CHANGELOG.md +1 -0
- package/README.md +7 -4
- package/package.json +1 -1
- package/src/ApplicationTypes.d.ts +1 -1
- package/src/{Configuration-JQ1qyaU0.js → Configuration-CMweD9bn.js} +3 -3
- package/src/{Configuration-JQ1qyaU0.js.map → Configuration-CMweD9bn.js.map} +1 -1
- package/src/Configuration.d.ts +1 -1
- package/src/Content.js +4 -4
- package/src/Content.js.map +1 -1
- package/src/{DocumentEngine-j6Vi7nQo.js → DocumentEngine-tYtwbBjr.js} +7 -7
- package/src/DocumentEngine-tYtwbBjr.js.map +1 -0
- package/src/{HttpPaths-c9nLZ9H2.js → HttpPaths-Be3vshPJ.js} +2 -3
- package/src/HttpPaths-Be3vshPJ.js.map +1 -0
- package/src/{I18n-zbqpWxki.d.ts → I18n-wxswIRyY.d.ts} +3 -2
- package/src/I18n.d.ts +1 -1
- package/src/Module.js +2 -13
- package/src/Module.js.map +1 -1
- package/src/{S3MediaObjects-BRuPQbxl.js → S3MediaObjects-BXfjaZOu.js} +20 -6
- package/src/S3MediaObjects-BXfjaZOu.js.map +1 -0
- package/src/cli.js +3 -3
- package/src/{dev-lifecycle-CExksm2R.js → dev-lifecycle-3I_pozUl.js} +8 -8
- package/src/dev-lifecycle-3I_pozUl.js.map +1 -0
- package/src/{installation-BoG8E3nJ.js → installation-DxqSSVbH.js} +11 -22
- package/src/installation-DxqSSVbH.js.map +1 -0
- package/src/internal/authoring-catalog.js +1 -1
- package/src/internal/authoring-metadata.js +1 -1
- package/src/internal/configuration.js +1 -1
- package/src/internal/dev-lifecycle.js +1 -1
- package/src/internal/document-model.js +3 -3
- package/src/internal/document-model.js.map +1 -1
- package/src/internal/i18n.js +2 -2
- package/src/internal/i18n.js.map +1 -1
- package/src/internal/studio-app.js +3 -3
- package/src/internal/studio-app.js.map +1 -1
- package/src/{metadata-UzZmjwxM.js → metadata-DN9_K6Yl.js} +87 -7
- package/src/metadata-DN9_K6Yl.js.map +1 -0
- package/src/runtime/delivery/plugin.js +7 -2
- package/src/runtime/delivery/plugin.js.map +1 -1
- package/src/runtime/delivery/useDocument.js +1 -1
- package/src/runtime/delivery/useDocumentQuery.js +1 -1
- package/src/runtime/forms/useCmsForm.js +1 -1
- package/src/runtime/i18n/translator.js +10 -3
- package/src/runtime/i18n/translator.js.map +1 -1
- package/src/runtime/i18n/useCmsI18n.d.ts +1 -1
- package/src/runtime/installation.js +1 -1
- package/src/runtime/plugin.js +1 -1
- package/src/runtime/preview/controller.js +3 -2
- package/src/runtime/preview/controller.js.map +1 -1
- package/src/runtime/preview/crypto.js +16 -0
- package/src/runtime/preview/crypto.js.map +1 -0
- package/src/runtime/preview/plugin.client.js +1 -1
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/sitemap.js +1 -1
- package/src/runtime/studio-app.js +1 -1
- package/src/runtime/studio-app.js.map +1 -1
- package/src/runtime/studio-document.js +46 -0
- package/src/runtime/studio-document.js.map +1 -0
- package/src/runtime/studio-entry.js +5 -22
- package/src/runtime/studio-entry.js.map +1 -1
- package/src/runtime/studio-navigation.js +2 -2
- package/src/runtime/studio-navigation.js.map +1 -1
- package/src/{store-PKKB8xa2.js → store-X1e1o_MF.js} +2 -2
- package/src/{store-PKKB8xa2.js.map → store-X1e1o_MF.js.map} +1 -1
- package/studio/{CreateDocumentDialog-DqvusuGU.js → CreateDocumentDialog-C4_JBo1w.js} +90 -90
- package/studio/{SelectMenu-BgikeouH.js → SelectMenu-wXqxymUw.js} +8626 -8496
- package/studio/host.js +4244 -4151
- package/src/DocumentEngine-j6Vi7nQo.js.map +0 -1
- package/src/HttpPaths-c9nLZ9H2.js.map +0 -1
- package/src/S3MediaObjects-BRuPQbxl.js.map +0 -1
- package/src/dev-lifecycle-CExksm2R.js.map +0 -1
- package/src/installation-BoG8E3nJ.js.map +0 -1
- package/src/metadata-UzZmjwxM.js.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as scopedDatabaseUrl, r as toS3MediaObjectStoreOptions, t as installCms } from "../installation-
|
|
1
|
+
import { n as scopedDatabaseUrl, r as toS3MediaObjectStoreOptions, t as installCms } from "../installation-DxqSSVbH.js";
|
|
2
2
|
|
|
3
3
|
export { installCms, scopedDatabaseUrl, toS3MediaObjectStoreOptions };
|
package/src/runtime/plugin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveCmsInstallation } from "../internal/configuration.js";
|
|
2
|
-
import { t as installCms } from "../installation-
|
|
2
|
+
import { t as installCms } from "../installation-DxqSSVbH.js";
|
|
3
3
|
import { diagnosticFromCause, renderDiagnostic } from "../internal/diagnostics.js";
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
import { defineNitroPlugin, useNitroApp, useRuntimeConfig } from "nitropack/runtime";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { a as EditorNodeId, c as RevisionNumber, r as DocumentId } from "../../scalars-CVZqT3L0.js";
|
|
2
2
|
import { st as RequestId } from "../../models-VmGmG19-.js";
|
|
3
3
|
import { r as PreviewIntentId } from "../../models-5j67LMqW.js";
|
|
4
|
+
import { randomUUIDv4 } from "./crypto.js";
|
|
4
5
|
import { mountPreviewOverlay } from "./overlay.js";
|
|
5
6
|
import { mountPreviewRegions } from "./regions.js";
|
|
6
7
|
import { Schema } from "effect";
|
|
@@ -170,7 +171,7 @@ function mountPreviewController(options) {
|
|
|
170
171
|
const nodeId = Schema.is(EditorNodeId)(nodeIdValue) ? nodeIdValue : void 0;
|
|
171
172
|
const activationFocus = {
|
|
172
173
|
documentId: documentIdValue,
|
|
173
|
-
id: PreviewIntentId.make(
|
|
174
|
+
id: PreviewIntentId.make(randomUUIDv4(view.crypto)),
|
|
174
175
|
origin: "preview",
|
|
175
176
|
reveal: false,
|
|
176
177
|
revision
|
|
@@ -182,7 +183,7 @@ function mountPreviewController(options) {
|
|
|
182
183
|
lastApplied = "";
|
|
183
184
|
const activation = {
|
|
184
185
|
documentId: desiredFocus.documentId,
|
|
185
|
-
requestId: RequestId.make(
|
|
186
|
+
requestId: RequestId.make(randomUUIDv4(view.crypto)),
|
|
186
187
|
revision,
|
|
187
188
|
type: "preview:activate"
|
|
188
189
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.js","names":[],"sources":["../../../../../src/runtime/preview/controller.ts"],"sourcesContent":["import type { DocumentPreviewFocusIntent, PreviewSiteBridge, StudioPreviewPayload } from '@internal/protocol/Preview'\nimport type { StudioPreviewStore } from './store'\nimport { DocumentId, EditorNodeId, RevisionNumber } from '@internal/protocol/Documents'\nimport { RequestId } from '@internal/protocol/Identity'\nimport { PreviewIntentId } from '@internal/protocol/Preview'\nimport { Schema } from 'effect'\nimport { mountPreviewOverlay } from './overlay'\nimport { mountPreviewRegions } from './regions'\n\nexport function mountPreviewController(options: {\n readonly bridge: PreviewSiteBridge\n readonly navigate: (path: string) => Promise<void> | void\n readonly onPatchError: (message: string | null) => void\n readonly root: Document\n readonly store: StudioPreviewStore\n readonly view: Window\n}): () => void {\n type PreviewFallbacks = Extract<StudioPreviewPayload, { readonly type: 'studio:patch' }>['fallbacks']\n\n const { bridge, root, store, view } = options\n const selection = mountPreviewOverlay(root, view)\n const hover = mountPreviewOverlay(root, view, 'hover')\n const regions = mountPreviewRegions(root, view)\n let active = false\n let desiredFocus: DocumentPreviewFocusIntent | undefined\n let fallbacks: PreviewFallbacks = {}\n let mode: 'browse' | 'edit' = 'edit'\n let renderSequence = 0\n let revision = RevisionNumber.make(0)\n let lastApplied = ''\n let revealedIntentId = ''\n\n const sendManifest = (): void => {\n bridge.send({ manifest: store.manifest(), revision, type: 'preview:manifest' })\n }\n\n const stopManifest = store.subscribe(sendManifest)\n\n const sendApplied = (result: 'exact' | 'fallback' | 'missing'): void => {\n if (!desiredFocus) return\n const signature = `${desiredFocus.id}:${result}`\n\n if (signature === lastApplied) return\n lastApplied = signature\n\n const applied = {\n intentId: desiredFocus.id,\n result,\n revision,\n type: 'preview:applied',\n } as const\n\n bridge.send(desiredFocus.nodeId ? { ...applied, nodeId: desiredFocus.nodeId } : applied)\n }\n\n const documentRoot = (documentId: string): ParentNode =>\n [...root.querySelectorAll('[data-cms-document]')].find(\n (element) => element.getAttribute('data-cms-document') === documentId,\n ) ?? root\n\n const applyFocus = (reveal = false): void => {\n if (!active && mode === 'edit') {\n selection.setPending(true)\n\n return\n }\n\n selection.setPending(false)\n\n if (mode !== 'edit') {\n selection.show([])\n\n return\n }\n\n const intent = desiredFocus\n const nodeId = intent?.nodeId\n\n if (!intent || !nodeId) {\n selection.show([])\n sendApplied('exact')\n\n return\n }\n\n const scope = documentRoot(intent.documentId)\n const target = regions.locate(nodeId, fallbacks, scope)\n const result = !target.nodeId ? 'missing' : target.nodeId === nodeId ? 'exact' : 'fallback'\n\n selection.show(target.geometries, {\n label: intent.label,\n match: result === 'missing' ? undefined : result,\n reveal,\n })\n\n if (reveal && result !== 'missing' && revealedIntentId !== intent.id) {\n revealedIntentId = intent.id\n revealElement(regions.nearest(target.geometries), view)\n }\n\n sendApplied(result)\n }\n\n const hoverElements = (target?: Element, x?: number, y?: number): void => {\n if (!active || mode !== 'edit' || !target || x === undefined || y === undefined) {\n hover.show([])\n\n return\n }\n\n const scope = target.closest('[data-cms-document]') ?? root\n const nodeId = regions.hitTest(x, y, scope)\n\n if (!nodeId) {\n hover.show([])\n\n return\n }\n\n hover.show(regions.locate(nodeId, fallbacks, scope).geometries)\n }\n\n const settleRender = (sequence: number): void => {\n view.requestAnimationFrame(() =>\n view.requestAnimationFrame(() => {\n if (sequence !== renderSequence) return\n active = true\n regions.decorate()\n bridge.send({ revision, type: 'preview:rendered' })\n applyFocus(desiredFocus?.reveal)\n }),\n )\n }\n\n const stopBridge = bridge.subscribe((message) => {\n if (message.type === 'studio:connect') {\n active = true\n regions.clear()\n regions.decorate()\n sendManifest()\n\n return\n }\n\n if (message.type === 'studio:mode') {\n mode = message.mode\n\n if (mode === 'browse') {\n hoverElements()\n selection.setPending(false)\n selection.show([])\n regions.clear()\n } else {\n regions.decorate()\n applyFocus()\n }\n\n return\n }\n\n if (message.type === 'studio:navigate') {\n void options.navigate(message.path)\n\n return\n }\n\n if (message.type === 'studio:focus') {\n if (message.focus.revision !== revision) return\n desiredFocus = message.focus\n applyFocus(desiredFocus.reveal)\n\n return\n }\n\n if (message.type !== 'studio:patch' || message.revision < revision) return\n revision = message.revision\n active = false\n selection.setPending(true)\n desiredFocus = message.focus\n lastApplied = ''\n const sequence = ++renderSequence\n void store.patch(message.document).then(\n (localFallbacks) => {\n if (sequence !== renderSequence) return\n options.onPatchError(null)\n fallbacks = Object.assign({}, message.fallbacks, localFallbacks)\n settleRender(sequence)\n },\n () => {\n if (sequence !== renderSequence) return\n options.onPatchError('Preview could not apply this update.')\n },\n )\n })\n\n const handleClick = (event: MouseEvent) => {\n if (!active) return\n const target = event.target instanceof Element ? event.target : null\n\n if (mode === 'browse') {\n const link = target?.closest('a[href]')\n\n if (\n !(link instanceof HTMLAnchorElement) ||\n link.target ||\n link.hasAttribute('download') ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n )\n return\n const destination = new URL(link.href, view.location.href)\n\n if (destination.origin !== view.location.origin) return\n event.preventDefault()\n event.stopPropagation()\n void options.navigate(`${destination.pathname}${destination.search}${destination.hash}`)\n\n return\n }\n\n const scope = target?.closest('[data-cms-document]')\n const documentIdValue = scope?.getAttribute('data-cms-document')\n\n if (!target || !scope || !Schema.is(DocumentId)(documentIdValue)) return\n event.preventDefault()\n event.stopPropagation()\n const nodeIdValue = regions.hitTest(event.clientX, event.clientY, scope)\n const nodeId = Schema.is(EditorNodeId)(nodeIdValue) ? nodeIdValue : undefined\n\n const activationFocus = {\n documentId: documentIdValue,\n // oxlint-disable-next-line effecttsgo/crypto-random-uuid -- Browser interactions use the native Web Crypto host API.\n id: PreviewIntentId.make(globalThis.crypto.randomUUID()),\n origin: 'preview',\n reveal: false,\n revision,\n } as const\n\n desiredFocus = nodeId ? { ...activationFocus, nodeId } : activationFocus\n lastApplied = ''\n\n const activation = {\n documentId: desiredFocus.documentId,\n // oxlint-disable-next-line effecttsgo/crypto-random-uuid -- Browser interactions use the native Web Crypto host API.\n requestId: RequestId.make(globalThis.crypto.randomUUID()),\n revision,\n type: 'preview:activate',\n } as const\n\n if (nodeId) bridge.send({ ...activation, nodeId })\n else bridge.send(activation)\n applyFocus()\n }\n\n let hoverFrame = 0\n let hoverPointer: { readonly target: Element; readonly x: number; readonly y: number } | undefined\n\n const handlePointerMove = (event: PointerEvent) => {\n if (!(event.target instanceof Element)) return\n hoverPointer = { target: event.target, x: event.clientX, y: event.clientY }\n\n if (hoverFrame) return\n hoverFrame = view.requestAnimationFrame(() => {\n hoverFrame = 0\n const pointer = hoverPointer\n\n if (pointer) hoverElements(pointer.target, pointer.x, pointer.y)\n })\n }\n\n const handlePointerOut = (event: PointerEvent) => {\n if (!(event.relatedTarget instanceof Element)) {\n hoverPointer = undefined\n hoverElements()\n }\n }\n\n let mutationQueued = false\n\n const observer = new MutationObserver((records) => {\n if (\n records.every((record) => record.target instanceof Element && record.target.closest('[data-cms-preview-overlay]'))\n )\n return\n\n if (mutationQueued) return\n mutationQueued = true\n queueMicrotask(() => {\n mutationQueued = false\n\n if (!active) return\n hoverElements()\n regions.decorate()\n\n if (desiredFocus) applyFocus(false)\n })\n })\n\n root.addEventListener('click', handleClick, true)\n root.addEventListener('pointermove', handlePointerMove, true)\n root.addEventListener('pointerout', handlePointerOut, true)\n observer.observe(root.documentElement, { childList: true, subtree: true })\n\n return () => {\n stopBridge()\n stopManifest()\n observer.disconnect()\n\n if (hoverFrame) view.cancelAnimationFrame(hoverFrame)\n selection.destroy()\n hover.destroy()\n root.removeEventListener('click', handleClick, true)\n root.removeEventListener('pointermove', handlePointerMove, true)\n root.removeEventListener('pointerout', handlePointerOut, true)\n regions.clear()\n }\n}\n\nfunction revealElement(element: Element | undefined, view: Window): void {\n if (!element) return\n const rect = element.getBoundingClientRect()\n\n if (rect.bottom > 0 && rect.top < view.innerHeight && rect.right > 0 && rect.left < view.innerWidth) return\n element.scrollIntoView({\n behavior: 'instant',\n block: 'center',\n inline: 'nearest',\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"controller.js","names":[],"sources":["../../../../../src/runtime/preview/controller.ts"],"sourcesContent":["import type { DocumentPreviewFocusIntent, PreviewSiteBridge, StudioPreviewPayload } from '@internal/protocol/Preview'\nimport type { StudioPreviewStore } from './store'\nimport { DocumentId, EditorNodeId, RevisionNumber } from '@internal/protocol/Documents'\nimport { RequestId } from '@internal/protocol/Identity'\nimport { PreviewIntentId } from '@internal/protocol/Preview'\nimport { Schema } from 'effect'\nimport { randomUUIDv4 } from './crypto'\nimport { mountPreviewOverlay } from './overlay'\nimport { mountPreviewRegions } from './regions'\n\nexport function mountPreviewController(options: {\n readonly bridge: PreviewSiteBridge\n readonly navigate: (path: string) => Promise<void> | void\n readonly onPatchError: (message: string | null) => void\n readonly root: Document\n readonly store: StudioPreviewStore\n readonly view: Window\n}): () => void {\n type PreviewFallbacks = Extract<StudioPreviewPayload, { readonly type: 'studio:patch' }>['fallbacks']\n\n const { bridge, root, store, view } = options\n const selection = mountPreviewOverlay(root, view)\n const hover = mountPreviewOverlay(root, view, 'hover')\n const regions = mountPreviewRegions(root, view)\n let active = false\n let desiredFocus: DocumentPreviewFocusIntent | undefined\n let fallbacks: PreviewFallbacks = {}\n let mode: 'browse' | 'edit' = 'edit'\n let renderSequence = 0\n let revision = RevisionNumber.make(0)\n let lastApplied = ''\n let revealedIntentId = ''\n\n const sendManifest = (): void => {\n bridge.send({ manifest: store.manifest(), revision, type: 'preview:manifest' })\n }\n\n const stopManifest = store.subscribe(sendManifest)\n\n const sendApplied = (result: 'exact' | 'fallback' | 'missing'): void => {\n if (!desiredFocus) return\n const signature = `${desiredFocus.id}:${result}`\n\n if (signature === lastApplied) return\n lastApplied = signature\n\n const applied = {\n intentId: desiredFocus.id,\n result,\n revision,\n type: 'preview:applied',\n } as const\n\n bridge.send(desiredFocus.nodeId ? { ...applied, nodeId: desiredFocus.nodeId } : applied)\n }\n\n const documentRoot = (documentId: string): ParentNode =>\n [...root.querySelectorAll('[data-cms-document]')].find(\n (element) => element.getAttribute('data-cms-document') === documentId,\n ) ?? root\n\n const applyFocus = (reveal = false): void => {\n if (!active && mode === 'edit') {\n selection.setPending(true)\n\n return\n }\n\n selection.setPending(false)\n\n if (mode !== 'edit') {\n selection.show([])\n\n return\n }\n\n const intent = desiredFocus\n const nodeId = intent?.nodeId\n\n if (!intent || !nodeId) {\n selection.show([])\n sendApplied('exact')\n\n return\n }\n\n const scope = documentRoot(intent.documentId)\n const target = regions.locate(nodeId, fallbacks, scope)\n const result = !target.nodeId ? 'missing' : target.nodeId === nodeId ? 'exact' : 'fallback'\n\n selection.show(target.geometries, {\n label: intent.label,\n match: result === 'missing' ? undefined : result,\n reveal,\n })\n\n if (reveal && result !== 'missing' && revealedIntentId !== intent.id) {\n revealedIntentId = intent.id\n revealElement(regions.nearest(target.geometries), view)\n }\n\n sendApplied(result)\n }\n\n const hoverElements = (target?: Element, x?: number, y?: number): void => {\n if (!active || mode !== 'edit' || !target || x === undefined || y === undefined) {\n hover.show([])\n\n return\n }\n\n const scope = target.closest('[data-cms-document]') ?? root\n const nodeId = regions.hitTest(x, y, scope)\n\n if (!nodeId) {\n hover.show([])\n\n return\n }\n\n hover.show(regions.locate(nodeId, fallbacks, scope).geometries)\n }\n\n const settleRender = (sequence: number): void => {\n view.requestAnimationFrame(() =>\n view.requestAnimationFrame(() => {\n if (sequence !== renderSequence) return\n active = true\n regions.decorate()\n bridge.send({ revision, type: 'preview:rendered' })\n applyFocus(desiredFocus?.reveal)\n }),\n )\n }\n\n const stopBridge = bridge.subscribe((message) => {\n if (message.type === 'studio:connect') {\n active = true\n regions.clear()\n regions.decorate()\n sendManifest()\n\n return\n }\n\n if (message.type === 'studio:mode') {\n mode = message.mode\n\n if (mode === 'browse') {\n hoverElements()\n selection.setPending(false)\n selection.show([])\n regions.clear()\n } else {\n regions.decorate()\n applyFocus()\n }\n\n return\n }\n\n if (message.type === 'studio:navigate') {\n void options.navigate(message.path)\n\n return\n }\n\n if (message.type === 'studio:focus') {\n if (message.focus.revision !== revision) return\n desiredFocus = message.focus\n applyFocus(desiredFocus.reveal)\n\n return\n }\n\n if (message.type !== 'studio:patch' || message.revision < revision) return\n revision = message.revision\n active = false\n selection.setPending(true)\n desiredFocus = message.focus\n lastApplied = ''\n const sequence = ++renderSequence\n void store.patch(message.document).then(\n (localFallbacks) => {\n if (sequence !== renderSequence) return\n options.onPatchError(null)\n fallbacks = Object.assign({}, message.fallbacks, localFallbacks)\n settleRender(sequence)\n },\n () => {\n if (sequence !== renderSequence) return\n options.onPatchError('Preview could not apply this update.')\n },\n )\n })\n\n const handleClick = (event: MouseEvent) => {\n if (!active) return\n const target = event.target instanceof Element ? event.target : null\n\n if (mode === 'browse') {\n const link = target?.closest('a[href]')\n\n if (\n !(link instanceof HTMLAnchorElement) ||\n link.target ||\n link.hasAttribute('download') ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n )\n return\n const destination = new URL(link.href, view.location.href)\n\n if (destination.origin !== view.location.origin) return\n event.preventDefault()\n event.stopPropagation()\n void options.navigate(`${destination.pathname}${destination.search}${destination.hash}`)\n\n return\n }\n\n const scope = target?.closest('[data-cms-document]')\n const documentIdValue = scope?.getAttribute('data-cms-document')\n\n if (!target || !scope || !Schema.is(DocumentId)(documentIdValue)) return\n event.preventDefault()\n event.stopPropagation()\n const nodeIdValue = regions.hitTest(event.clientX, event.clientY, scope)\n const nodeId = Schema.is(EditorNodeId)(nodeIdValue) ? nodeIdValue : undefined\n\n const activationFocus = {\n documentId: documentIdValue,\n id: PreviewIntentId.make(randomUUIDv4(view.crypto)),\n origin: 'preview',\n reveal: false,\n revision,\n } as const\n\n desiredFocus = nodeId ? { ...activationFocus, nodeId } : activationFocus\n lastApplied = ''\n\n const activation = {\n documentId: desiredFocus.documentId,\n requestId: RequestId.make(randomUUIDv4(view.crypto)),\n revision,\n type: 'preview:activate',\n } as const\n\n if (nodeId) bridge.send({ ...activation, nodeId })\n else bridge.send(activation)\n applyFocus()\n }\n\n let hoverFrame = 0\n let hoverPointer: { readonly target: Element; readonly x: number; readonly y: number } | undefined\n\n const handlePointerMove = (event: PointerEvent) => {\n if (!(event.target instanceof Element)) return\n hoverPointer = { target: event.target, x: event.clientX, y: event.clientY }\n\n if (hoverFrame) return\n hoverFrame = view.requestAnimationFrame(() => {\n hoverFrame = 0\n const pointer = hoverPointer\n\n if (pointer) hoverElements(pointer.target, pointer.x, pointer.y)\n })\n }\n\n const handlePointerOut = (event: PointerEvent) => {\n if (!(event.relatedTarget instanceof Element)) {\n hoverPointer = undefined\n hoverElements()\n }\n }\n\n let mutationQueued = false\n\n const observer = new MutationObserver((records) => {\n if (\n records.every((record) => record.target instanceof Element && record.target.closest('[data-cms-preview-overlay]'))\n )\n return\n\n if (mutationQueued) return\n mutationQueued = true\n queueMicrotask(() => {\n mutationQueued = false\n\n if (!active) return\n hoverElements()\n regions.decorate()\n\n if (desiredFocus) applyFocus(false)\n })\n })\n\n root.addEventListener('click', handleClick, true)\n root.addEventListener('pointermove', handlePointerMove, true)\n root.addEventListener('pointerout', handlePointerOut, true)\n observer.observe(root.documentElement, { childList: true, subtree: true })\n\n return () => {\n stopBridge()\n stopManifest()\n observer.disconnect()\n\n if (hoverFrame) view.cancelAnimationFrame(hoverFrame)\n selection.destroy()\n hover.destroy()\n root.removeEventListener('click', handleClick, true)\n root.removeEventListener('pointermove', handlePointerMove, true)\n root.removeEventListener('pointerout', handlePointerOut, true)\n regions.clear()\n }\n}\n\nfunction revealElement(element: Element | undefined, view: Window): void {\n if (!element) return\n const rect = element.getBoundingClientRect()\n\n if (rect.bottom > 0 && rect.top < view.innerHeight && rect.right > 0 && rect.left < view.innerWidth) return\n element.scrollIntoView({\n behavior: 'instant',\n block: 'center',\n inline: 'nearest',\n })\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Crypto, Effect } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/runtime/preview/crypto.ts
|
|
4
|
+
function browserCrypto(host) {
|
|
5
|
+
return Crypto.make({
|
|
6
|
+
digest: (algorithm, data) => Effect.promise(() => host.subtle.digest(algorithm, new Uint8Array(data)).then((digest) => new Uint8Array(digest))),
|
|
7
|
+
randomBytes: (size) => host.getRandomValues(new Uint8Array(size))
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
function randomUUIDv4(host) {
|
|
11
|
+
return Effect.runSync(browserCrypto(host).randomUUIDv4.pipe(Effect.orDie));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { randomUUIDv4 };
|
|
16
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","names":["EffectCrypto"],"sources":["../../../../../src/runtime/preview/crypto.ts"],"sourcesContent":["import { Crypto as EffectCrypto, Effect } from 'effect'\n\nfunction browserCrypto(host: Crypto): EffectCrypto.Crypto {\n return EffectCrypto.make({\n digest: (algorithm, data) =>\n Effect.promise(() =>\n host.subtle.digest(algorithm, new Uint8Array(data)).then((digest) => new Uint8Array(digest)),\n ),\n randomBytes: (size) => host.getRandomValues(new Uint8Array(size)),\n })\n}\n\nexport function randomUUIDv4(host: Crypto): string {\n return Effect.runSync(browserCrypto(host).randomUUIDv4.pipe(Effect.orDie))\n}\n"],"mappings":";;;AAEA,SAAS,cAAc,MAAmC;CACxD,OAAOA,OAAa,KAAK;EACvB,SAAS,WAAW,SAClB,OAAO,cACL,KAAK,OAAO,OAAO,WAAW,IAAI,WAAW,IAAI,CAAC,CAAC,CAAC,MAAM,WAAW,IAAI,WAAW,MAAM,CAAC,CAC7F;EACF,cAAc,SAAS,KAAK,gBAAgB,IAAI,WAAW,IAAI,CAAC;CAClE,CAAC;AACH;AAEA,SAAgB,aAAa,MAAsB;CACjD,OAAO,OAAO,QAAQ,cAAc,IAAI,CAAC,CAAC,aAAa,KAAK,OAAO,KAAK,CAAC;AAC3E"}
|
|
@@ -4,7 +4,7 @@ import { n as readPreviewLocation, r as withPreviewLocation } from "../../locati
|
|
|
4
4
|
import { formComponentsKey } from "../delivery/blocks.js";
|
|
5
5
|
import { documentPreviewStoreKey } from "../delivery/preview.js";
|
|
6
6
|
import { mountPreviewController } from "./controller.js";
|
|
7
|
-
import { t as createStudioPreviewStore } from "../../store-
|
|
7
|
+
import { t as createStudioPreviewStore } from "../../store-X1e1o_MF.js";
|
|
8
8
|
import { Result, Schema } from "effect";
|
|
9
9
|
import { inject, watch } from "vue";
|
|
10
10
|
import { defineNuxtPlugin, navigateTo, onNuxtReady, useNuxtApp, useState } from "nuxt/app";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { documentPreviewStoreKey } from "../delivery/preview.js";
|
|
2
|
-
import { t as createStudioPreviewStore } from "../../store-
|
|
2
|
+
import { t as createStudioPreviewStore } from "../../store-X1e1o_MF.js";
|
|
3
3
|
|
|
4
4
|
export { createStudioPreviewStore, documentPreviewStoreKey };
|
package/src/runtime/sitemap.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Y as SitemapEntry } from "../models-VmGmG19-.js";
|
|
2
|
-
import { i as CMS_DELIVERY_SITEMAP_PATH } from "../HttpPaths-
|
|
2
|
+
import { i as CMS_DELIVERY_SITEMAP_PATH } from "../HttpPaths-Be3vshPJ.js";
|
|
3
3
|
import { useCmsInstallation } from "./plugin.js";
|
|
4
4
|
import { toNuxtSitemapEntries } from "./sitemap-entries.js";
|
|
5
5
|
import { Schema } from "effect";
|
|
@@ -4,7 +4,7 @@ import { defineEventHandler, setResponseHeader } from "h3";
|
|
|
4
4
|
function createStudioAppHandler(entryUrl, hmrUrl) {
|
|
5
5
|
const escape = (value) => value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<");
|
|
6
6
|
const script = (url) => `<script type="module" src="${escape(url)}"><\/script>`;
|
|
7
|
-
const shell = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>CMS Studio</title></head><body
|
|
7
|
+
const shell = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>CMS Studio</title></head><body>${hmrUrl ? script(hmrUrl) : ""}${script(entryUrl)}</body></html>`;
|
|
8
8
|
return defineEventHandler((event) => {
|
|
9
9
|
setResponseHeader(event, "content-type", "text/html; charset=utf-8");
|
|
10
10
|
setResponseHeader(event, "cache-control", "no-store");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studio-app.js","names":[],"sources":["../../../../src/runtime/studio-app.ts"],"sourcesContent":["import { defineEventHandler, setResponseHeader } from 'h3'\n\nexport function createStudioAppHandler(entryUrl: string, hmrUrl?: string) {\n const escape = (value: string) => value.replaceAll('&', '&').replaceAll('\"', '"').replaceAll('<', '<')\n const script = (url: string) => `<script type=\"module\" src=\"${escape(url)}\"></script>`\n const shell = `<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>CMS Studio</title></head><body
|
|
1
|
+
{"version":3,"file":"studio-app.js","names":[],"sources":["../../../../src/runtime/studio-app.ts"],"sourcesContent":["import { defineEventHandler, setResponseHeader } from 'h3'\n\nexport function createStudioAppHandler(entryUrl: string, hmrUrl?: string) {\n const escape = (value: string) => value.replaceAll('&', '&').replaceAll('\"', '"').replaceAll('<', '<')\n const script = (url: string) => `<script type=\"module\" src=\"${escape(url)}\"></script>`\n const shell = `<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>CMS Studio</title></head><body>${hmrUrl ? script(hmrUrl) : ''}${script(entryUrl)}</body></html>`\n\n return defineEventHandler((event) => {\n setResponseHeader(event, 'content-type', 'text/html; charset=utf-8')\n setResponseHeader(event, 'cache-control', 'no-store')\n\n return shell\n })\n}\n"],"mappings":";;;AAEA,SAAgB,uBAAuB,UAAkB,QAAiB;CACxE,MAAM,UAAU,UAAkB,MAAM,WAAW,KAAK,OAAO,CAAC,CAAC,WAAW,MAAK,QAAQ,CAAC,CAAC,WAAW,KAAK,MAAM;CACjH,MAAM,UAAU,QAAgB,8BAA8B,OAAO,GAAG,EAAE;CAC1E,MAAM,QAAQ,wKAAwK,SAAS,OAAO,MAAM,IAAI,KAAK,OAAO,QAAQ,EAAE;CAEtO,OAAO,oBAAoB,UAAU;EACnC,kBAAkB,OAAO,gBAAgB,0BAA0B;EACnE,kBAAkB,OAAO,iBAAiB,UAAU;EAEpD,OAAO;CACT,CAAC;AACH"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { d as STUDIO_BASE_PATH } from "../HttpPaths-Be3vshPJ.js";
|
|
2
|
+
|
|
3
|
+
//#region src/runtime/studio-document.ts
|
|
4
|
+
function resolveStudioRoot(document, pathname) {
|
|
5
|
+
const root = document.getElementById("cms-studio");
|
|
6
|
+
if (root) return root;
|
|
7
|
+
if (pathname !== "/_cms" && !pathname.startsWith(`${"/_cms"}/`)) return null;
|
|
8
|
+
const created = document.createElement("div");
|
|
9
|
+
created.id = "cms-studio";
|
|
10
|
+
document.body.replaceChildren(created);
|
|
11
|
+
return created;
|
|
12
|
+
}
|
|
13
|
+
function startStudioDocument(root, catalog, stylesheet, mountStudio) {
|
|
14
|
+
if (!root) return {
|
|
15
|
+
unmount: () => void 0,
|
|
16
|
+
updateAuthoring: () => void 0
|
|
17
|
+
};
|
|
18
|
+
let currentCatalog = catalog;
|
|
19
|
+
let studio;
|
|
20
|
+
const link = document.createElement("link");
|
|
21
|
+
link.rel = "stylesheet";
|
|
22
|
+
link.href = stylesheet;
|
|
23
|
+
link.onload = () => {
|
|
24
|
+
studio = mountStudio(root, currentCatalog);
|
|
25
|
+
};
|
|
26
|
+
link.onerror = () => {
|
|
27
|
+
root.textContent = "CMS Studio styles could not load. Reload this page to retry.";
|
|
28
|
+
};
|
|
29
|
+
document.head.append(link);
|
|
30
|
+
return {
|
|
31
|
+
unmount() {
|
|
32
|
+
link.onload = null;
|
|
33
|
+
link.onerror = null;
|
|
34
|
+
studio?.unmount();
|
|
35
|
+
link.remove();
|
|
36
|
+
},
|
|
37
|
+
updateAuthoring(next) {
|
|
38
|
+
currentCatalog = next;
|
|
39
|
+
studio?.updateAuthoring(next);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
export { resolveStudioRoot, startStudioDocument };
|
|
46
|
+
//# sourceMappingURL=studio-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"studio-document.js","names":[],"sources":["../../../../src/runtime/studio-document.ts"],"sourcesContent":["import type { AuthoringCatalog } from '@internal/protocol/Configuration'\nimport { STUDIO_BASE_PATH } from '@internal/protocol/HttpPaths'\n\ninterface MountedStudio {\n readonly unmount: () => void\n readonly updateAuthoring: (catalog: AuthoringCatalog) => void\n}\n\ninterface StudioDocument {\n readonly unmount: () => void\n readonly updateAuthoring: (catalog: AuthoringCatalog) => void\n}\n\nexport function resolveStudioRoot(document: Document, pathname: string): HTMLElement | null {\n const root = document.getElementById('cms-studio')\n\n if (root) return root\n\n if (pathname !== STUDIO_BASE_PATH && !pathname.startsWith(`${STUDIO_BASE_PATH}/`)) return null\n\n const created = document.createElement('div')\n created.id = 'cms-studio'\n document.body.replaceChildren(created)\n\n return created\n}\n\nexport function startStudioDocument(\n root: HTMLElement | null,\n catalog: AuthoringCatalog,\n stylesheet: string,\n mountStudio: (root: HTMLElement, catalog: AuthoringCatalog) => MountedStudio,\n): StudioDocument {\n if (!root) return { unmount: () => undefined, updateAuthoring: () => undefined }\n\n let currentCatalog = catalog\n let studio: MountedStudio | undefined\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = stylesheet\n link.onload = () => {\n studio = mountStudio(root, currentCatalog)\n }\n\n link.onerror = () => {\n root.textContent = 'CMS Studio styles could not load. Reload this page to retry.'\n }\n\n document.head.append(link)\n\n return {\n unmount() {\n link.onload = null\n link.onerror = null\n studio?.unmount()\n link.remove()\n },\n updateAuthoring(next: AuthoringCatalog) {\n currentCatalog = next\n studio?.updateAuthoring(next)\n },\n }\n}\n"],"mappings":";;;AAaA,SAAgB,kBAAkB,UAAoB,UAAsC;CAC1F,MAAM,OAAO,SAAS,eAAe,YAAY;CAEjD,IAAI,MAAM,OAAO;CAEjB,IAAI,wBAAiC,CAAC,SAAS,WAAW,WAAoB,EAAE,GAAG,OAAO;CAE1F,MAAM,UAAU,SAAS,cAAc,KAAK;CAC5C,QAAQ,KAAK;CACb,SAAS,KAAK,gBAAgB,OAAO;CAErC,OAAO;AACT;AAEA,SAAgB,oBACd,MACA,SACA,YACA,aACgB;CAChB,IAAI,CAAC,MAAM,OAAO;EAAE,eAAe;EAAW,uBAAuB;CAAU;CAE/E,IAAI,iBAAiB;CACrB,IAAI;CACJ,MAAM,OAAO,SAAS,cAAc,MAAM;CAC1C,KAAK,MAAM;CACX,KAAK,OAAO;CACZ,KAAK,eAAe;EAClB,SAAS,YAAY,MAAM,cAAc;CAC3C;CAEA,KAAK,gBAAgB;EACnB,KAAK,cAAc;CACrB;CAEA,SAAS,KAAK,OAAO,IAAI;CAEzB,OAAO;EACL,UAAU;GACR,KAAK,SAAS;GACd,KAAK,UAAU;GACf,QAAQ,QAAQ;GAChB,KAAK,OAAO;EACd;EACA,gBAAgB,MAAwB;GACtC,iBAAiB;GACjB,QAAQ,gBAAgB,IAAI;EAC9B;CACF;AACF"}
|
|
@@ -1,34 +1,17 @@
|
|
|
1
|
+
import { resolveStudioRoot, startStudioDocument } from "./studio-document.js";
|
|
1
2
|
import authoring from "#cms/authoring";
|
|
2
3
|
import { mountStudio } from "#cms/studio";
|
|
3
4
|
import stylesheet from "#cms/studio-styles";
|
|
4
5
|
|
|
5
6
|
//#region src/runtime/studio-entry.ts
|
|
6
|
-
const root = document.
|
|
7
|
-
|
|
8
|
-
let currentCatalog = authoring;
|
|
9
|
-
let studio;
|
|
10
|
-
const link = document.createElement("link");
|
|
11
|
-
link.rel = "stylesheet";
|
|
12
|
-
link.href = stylesheet;
|
|
13
|
-
link.onload = () => {
|
|
14
|
-
studio = mountStudio(root, currentCatalog);
|
|
15
|
-
};
|
|
16
|
-
link.onerror = () => {
|
|
17
|
-
root.textContent = "CMS Studio styles could not load. Reload this page to retry.";
|
|
18
|
-
};
|
|
19
|
-
document.head.append(link);
|
|
7
|
+
const root = resolveStudioRoot(document, window.location.pathname);
|
|
8
|
+
const studio = startStudioDocument(root, authoring, stylesheet, mountStudio);
|
|
20
9
|
if (import.meta.hot) {
|
|
21
10
|
import.meta.hot.accept("#cms/authoring", (module) => {
|
|
22
11
|
if (!module) return;
|
|
23
|
-
|
|
24
|
-
studio?.updateAuthoring(currentCatalog);
|
|
25
|
-
});
|
|
26
|
-
import.meta.hot.dispose(() => {
|
|
27
|
-
link.onload = null;
|
|
28
|
-
link.onerror = null;
|
|
29
|
-
studio?.unmount();
|
|
30
|
-
link.remove();
|
|
12
|
+
studio.updateAuthoring(module.default);
|
|
31
13
|
});
|
|
14
|
+
import.meta.hot.dispose(studio.unmount);
|
|
32
15
|
}
|
|
33
16
|
|
|
34
17
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studio-entry.js","names":["catalog"],"sources":["../../../../src/runtime/studio-entry.ts"],"sourcesContent":["import { mountStudio } from '#cms/studio'\nimport catalog from '#cms/authoring'\nimport stylesheet from '#cms/studio-styles'\
|
|
1
|
+
{"version":3,"file":"studio-entry.js","names":["catalog"],"sources":["../../../../src/runtime/studio-entry.ts"],"sourcesContent":["import { mountStudio } from '#cms/studio'\nimport catalog from '#cms/authoring'\nimport stylesheet from '#cms/studio-styles'\nimport { resolveStudioRoot, startStudioDocument } from './studio-document'\n\nconst root = resolveStudioRoot(document, window.location.pathname)\n\nconst studio = startStudioDocument(root, catalog, stylesheet, mountStudio)\n\nif (import.meta.hot) {\n import.meta.hot.accept('#cms/authoring', (module) => {\n if (!module) return\n studio.updateAuthoring(module.default)\n })\n import.meta.hot.dispose(studio.unmount)\n}\n"],"mappings":";;;;;;AAKA,MAAM,OAAO,kBAAkB,UAAU,OAAO,SAAS,QAAQ;AAEjE,MAAM,SAAS,oBAAoB,MAAMA,WAAS,YAAY,WAAW;AAEzE,IAAI,YAAY,KAAK;CACnB,YAAY,IAAI,OAAO,mBAAmB,WAAW;EACnD,IAAI,CAAC,QAAQ;EACb,OAAO,gBAAgB,OAAO,OAAO;CACvC,CAAC;CACD,YAAY,IAAI,QAAQ,OAAO,OAAO;AACxC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { d as
|
|
1
|
+
import { d as STUDIO_BASE_PATH } from "../HttpPaths-Be3vshPJ.js";
|
|
2
2
|
import { defineNuxtRouteMiddleware, navigateTo } from "nuxt/app";
|
|
3
3
|
|
|
4
4
|
//#region src/runtime/studio-navigation.ts
|
|
5
5
|
var studio_navigation_default = defineNuxtRouteMiddleware((to) => {
|
|
6
|
-
if (to.path === "/_cms" || to.path
|
|
6
|
+
if (to.path === "/_cms" || to.path.startsWith(`${"/_cms"}/`)) return navigateTo(to.fullPath, { external: true });
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studio-navigation.js","names":[],"sources":["../../../../src/runtime/studio-navigation.ts"],"sourcesContent":["import { defineNuxtRouteMiddleware, navigateTo } from 'nuxt/app'\nimport {
|
|
1
|
+
{"version":3,"file":"studio-navigation.js","names":[],"sources":["../../../../src/runtime/studio-navigation.ts"],"sourcesContent":["import { defineNuxtRouteMiddleware, navigateTo } from 'nuxt/app'\nimport { STUDIO_BASE_PATH } from '@internal/protocol/HttpPaths'\n\nexport default defineNuxtRouteMiddleware((to) => {\n if (to.path === STUDIO_BASE_PATH || to.path.startsWith(`${STUDIO_BASE_PATH}/`)) {\n return navigateTo(to.fullPath, { external: true })\n }\n})\n"],"mappings":";;;;AAGA,gCAAe,2BAA2B,OAAO;CAC/C,IAAI,GAAG,oBAA6B,GAAG,KAAK,WAAW,WAAoB,EAAE,GAC3E,OAAO,WAAW,GAAG,UAAU,EAAE,UAAU,KAAK,CAAC;AAErD,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { o as PublicPath, r as DocumentId } from "./scalars-CVZqT3L0.js";
|
|
2
2
|
import { it as CollectionName, n as CmsMarkdownDocument } from "./models-VmGmG19-.js";
|
|
3
3
|
import { f as mutableJson, p as mutableJsonObject } from "./Forms-CX-hwmJF.js";
|
|
4
|
-
import { n as editorMetadata } from "./metadata-
|
|
4
|
+
import { n as editorMetadata } from "./metadata-DN9_K6Yl.js";
|
|
5
5
|
import { prepareFormDocument } from "./runtime/forms/document.js";
|
|
6
6
|
import { CMS_PREVIEW_EDGE_PROPERTY, CMS_PREVIEW_KIND_PROPERTY, CMS_PREVIEW_MARKER_TAG, CMS_PREVIEW_NODE_PROPERTY } from "./runtime/preview/protocol.js";
|
|
7
7
|
import { toPreviewRenderDocument } from "./runtime/preview/comark-document.js";
|
|
@@ -206,4 +206,4 @@ function createPreviewDocument(body) {
|
|
|
206
206
|
|
|
207
207
|
//#endregion
|
|
208
208
|
export { createStudioPreviewStore as t };
|
|
209
|
-
//# sourceMappingURL=store-
|
|
209
|
+
//# sourceMappingURL=store-X1e1o_MF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-PKKB8xa2.js","names":["CmsMarkdownDocumentSchema"],"sources":["../../../../document/src/PreviewProjection.ts","../../../src/runtime/preview/store.ts"],"sourcesContent":["import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { EditorNodeId } from '@internal/protocol/Documents'\nimport { CmsMarkdownDocument as CmsMarkdownDocumentSchema } from '@internal/protocol/Documents'\nimport { Predicate, Result, Schema } from 'effect'\nimport { mutableJson, mutableJsonObject } from './internal/comark/document-adapter'\nimport { editorMetadata } from './internal/editor/metadata'\n\nexport interface PreviewProjectionMarkers {\n readonly edgeProperty: string\n readonly kindProperty: string\n readonly nodeProperty: string\n readonly tag: string\n}\n\nexport interface PreviewProjection {\n readonly body: CmsMarkdownDocument\n readonly fallbacks: Readonly<Record<string, string>>\n}\n\nexport class PreviewProjectionInvalid extends Schema.TaggedError<PreviewProjectionInvalid>()(\n 'PreviewProjection.Invalid',\n {\n message: Schema.NonEmptyString,\n cause: Schema.Defect(),\n },\n) {}\n\nconst NATIVE_BLOCK_TAGS = new Set([\n 'blockquote',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'img',\n 'li',\n 'math',\n 'ol',\n 'p',\n 'pre',\n 'table',\n 'tbody',\n 'td',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n])\n\nexport function projectPreviewDocument(\n body: CmsMarkdownDocument,\n markers: PreviewProjectionMarkers,\n): Result.Result<PreviewProjection, PreviewProjectionInvalid> {\n return Result.try({\n try: () => projectPreviewDocumentUnsafe(body, markers),\n catch: (cause) =>\n new PreviewProjectionInvalid({\n cause,\n message: cause instanceof Error && cause.message ? cause.message : 'The preview projection is invalid.',\n }),\n })\n}\n\nfunction projectPreviewDocumentUnsafe(body: CmsMarkdownDocument, markers: PreviewProjectionMarkers): PreviewProjection {\n const fallbacks: Record<string, string> = {}\n let identifiedTargets = 0\n\n function cloneNode(\n node: MarkdownNode,\n componentId?: EditorNodeId,\n slotId?: EditorNodeId,\n ): ReadonlyArray<Schema.Json> {\n if (Predicate.isString(node) || node[0] === null) return [mutableJson(node)]\n const [tag, originalAttributes, ...originalChildren] = node\n const isSlot = tag === 'template'\n const isNative = NATIVE_BLOCK_TAGS.has(tag)\n const attributes = mutableJsonObject(originalAttributes)\n const metadata = editorMetadata(attributes)\n const id = metadata?.nodeId\n\n if (id) {\n identifiedTargets++\n const parentId = slotId ?? componentId\n\n if (parentId) fallbacks[id] = parentId\n }\n\n const nextComponentId = !isNative && !isSlot && id ? id : componentId\n\n const implicitSlotId =\n id && metadata?.implicitSlotId && !isNative && !isSlot && hasImplicitDefaultContent(originalChildren)\n ? metadata.implicitSlotId\n : undefined\n\n const children = originalChildren.flatMap((child) => {\n const childSlotId = explicitSlotId(child) ?? (isSlot ? id : implicitSlotId) ?? slotId\n const projected = cloneNode(child, nextComponentId, childSlotId)\n\n return implicitSlotId && !isSlot && !isSlotNode(child)\n ? previewRange(implicitSlotId, 'field', projected, markers)\n : projected\n })\n\n if (id && implicitSlotId) fallbacks[implicitSlotId] = id\n\n if (isSlot && id && componentId) fallbacks[id] = componentId\n\n const cloned: Schema.Json = [tag, attributes, ...children]\n\n if (isSlot && id && componentId) return [[tag, attributes, ...previewRange(id, 'field', children, markers)]]\n\n if (id && isNative) return previewRange(id, 'native', [cloned], markers)\n\n if (id && !isSlot) return previewRange(id, 'component', [cloned], markers)\n\n return [cloned]\n }\n\n const nodes = body.nodes.flatMap((node) => cloneNode(node))\n\n if (body.nodes.length && !identifiedTargets)\n throw new Error('Studio preview requires an identified authoring document.')\n\n return {\n body: CmsMarkdownDocumentSchema.make({\n frontmatter: mutableJsonObject(body.frontmatter),\n meta: mutableJsonObject(body.meta),\n nodes,\n }),\n fallbacks,\n }\n}\n\nfunction previewRange(\n nodeId: EditorNodeId,\n kind: 'component' | 'field' | 'native',\n children: ReadonlyArray<Schema.Json>,\n markers: PreviewProjectionMarkers,\n): ReadonlyArray<Schema.Json> {\n const marker = (edge: 'end' | 'start'): Schema.Json => [\n markers.tag,\n {\n [markers.edgeProperty]: edge,\n [markers.kindProperty]: kind,\n [markers.nodeProperty]: nodeId,\n },\n ]\n\n return [marker('start'), ...children, marker('end')]\n}\n\nfunction explicitSlotId(node: MarkdownNode): EditorNodeId | undefined {\n if (Predicate.isString(node) || node[0] !== 'template') return undefined\n\n return editorMetadata(node[1])?.nodeId\n}\n\nfunction isSlotNode(node: MarkdownNode): boolean {\n return !Predicate.isString(node) && node[0] === 'template'\n}\n\nfunction hasImplicitDefaultContent(nodes: ReadonlyArray<MarkdownNode>): boolean {\n const hasExplicitDefault = nodes.some(\n (node) => Array.isArray(node) && node[0] === 'template' && node[1].name === 'default',\n )\n\n return (\n !hasExplicitDefault && nodes.some((node) => (Predicate.isString(node) ? Boolean(node) : node[0] !== 'template'))\n )\n}\n","import { prepareFormDocument } from '../forms/document'\nimport type { ComponentDefinition } from '@internal/protocol/Configuration'\nimport type { RenderedCompiledDocument, RenderedDocumentManifest } from '@internal/protocol/Preview'\nimport { projectPreviewDocument } from '@internal/document/PreviewProjection'\nimport { CollectionName } from '@internal/protocol/Configuration'\nimport { DocumentId, PublicPath } from '@internal/protocol/Documents'\nimport { Result } from 'effect'\nimport { createComarkContext } from 'comark'\nimport { shallowRef } from 'vue'\nimport type { DeliveryDocument as PreviewCompiledDocument } from '../delivery/types'\nimport type { DocumentPreviewStore, PreviewDocumentRole } from '../delivery/preview'\nimport { toPreviewRenderDocument } from './comark-document'\nimport {\n CMS_PREVIEW_EDGE_PROPERTY,\n CMS_PREVIEW_KIND_PROPERTY,\n CMS_PREVIEW_MARKER_TAG,\n CMS_PREVIEW_NODE_PROPERTY,\n} from './protocol'\n\nexport { documentPreviewStoreKey, type DocumentPreviewStore, type PreviewDocumentRole } from '../delivery/preview'\n\nexport type { DeliveryDocument as PreviewCompiledDocument } from '../delivery/types'\n\nexport interface StudioPreviewStore extends DocumentPreviewStore {\n readonly manifest: () => RenderedDocumentManifest\n readonly patch: (document: PreviewCompiledDocument) => Promise<Readonly<Record<string, string>>>\n readonly routeChanged: () => void\n readonly subscribe: (listener: (manifest: RenderedDocumentManifest) => void) => () => void\n}\n\nexport function createStudioPreviewStore(\n route: () => RenderedDocumentManifest['route'],\n forms: () => ReadonlyArray<ComponentDefinition> = () => [],\n): StudioPreviewStore {\n const context = createComarkContext()\n const patches = shallowRef(new Map<string, PreviewCompiledDocument>())\n\n const registrations = new Map<\n symbol,\n { readonly document: PreviewCompiledDocument; readonly role: PreviewDocumentRole }\n >()\n\n const listeners = new Set<(manifest: RenderedDocumentManifest) => void>()\n\n const manifest = (): RenderedDocumentManifest => ({\n documents: renderedDocuments(registrations.values(), patches.value),\n route: route(),\n })\n\n const notify = (): void => {\n const value = manifest()\n\n for (const listener of listeners) listener(value)\n }\n\n return {\n manifest,\n // oxlint-disable-next-line effecttsgo/async-function -- The Promise contract turns synchronous projection failures into patch rejections for the preview controller.\n async patch(document) {\n const preview = createPreviewDocument(document.body)\n const patched = prepareFormDocument({ ...document, body: preview.body }, forms(), true)\n patches.value = new Map(patches.value).set(document.id, patched)\n const renderBody = toPreviewRenderDocument(patched.body)\n context.get(document.id, renderBody).set(renderBody)\n notify()\n\n return preview.fallbacks\n },\n register(document, role) {\n const registration = Symbol(document.id)\n registrations.set(registration, { document, role })\n notify()\n\n return () => {\n registrations.delete(registration)\n notify()\n }\n },\n resolve(document) {\n return patches.value.get(document.id) ?? document\n },\n routeChanged: notify,\n subscribe(listener) {\n listeners.add(listener)\n listener(manifest())\n\n return () => listeners.delete(listener)\n },\n }\n}\n\nfunction renderedDocuments(\n registrations: Iterable<{ readonly document: PreviewCompiledDocument; readonly role: PreviewDocumentRole }>,\n patches: ReadonlyMap<string, PreviewCompiledDocument>,\n): ReadonlyArray<RenderedCompiledDocument> {\n const priority = { embedded: 1, primary: 4, related: 2, summary: 3 } satisfies Record<PreviewDocumentRole, number>\n const documents = new Map<string, RenderedCompiledDocument>()\n\n for (const registration of registrations) {\n const document = patches.get(registration.document.id) ?? registration.document\n const current = documents.get(document.id)\n\n if (current && priority[current.role] >= priority[registration.role]) continue\n documents.set(document.id, {\n collection: CollectionName.make(document.collection),\n documentId: DocumentId.make(document.id),\n path: PublicPath.make(document.path),\n role: registration.role,\n title: document.title,\n })\n }\n\n return [...documents.values()].sort(\n (left, right) => priority[right.role] - priority[left.role] || left.title.localeCompare(right.title),\n )\n}\n\nfunction createPreviewDocument(body: PreviewCompiledDocument['body']) {\n const projection = projectPreviewDocument(body, {\n edgeProperty: CMS_PREVIEW_EDGE_PROPERTY,\n kindProperty: CMS_PREVIEW_KIND_PROPERTY,\n nodeProperty: CMS_PREVIEW_NODE_PROPERTY,\n tag: CMS_PREVIEW_MARKER_TAG,\n })\n\n if (Result.isFailure(projection)) throw projection.failure\n\n return projection.success\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"store-X1e1o_MF.js","names":["CmsMarkdownDocumentSchema"],"sources":["../../../../document/src/PreviewProjection.ts","../../../src/runtime/preview/store.ts"],"sourcesContent":["import type { CmsMarkdownDocument, MarkdownNode } from '@internal/protocol/Documents'\nimport type { EditorNodeId } from '@internal/protocol/Documents'\nimport { CmsMarkdownDocument as CmsMarkdownDocumentSchema } from '@internal/protocol/Documents'\nimport { Predicate, Result, Schema } from 'effect'\nimport { mutableJson, mutableJsonObject } from './internal/comark/document-adapter'\nimport { editorMetadata } from './internal/editor/metadata'\n\nexport interface PreviewProjectionMarkers {\n readonly edgeProperty: string\n readonly kindProperty: string\n readonly nodeProperty: string\n readonly tag: string\n}\n\nexport interface PreviewProjection {\n readonly body: CmsMarkdownDocument\n readonly fallbacks: Readonly<Record<string, string>>\n}\n\nexport class PreviewProjectionInvalid extends Schema.TaggedError<PreviewProjectionInvalid>()(\n 'PreviewProjection.Invalid',\n {\n message: Schema.NonEmptyString,\n cause: Schema.Defect(),\n },\n) {}\n\nconst NATIVE_BLOCK_TAGS = new Set([\n 'blockquote',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'img',\n 'li',\n 'math',\n 'ol',\n 'p',\n 'pre',\n 'table',\n 'tbody',\n 'td',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n])\n\nexport function projectPreviewDocument(\n body: CmsMarkdownDocument,\n markers: PreviewProjectionMarkers,\n): Result.Result<PreviewProjection, PreviewProjectionInvalid> {\n return Result.try({\n try: () => projectPreviewDocumentUnsafe(body, markers),\n catch: (cause) =>\n new PreviewProjectionInvalid({\n cause,\n message: cause instanceof Error && cause.message ? cause.message : 'The preview projection is invalid.',\n }),\n })\n}\n\nfunction projectPreviewDocumentUnsafe(body: CmsMarkdownDocument, markers: PreviewProjectionMarkers): PreviewProjection {\n const fallbacks: Record<string, string> = {}\n let identifiedTargets = 0\n\n function cloneNode(\n node: MarkdownNode,\n componentId?: EditorNodeId,\n slotId?: EditorNodeId,\n ): ReadonlyArray<Schema.Json> {\n if (Predicate.isString(node) || node[0] === null) return [mutableJson(node)]\n const [tag, originalAttributes, ...originalChildren] = node\n const isSlot = tag === 'template'\n const isNative = NATIVE_BLOCK_TAGS.has(tag)\n const attributes = mutableJsonObject(originalAttributes)\n const metadata = editorMetadata(attributes)\n const id = metadata?.nodeId\n\n if (id) {\n identifiedTargets++\n const parentId = slotId ?? componentId\n\n if (parentId) fallbacks[id] = parentId\n }\n\n const nextComponentId = !isNative && !isSlot && id ? id : componentId\n\n const implicitSlotId =\n id && metadata?.implicitSlotId && !isNative && !isSlot && hasImplicitDefaultContent(originalChildren)\n ? metadata.implicitSlotId\n : undefined\n\n const children = originalChildren.flatMap((child) => {\n const childSlotId = explicitSlotId(child) ?? (isSlot ? id : implicitSlotId) ?? slotId\n const projected = cloneNode(child, nextComponentId, childSlotId)\n\n return implicitSlotId && !isSlot && !isSlotNode(child)\n ? previewRange(implicitSlotId, 'field', projected, markers)\n : projected\n })\n\n if (id && implicitSlotId) fallbacks[implicitSlotId] = id\n\n if (isSlot && id && componentId) fallbacks[id] = componentId\n\n const cloned: Schema.Json = [tag, attributes, ...children]\n\n if (isSlot && id && componentId) return [[tag, attributes, ...previewRange(id, 'field', children, markers)]]\n\n if (id && isNative) return previewRange(id, 'native', [cloned], markers)\n\n if (id && !isSlot) return previewRange(id, 'component', [cloned], markers)\n\n return [cloned]\n }\n\n const nodes = body.nodes.flatMap((node) => cloneNode(node))\n\n if (body.nodes.length && !identifiedTargets)\n throw new Error('Studio preview requires an identified authoring document.')\n\n return {\n body: CmsMarkdownDocumentSchema.make({\n frontmatter: mutableJsonObject(body.frontmatter),\n meta: mutableJsonObject(body.meta),\n nodes,\n }),\n fallbacks,\n }\n}\n\nfunction previewRange(\n nodeId: EditorNodeId,\n kind: 'component' | 'field' | 'native',\n children: ReadonlyArray<Schema.Json>,\n markers: PreviewProjectionMarkers,\n): ReadonlyArray<Schema.Json> {\n const marker = (edge: 'end' | 'start'): Schema.Json => [\n markers.tag,\n {\n [markers.edgeProperty]: edge,\n [markers.kindProperty]: kind,\n [markers.nodeProperty]: nodeId,\n },\n ]\n\n return [marker('start'), ...children, marker('end')]\n}\n\nfunction explicitSlotId(node: MarkdownNode): EditorNodeId | undefined {\n if (Predicate.isString(node) || node[0] !== 'template') return undefined\n\n return editorMetadata(node[1])?.nodeId\n}\n\nfunction isSlotNode(node: MarkdownNode): boolean {\n return !Predicate.isString(node) && node[0] === 'template'\n}\n\nfunction hasImplicitDefaultContent(nodes: ReadonlyArray<MarkdownNode>): boolean {\n const hasExplicitDefault = nodes.some(\n (node) => Array.isArray(node) && node[0] === 'template' && node[1].name === 'default',\n )\n\n return (\n !hasExplicitDefault && nodes.some((node) => (Predicate.isString(node) ? Boolean(node) : node[0] !== 'template'))\n )\n}\n","import { prepareFormDocument } from '../forms/document'\nimport type { ComponentDefinition } from '@internal/protocol/Configuration'\nimport type { RenderedCompiledDocument, RenderedDocumentManifest } from '@internal/protocol/Preview'\nimport { projectPreviewDocument } from '@internal/document/PreviewProjection'\nimport { CollectionName } from '@internal/protocol/Configuration'\nimport { DocumentId, PublicPath } from '@internal/protocol/Documents'\nimport { Result } from 'effect'\nimport { createComarkContext } from 'comark'\nimport { shallowRef } from 'vue'\nimport type { DeliveryDocument as PreviewCompiledDocument } from '../delivery/types'\nimport type { DocumentPreviewStore, PreviewDocumentRole } from '../delivery/preview'\nimport { toPreviewRenderDocument } from './comark-document'\nimport {\n CMS_PREVIEW_EDGE_PROPERTY,\n CMS_PREVIEW_KIND_PROPERTY,\n CMS_PREVIEW_MARKER_TAG,\n CMS_PREVIEW_NODE_PROPERTY,\n} from './protocol'\n\nexport { documentPreviewStoreKey, type DocumentPreviewStore, type PreviewDocumentRole } from '../delivery/preview'\n\nexport type { DeliveryDocument as PreviewCompiledDocument } from '../delivery/types'\n\nexport interface StudioPreviewStore extends DocumentPreviewStore {\n readonly manifest: () => RenderedDocumentManifest\n readonly patch: (document: PreviewCompiledDocument) => Promise<Readonly<Record<string, string>>>\n readonly routeChanged: () => void\n readonly subscribe: (listener: (manifest: RenderedDocumentManifest) => void) => () => void\n}\n\nexport function createStudioPreviewStore(\n route: () => RenderedDocumentManifest['route'],\n forms: () => ReadonlyArray<ComponentDefinition> = () => [],\n): StudioPreviewStore {\n const context = createComarkContext()\n const patches = shallowRef(new Map<string, PreviewCompiledDocument>())\n\n const registrations = new Map<\n symbol,\n { readonly document: PreviewCompiledDocument; readonly role: PreviewDocumentRole }\n >()\n\n const listeners = new Set<(manifest: RenderedDocumentManifest) => void>()\n\n const manifest = (): RenderedDocumentManifest => ({\n documents: renderedDocuments(registrations.values(), patches.value),\n route: route(),\n })\n\n const notify = (): void => {\n const value = manifest()\n\n for (const listener of listeners) listener(value)\n }\n\n return {\n manifest,\n // oxlint-disable-next-line effecttsgo/async-function -- The Promise contract turns synchronous projection failures into patch rejections for the preview controller.\n async patch(document) {\n const preview = createPreviewDocument(document.body)\n const patched = prepareFormDocument({ ...document, body: preview.body }, forms(), true)\n patches.value = new Map(patches.value).set(document.id, patched)\n const renderBody = toPreviewRenderDocument(patched.body)\n context.get(document.id, renderBody).set(renderBody)\n notify()\n\n return preview.fallbacks\n },\n register(document, role) {\n const registration = Symbol(document.id)\n registrations.set(registration, { document, role })\n notify()\n\n return () => {\n registrations.delete(registration)\n notify()\n }\n },\n resolve(document) {\n return patches.value.get(document.id) ?? document\n },\n routeChanged: notify,\n subscribe(listener) {\n listeners.add(listener)\n listener(manifest())\n\n return () => listeners.delete(listener)\n },\n }\n}\n\nfunction renderedDocuments(\n registrations: Iterable<{ readonly document: PreviewCompiledDocument; readonly role: PreviewDocumentRole }>,\n patches: ReadonlyMap<string, PreviewCompiledDocument>,\n): ReadonlyArray<RenderedCompiledDocument> {\n const priority = { embedded: 1, primary: 4, related: 2, summary: 3 } satisfies Record<PreviewDocumentRole, number>\n const documents = new Map<string, RenderedCompiledDocument>()\n\n for (const registration of registrations) {\n const document = patches.get(registration.document.id) ?? registration.document\n const current = documents.get(document.id)\n\n if (current && priority[current.role] >= priority[registration.role]) continue\n documents.set(document.id, {\n collection: CollectionName.make(document.collection),\n documentId: DocumentId.make(document.id),\n path: PublicPath.make(document.path),\n role: registration.role,\n title: document.title,\n })\n }\n\n return [...documents.values()].sort(\n (left, right) => priority[right.role] - priority[left.role] || left.title.localeCompare(right.title),\n )\n}\n\nfunction createPreviewDocument(body: PreviewCompiledDocument['body']) {\n const projection = projectPreviewDocument(body, {\n edgeProperty: CMS_PREVIEW_EDGE_PROPERTY,\n kindProperty: CMS_PREVIEW_KIND_PROPERTY,\n nodeProperty: CMS_PREVIEW_NODE_PROPERTY,\n tag: CMS_PREVIEW_MARKER_TAG,\n })\n\n if (Result.isFailure(projection)) throw projection.failure\n\n return projection.success\n}\n"],"mappings":"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"}
|