@smoothstream/vue 0.1.0 → 0.1.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/base.css CHANGED
@@ -64,6 +64,23 @@
64
64
  }
65
65
  }
66
66
 
67
+ @keyframes smoothstream-code-copy-in {
68
+ from {
69
+ opacity: 0;
70
+ transform: scale(0.9);
71
+ }
72
+ }
73
+
74
+ @keyframes smoothstream-code-block-in {
75
+ from {
76
+ opacity: 0;
77
+ }
78
+
79
+ to {
80
+ opacity: 1;
81
+ }
82
+ }
83
+
67
84
  [data-smoothstream-mode="streaming"][data-smoothstream-motion="animate"] {
68
85
  font-kerning: none;
69
86
  }
@@ -117,17 +134,10 @@
117
134
  }
118
135
 
119
136
  [data-smoothstream-code-copy] {
120
- visibility: hidden;
121
- opacity: 0;
122
- pointer-events: none;
123
- transition: opacity var(--smoothstream-duration, 400ms)
124
- cubic-bezier(0.22, 1, 0.36, 1);
125
- }
126
-
127
- [data-smoothstream-code-copy][data-smoothstream-ready="true"] {
128
- visibility: visible;
129
137
  opacity: 1;
130
- pointer-events: auto;
138
+ animation: smoothstream-code-copy-in
139
+ var(--smoothstream-code-copy-enter-duration, 400ms)
140
+ cubic-bezier(0.22, 1, 0.36, 1) backwards;
131
141
  }
132
142
 
133
143
  /*
@@ -155,6 +165,11 @@ pre[data-smoothstream-code-block] {
155
165
  font-size: inherit;
156
166
  }
157
167
 
168
+ pre[data-smoothstream-code-block][data-smoothstream-code-enter="active"] {
169
+ animation: smoothstream-code-block-in var(--smoothstream-duration, 400ms)
170
+ cubic-bezier(0.22, 1, 0.36, 1) var(--smoothstream-animation-delay, 0ms) both;
171
+ }
172
+
158
173
  [data-smoothstream-code-toolbar] {
159
174
  display: flex;
160
175
  align-items: center;
@@ -173,6 +188,15 @@ pre[data-smoothstream-code-block] {
173
188
  white-space: nowrap;
174
189
  }
175
190
 
191
+ [data-smoothstream-code-copy-slot] {
192
+ display: grid;
193
+ inline-size: var(--smoothstream-code-copy-button-size, max(1.75rem, 1.75em));
194
+ block-size: var(--smoothstream-code-copy-button-size, max(1.75rem, 1.75em));
195
+ flex: 0 0 auto;
196
+ place-items: center;
197
+ pointer-events: none;
198
+ }
199
+
176
200
  [data-smoothstream-code-copy] {
177
201
  display: grid;
178
202
  inline-size: var(--smoothstream-code-copy-button-size, max(1.75rem, 1.75em));
@@ -186,6 +210,7 @@ pre[data-smoothstream-code-block] {
186
210
  color: inherit;
187
211
  cursor: pointer;
188
212
  font: inherit;
213
+ pointer-events: auto;
189
214
  }
190
215
 
191
216
  pre[data-smoothstream-code-block] > code {
@@ -214,14 +239,24 @@ pre[data-smoothstream-code-block][data-smoothstream-code-language-hidden]
214
239
  pointer-events: none;
215
240
  }
216
241
 
242
+ pre[data-smoothstream-code-block][data-smoothstream-code-language-hidden][data-smoothstream-code-single-line]
243
+ [data-smoothstream-code-toolbar] {
244
+ inset-block-start: 50%;
245
+ transform: translateY(-50%);
246
+ }
247
+
217
248
  pre[data-smoothstream-code-block][data-smoothstream-code-language-hidden]
218
249
  [data-smoothstream-code-language] {
219
250
  display: none;
220
251
  }
221
252
 
222
253
  pre[data-smoothstream-code-block][data-smoothstream-code-language-hidden]
223
- [data-smoothstream-code-copy] {
254
+ [data-smoothstream-code-copy-slot] {
224
255
  margin-inline-end: 0;
256
+ }
257
+
258
+ pre[data-smoothstream-code-block][data-smoothstream-code-language-hidden]
259
+ [data-smoothstream-code-copy] {
225
260
  border-radius: var(--smoothstream-code-copy-border-radius, 0.375rem);
226
261
  background-color: var(
227
262
  --smoothstream-code-copy-background,
package/dist/index.js CHANGED
@@ -65,14 +65,6 @@ var vueElementProperties = (node) => {
65
65
  }
66
66
  return result;
67
67
  };
68
- var textContent = (node) => node.type === "text" ? node.value : node.children.map(textContent).join("");
69
- var codeBlockValue = (node) => {
70
- const code = node.children.find(
71
- (child) => child.type === "element" && child.tagName === "code"
72
- );
73
- const value = code ? textContent(code) : "";
74
- return value.endsWith("\n") ? value.slice(0, -1) : value;
75
- };
76
68
  var writeClipboardText = async (button, value) => {
77
69
  const document = button.ownerDocument;
78
70
  const view = document.defaultView;
@@ -137,7 +129,7 @@ var WebCodeBlock = defineComponent({
137
129
  resetTimer = void 0;
138
130
  };
139
131
  watch(
140
- () => codeBlockValue(props.node),
132
+ () => props.node.codeCopyValue,
141
133
  () => {
142
134
  copied.value = false;
143
135
  clearResetTimer();
@@ -150,7 +142,8 @@ var WebCodeBlock = defineComponent({
150
142
  }
151
143
  const button = event.currentTarget;
152
144
  if (!button || button.localName !== "button") return;
153
- const code = codeBlockValue(props.node);
145
+ const code = props.node.codeCopyValue;
146
+ if (code === void 0) return;
154
147
  void writeClipboardText(button, code).then(
155
148
  () => {
156
149
  copied.value = true;
@@ -660,6 +653,7 @@ var Smoothstream = defineComponent2({
660
653
  codeHighlights: codeHighlights.value,
661
654
  compactedBlockIds: presentation.compactedBlockIds,
662
655
  compactedUnitIds: presentation.compactedUnitIds,
656
+ confirmedBlockIds: input.plan.confirmedBlockIds,
663
657
  images: imageReadiness.value,
664
658
  immediate: presentationImmediate(),
665
659
  now,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Smoothstream.ts","../src/render-web.ts"],"sourcesContent":["import \"@smoothstream/styles/base.css\";\nimport \"@smoothstream/styles/styles.css\";\n\nexport { Smoothstream } from \"./Smoothstream\";\nexport type {\n SmoothstreamMode,\n SmoothstreamProps,\n SmoothstreamReducedMotion,\n SmoothstreamReveal,\n} from \"./types\";\nexport type {\n CodeHighlighter,\n CodeHighlightLine,\n CodeHighlightPalette,\n CodeHighlightRequest,\n CodeHighlightResult,\n CodeHighlightToken,\n CodeTokenStyle,\n} from \"@smoothstream/core\";\n","import {\n codeBlockRequestKey,\n resolveCodeHighlight,\n StreamingSession,\n unitsReadyForCodeHighlights,\n type Clock,\n type CodeBlockRequest,\n type CodeHighlighter,\n type ImageDescriptor,\n type ImageReadiness,\n type ResolvedCodeHighlight,\n type StreamingInputSnapshot,\n type StreamingPlaybackSnapshot,\n type StreamingPresentationSnapshot,\n} from \"@smoothstream/core\";\nimport {\n createWebPresentation,\n createWebPresentationCache,\n type WebPresentationCache,\n} from \"@smoothstream/core/web\";\nimport {\n computed,\n defineComponent,\n Fragment,\n h,\n mergeProps,\n nextTick,\n onBeforeUnmount,\n onMounted,\n onUpdated,\n shallowRef,\n Teleport,\n ref,\n watch,\n type PropType,\n type VNode,\n} from \"vue\";\nimport { webNodesToVue } from \"./render-web\";\nimport type {\n SmoothstreamMode,\n SmoothstreamReducedMotion,\n SmoothstreamReveal,\n} from \"./types\";\n\nconst COMPLETION_ANNOUNCEMENT = \"Content ready.\";\nconst REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst PHASE_SELECTOR = \"[data-smoothstream-animation-start]\";\nconst PHASE_PROPERTY = \"--smoothstream-animation-delay\";\n\nconst screenReaderOnlyStyle = {\n border: 0,\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"-1px\",\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n whiteSpace: \"nowrap\",\n width: \"1px\",\n} as const;\n\nconst browserClock: Clock = {\n now: () =>\n typeof window === \"undefined\"\n ? 0\n : window.performance?.now() ?? Date.now(),\n};\n\nconst emptyPlayback = (): StreamingPlaybackSnapshot => ({\n animationComplete: true,\n immediate: false,\n now: 0,\n schedules: new Map(),\n visibleUnitCount: 0,\n});\n\ninterface PendingInput {\n readonly receiving: boolean;\n readonly source: string;\n}\n\ninterface SynchronizedPhase {\n readonly delay: string;\n readonly duration: number;\n readonly startAt: number;\n}\n\nexport const Smoothstream = defineComponent({\n name: \"Smoothstream\",\n inheritAttrs: false,\n props: {\n codeHighlighter: Object as PropType<CodeHighlighter | undefined>,\n duration: {\n default: 1_000,\n type: Number,\n },\n interval: {\n default: 3,\n type: Number,\n },\n markdown: {\n default: \"\",\n type: String,\n },\n mode: {\n default: \"streaming\",\n type: String as PropType<SmoothstreamMode>,\n },\n receiving: {\n default: false,\n type: Boolean,\n },\n reducedMotion: {\n default: \"system\",\n type: String as PropType<SmoothstreamReducedMotion>,\n },\n reveal: {\n default: \"character\",\n type: String as PropType<SmoothstreamReveal>,\n },\n unstyled: {\n default: false,\n type: Boolean,\n },\n },\n setup(props, { attrs }) {\n const root = ref<HTMLDivElement | null>(null);\n const mounted = ref(false);\n const motionDisabled = ref(props.reducedMotion === \"always\");\n const currentInput = shallowRef<StreamingInputSnapshot>();\n const currentPlayback = shallowRef<StreamingPlaybackSnapshot>(\n emptyPlayback(),\n );\n const codeHighlights = shallowRef<ReadonlyMap<number, ResolvedCodeHighlight>>(\n new Map(),\n );\n const imageReadiness = shallowRef<ReadonlyMap<string, ImageReadiness>>(\n new Map(),\n );\n const resourceNow = ref(0);\n const completionAnnouncement = ref(\"\");\n\n let session = new StreamingSession(browserClock, {\n duration: props.duration,\n interval: props.interval,\n });\n let presentationCache: WebPresentationCache = createWebPresentationCache();\n let lastPresentation: StreamingPresentationSnapshot | undefined;\n let requestedSource = props.markdown;\n let pendingInput: PendingInput | undefined = {\n receiving: props.receiving,\n source: props.markdown,\n };\n let inputFrame: number | undefined;\n let playbackFrame: number | undefined;\n let mediaQuery: MediaQueryList | undefined;\n let destroyed = false;\n let announcedSource: string | undefined;\n let completionRendered = false;\n\n const codeRequestsByBlock = new Map<number, string>();\n const codeSessionsByBlock = new Map<number, object>();\n const imageLoaders = new Map<string, HTMLImageElement>();\n const resourceTimers = new Set<number>();\n const synchronizedPhases = new WeakMap<HTMLElement, SynchronizedPhase>();\n let phasedElements = new Set<HTMLElement>();\n\n const resolvedMotion = computed<\"pending\" | \"animate\" | \"none\">(() => {\n if (props.reducedMotion === \"always\") return \"none\";\n if (props.reducedMotion === \"never\") return \"animate\";\n if (!mounted.value) return \"pending\";\n return motionDisabled.value ? \"none\" : \"animate\";\n });\n\n const presentationImmediate = (): boolean =>\n props.mode === \"static\" || resolvedMotion.value === \"none\";\n\n const requestFrame = (callback: FrameRequestCallback): number =>\n typeof window.requestAnimationFrame === \"function\"\n ? window.requestAnimationFrame(callback)\n : window.setTimeout(() => callback(browserClock.now()), 16);\n\n const cancelFrame = (frame: number): void => {\n if (typeof window.cancelAnimationFrame === \"function\") {\n window.cancelAnimationFrame(frame);\n } else {\n window.clearTimeout(frame);\n }\n };\n\n const playbackUnits = (\n input: StreamingInputSnapshot,\n ) => presentationImmediate()\n ? input.plan.units\n : unitsReadyForCodeHighlights(\n input.plan.units,\n props.codeHighlighter,\n codeHighlights.value,\n );\n\n const cancelPlaybackFrame = (): void => {\n if (playbackFrame === undefined || typeof window === \"undefined\") return;\n cancelFrame(playbackFrame);\n playbackFrame = undefined;\n };\n\n const ensurePlaybackFrame = (): void => {\n if (\n destroyed ||\n typeof window === \"undefined\" ||\n presentationImmediate() ||\n currentPlayback.value.animationComplete ||\n playbackFrame !== undefined\n ) {\n return;\n }\n\n playbackFrame = requestFrame(() => {\n playbackFrame = undefined;\n const previous = currentPlayback.value;\n const next = session.advance();\n if (\n next.visibleUnitCount !== previous.visibleUnitCount ||\n (next.animationComplete && !completionRendered)\n ) {\n completionRendered = next.animationComplete;\n currentPlayback.value = next;\n }\n ensurePlaybackFrame();\n });\n };\n\n const refreshPlayback = (input = currentInput.value): void => {\n if (!input) return;\n cancelPlaybackFrame();\n const units = playbackUnits(input);\n if (presentationImmediate()) {\n currentPlayback.value = session.immediate(input, units);\n } else if (mounted.value && resolvedMotion.value === \"animate\") {\n currentPlayback.value = session.schedule(input, units);\n } else {\n currentPlayback.value = emptyPlayback();\n }\n completionRendered = currentPlayback.value.animationComplete;\n ensurePlaybackFrame();\n };\n\n const publishResourceChange = (): void => {\n resourceNow.value = browserClock.now();\n };\n\n const ensureImages = (descriptors: ReadonlyArray<ImageDescriptor>): void => {\n if (\n typeof window === \"undefined\" ||\n presentationImmediate()\n ) {\n return;\n }\n\n for (const descriptor of descriptors) {\n if (\n imageLoaders.has(descriptor.id) ||\n imageReadiness.value.has(descriptor.id)\n ) {\n continue;\n }\n\n let finished = false;\n const finish = (\n status: ImageReadiness[\"status\"],\n image?: HTMLImageElement,\n ): void => {\n if (finished || destroyed) return;\n finished = true;\n imageLoaders.delete(descriptor.id);\n\n const readyAt = browserClock.now();\n const width = image?.naturalWidth ?? 0;\n const height = image?.naturalHeight ?? 0;\n const next = new Map(imageReadiness.value);\n next.set(\n descriptor.id,\n status === \"ready\" && width > 0 && height > 0\n ? { height, readyAt, status, width }\n : { readyAt, status },\n );\n imageReadiness.value = next;\n publishResourceChange();\n\n const timer = window.setTimeout(() => {\n resourceTimers.delete(timer);\n publishResourceChange();\n }, props.duration + 20);\n resourceTimers.add(timer);\n };\n\n if (descriptor.src.length === 0) {\n finish(\"error\");\n continue;\n }\n\n const image = new window.Image();\n imageLoaders.set(descriptor.id, image);\n image.decoding = \"async\";\n image.onerror = () => finish(\"error\");\n let decodeStarted = false;\n const handleLoad = (): void => {\n if (decodeStarted || finished) return;\n decodeStarted = true;\n const decoded = typeof image.decode === \"function\"\n ? image.decode().catch(() => undefined)\n : Promise.resolve();\n void decoded.then(() => finish(\"ready\", image));\n };\n image.onload = handleLoad;\n image.src = descriptor.src;\n if (image.complete && image.naturalWidth > 0) handleLoad();\n }\n };\n\n const commitCodeHighlight = (\n highlighter: CodeHighlighter,\n request: CodeBlockRequest,\n key: string,\n result: Parameters<typeof resolveCodeHighlight>[1],\n ): void => {\n if (\n destroyed ||\n props.codeHighlighter !== highlighter ||\n codeRequestsByBlock.get(request.blockStart) !== key\n ) {\n return;\n }\n\n const next = new Map(codeHighlights.value);\n next.set(\n request.blockStart,\n resolveCodeHighlight(\n request,\n result,\n codeHighlights.value.get(request.blockStart),\n ),\n );\n codeHighlights.value = next;\n refreshPlayback();\n };\n\n const ensureCodeHighlights = (\n requests: ReadonlyArray<CodeBlockRequest>,\n ): void => {\n const highlighter = props.codeHighlighter;\n if (!mounted.value || !highlighter) return;\n\n for (const request of requests) {\n const key = codeBlockRequestKey(request);\n const current = codeHighlights.value.get(request.blockStart);\n if (\n (current?.language === request.language &&\n current.code === request.code) ||\n codeRequestsByBlock.get(request.blockStart) === key\n ) {\n continue;\n }\n codeRequestsByBlock.set(request.blockStart, key);\n let privateSession = codeSessionsByBlock.get(request.blockStart);\n if (!privateSession) {\n privateSession = {};\n codeSessionsByBlock.set(request.blockStart, privateSession);\n }\n\n void Promise.resolve(highlighter.highlight({\n code: request.code,\n language: request.language,\n session: privateSession,\n })).then(\n (result) => commitCodeHighlight(highlighter, request, key, result),\n () => commitCodeHighlight(highlighter, request, key, undefined),\n );\n }\n };\n\n const flushInput = (): void => {\n const pending = pendingInput;\n pendingInput = undefined;\n if (!pending || destroyed) return;\n\n const input = session.prepareInput(\n pending.source,\n pending.receiving,\n props.reveal,\n );\n session.commitInput(input);\n currentInput.value = input;\n if (mounted.value) {\n ensureCodeHighlights(input.codeBlocks);\n ensureImages(input.images);\n }\n refreshPlayback(input);\n };\n\n const scheduleInputFlush = (): void => {\n if (!mounted.value || typeof window === \"undefined\") {\n flushInput();\n return;\n }\n if (inputFrame !== undefined) return;\n inputFrame = requestFrame(() => {\n inputFrame = undefined;\n flushInput();\n });\n };\n\n const clearResourceWork = (): void => {\n for (const image of imageLoaders.values()) {\n image.onload = null;\n image.onerror = null;\n }\n imageLoaders.clear();\n if (typeof window !== \"undefined\") {\n for (const timer of resourceTimers) window.clearTimeout(timer);\n }\n resourceTimers.clear();\n };\n\n const resetSession = (): void => {\n if (typeof window !== \"undefined\") {\n if (inputFrame !== undefined) cancelFrame(inputFrame);\n inputFrame = undefined;\n cancelPlaybackFrame();\n }\n clearResourceWork();\n codeRequestsByBlock.clear();\n codeSessionsByBlock.clear();\n codeHighlights.value = new Map();\n imageReadiness.value = new Map();\n resourceNow.value = 0;\n presentationCache = createWebPresentationCache();\n session = new StreamingSession(browserClock, {\n duration: props.duration,\n interval: props.interval,\n });\n requestedSource = props.markdown;\n pendingInput = {\n receiving: props.receiving,\n source: props.markdown,\n };\n announcedSource = undefined;\n completionAnnouncement.value = \"\";\n flushInput();\n };\n\n function handleMotionChange(event: MediaQueryListEvent): void {\n if (!event.matches || motionDisabled.value) return;\n motionDisabled.value = true;\n refreshPlayback();\n }\n\n const removeMediaListener = (): void => {\n if (!mediaQuery) return;\n if (typeof mediaQuery.removeEventListener === \"function\") {\n mediaQuery.removeEventListener(\"change\", handleMotionChange);\n } else {\n mediaQuery.removeListener?.(handleMotionChange);\n }\n mediaQuery = undefined;\n };\n\n const configureMotion = (): void => {\n removeMediaListener();\n if (\n !mounted.value ||\n typeof window === \"undefined\" ||\n props.reducedMotion !== \"system\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return;\n }\n mediaQuery = window.matchMedia(REDUCED_MOTION_QUERY);\n if (mediaQuery.matches) motionDisabled.value = true;\n if (typeof mediaQuery.addEventListener === \"function\") {\n mediaQuery.addEventListener(\"change\", handleMotionChange);\n } else {\n mediaQuery.addListener?.(handleMotionChange);\n }\n };\n\n const synchronizeAnimationPhases = (): void => {\n const element = root.value;\n if (!element) return;\n const now = browserClock.now();\n const nextElements = new Set<HTMLElement>();\n for (const animated of element.querySelectorAll<HTMLElement>(PHASE_SELECTOR)) {\n nextElements.add(animated);\n const startAt = Number(animated.dataset.smoothstreamAnimationStart);\n const duration = Number(animated.dataset.smoothstreamAnimationDuration);\n if (!Number.isFinite(startAt) || !Number.isFinite(duration)) continue;\n\n const synchronized = synchronizedPhases.get(animated);\n if (\n synchronized?.startAt === startAt &&\n synchronized.duration === duration\n ) {\n animated.style.setProperty(PHASE_PROPERTY, synchronized.delay);\n continue;\n }\n const currentTime = Math.max(0, Math.min(duration, now - startAt));\n const delay = String(-currentTime) + \"ms\";\n animated.style.setProperty(PHASE_PROPERTY, delay);\n synchronizedPhases.set(animated, { delay, duration, startAt });\n }\n\n for (const previous of phasedElements) {\n if (!nextElements.has(previous)) {\n previous.style.removeProperty(PHASE_PROPERTY);\n if (previous.style.length === 0) previous.removeAttribute(\"style\");\n }\n }\n phasedElements = nextElements;\n };\n\n const publishCompletionIfReady = (): void => {\n const input = currentInput.value;\n const presentation = lastPresentation;\n const element = root.value;\n if (\n props.mode !== \"streaming\" ||\n !mounted.value ||\n !input ||\n !presentation ||\n !element\n ) {\n return;\n }\n if (input.inputOpen) completionAnnouncement.value = \"\";\n if (\n input.inputOpen ||\n input.plan.tree.children.length === 0 ||\n !presentation.allPlannedUnitsCompacted ||\n element.querySelector(\"[data-smoothstream-unit]\") !== null ||\n announcedSource === input.source\n ) {\n return;\n }\n announcedSource = input.source;\n completionAnnouncement.value = COMPLETION_ANNOUNCEMENT;\n };\n\n const afterRender = (): void => {\n synchronizeAnimationPhases();\n publishCompletionIfReady();\n };\n\n watch(\n () => [props.markdown, props.receiving] as const,\n ([source, receiving]) => {\n if (!source.startsWith(requestedSource)) {\n throw new Error(\n \"Smoothstream Markdown must be append-only. Give a different response a new Vue key.\",\n );\n }\n requestedSource = source;\n pendingInput = { receiving, source };\n if (receiving || announcedSource !== source) {\n announcedSource = undefined;\n completionAnnouncement.value = \"\";\n }\n scheduleInputFlush();\n },\n { flush: \"sync\" },\n );\n\n watch(\n () => [props.duration, props.interval, props.mode, props.reveal] as const,\n resetSession,\n { flush: \"sync\" },\n );\n\n watch(\n () => props.codeHighlighter,\n () => {\n codeRequestsByBlock.clear();\n codeSessionsByBlock.clear();\n codeHighlights.value = new Map();\n const input = currentInput.value;\n if (input) ensureCodeHighlights(input.codeBlocks);\n refreshPlayback(input);\n },\n { flush: \"sync\" },\n );\n\n watch(\n () => props.reducedMotion,\n () => {\n configureMotion();\n const input = currentInput.value;\n if (input && !presentationImmediate()) ensureImages(input.images);\n refreshPlayback(input);\n },\n { flush: \"sync\" },\n );\n\n flushInput();\n\n onMounted(() => {\n mounted.value = true;\n configureMotion();\n const input = currentInput.value;\n if (input) {\n ensureCodeHighlights(input.codeBlocks);\n ensureImages(input.images);\n refreshPlayback(input);\n }\n void nextTick(afterRender);\n });\n\n onUpdated(afterRender);\n\n onBeforeUnmount(() => {\n destroyed = true;\n removeMediaListener();\n if (typeof window !== \"undefined\") {\n if (inputFrame !== undefined) cancelFrame(inputFrame);\n cancelPlaybackFrame();\n }\n clearResourceWork();\n codeRequestsByBlock.clear();\n codeSessionsByBlock.clear();\n });\n\n const renderContent = (): VNode[] => {\n const input = currentInput.value;\n if (\n !input ||\n (props.mode === \"streaming\" && resolvedMotion.value === \"pending\")\n ) {\n lastPresentation = undefined;\n return [];\n }\n const playback = currentPlayback.value;\n const now = Math.max(playback.now, resourceNow.value);\n const presentation = session.present(input, playback, { now });\n lastPresentation = presentation;\n return webNodesToVue(createWebPresentation({\n cache: presentationCache,\n codeHighlighterEnabled: props.codeHighlighter !== undefined,\n codeHighlights: codeHighlights.value,\n compactedBlockIds: presentation.compactedBlockIds,\n compactedUnitIds: presentation.compactedUnitIds,\n images: imageReadiness.value,\n immediate: presentationImmediate(),\n now,\n reveal: input.reveal,\n schedules: presentation.schedules,\n showLanguageLabels: props.codeHighlighter?.showLanguageLabels !== false,\n tree: input.plan.tree,\n units: input.plan.units,\n }));\n };\n\n return () => {\n const motion = props.mode === \"streaming\" &&\n resolvedMotion.value === \"pending\"\n ? \"pending\"\n : resolvedMotion.value === \"none\"\n ? \"none\"\n : \"animate\";\n const rootNode = h(\n \"div\",\n mergeProps(attrs, {\n \"data-smoothstream\": true,\n \"data-smoothstream-mode\": props.mode,\n \"data-smoothstream-motion\": motion,\n \"data-smoothstream-reduced-motion\": props.reducedMotion,\n \"data-smoothstream-reveal\": props.reveal,\n \"data-smoothstream-theme\": props.unstyled ? undefined : \"default\",\n ref: root,\n style: {\n \"--smoothstream-duration\":\n String(resolvedMotion.value === \"none\" ? 0 : props.duration) +\n \"ms\",\n \"--smoothstream-interval\":\n String(resolvedMotion.value === \"none\" ? 0 : props.interval) +\n \"ms\",\n },\n }),\n renderContent(),\n );\n const announcer = props.mode === \"streaming\" && mounted.value\n ? h(Teleport, { to: \"body\" }, h(\"div\", {\n \"aria-atomic\": true,\n \"aria-live\": \"polite\",\n \"data-smoothstream-announcer\": true,\n role: \"status\",\n style: screenReaderOnlyStyle,\n }, completionAnnouncement.value))\n : null;\n return h(Fragment, null, [rootNode, announcer]);\n };\n },\n});\n","import { find, html, svg } from \"property-information\";\nimport {\n defineComponent,\n createTextVNode,\n h,\n onBeforeUnmount,\n ref,\n watch,\n type PropType,\n type VNode,\n} from \"vue\";\nimport type {\n WebElementNode,\n WebProperties,\n WebRenderNode,\n} from \"@smoothstream/core/web\";\n\ninterface VuePropertyInfo {\n readonly commaSeparated: boolean;\n readonly name: string;\n}\n\ninterface CopyContext {\n readonly copied: boolean;\n readonly copy: (event: MouseEvent) => void;\n}\n\nconst htmlPropertyInfoByName = new Map<string, VuePropertyInfo>();\nconst svgPropertyInfoByName = new Map<string, VuePropertyInfo>();\nconst tableContainers = new Set([\"table\", \"tbody\", \"tfoot\", \"thead\", \"tr\"]);\n\nconst vuePropertyInfo = (\n property: string,\n namespace: \"svg\" | undefined,\n): VuePropertyInfo => {\n const cache = namespace === \"svg\"\n ? svgPropertyInfoByName\n : htmlPropertyInfoByName;\n const cached = cache.get(property);\n if (cached) return cached;\n\n const information = find(namespace === \"svg\" ? svg : html, property);\n const result = {\n commaSeparated: information.commaSeparated,\n name: information.attribute,\n };\n cache.set(property, result);\n return result;\n};\n\nconst vueElementProperties = (\n node: WebElementNode,\n): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [property, originalValue] of Object.entries(node.properties)) {\n if (\n property === \"children\" ||\n originalValue === null ||\n originalValue === undefined ||\n (typeof originalValue === \"number\" && Number.isNaN(originalValue))\n ) {\n continue;\n }\n\n const information = vuePropertyInfo(property, node.namespace);\n result[information.name] = Array.isArray(originalValue)\n ? originalValue\n .map(String)\n .join(information.commaSeparated ? \", \" : \" \")\n .trim()\n : originalValue;\n }\n return result;\n};\n\nconst textContent = (node: WebRenderNode): string =>\n node.type === \"text\"\n ? node.value\n : node.children.map(textContent).join(\"\");\n\nconst codeBlockValue = (node: WebElementNode): string => {\n const code = node.children.find(\n (child): child is WebElementNode =>\n child.type === \"element\" && child.tagName === \"code\",\n );\n const value = code ? textContent(code) : \"\";\n return value.endsWith(\"\\n\") ? value.slice(0, -1) : value;\n};\n\nconst writeClipboardText = async (\n button: HTMLButtonElement,\n value: string,\n): Promise<void> => {\n const document = button.ownerDocument;\n const view = document.defaultView;\n if (!view) throw new Error(\"Clipboard copy requires a browser window.\");\n\n if (view.navigator.clipboard?.writeText) {\n await view.navigator.clipboard.writeText(value);\n return;\n }\n\n const textarea = document.createElement(\"textarea\");\n textarea.value = value;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"fixed\";\n textarea.style.opacity = \"0\";\n document.body.append(textarea);\n textarea.select();\n const copied = document.execCommand?.(\"copy\") === true;\n textarea.remove();\n if (!copied) throw new Error(\"Clipboard copy is unavailable.\");\n};\n\nconst webChildrenToVue = (\n children: ReadonlyArray<WebRenderNode>,\n filterTableWhitespace: boolean,\n copyContext?: CopyContext,\n): VNode[] => children.flatMap((child) => {\n if (\n filterTableWhitespace &&\n child.type === \"text\" &&\n /^\\s*$/u.test(child.value)\n ) {\n return [];\n }\n return [webNodeToVue(child, copyContext)];\n});\n\nconst webElementToVue = (\n node: WebElementNode,\n copyContext?: CopyContext,\n): VNode => {\n const properties = vueElementProperties(node);\n if (copyContext) {\n if (node.properties[\"data-smoothstream-code-copy\"] === true) {\n properties.onClick = copyContext.copy;\n if (copyContext.copied) properties[\"aria-label\"] = \"Code copied\";\n }\n if (node.properties[\"data-smoothstream-code-icon-swap\"] === true) {\n properties[\"data-state\"] = copyContext.copied ? \"check\" : \"copy\";\n }\n }\n\n return h(\n node.tagName,\n { ...properties, key: node.key },\n webChildrenToVue(\n node.children,\n tableContainers.has(node.tagName),\n copyContext,\n ),\n );\n};\n\nconst WebCodeBlock = defineComponent({\n name: \"SmoothstreamCodeBlock\",\n props: {\n node: {\n required: true,\n type: Object as PropType<WebElementNode>,\n },\n },\n setup(props) {\n const copied = ref(false);\n let resetTimer: number | undefined;\n\n const clearResetTimer = (): void => {\n if (resetTimer === undefined) return;\n const view = typeof window === \"undefined\" ? undefined : window;\n view?.clearTimeout(resetTimer);\n resetTimer = undefined;\n };\n\n watch(\n () => codeBlockValue(props.node),\n () => {\n copied.value = false;\n clearResetTimer();\n },\n );\n\n onBeforeUnmount(clearResetTimer);\n\n const copy = (event: MouseEvent): void => {\n if (props.node.properties[\"data-smoothstream-code-copy-ready\"] !== true) {\n return;\n }\n const button = event.currentTarget as HTMLButtonElement | null;\n if (!button || button.localName !== \"button\") return;\n const code = codeBlockValue(props.node);\n void writeClipboardText(button, code).then(\n () => {\n copied.value = true;\n clearResetTimer();\n const view = button.ownerDocument.defaultView;\n if (!view) return;\n resetTimer = view.setTimeout(() => {\n copied.value = false;\n resetTimer = undefined;\n }, 2_000);\n },\n () => {\n copied.value = false;\n },\n );\n };\n\n return () => webElementToVue(props.node, {\n copied: copied.value,\n copy,\n });\n },\n});\n\nconst webNodeToVue = (\n node: WebRenderNode,\n copyContext?: CopyContext,\n): VNode => {\n if (node.type === \"text\") {\n const text = createTextVNode(node.value);\n text.key = node.key;\n return text;\n }\n if (\n !copyContext &&\n node.tagName === \"pre\" &&\n node.properties[\"data-smoothstream-code-block\"] === true\n ) {\n return h(WebCodeBlock, { key: node.key, node });\n }\n return webElementToVue(node, copyContext);\n};\n\nexport const webNodesToVue = (\n nodes: ReadonlyArray<WebRenderNode>,\n): VNode[] => nodes.map((node) => webNodeToVue(node));\n\nexport type { WebProperties };\n"],"mappings":"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","names":["defineComponent","h","onBeforeUnmount","ref","watch","defineComponent","ref","image","watch","onBeforeUnmount","h"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Smoothstream.ts","../src/render-web.ts"],"sourcesContent":["import \"@smoothstream/styles/base.css\";\nimport \"@smoothstream/styles/styles.css\";\n\nexport { Smoothstream } from \"./Smoothstream\";\nexport type {\n SmoothstreamMode,\n SmoothstreamProps,\n SmoothstreamReducedMotion,\n SmoothstreamReveal,\n} from \"./types\";\nexport type {\n CodeHighlighter,\n CodeHighlightLine,\n CodeHighlightPalette,\n CodeHighlightRequest,\n CodeHighlightResult,\n CodeHighlightToken,\n CodeTokenStyle,\n} from \"@smoothstream/core\";\n","import {\n codeBlockRequestKey,\n resolveCodeHighlight,\n StreamingSession,\n unitsReadyForCodeHighlights,\n type Clock,\n type CodeBlockRequest,\n type CodeHighlighter,\n type ImageDescriptor,\n type ImageReadiness,\n type ResolvedCodeHighlight,\n type StreamingInputSnapshot,\n type StreamingPlaybackSnapshot,\n type StreamingPresentationSnapshot,\n} from \"@smoothstream/core\";\nimport {\n createWebPresentation,\n createWebPresentationCache,\n type WebPresentationCache,\n} from \"@smoothstream/core/web\";\nimport {\n computed,\n defineComponent,\n Fragment,\n h,\n mergeProps,\n nextTick,\n onBeforeUnmount,\n onMounted,\n onUpdated,\n shallowRef,\n Teleport,\n ref,\n watch,\n type PropType,\n type VNode,\n} from \"vue\";\nimport { webNodesToVue } from \"./render-web\";\nimport type {\n SmoothstreamMode,\n SmoothstreamReducedMotion,\n SmoothstreamReveal,\n} from \"./types\";\n\nconst COMPLETION_ANNOUNCEMENT = \"Content ready.\";\nconst REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\nconst PHASE_SELECTOR = \"[data-smoothstream-animation-start]\";\nconst PHASE_PROPERTY = \"--smoothstream-animation-delay\";\n\nconst screenReaderOnlyStyle = {\n border: 0,\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"-1px\",\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n whiteSpace: \"nowrap\",\n width: \"1px\",\n} as const;\n\nconst browserClock: Clock = {\n now: () =>\n typeof window === \"undefined\"\n ? 0\n : window.performance?.now() ?? Date.now(),\n};\n\nconst emptyPlayback = (): StreamingPlaybackSnapshot => ({\n animationComplete: true,\n immediate: false,\n now: 0,\n schedules: new Map(),\n visibleUnitCount: 0,\n});\n\ninterface PendingInput {\n readonly receiving: boolean;\n readonly source: string;\n}\n\ninterface SynchronizedPhase {\n readonly delay: string;\n readonly duration: number;\n readonly startAt: number;\n}\n\nexport const Smoothstream = defineComponent({\n name: \"Smoothstream\",\n inheritAttrs: false,\n props: {\n codeHighlighter: Object as PropType<CodeHighlighter | undefined>,\n duration: {\n default: 1_000,\n type: Number,\n },\n interval: {\n default: 3,\n type: Number,\n },\n markdown: {\n default: \"\",\n type: String,\n },\n mode: {\n default: \"streaming\",\n type: String as PropType<SmoothstreamMode>,\n },\n receiving: {\n default: false,\n type: Boolean,\n },\n reducedMotion: {\n default: \"system\",\n type: String as PropType<SmoothstreamReducedMotion>,\n },\n reveal: {\n default: \"character\",\n type: String as PropType<SmoothstreamReveal>,\n },\n unstyled: {\n default: false,\n type: Boolean,\n },\n },\n setup(props, { attrs }) {\n const root = ref<HTMLDivElement | null>(null);\n const mounted = ref(false);\n const motionDisabled = ref(props.reducedMotion === \"always\");\n const currentInput = shallowRef<StreamingInputSnapshot>();\n const currentPlayback = shallowRef<StreamingPlaybackSnapshot>(\n emptyPlayback(),\n );\n const codeHighlights = shallowRef<ReadonlyMap<number, ResolvedCodeHighlight>>(\n new Map(),\n );\n const imageReadiness = shallowRef<ReadonlyMap<string, ImageReadiness>>(\n new Map(),\n );\n const resourceNow = ref(0);\n const completionAnnouncement = ref(\"\");\n\n let session = new StreamingSession(browserClock, {\n duration: props.duration,\n interval: props.interval,\n });\n let presentationCache: WebPresentationCache = createWebPresentationCache();\n let lastPresentation: StreamingPresentationSnapshot | undefined;\n let requestedSource = props.markdown;\n let pendingInput: PendingInput | undefined = {\n receiving: props.receiving,\n source: props.markdown,\n };\n let inputFrame: number | undefined;\n let playbackFrame: number | undefined;\n let mediaQuery: MediaQueryList | undefined;\n let destroyed = false;\n let announcedSource: string | undefined;\n let completionRendered = false;\n\n const codeRequestsByBlock = new Map<number, string>();\n const codeSessionsByBlock = new Map<number, object>();\n const imageLoaders = new Map<string, HTMLImageElement>();\n const resourceTimers = new Set<number>();\n const synchronizedPhases = new WeakMap<HTMLElement, SynchronizedPhase>();\n let phasedElements = new Set<HTMLElement>();\n\n const resolvedMotion = computed<\"pending\" | \"animate\" | \"none\">(() => {\n if (props.reducedMotion === \"always\") return \"none\";\n if (props.reducedMotion === \"never\") return \"animate\";\n if (!mounted.value) return \"pending\";\n return motionDisabled.value ? \"none\" : \"animate\";\n });\n\n const presentationImmediate = (): boolean =>\n props.mode === \"static\" || resolvedMotion.value === \"none\";\n\n const requestFrame = (callback: FrameRequestCallback): number =>\n typeof window.requestAnimationFrame === \"function\"\n ? window.requestAnimationFrame(callback)\n : window.setTimeout(() => callback(browserClock.now()), 16);\n\n const cancelFrame = (frame: number): void => {\n if (typeof window.cancelAnimationFrame === \"function\") {\n window.cancelAnimationFrame(frame);\n } else {\n window.clearTimeout(frame);\n }\n };\n\n const playbackUnits = (\n input: StreamingInputSnapshot,\n ) => presentationImmediate()\n ? input.plan.units\n : unitsReadyForCodeHighlights(\n input.plan.units,\n props.codeHighlighter,\n codeHighlights.value,\n );\n\n const cancelPlaybackFrame = (): void => {\n if (playbackFrame === undefined || typeof window === \"undefined\") return;\n cancelFrame(playbackFrame);\n playbackFrame = undefined;\n };\n\n const ensurePlaybackFrame = (): void => {\n if (\n destroyed ||\n typeof window === \"undefined\" ||\n presentationImmediate() ||\n currentPlayback.value.animationComplete ||\n playbackFrame !== undefined\n ) {\n return;\n }\n\n playbackFrame = requestFrame(() => {\n playbackFrame = undefined;\n const previous = currentPlayback.value;\n const next = session.advance();\n if (\n next.visibleUnitCount !== previous.visibleUnitCount ||\n (next.animationComplete && !completionRendered)\n ) {\n completionRendered = next.animationComplete;\n currentPlayback.value = next;\n }\n ensurePlaybackFrame();\n });\n };\n\n const refreshPlayback = (input = currentInput.value): void => {\n if (!input) return;\n cancelPlaybackFrame();\n const units = playbackUnits(input);\n if (presentationImmediate()) {\n currentPlayback.value = session.immediate(input, units);\n } else if (mounted.value && resolvedMotion.value === \"animate\") {\n currentPlayback.value = session.schedule(input, units);\n } else {\n currentPlayback.value = emptyPlayback();\n }\n completionRendered = currentPlayback.value.animationComplete;\n ensurePlaybackFrame();\n };\n\n const publishResourceChange = (): void => {\n resourceNow.value = browserClock.now();\n };\n\n const ensureImages = (descriptors: ReadonlyArray<ImageDescriptor>): void => {\n if (\n typeof window === \"undefined\" ||\n presentationImmediate()\n ) {\n return;\n }\n\n for (const descriptor of descriptors) {\n if (\n imageLoaders.has(descriptor.id) ||\n imageReadiness.value.has(descriptor.id)\n ) {\n continue;\n }\n\n let finished = false;\n const finish = (\n status: ImageReadiness[\"status\"],\n image?: HTMLImageElement,\n ): void => {\n if (finished || destroyed) return;\n finished = true;\n imageLoaders.delete(descriptor.id);\n\n const readyAt = browserClock.now();\n const width = image?.naturalWidth ?? 0;\n const height = image?.naturalHeight ?? 0;\n const next = new Map(imageReadiness.value);\n next.set(\n descriptor.id,\n status === \"ready\" && width > 0 && height > 0\n ? { height, readyAt, status, width }\n : { readyAt, status },\n );\n imageReadiness.value = next;\n publishResourceChange();\n\n const timer = window.setTimeout(() => {\n resourceTimers.delete(timer);\n publishResourceChange();\n }, props.duration + 20);\n resourceTimers.add(timer);\n };\n\n if (descriptor.src.length === 0) {\n finish(\"error\");\n continue;\n }\n\n const image = new window.Image();\n imageLoaders.set(descriptor.id, image);\n image.decoding = \"async\";\n image.onerror = () => finish(\"error\");\n let decodeStarted = false;\n const handleLoad = (): void => {\n if (decodeStarted || finished) return;\n decodeStarted = true;\n const decoded = typeof image.decode === \"function\"\n ? image.decode().catch(() => undefined)\n : Promise.resolve();\n void decoded.then(() => finish(\"ready\", image));\n };\n image.onload = handleLoad;\n image.src = descriptor.src;\n if (image.complete && image.naturalWidth > 0) handleLoad();\n }\n };\n\n const commitCodeHighlight = (\n highlighter: CodeHighlighter,\n request: CodeBlockRequest,\n key: string,\n result: Parameters<typeof resolveCodeHighlight>[1],\n ): void => {\n if (\n destroyed ||\n props.codeHighlighter !== highlighter ||\n codeRequestsByBlock.get(request.blockStart) !== key\n ) {\n return;\n }\n\n const next = new Map(codeHighlights.value);\n next.set(\n request.blockStart,\n resolveCodeHighlight(\n request,\n result,\n codeHighlights.value.get(request.blockStart),\n ),\n );\n codeHighlights.value = next;\n refreshPlayback();\n };\n\n const ensureCodeHighlights = (\n requests: ReadonlyArray<CodeBlockRequest>,\n ): void => {\n const highlighter = props.codeHighlighter;\n if (!mounted.value || !highlighter) return;\n\n for (const request of requests) {\n const key = codeBlockRequestKey(request);\n const current = codeHighlights.value.get(request.blockStart);\n if (\n (current?.language === request.language &&\n current.code === request.code) ||\n codeRequestsByBlock.get(request.blockStart) === key\n ) {\n continue;\n }\n codeRequestsByBlock.set(request.blockStart, key);\n let privateSession = codeSessionsByBlock.get(request.blockStart);\n if (!privateSession) {\n privateSession = {};\n codeSessionsByBlock.set(request.blockStart, privateSession);\n }\n\n void Promise.resolve(highlighter.highlight({\n code: request.code,\n language: request.language,\n session: privateSession,\n })).then(\n (result) => commitCodeHighlight(highlighter, request, key, result),\n () => commitCodeHighlight(highlighter, request, key, undefined),\n );\n }\n };\n\n const flushInput = (): void => {\n const pending = pendingInput;\n pendingInput = undefined;\n if (!pending || destroyed) return;\n\n const input = session.prepareInput(\n pending.source,\n pending.receiving,\n props.reveal,\n );\n session.commitInput(input);\n currentInput.value = input;\n if (mounted.value) {\n ensureCodeHighlights(input.codeBlocks);\n ensureImages(input.images);\n }\n refreshPlayback(input);\n };\n\n const scheduleInputFlush = (): void => {\n if (!mounted.value || typeof window === \"undefined\") {\n flushInput();\n return;\n }\n if (inputFrame !== undefined) return;\n inputFrame = requestFrame(() => {\n inputFrame = undefined;\n flushInput();\n });\n };\n\n const clearResourceWork = (): void => {\n for (const image of imageLoaders.values()) {\n image.onload = null;\n image.onerror = null;\n }\n imageLoaders.clear();\n if (typeof window !== \"undefined\") {\n for (const timer of resourceTimers) window.clearTimeout(timer);\n }\n resourceTimers.clear();\n };\n\n const resetSession = (): void => {\n if (typeof window !== \"undefined\") {\n if (inputFrame !== undefined) cancelFrame(inputFrame);\n inputFrame = undefined;\n cancelPlaybackFrame();\n }\n clearResourceWork();\n codeRequestsByBlock.clear();\n codeSessionsByBlock.clear();\n codeHighlights.value = new Map();\n imageReadiness.value = new Map();\n resourceNow.value = 0;\n presentationCache = createWebPresentationCache();\n session = new StreamingSession(browserClock, {\n duration: props.duration,\n interval: props.interval,\n });\n requestedSource = props.markdown;\n pendingInput = {\n receiving: props.receiving,\n source: props.markdown,\n };\n announcedSource = undefined;\n completionAnnouncement.value = \"\";\n flushInput();\n };\n\n function handleMotionChange(event: MediaQueryListEvent): void {\n if (!event.matches || motionDisabled.value) return;\n motionDisabled.value = true;\n refreshPlayback();\n }\n\n const removeMediaListener = (): void => {\n if (!mediaQuery) return;\n if (typeof mediaQuery.removeEventListener === \"function\") {\n mediaQuery.removeEventListener(\"change\", handleMotionChange);\n } else {\n mediaQuery.removeListener?.(handleMotionChange);\n }\n mediaQuery = undefined;\n };\n\n const configureMotion = (): void => {\n removeMediaListener();\n if (\n !mounted.value ||\n typeof window === \"undefined\" ||\n props.reducedMotion !== \"system\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return;\n }\n mediaQuery = window.matchMedia(REDUCED_MOTION_QUERY);\n if (mediaQuery.matches) motionDisabled.value = true;\n if (typeof mediaQuery.addEventListener === \"function\") {\n mediaQuery.addEventListener(\"change\", handleMotionChange);\n } else {\n mediaQuery.addListener?.(handleMotionChange);\n }\n };\n\n const synchronizeAnimationPhases = (): void => {\n const element = root.value;\n if (!element) return;\n const now = browserClock.now();\n const nextElements = new Set<HTMLElement>();\n for (const animated of element.querySelectorAll<HTMLElement>(PHASE_SELECTOR)) {\n nextElements.add(animated);\n const startAt = Number(animated.dataset.smoothstreamAnimationStart);\n const duration = Number(animated.dataset.smoothstreamAnimationDuration);\n if (!Number.isFinite(startAt) || !Number.isFinite(duration)) continue;\n\n const synchronized = synchronizedPhases.get(animated);\n if (\n synchronized?.startAt === startAt &&\n synchronized.duration === duration\n ) {\n animated.style.setProperty(PHASE_PROPERTY, synchronized.delay);\n continue;\n }\n const currentTime = Math.max(0, Math.min(duration, now - startAt));\n const delay = String(-currentTime) + \"ms\";\n animated.style.setProperty(PHASE_PROPERTY, delay);\n synchronizedPhases.set(animated, { delay, duration, startAt });\n }\n\n for (const previous of phasedElements) {\n if (!nextElements.has(previous)) {\n previous.style.removeProperty(PHASE_PROPERTY);\n if (previous.style.length === 0) previous.removeAttribute(\"style\");\n }\n }\n phasedElements = nextElements;\n };\n\n const publishCompletionIfReady = (): void => {\n const input = currentInput.value;\n const presentation = lastPresentation;\n const element = root.value;\n if (\n props.mode !== \"streaming\" ||\n !mounted.value ||\n !input ||\n !presentation ||\n !element\n ) {\n return;\n }\n if (input.inputOpen) completionAnnouncement.value = \"\";\n if (\n input.inputOpen ||\n input.plan.tree.children.length === 0 ||\n !presentation.allPlannedUnitsCompacted ||\n element.querySelector(\"[data-smoothstream-unit]\") !== null ||\n announcedSource === input.source\n ) {\n return;\n }\n announcedSource = input.source;\n completionAnnouncement.value = COMPLETION_ANNOUNCEMENT;\n };\n\n const afterRender = (): void => {\n synchronizeAnimationPhases();\n publishCompletionIfReady();\n };\n\n watch(\n () => [props.markdown, props.receiving] as const,\n ([source, receiving]) => {\n if (!source.startsWith(requestedSource)) {\n throw new Error(\n \"Smoothstream Markdown must be append-only. Give a different response a new Vue key.\",\n );\n }\n requestedSource = source;\n pendingInput = { receiving, source };\n if (receiving || announcedSource !== source) {\n announcedSource = undefined;\n completionAnnouncement.value = \"\";\n }\n scheduleInputFlush();\n },\n { flush: \"sync\" },\n );\n\n watch(\n () => [props.duration, props.interval, props.mode, props.reveal] as const,\n resetSession,\n { flush: \"sync\" },\n );\n\n watch(\n () => props.codeHighlighter,\n () => {\n codeRequestsByBlock.clear();\n codeSessionsByBlock.clear();\n codeHighlights.value = new Map();\n const input = currentInput.value;\n if (input) ensureCodeHighlights(input.codeBlocks);\n refreshPlayback(input);\n },\n { flush: \"sync\" },\n );\n\n watch(\n () => props.reducedMotion,\n () => {\n configureMotion();\n const input = currentInput.value;\n if (input && !presentationImmediate()) ensureImages(input.images);\n refreshPlayback(input);\n },\n { flush: \"sync\" },\n );\n\n flushInput();\n\n onMounted(() => {\n mounted.value = true;\n configureMotion();\n const input = currentInput.value;\n if (input) {\n ensureCodeHighlights(input.codeBlocks);\n ensureImages(input.images);\n refreshPlayback(input);\n }\n void nextTick(afterRender);\n });\n\n onUpdated(afterRender);\n\n onBeforeUnmount(() => {\n destroyed = true;\n removeMediaListener();\n if (typeof window !== \"undefined\") {\n if (inputFrame !== undefined) cancelFrame(inputFrame);\n cancelPlaybackFrame();\n }\n clearResourceWork();\n codeRequestsByBlock.clear();\n codeSessionsByBlock.clear();\n });\n\n const renderContent = (): VNode[] => {\n const input = currentInput.value;\n if (\n !input ||\n (props.mode === \"streaming\" && resolvedMotion.value === \"pending\")\n ) {\n lastPresentation = undefined;\n return [];\n }\n const playback = currentPlayback.value;\n const now = Math.max(playback.now, resourceNow.value);\n const presentation = session.present(input, playback, { now });\n lastPresentation = presentation;\n return webNodesToVue(createWebPresentation({\n cache: presentationCache,\n codeHighlighterEnabled: props.codeHighlighter !== undefined,\n codeHighlights: codeHighlights.value,\n compactedBlockIds: presentation.compactedBlockIds,\n compactedUnitIds: presentation.compactedUnitIds,\n confirmedBlockIds: input.plan.confirmedBlockIds,\n images: imageReadiness.value,\n immediate: presentationImmediate(),\n now,\n reveal: input.reveal,\n schedules: presentation.schedules,\n showLanguageLabels: props.codeHighlighter?.showLanguageLabels !== false,\n tree: input.plan.tree,\n units: input.plan.units,\n }));\n };\n\n return () => {\n const motion = props.mode === \"streaming\" &&\n resolvedMotion.value === \"pending\"\n ? \"pending\"\n : resolvedMotion.value === \"none\"\n ? \"none\"\n : \"animate\";\n const rootNode = h(\n \"div\",\n mergeProps(attrs, {\n \"data-smoothstream\": true,\n \"data-smoothstream-mode\": props.mode,\n \"data-smoothstream-motion\": motion,\n \"data-smoothstream-reduced-motion\": props.reducedMotion,\n \"data-smoothstream-reveal\": props.reveal,\n \"data-smoothstream-theme\": props.unstyled ? undefined : \"default\",\n ref: root,\n style: {\n \"--smoothstream-duration\":\n String(resolvedMotion.value === \"none\" ? 0 : props.duration) +\n \"ms\",\n \"--smoothstream-interval\":\n String(resolvedMotion.value === \"none\" ? 0 : props.interval) +\n \"ms\",\n },\n }),\n renderContent(),\n );\n const announcer = props.mode === \"streaming\" && mounted.value\n ? h(Teleport, { to: \"body\" }, h(\"div\", {\n \"aria-atomic\": true,\n \"aria-live\": \"polite\",\n \"data-smoothstream-announcer\": true,\n role: \"status\",\n style: screenReaderOnlyStyle,\n }, completionAnnouncement.value))\n : null;\n return h(Fragment, null, [rootNode, announcer]);\n };\n },\n});\n","import { find, html, svg } from \"property-information\";\nimport {\n defineComponent,\n createTextVNode,\n h,\n onBeforeUnmount,\n ref,\n watch,\n type PropType,\n type VNode,\n} from \"vue\";\nimport type {\n WebElementNode,\n WebProperties,\n WebRenderNode,\n} from \"@smoothstream/core/web\";\n\ninterface VuePropertyInfo {\n readonly commaSeparated: boolean;\n readonly name: string;\n}\n\ninterface CopyContext {\n readonly copied: boolean;\n readonly copy: (event: MouseEvent) => void;\n}\n\nconst htmlPropertyInfoByName = new Map<string, VuePropertyInfo>();\nconst svgPropertyInfoByName = new Map<string, VuePropertyInfo>();\nconst tableContainers = new Set([\"table\", \"tbody\", \"tfoot\", \"thead\", \"tr\"]);\n\nconst vuePropertyInfo = (\n property: string,\n namespace: \"svg\" | undefined,\n): VuePropertyInfo => {\n const cache = namespace === \"svg\"\n ? svgPropertyInfoByName\n : htmlPropertyInfoByName;\n const cached = cache.get(property);\n if (cached) return cached;\n\n const information = find(namespace === \"svg\" ? svg : html, property);\n const result = {\n commaSeparated: information.commaSeparated,\n name: information.attribute,\n };\n cache.set(property, result);\n return result;\n};\n\nconst vueElementProperties = (\n node: WebElementNode,\n): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [property, originalValue] of Object.entries(node.properties)) {\n if (\n property === \"children\" ||\n originalValue === null ||\n originalValue === undefined ||\n (typeof originalValue === \"number\" && Number.isNaN(originalValue))\n ) {\n continue;\n }\n\n const information = vuePropertyInfo(property, node.namespace);\n result[information.name] = Array.isArray(originalValue)\n ? originalValue\n .map(String)\n .join(information.commaSeparated ? \", \" : \" \")\n .trim()\n : originalValue;\n }\n return result;\n};\n\nconst writeClipboardText = async (\n button: HTMLButtonElement,\n value: string,\n): Promise<void> => {\n const document = button.ownerDocument;\n const view = document.defaultView;\n if (!view) throw new Error(\"Clipboard copy requires a browser window.\");\n\n if (view.navigator.clipboard?.writeText) {\n await view.navigator.clipboard.writeText(value);\n return;\n }\n\n const textarea = document.createElement(\"textarea\");\n textarea.value = value;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"fixed\";\n textarea.style.opacity = \"0\";\n document.body.append(textarea);\n textarea.select();\n const copied = document.execCommand?.(\"copy\") === true;\n textarea.remove();\n if (!copied) throw new Error(\"Clipboard copy is unavailable.\");\n};\n\nconst webChildrenToVue = (\n children: ReadonlyArray<WebRenderNode>,\n filterTableWhitespace: boolean,\n copyContext?: CopyContext,\n): VNode[] => children.flatMap((child) => {\n if (\n filterTableWhitespace &&\n child.type === \"text\" &&\n /^\\s*$/u.test(child.value)\n ) {\n return [];\n }\n return [webNodeToVue(child, copyContext)];\n});\n\nconst webElementToVue = (\n node: WebElementNode,\n copyContext?: CopyContext,\n): VNode => {\n const properties = vueElementProperties(node);\n if (copyContext) {\n if (node.properties[\"data-smoothstream-code-copy\"] === true) {\n properties.onClick = copyContext.copy;\n if (copyContext.copied) properties[\"aria-label\"] = \"Code copied\";\n }\n if (node.properties[\"data-smoothstream-code-icon-swap\"] === true) {\n properties[\"data-state\"] = copyContext.copied ? \"check\" : \"copy\";\n }\n }\n\n return h(\n node.tagName,\n { ...properties, key: node.key },\n webChildrenToVue(\n node.children,\n tableContainers.has(node.tagName),\n copyContext,\n ),\n );\n};\n\nconst WebCodeBlock = defineComponent({\n name: \"SmoothstreamCodeBlock\",\n props: {\n node: {\n required: true,\n type: Object as PropType<WebElementNode>,\n },\n },\n setup(props) {\n const copied = ref(false);\n let resetTimer: number | undefined;\n\n const clearResetTimer = (): void => {\n if (resetTimer === undefined) return;\n const view = typeof window === \"undefined\" ? undefined : window;\n view?.clearTimeout(resetTimer);\n resetTimer = undefined;\n };\n\n watch(\n () => props.node.codeCopyValue,\n () => {\n copied.value = false;\n clearResetTimer();\n },\n );\n\n onBeforeUnmount(clearResetTimer);\n\n const copy = (event: MouseEvent): void => {\n if (props.node.properties[\"data-smoothstream-code-copy-ready\"] !== true) {\n return;\n }\n const button = event.currentTarget as HTMLButtonElement | null;\n if (!button || button.localName !== \"button\") return;\n const code = props.node.codeCopyValue;\n if (code === undefined) return;\n void writeClipboardText(button, code).then(\n () => {\n copied.value = true;\n clearResetTimer();\n const view = button.ownerDocument.defaultView;\n if (!view) return;\n resetTimer = view.setTimeout(() => {\n copied.value = false;\n resetTimer = undefined;\n }, 2_000);\n },\n () => {\n copied.value = false;\n },\n );\n };\n\n return () => webElementToVue(props.node, {\n copied: copied.value,\n copy,\n });\n },\n});\n\nconst webNodeToVue = (\n node: WebRenderNode,\n copyContext?: CopyContext,\n): VNode => {\n if (node.type === \"text\") {\n const text = createTextVNode(node.value);\n text.key = node.key;\n return text;\n }\n if (\n !copyContext &&\n node.tagName === \"pre\" &&\n node.properties[\"data-smoothstream-code-block\"] === true\n ) {\n return h(WebCodeBlock, { key: node.key, node });\n }\n return webElementToVue(node, copyContext);\n};\n\nexport const webNodesToVue = (\n nodes: ReadonlyArray<WebRenderNode>,\n): VNode[] => nodes.map((node) => webNodeToVue(node));\n\nexport type { WebProperties };\n"],"mappings":"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","names":["defineComponent","h","onBeforeUnmount","ref","watch","defineComponent","ref","image","watch","onBeforeUnmount","h"]}
package/dist/styles.css CHANGED
@@ -117,6 +117,7 @@
117
117
  transparent
118
118
  );
119
119
  --smoothstream-code-padding-inline: 1rem;
120
+ --smoothstream-code-hidden-padding-block: 0.725em;
120
121
  --smoothstream-code-margin-block: 0.75em;
121
122
  --smoothstream-p-margin-block-start: 0;
122
123
  --smoothstream-p-margin-block-end: 1em;
@@ -483,7 +484,7 @@
483
484
  line-height: 1.5;
484
485
  }
485
486
 
486
- :where([data-smoothstream-theme="default"] [data-smoothstream-code-copy]) {
487
+ :where([data-smoothstream-theme="default"] [data-smoothstream-code-copy-slot]) {
487
488
  /* Pull the larger hit target so its icon lines up with the inline inset. */
488
489
  margin-inline-end: calc(
489
490
  (
@@ -537,6 +538,14 @@
537
538
  padding: 0.55em var(--smoothstream-code-padding-inline) 0.9em;
538
539
  }
539
540
 
541
+ :where(
542
+ [data-smoothstream-theme="default"]
543
+ [data-smoothstream-code-block][data-smoothstream-code-language-hidden]
544
+ > code
545
+ ) {
546
+ padding-block: var(--smoothstream-code-hidden-padding-block);
547
+ }
548
+
540
549
  :where([data-smoothstream-theme="default"] [data-smoothstream-table-shell]) {
541
550
  margin-block: var(--smoothstream-table-margin-block);
542
551
  border: var(--smoothstream-table-border-width)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smoothstream/vue",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Deterministic, paced Markdown reveal for Vue 3",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -38,8 +38,8 @@
38
38
  "vue": "^3.5.0"
39
39
  },
40
40
  "dependencies": {
41
- "@smoothstream/core": "^0.1.2",
42
- "@smoothstream/styles": "^0.1.0",
41
+ "@smoothstream/core": "^0.1.3",
42
+ "@smoothstream/styles": "^0.1.4",
43
43
  "property-information": "^7.2.0"
44
44
  },
45
45
  "repository": {