@pstdio/sdk 0.19.0 → 0.20.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/dist/extensions/define-extension-view.d.ts +2 -0
- package/dist/extensions/define-extension.d.ts +1 -1
- package/dist/extensions/index.d.ts +1 -0
- package/dist/extensions/index.js +30 -0
- package/dist/extensions/react/index.d.ts +16 -0
- package/dist/extensions/react/index.js +38 -0
- package/dist/extensions/webview-client.d.ts +41 -0
- package/package.json +21 -2
|
@@ -12,6 +12,8 @@ export type GuestHost = {
|
|
|
12
12
|
call: <TResult = unknown>(method: string, params?: unknown) => Promise<TResult>;
|
|
13
13
|
/** Subscribe to host-pushed events for a capability scope (e.g. "terminal.session"). */
|
|
14
14
|
onEvent: (scope: string, handler: (payload: unknown) => void) => () => void;
|
|
15
|
+
/** Id of the extension that owns this webview. Missing only on hosts older than the bridge that sends it. */
|
|
16
|
+
extensionId?: string;
|
|
15
17
|
};
|
|
16
18
|
export type PropsStore<TProps = unknown> = {
|
|
17
19
|
get: () => TProps;
|
|
@@ -17,7 +17,7 @@ type SettingValue<TProperty> = TProperty extends {
|
|
|
17
17
|
} ? unknown[] : TProperty extends {
|
|
18
18
|
type: "object";
|
|
19
19
|
} ? Record<string, unknown> : unknown;
|
|
20
|
-
type SettingsMap<TSettings> = TSettings extends {
|
|
20
|
+
export type SettingsMap<TSettings> = TSettings extends {
|
|
21
21
|
properties: infer TProperties;
|
|
22
22
|
} ? {
|
|
23
23
|
[K in keyof TProperties & string]: SettingValue<TProperties[K]>;
|
|
@@ -9,4 +9,5 @@ export { defineExtensionView, type ExtensionViewModule, type ExtensionViewRender
|
|
|
9
9
|
export { params } from "./params";
|
|
10
10
|
export { commandEvent, commandRef, eventRef } from "./refs";
|
|
11
11
|
export { createTerminalSessionBridge, type TerminalSessionAdapter, type TerminalSessionBridge, type TerminalSessionExit, } from "./terminal-session-bridge";
|
|
12
|
+
export { createWebviewClient, type WebviewClient, type WebviewClientOptions, type WebviewCommandsClient, type WebviewSettingsClient, } from "./webview-client";
|
|
12
13
|
export { matchesResourceWhen } from "./when";
|
package/dist/extensions/index.js
CHANGED
|
@@ -377,6 +377,35 @@ var createTerminalSessionBridge = (host) => ({
|
|
|
377
377
|
};
|
|
378
378
|
}
|
|
379
379
|
});
|
|
380
|
+
// src/extensions/webview-client.ts
|
|
381
|
+
var createWebviewClient = (host, options) => {
|
|
382
|
+
const extensionId = options?.extensionId ?? host.extensionId;
|
|
383
|
+
if (!extensionId) {
|
|
384
|
+
throw new Error("The host bridge did not provide an extension id. Pass { extensionId } to createWebviewClient.");
|
|
385
|
+
}
|
|
386
|
+
const runCommand = async (commandKey, params2) => {
|
|
387
|
+
const response = await host.call("commands.execute", {
|
|
388
|
+
commandId: `${extensionId}.${commandKey}`,
|
|
389
|
+
params: params2
|
|
390
|
+
});
|
|
391
|
+
return unwrapCommandOutcome(response);
|
|
392
|
+
};
|
|
393
|
+
const commands = new Proxy({}, {
|
|
394
|
+
get: (_target, commandKey) => {
|
|
395
|
+
if (typeof commandKey !== "string")
|
|
396
|
+
return;
|
|
397
|
+
return (params2) => runCommand(commandKey, params2);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
const settings = {
|
|
401
|
+
all: async () => await host.call("extension.settings.all", {}) ?? {},
|
|
402
|
+
get: (key) => host.call("extension.settings.get", { key }),
|
|
403
|
+
set: async (key, value) => {
|
|
404
|
+
await host.call("extension.settings.set", { key, value });
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
return { commands, settings };
|
|
408
|
+
};
|
|
380
409
|
// src/extensions/when.ts
|
|
381
410
|
var matchesResourceWhen = (when, resourceType) => {
|
|
382
411
|
const resourceTypes = when?.resourceType;
|
|
@@ -416,6 +445,7 @@ export {
|
|
|
416
445
|
defineExtensionView,
|
|
417
446
|
defineExtension,
|
|
418
447
|
defineCommand,
|
|
448
|
+
createWebviewClient,
|
|
419
449
|
createTerminalSessionBridge,
|
|
420
450
|
commandRef,
|
|
421
451
|
commandEvent,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type QueryKey } from "@tanstack/react-query";
|
|
2
|
+
interface CommandQueryInput<TResult> {
|
|
3
|
+
queryKey: QueryKey;
|
|
4
|
+
command: () => Promise<TResult>;
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
staleTime?: number;
|
|
7
|
+
}
|
|
8
|
+
/** Reads server state via a typed client command, cached and deduped by react-query. */
|
|
9
|
+
export declare const useCommandQuery: <TResult>(input: CommandQueryInput<TResult>) => import("@tanstack/react-query").UseQueryResult<import("@tanstack/react-query").NoInfer<TResult>, Error>;
|
|
10
|
+
interface CommandMutationInput<TParams, TResult> {
|
|
11
|
+
command: (params: TParams) => Promise<TResult>;
|
|
12
|
+
invalidate?: QueryKey[];
|
|
13
|
+
}
|
|
14
|
+
/** Writes server state via a typed client command and refreshes affected queries on success. */
|
|
15
|
+
export declare const useCommandMutation: <TParams, TResult>(input: CommandMutationInput<TParams, TResult>) => import("@tanstack/react-query").UseMutationResult<TResult, Error, TParams, unknown>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __returnValue = (v) => v;
|
|
3
|
+
function __exportSetter(name, newValue) {
|
|
4
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
5
|
+
}
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
set: __exportSetter.bind(all, name)
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/extensions/react/index.ts
|
|
17
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
18
|
+
var useCommandQuery = (input) => {
|
|
19
|
+
const { command, enabled, queryKey, staleTime } = input;
|
|
20
|
+
return useQuery({
|
|
21
|
+
queryKey,
|
|
22
|
+
enabled,
|
|
23
|
+
staleTime,
|
|
24
|
+
queryFn: () => command()
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
var useCommandMutation = (input) => {
|
|
28
|
+
const { command, invalidate } = input;
|
|
29
|
+
const queryClient = useQueryClient();
|
|
30
|
+
return useMutation({
|
|
31
|
+
mutationFn: (params) => command(params),
|
|
32
|
+
onSuccess: () => invalidate?.forEach((queryKey) => void queryClient.invalidateQueries({ queryKey }))
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
export {
|
|
36
|
+
useCommandQuery,
|
|
37
|
+
useCommandMutation
|
|
38
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CommandDefinition, ParamObjectSchema, ParamsOf } from "pstdio-api-contracts/extension-kernel";
|
|
2
|
+
import type { SettingsMap } from "./define-extension";
|
|
3
|
+
import type { GuestHost } from "./define-extension-view";
|
|
4
|
+
type CommandFn<TDefinition> = TDefinition extends CommandDefinition<infer TSchema, infer TResult, infer _TSettings> ? TSchema extends ParamObjectSchema ? Partial<ParamsOf<TSchema>> extends ParamsOf<TSchema> ? (params?: ParamsOf<TSchema>) => Promise<TResult> : (params: ParamsOf<TSchema>) => Promise<TResult> : () => Promise<TResult> : never;
|
|
5
|
+
export type WebviewCommandsClient<TCommands> = {
|
|
6
|
+
[K in keyof TCommands & string]: CommandFn<TCommands[K]>;
|
|
7
|
+
};
|
|
8
|
+
export type WebviewSettingsClient<TSettings> = {
|
|
9
|
+
all: () => Promise<Partial<TSettings>>;
|
|
10
|
+
get: <K extends keyof TSettings & string>(key: K) => Promise<TSettings[K] | undefined>;
|
|
11
|
+
set: <K extends keyof TSettings & string>(key: K, value: TSettings[K]) => Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
type ClientSettingsMap<TSettings> = TSettings extends {
|
|
14
|
+
properties: unknown;
|
|
15
|
+
} ? SettingsMap<TSettings> : Record<never, never>;
|
|
16
|
+
export type WebviewClient<TCommands, TSettings = undefined> = {
|
|
17
|
+
commands: WebviewCommandsClient<TCommands>;
|
|
18
|
+
settings: WebviewSettingsClient<ClientSettingsMap<TSettings>>;
|
|
19
|
+
};
|
|
20
|
+
export interface WebviewClientOptions {
|
|
21
|
+
/** Overrides the extension id provided by the host bridge (e.g. in tests). */
|
|
22
|
+
extensionId?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Typed guest-side client over the host bridge. Command params and results come from
|
|
26
|
+
* the extension's exported commands record (`defineCommand` values); settings come
|
|
27
|
+
* from its exported settings contribution. Command outcomes are unwrapped, so
|
|
28
|
+
* failures throw.
|
|
29
|
+
*
|
|
30
|
+
* Import both as types only, so no server code enters the webview bundle:
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* import type { commands } from "../commands";
|
|
34
|
+
* import type { settings } from "../settings";
|
|
35
|
+
*
|
|
36
|
+
* const client = createWebviewClient<typeof commands, typeof settings>(host);
|
|
37
|
+
* const { statuses } = await client.commands["ticketStatus.read"]();
|
|
38
|
+
* const enabled = await client.settings.get("counter.enabled");
|
|
39
|
+
*/
|
|
40
|
+
export declare const createWebviewClient: <TCommands extends object, TSettings = undefined>(host: GuestHost, options?: WebviewClientOptions) => WebviewClient<TCommands, TSettings>;
|
|
41
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pstdio/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/pufflyai/prompt-studio"
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"types": "./dist/extensions/index.d.ts",
|
|
30
30
|
"import": "./dist/extensions/index.js"
|
|
31
31
|
},
|
|
32
|
+
"./extensions/react": {
|
|
33
|
+
"types": "./dist/extensions/react/index.d.ts",
|
|
34
|
+
"import": "./dist/extensions/react/index.js"
|
|
35
|
+
},
|
|
32
36
|
"./prompts": {
|
|
33
37
|
"types": "./dist/prompts/index.d.ts",
|
|
34
38
|
"import": "./dist/prompts/index.js"
|
|
@@ -40,7 +44,7 @@
|
|
|
40
44
|
},
|
|
41
45
|
"scripts": {
|
|
42
46
|
"build": "rm -rf ./dist && bun run build:js && bun run build:types",
|
|
43
|
-
"build:js": "bun build ./src/api/index.ts ./src/client/index.ts ./src/extensions/index.ts ./src/prompts/index.ts ./src/hooks/index.ts ./src/resources/index.ts --outdir ./dist --root ./src --target node --format esm --external mustache",
|
|
47
|
+
"build:js": "bun build ./src/api/index.ts ./src/client/index.ts ./src/extensions/index.ts ./src/extensions/react/index.ts ./src/prompts/index.ts ./src/hooks/index.ts ./src/resources/index.ts --outdir ./dist --root ./src --target node --format esm --external mustache --external react --external @tanstack/react-query",
|
|
44
48
|
"build:types": "tsc --project ./tsconfig.build.json",
|
|
45
49
|
"prepack": "bun run build",
|
|
46
50
|
"typecheck": "tsc --noEmit",
|
|
@@ -52,10 +56,25 @@
|
|
|
52
56
|
"dependencies": {
|
|
53
57
|
"mustache": "^4.2.0"
|
|
54
58
|
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@tanstack/react-query": "^5.0.0",
|
|
61
|
+
"react": "^19.0.0"
|
|
62
|
+
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"@tanstack/react-query": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"react": {
|
|
68
|
+
"optional": true
|
|
69
|
+
}
|
|
70
|
+
},
|
|
55
71
|
"devDependencies": {
|
|
72
|
+
"@tanstack/react-query": "^5.90.21",
|
|
56
73
|
"@types/bun": "1.3.13",
|
|
57
74
|
"@types/mustache": "^4.2.6",
|
|
75
|
+
"@types/react": "^19.2.0",
|
|
58
76
|
"pstdio-api-contracts": "workspace:*",
|
|
77
|
+
"react": "^19.0.0",
|
|
59
78
|
"typescript": "6.0.2"
|
|
60
79
|
}
|
|
61
80
|
}
|