@tx5dr/plugin-api 1.0.0 → 1.2.0

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.
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Ambient type definitions for the TX-5DR Plugin Bridge SDK.
3
+ *
4
+ * The Bridge SDK is automatically injected into plugin iframe pages by the
5
+ * host. It is available as `window.tx5dr` (or simply `tx5dr` in global
6
+ * scope) — plugin code does **not** need to import or install anything at
7
+ * runtime.
8
+ *
9
+ * ## Enabling IDE autocomplete
10
+ *
11
+ * **TypeScript** — add to `tsconfig.json`:
12
+ * ```json
13
+ * { "compilerOptions": { "types": ["@tx5dr/plugin-api/bridge"] } }
14
+ * ```
15
+ *
16
+ * **JavaScript (VS Code)** — add to `jsconfig.json`:
17
+ * ```json
18
+ * { "compilerOptions": { "types": ["@tx5dr/plugin-api/bridge"] } }
19
+ * ```
20
+ *
21
+ * Or add a triple-slash reference at the top of any `.js` / `.ts` file:
22
+ * ```js
23
+ * /// <reference types="@tx5dr/plugin-api/bridge" />
24
+ * ```
25
+ *
26
+ * @see https://github.com/boybook/tx-5dr/blob/main/docs/plugin-system.md
27
+ */
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Bridge SDK interface
31
+ // ---------------------------------------------------------------------------
32
+
33
+ /**
34
+ * The TX-5DR Plugin Bridge SDK exposed as `window.tx5dr` inside plugin
35
+ * iframe pages.
36
+ *
37
+ * All async methods communicate with the host via `postMessage` and return
38
+ * Promises that resolve when the host responds.
39
+ */
40
+ interface Tx5drBridge {
41
+ // ── State (read-only) ────────────────────────────────────────────────
42
+
43
+ /** URL query parameters passed to this iframe page (read-only). */
44
+ readonly params: Readonly<Record<string, string>>;
45
+
46
+ /** Current theme: `'dark'` or `'light'`. */
47
+ readonly theme: 'dark' | 'light';
48
+
49
+ /** Current locale code (e.g. `'zh'`, `'en'`). */
50
+ readonly locale: string;
51
+
52
+ /** Unique session ID assigned to this iframe instance by the host. */
53
+ readonly pageSessionId: string;
54
+
55
+ // ── RPC ──────────────────────────────────────────────────────────────
56
+
57
+ /**
58
+ * Send a request to the plugin's server-side page handler
59
+ * (`ctx.ui.registerPageHandler`).
60
+ *
61
+ * @param action An application-defined action name.
62
+ * @param data Optional payload forwarded to the handler.
63
+ * @returns The value returned by the handler's `onMessage` method.
64
+ */
65
+ invoke(action: string, data?: unknown): Promise<unknown>;
66
+
67
+ // ── Push messaging ───────────────────────────────────────────────────
68
+
69
+ /**
70
+ * Subscribe to server-initiated push messages.
71
+ *
72
+ * The server sends pushes via `ctx.ui.pushToPage(pageId, action, data)`
73
+ * or `requestContext.page.push(action, data)`.
74
+ */
75
+ onPush(action: string, callback: (data: any) => void): void;
76
+
77
+ /** Unsubscribe a previously registered push listener. */
78
+ offPush(action: string, callback: (data: any) => void): void;
79
+
80
+ // ── Key-value store ──────────────────────────────────────────────────
81
+
82
+ /**
83
+ * Read a value from the page-scoped persistent KV store.
84
+ *
85
+ * Scope is determined by the page's instance target and resource binding
86
+ * (e.g. per-callsign).
87
+ */
88
+ storeGet<T = unknown>(key: string, defaultValue?: T): Promise<T>;
89
+
90
+ /** Write a value to the page-scoped persistent KV store. */
91
+ storeSet(key: string, value: unknown): Promise<void>;
92
+
93
+ /** Delete a key from the page-scoped persistent KV store. */
94
+ storeDelete(key: string): Promise<void>;
95
+
96
+ // ── File storage ─────────────────────────────────────────────────────
97
+
98
+ /**
99
+ * Upload a file to the page-scoped file storage.
100
+ *
101
+ * Files are stored under a sandboxed directory determined by the page's
102
+ * instance target and resource binding.
103
+ */
104
+ fileUpload(path: string, file: File | Blob): Promise<void>;
105
+
106
+ /** Read a file from page-scoped storage. Returns `null` if not found. */
107
+ fileRead(path: string): Promise<Blob | null>;
108
+
109
+ /** Delete a file from page-scoped storage. */
110
+ fileDelete(path: string): Promise<boolean>;
111
+
112
+ /** List file paths under the given prefix in page-scoped storage. */
113
+ fileList(prefix?: string): Promise<string[]>;
114
+
115
+ // ── UI controls ──────────────────────────────────────────────────────
116
+
117
+ /**
118
+ * Report the iframe content height so the host can resize the iframe.
119
+ *
120
+ * Recommended: use a `ResizeObserver` on `document.body` and call
121
+ * `tx5dr.resize(document.body.scrollHeight)` on every change.
122
+ */
123
+ resize(height: number): void;
124
+
125
+ /** Ask the parent component to close this iframe (e.g. close a modal). */
126
+ requestClose(): void;
127
+
128
+ /** Register a callback invoked when the host theme changes. */
129
+ onThemeChange(callback: (theme: 'dark' | 'light') => void): void;
130
+ }
131
+
132
+ // ---------------------------------------------------------------------------
133
+ // Global augmentation
134
+ // ---------------------------------------------------------------------------
135
+
136
+ interface Window {
137
+ /** TX-5DR Plugin Bridge SDK — injected by the host into iframe pages. */
138
+ readonly tx5dr: Tx5drBridge;
139
+ }
140
+
141
+ /**
142
+ * Shorthand global reference to the Bridge SDK.
143
+ *
144
+ * Equivalent to `window.tx5dr`. Available because the SDK is injected as a
145
+ * global before any plugin script runs.
146
+ */
147
+ declare var tx5dr: Tx5drBridge;
package/tokens.css ADDED
@@ -0,0 +1,60 @@
1
+ /*
2
+ * TX-5DR Plugin Design Tokens (Reference File)
3
+ *
4
+ * This file is a REFERENCE COPY of the CSS custom properties injected by
5
+ * the TX-5DR host into every plugin iframe page. Its purpose is to enable
6
+ * IDE autocomplete when authoring plugin CSS — the actual runtime values
7
+ * are injected by the host and may differ from these defaults.
8
+ *
9
+ * Usage:
10
+ * Copy this file into your plugin project root (or ui/ directory).
11
+ * VS Code's CSS Language Service will pick up the custom property names
12
+ * and offer autocomplete when you type `var(--tx5dr-`.
13
+ *
14
+ * DO NOT import or link this file in your HTML — the host already injects
15
+ * the tokens via <link rel="stylesheet" href="/api/plugins/_bridge/tokens.css">.
16
+ *
17
+ * The values below correspond to the "dark" theme. Light-theme overrides
18
+ * are applied automatically at runtime by the host when the user switches
19
+ * themes.
20
+ */
21
+ :root {
22
+ /* ── Background ── */
23
+ --tx5dr-bg: #18181b;
24
+ --tx5dr-bg-content: #27272a;
25
+ --tx5dr-bg-hover: #3f3f46;
26
+
27
+ /* ── Text ── */
28
+ --tx5dr-text: #fafafa;
29
+ --tx5dr-text-secondary: #a1a1aa;
30
+
31
+ /* ── Semantic colors ── */
32
+ --tx5dr-primary: #006FEE;
33
+ --tx5dr-primary-hover: #005bc4;
34
+ --tx5dr-success: #17c964;
35
+ --tx5dr-warning: #f5a524;
36
+ --tx5dr-danger: #f31260;
37
+
38
+ /* ── Border ── */
39
+ --tx5dr-border: #3f3f46;
40
+ --tx5dr-focus-ring: rgba(0, 111, 238, 0.4);
41
+
42
+ /* ── Border radius ── */
43
+ --tx5dr-radius-sm: 8px;
44
+ --tx5dr-radius-md: 12px;
45
+ --tx5dr-radius-lg: 16px;
46
+
47
+ /* ── Spacing ── */
48
+ --tx5dr-spacing-xs: 4px;
49
+ --tx5dr-spacing-sm: 8px;
50
+ --tx5dr-spacing-md: 12px;
51
+ --tx5dr-spacing-lg: 16px;
52
+ --tx5dr-spacing-xl: 24px;
53
+
54
+ /* ── Typography ── */
55
+ --tx5dr-font: 'Inter', system-ui, -apple-system, sans-serif;
56
+ --tx5dr-font-mono: 'JetBrains Mono', ui-monospace, monospace;
57
+ --tx5dr-font-size-sm: 13px;
58
+ --tx5dr-font-size-md: 14px;
59
+ --tx5dr-font-size-lg: 16px;
60
+ }