-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPreviewSetup.swift
More file actions
51 lines (47 loc) · 2.33 KB
/
Copy pathPreviewSetup.swift
File metadata and controls
51 lines (47 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import SwiftUI
/// Conform to this protocol in a dedicated target to customize how PreviewsMCP
/// renders your previews. The setup target replaces micro apps / dev apps: it
/// provides the same mock dependency setup and theme wrapping, but PreviewsMCP
/// provides the app shell, hot-reload, and rendering infrastructure.
///
/// `setUp()` runs once when the host app launches — before any preview dylib is
/// loaded. It runs in a real UIApplication process (iOS) or NSApplication process
/// (macOS) with full app lifecycle. Use it for SDK initialization, authentication,
/// font registration, DI container setup, and mock service registration. It is
/// completely outside the hot-reload path.
///
/// `wrap(_:)` runs on every preview render (each structural recompile). Use it for
/// theme providers, custom environment values, and view-level setup that must
/// surround every preview.
///
/// Trait modifiers from `preview_configure` are applied outside this wrapper, so
/// explicit overrides always take precedence.
///
/// `AnyView` is required because the view type must be erased across the dynamic
/// library boundary.
public protocol PreviewSetup {
/// Called once per session before the first preview renders.
/// Async to support real auth flows and network calls.
/// If this throws, the preview renders without setup and the error is
/// reported as a warning to the MCP client.
static func setUp() async throws
/// Wraps every preview view. Called on each dylib load.
static func wrap(_ content: AnyView) -> AnyView
}
public extension PreviewSetup {
static func setUp() async throws {}
static func wrap(_ content: AnyView) -> AnyView {
content
}
}
/// Process-lifetime record of a failed `setUp()`. Lives in the kit — which
/// the shared setup dylib links exactly once per agent process — rather
/// than in the generated bridge, whose statics reset with every JIT
/// generation: a per-generation flag would silently re-enable `wrap` on
/// the first edit after a failure, handing the plugin half-initialized
/// state (docs/phase-error-protocol.md, setup integrity).
public enum PreviewSetupState {
/// Written once by the generated `previewSetUp` entry before any
/// render, read by every generated wrap call; never concurrent.
public nonisolated(unsafe) static var setUpFailed = false
}