@garretapp/sdk 0.1.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.
- package/README.md +57 -0
- package/dist/chunk-ENIDFSMM.js +29 -0
- package/dist/chunk-RZJO3X6O.js +9 -0
- package/dist/chunk-ZJYHRC5C.js +206 -0
- package/dist/host.cjs +263 -0
- package/dist/host.d.cts +54 -0
- package/dist/host.d.ts +54 -0
- package/dist/host.js +246 -0
- package/dist/index.cjs +77 -0
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +37 -0
- package/dist/platform-CZHtdUK0.d.ts +154 -0
- package/dist/platform-DnI7gJTx.d.cts +154 -0
- package/dist/protocol-Do0BJdeE.d.cts +64 -0
- package/dist/protocol-Do0BJdeE.d.ts +64 -0
- package/dist/react.cjs +496 -0
- package/dist/react.d.cts +128 -0
- package/dist/react.d.ts +128 -0
- package/dist/react.js +242 -0
- package/dist/types-BxSYAH_H.d.cts +88 -0
- package/dist/types-BxSYAH_H.d.ts +88 -0
- package/dist/ui.cjs +249 -0
- package/dist/ui.d.cts +23 -0
- package/dist/ui.d.ts +23 -0
- package/dist/ui.js +3 -0
- package/package.json +37 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { T as Transport } from './protocol-Do0BJdeE.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Platform capabilities — the Garret-brokered surface available to a widget UI in BOTH tiers
|
|
5
|
+
* (`useGarret()`). Every call is enforced in Garret's main process against the manifest's declared
|
|
6
|
+
* capabilities. The concrete implementation is injected by the preload as `window.__garret` (U3);
|
|
7
|
+
* outside Garret (dev in a browser) a fallback reports `inGarret === false` and throws on use.
|
|
8
|
+
*/
|
|
9
|
+
interface ServiceStatus {
|
|
10
|
+
connected: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface ServiceClient {
|
|
13
|
+
/** Connection state is async (the account is connected in Garret's Settings, brokered by main). */
|
|
14
|
+
status(): Promise<ServiceStatus>;
|
|
15
|
+
query<R = unknown>(method: string, params?: Record<string, unknown>): Promise<R>;
|
|
16
|
+
}
|
|
17
|
+
interface StorageApi {
|
|
18
|
+
get<T = unknown>(key: string): Promise<T | undefined>;
|
|
19
|
+
set(key: string, value: unknown): Promise<void>;
|
|
20
|
+
delete(key: string): Promise<void>;
|
|
21
|
+
keys(): Promise<string[]>;
|
|
22
|
+
clear(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
interface SecretsApi {
|
|
25
|
+
get(key: string): Promise<string | undefined>;
|
|
26
|
+
set(key: string, value: string): Promise<void>;
|
|
27
|
+
delete(key: string): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/** What `g.fetch` resolves to. NOT a DOM `Response` — a Response can't cross the contextBridge from
|
|
30
|
+
* the preload, so Garret hands back this serializable shape (primitive fields + body readers). */
|
|
31
|
+
interface GarretResponse {
|
|
32
|
+
ok: boolean;
|
|
33
|
+
status: number;
|
|
34
|
+
statusText: string;
|
|
35
|
+
headers: Record<string, string>;
|
|
36
|
+
text(): Promise<string>;
|
|
37
|
+
json<T = unknown>(): Promise<T>;
|
|
38
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
39
|
+
}
|
|
40
|
+
/** The pack-shared store (only usable when the pack manifest declares `shared`): one namespace across
|
|
41
|
+
* all the pack's widgets — e.g. a single credential set for a multi-widget service pack. */
|
|
42
|
+
interface SharedApi {
|
|
43
|
+
storage: StorageApi;
|
|
44
|
+
secrets: SecretsApi;
|
|
45
|
+
}
|
|
46
|
+
/** Options for opening a floating sibling surface. All fields optional; sizes in px. */
|
|
47
|
+
interface SurfaceOpenOptions {
|
|
48
|
+
/** initial props delivered to the opened surface as `g.props`; structured-cloned, so each surface
|
|
49
|
+
* gets its own isolated copy (mutations are local). Must be structured-cloneable (no functions). */
|
|
50
|
+
props?: Record<string, unknown>;
|
|
51
|
+
title?: string;
|
|
52
|
+
size?: {
|
|
53
|
+
w: number;
|
|
54
|
+
h: number;
|
|
55
|
+
};
|
|
56
|
+
/** default true — the window stays above normal windows while you work. */
|
|
57
|
+
alwaysOnTop?: boolean;
|
|
58
|
+
/** singleton: a repeat open with the same key focuses the existing window instead of spawning. */
|
|
59
|
+
key?: string;
|
|
60
|
+
}
|
|
61
|
+
/** A handle to a floating surface window opened via `g.surfaces.open`. */
|
|
62
|
+
interface SurfaceHandle {
|
|
63
|
+
readonly id: string;
|
|
64
|
+
close(): Promise<boolean>;
|
|
65
|
+
focus(): Promise<boolean>;
|
|
66
|
+
/** Resolves when the window closes — by the user, `close()`, or its opener being removed. */
|
|
67
|
+
closed(): Promise<void>;
|
|
68
|
+
onClose(cb: () => void): () => void;
|
|
69
|
+
}
|
|
70
|
+
/** Controls for the surface window THIS UI runs in (no-op for a board-placed widget). */
|
|
71
|
+
interface WindowControls {
|
|
72
|
+
/** Lock the window's aspect ratio (width/height); `0` clears it. Use once you know your content
|
|
73
|
+
* size — e.g. a mirror sets the device's ratio after the first video frame.
|
|
74
|
+
*
|
|
75
|
+
* `inset` reserves guest-drawn chrome (px) that is EXCLUDED from the aspect-locked area, so the
|
|
76
|
+
* ratio applies to your content, not the whole window — e.g. a fixed 48px side toolbar passes
|
|
77
|
+
* `{ width: 48 }` and the remaining area keeps `ratio`. Combined with the host's own titlebar. */
|
|
78
|
+
setAspectRatio(ratio: number, inset?: {
|
|
79
|
+
width?: number;
|
|
80
|
+
height?: number;
|
|
81
|
+
}): void;
|
|
82
|
+
/** Resize the window (px). */
|
|
83
|
+
resize(width: number, height: number): void;
|
|
84
|
+
/** Close this surface window (for a frameless surface's own close button). */
|
|
85
|
+
close(): void;
|
|
86
|
+
}
|
|
87
|
+
interface SurfaceApi {
|
|
88
|
+
/** Open a sibling surface (declared in this package's manifest) as a floating, focusable window.
|
|
89
|
+
* Rejects with an Error (message from Garret) if denied — e.g. missing `windows` capability,
|
|
90
|
+
* unknown surface, or the concurrent-window limit. */
|
|
91
|
+
open(surfaceId: string, opts?: SurfaceOpenOptions): Promise<SurfaceHandle>;
|
|
92
|
+
/** Observe closes of this opener's surfaces by instanceId. Unlike a handle's `onClose`/`closed()`
|
|
93
|
+
* (scoped to the current context), this SURVIVES an opener reload — re-subscribe on mount for
|
|
94
|
+
* reload-durable close tracking. */
|
|
95
|
+
onClosed(cb: (instanceId: string) => void): () => void;
|
|
96
|
+
}
|
|
97
|
+
interface GarretPlatform {
|
|
98
|
+
/** per-extension (shared across placements), atomic + key-merged. */
|
|
99
|
+
storage: StorageApi;
|
|
100
|
+
/** per-placement (isolated) — safe for cursors/state that mustn't clobber other instances. */
|
|
101
|
+
instanceStorage: StorageApi;
|
|
102
|
+
secrets: SecretsApi;
|
|
103
|
+
/** Brokered HTTPS fetch (capability `network:<host>` / `network:*`). Resolves to a GarretResponse
|
|
104
|
+
* (a Response-like shape — see the type), not a DOM Response. */
|
|
105
|
+
fetch(url: string, init?: RequestInit): Promise<GarretResponse>;
|
|
106
|
+
/** Pack-shared store — present only when the pack declares `shared`; otherwise its calls reject. */
|
|
107
|
+
shared: SharedApi;
|
|
108
|
+
service<T extends ServiceClient = ServiceClient>(id: string): T;
|
|
109
|
+
notify(title: string, body?: string): void;
|
|
110
|
+
openExternal(url: string): Promise<boolean>;
|
|
111
|
+
clipboard: {
|
|
112
|
+
readText(): Promise<string>;
|
|
113
|
+
writeText(value: string): Promise<void>;
|
|
114
|
+
};
|
|
115
|
+
/** false when the board is ambient/idle — pause rAF/animations, throttle polling. */
|
|
116
|
+
active: boolean;
|
|
117
|
+
onActiveChange(cb: (active: boolean) => void): () => void;
|
|
118
|
+
/** The host (frame ⋯→Settings) asks this widget to open its own config UI. */
|
|
119
|
+
onOpenSettings(cb: () => void): () => void;
|
|
120
|
+
/** Open sibling surfaces (same package) as floating windows. Requires the `windows` capability. */
|
|
121
|
+
surfaces: SurfaceApi;
|
|
122
|
+
/** Controls for this UI's own surface window (no-op for a board-placed widget). */
|
|
123
|
+
window: WindowControls;
|
|
124
|
+
/** Fires once the runtime has bound, with this surface's launch props (`{}` for the board surface).
|
|
125
|
+
* Fires immediately if already ready. Props arrive via the callback — NOT a live getter — because
|
|
126
|
+
* a getter would be frozen at contextBridge exposure time (before bind). Use `useProps()` in React. */
|
|
127
|
+
onReady(cb: (props: Record<string, unknown>) => void): () => void;
|
|
128
|
+
/** false in a plain browser (dev) — render a "run inside Garret" state instead of a blank UI. */
|
|
129
|
+
inGarret: boolean;
|
|
130
|
+
}
|
|
131
|
+
/** What the preload injects. Extends the platform with the wiring the SDK runtimes need. */
|
|
132
|
+
interface GarretRuntime extends GarretPlatform {
|
|
133
|
+
instanceId: string;
|
|
134
|
+
/** the per-widget host bridge; null for web widgets (no host). */
|
|
135
|
+
hostTransport: Transport | null;
|
|
136
|
+
config: {
|
|
137
|
+
get(): unknown;
|
|
138
|
+
/** replace=false → shallow merge (patch); true → full replace. */
|
|
139
|
+
set(value: unknown, replace?: boolean): void;
|
|
140
|
+
subscribe(cb: (config: unknown) => void): () => void;
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
declare global {
|
|
144
|
+
interface Window {
|
|
145
|
+
__garret?: GarretRuntime;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
declare function getRuntime(): GarretRuntime | undefined;
|
|
149
|
+
declare function getHostTransport(): Transport | null;
|
|
150
|
+
declare function getInstanceId(): string;
|
|
151
|
+
/** The platform capabilities. Real inside Garret; a fail-loud fallback in a plain browser. */
|
|
152
|
+
declare function getGarret(): GarretPlatform;
|
|
153
|
+
|
|
154
|
+
export { type GarretPlatform as G, type SurfaceApi as S, type WindowControls as W, type SurfaceHandle as a, type SurfaceOpenOptions as b, type GarretRuntime as c, type SecretsApi as d, type ServiceClient as e, type StorageApi as f, getGarret as g, getHostTransport as h, getInstanceId as i, getRuntime as j };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Garret wire protocol — the one envelope every widget call/event/stream rides on, across
|
|
3
|
+
* both hops (UI ⇄ main, main ⇄ host). Locked before the SDK: `defineHost`/`useHost`/`ctx.stream`
|
|
4
|
+
* are thin wrappers over this. Structured-clone only (Date/Map/Uint8Array survive; no functions).
|
|
5
|
+
* See docs/architecture.md §2.
|
|
6
|
+
*/
|
|
7
|
+
/** A correlation id, namespaced `${instanceId}:${seq}` so two placements never collide. */
|
|
8
|
+
type CallId = string;
|
|
9
|
+
type WireMessage = {
|
|
10
|
+
t: 'req';
|
|
11
|
+
id: CallId;
|
|
12
|
+
method: string;
|
|
13
|
+
args: unknown;
|
|
14
|
+
} | {
|
|
15
|
+
t: 'res';
|
|
16
|
+
id: CallId;
|
|
17
|
+
result: unknown;
|
|
18
|
+
} | {
|
|
19
|
+
t: 'err';
|
|
20
|
+
id: CallId;
|
|
21
|
+
code: string;
|
|
22
|
+
message: string;
|
|
23
|
+
hint?: string;
|
|
24
|
+
} | {
|
|
25
|
+
t: 'stream_start';
|
|
26
|
+
id: CallId;
|
|
27
|
+
method: string;
|
|
28
|
+
args: unknown;
|
|
29
|
+
} | {
|
|
30
|
+
t: 'chunk';
|
|
31
|
+
id: CallId;
|
|
32
|
+
data: unknown;
|
|
33
|
+
} | {
|
|
34
|
+
t: 'stream_end';
|
|
35
|
+
id: CallId;
|
|
36
|
+
result: unknown;
|
|
37
|
+
} | {
|
|
38
|
+
t: 'stream_err';
|
|
39
|
+
id: CallId;
|
|
40
|
+
code: string;
|
|
41
|
+
message: string;
|
|
42
|
+
} | {
|
|
43
|
+
t: 'cancel';
|
|
44
|
+
id: CallId;
|
|
45
|
+
} | {
|
|
46
|
+
t: 'event';
|
|
47
|
+
channel: string;
|
|
48
|
+
payload: unknown;
|
|
49
|
+
} | {
|
|
50
|
+
t: 'ready';
|
|
51
|
+
} | {
|
|
52
|
+
t: 'dispose';
|
|
53
|
+
};
|
|
54
|
+
/** Reserved event channel the host activity signal rides on (drives useActive / g.active). */
|
|
55
|
+
declare const ACTIVE_CHANNEL = "$active";
|
|
56
|
+
/** A minimal duplex a client/host binds to. The concrete transports (parentPort, the preload
|
|
57
|
+
* bridge) implement this in U2/U3; the runtimes here are transport-agnostic. */
|
|
58
|
+
interface Transport {
|
|
59
|
+
send(msg: WireMessage): void;
|
|
60
|
+
/** Subscribe to inbound messages; returns an unsubscribe fn. */
|
|
61
|
+
onMessage(cb: (msg: WireMessage) => void): () => void;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { ACTIVE_CHANNEL as A, type CallId as C, type Transport as T, type WireMessage as W };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Garret wire protocol — the one envelope every widget call/event/stream rides on, across
|
|
3
|
+
* both hops (UI ⇄ main, main ⇄ host). Locked before the SDK: `defineHost`/`useHost`/`ctx.stream`
|
|
4
|
+
* are thin wrappers over this. Structured-clone only (Date/Map/Uint8Array survive; no functions).
|
|
5
|
+
* See docs/architecture.md §2.
|
|
6
|
+
*/
|
|
7
|
+
/** A correlation id, namespaced `${instanceId}:${seq}` so two placements never collide. */
|
|
8
|
+
type CallId = string;
|
|
9
|
+
type WireMessage = {
|
|
10
|
+
t: 'req';
|
|
11
|
+
id: CallId;
|
|
12
|
+
method: string;
|
|
13
|
+
args: unknown;
|
|
14
|
+
} | {
|
|
15
|
+
t: 'res';
|
|
16
|
+
id: CallId;
|
|
17
|
+
result: unknown;
|
|
18
|
+
} | {
|
|
19
|
+
t: 'err';
|
|
20
|
+
id: CallId;
|
|
21
|
+
code: string;
|
|
22
|
+
message: string;
|
|
23
|
+
hint?: string;
|
|
24
|
+
} | {
|
|
25
|
+
t: 'stream_start';
|
|
26
|
+
id: CallId;
|
|
27
|
+
method: string;
|
|
28
|
+
args: unknown;
|
|
29
|
+
} | {
|
|
30
|
+
t: 'chunk';
|
|
31
|
+
id: CallId;
|
|
32
|
+
data: unknown;
|
|
33
|
+
} | {
|
|
34
|
+
t: 'stream_end';
|
|
35
|
+
id: CallId;
|
|
36
|
+
result: unknown;
|
|
37
|
+
} | {
|
|
38
|
+
t: 'stream_err';
|
|
39
|
+
id: CallId;
|
|
40
|
+
code: string;
|
|
41
|
+
message: string;
|
|
42
|
+
} | {
|
|
43
|
+
t: 'cancel';
|
|
44
|
+
id: CallId;
|
|
45
|
+
} | {
|
|
46
|
+
t: 'event';
|
|
47
|
+
channel: string;
|
|
48
|
+
payload: unknown;
|
|
49
|
+
} | {
|
|
50
|
+
t: 'ready';
|
|
51
|
+
} | {
|
|
52
|
+
t: 'dispose';
|
|
53
|
+
};
|
|
54
|
+
/** Reserved event channel the host activity signal rides on (drives useActive / g.active). */
|
|
55
|
+
declare const ACTIVE_CHANNEL = "$active";
|
|
56
|
+
/** A minimal duplex a client/host binds to. The concrete transports (parentPort, the preload
|
|
57
|
+
* bridge) implement this in U2/U3; the runtimes here are transport-agnostic. */
|
|
58
|
+
interface Transport {
|
|
59
|
+
send(msg: WireMessage): void;
|
|
60
|
+
/** Subscribe to inbound messages; returns an unsubscribe fn. */
|
|
61
|
+
onMessage(cb: (msg: WireMessage) => void): () => void;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { ACTIVE_CHANNEL as A, type CallId as C, type Transport as T, type WireMessage as W };
|