@pstdio/sdk 0.22.1 → 0.23.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 +26 -0
- package/dist/client/index.js +15 -10
- package/dist/client.d.ts +1 -0
- package/dist/extensions/index.js +198 -2
- package/dist/extensions.d.ts +70 -1
- package/dist/hooks.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,32 @@ Page targets change location. Panel targets preserve it. Compound targets contai
|
|
|
32
32
|
|
|
33
33
|
Use `qualifyRef(owner, ref)` in provider contract modules. Keep definitions local and pass qualified refs between extensions. For webviews, declare capabilities and call the typed `GuestHost`; `placement.close` closes the calling placement through the normal tab controller.
|
|
34
34
|
|
|
35
|
+
## Dashboard URLs
|
|
36
|
+
|
|
37
|
+
Use `serializePageUrl({ projectId, page, resource })` to return a dashboard link from a command. The page descriptor contains its `id`, qualified `ref`, and declared `path`; `resource` is optional. The workbench uses the same route and resource codec.
|
|
38
|
+
|
|
39
|
+
Use `parsePageUrl({ url, projectId, pages })` to resolve a saved link against the expected project and allowed page descriptors. It accepts root-relative URLs and returns a page ID and optional resource, or `undefined` for an unsupported destination. It never fetches the URL. The caller still checks its supported resource kind and owner. A URL grants no access.
|
|
40
|
+
|
|
41
|
+
Page and panel navigation targets remain the API for opening views and tabs.
|
|
42
|
+
|
|
43
|
+
## Webview change subscriptions
|
|
44
|
+
|
|
45
|
+
Use the typed client's `events.subscribe(event, listener)` to refetch after a command changes data:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const client = createWebviewClient<typeof commands>(host);
|
|
49
|
+
const stop = client.events.subscribe(
|
|
50
|
+
{ kind: "event", id: "notes.changed" },
|
|
51
|
+
() => void reloadNotes(),
|
|
52
|
+
);
|
|
53
|
+
// Dispose when the view unmounts.
|
|
54
|
+
stop();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Local event refs use the client's extension owner: `{ kind: "event", id: "notes.changed" }` resolves to `<extensionId>.event.notes.changed`. Qualified event refs can name another extension in the same project. String IDs are already resolved and stay unchanged. Host-owned and command-lifecycle refs follow the runtime's rules through the shared `resolveEventReferenceId` helper. Commands emit events after committing their changes through `ctx.events.emit`.
|
|
58
|
+
|
|
59
|
+
The host delivers only events matching the view's project. Projectless events reach global views only. Listeners also run when host sync connects or reconnects, so a mounted view can reconcile missed changes. Load current data when mounting, then subscribe; events are invalidations, not stored records or an exactly-once stream. Duplicate refetches must be safe. The subscription does not reload the webview document or grant new permissions.
|
|
60
|
+
|
|
35
61
|
## Package delivery
|
|
36
62
|
|
|
37
63
|
Development and installed consumers both load built SDK entries. Repository development builds this package before starting the source CLI. Builds stage release files under `.publish` through the shared release script. Package verification installs those same staged artifacts into a temporary directory outside the monorepo and checks every entry point.
|
package/dist/client/index.js
CHANGED
|
@@ -499,21 +499,26 @@ var createSyncClient = (clientOptions) => ({
|
|
|
499
499
|
if (event === "init")
|
|
500
500
|
setConnected();
|
|
501
501
|
};
|
|
502
|
+
const readConnection = async (signal) => {
|
|
503
|
+
const response = await resolveFetch(clientOptions)(resolveClientUrl(resolveBaseUrl(clientOptions), buildSyncStreamPath(lastSeq)), {
|
|
504
|
+
headers: Object.fromEntries(createRequestHeaders(clientOptions).entries()),
|
|
505
|
+
signal,
|
|
506
|
+
credentials: "same-origin"
|
|
507
|
+
});
|
|
508
|
+
if (!response.ok || !response.body)
|
|
509
|
+
throw new Error("SSE connection failed");
|
|
510
|
+
if (closed)
|
|
511
|
+
return;
|
|
512
|
+
if (lastSeq > 0)
|
|
513
|
+
setConnected();
|
|
514
|
+
await readSseStream(response.body, ({ event, data }) => handleEvent(event, data), { signal });
|
|
515
|
+
};
|
|
502
516
|
const connect = async () => {
|
|
503
517
|
if (closed)
|
|
504
518
|
return;
|
|
505
519
|
abortController = new AbortController;
|
|
506
520
|
try {
|
|
507
|
-
|
|
508
|
-
headers: Object.fromEntries(createRequestHeaders(clientOptions).entries()),
|
|
509
|
-
signal: abortController.signal,
|
|
510
|
-
credentials: "same-origin"
|
|
511
|
-
});
|
|
512
|
-
if (!response.ok || !response.body)
|
|
513
|
-
throw new Error("SSE connection failed");
|
|
514
|
-
await readSseStream(response.body, ({ event, data }) => handleEvent(event, data), {
|
|
515
|
-
signal: abortController.signal
|
|
516
|
-
});
|
|
521
|
+
await readConnection(abortController.signal);
|
|
517
522
|
} catch (err) {
|
|
518
523
|
if (closed || err.name === "AbortError")
|
|
519
524
|
return;
|
package/dist/client.d.ts
CHANGED
|
@@ -1432,6 +1432,7 @@ export declare type SseEvent = {
|
|
|
1432
1432
|
};
|
|
1433
1433
|
|
|
1434
1434
|
export declare type StartSyncInput = SyncWriterProvider & {
|
|
1435
|
+
/** Called after the initial snapshot, or when a cursor-based connection resumes. */
|
|
1435
1436
|
onConnected?: () => void;
|
|
1436
1437
|
onDisconnected?: () => void;
|
|
1437
1438
|
onConnectionLost?: () => void;
|
package/dist/extensions/index.js
CHANGED
|
@@ -215,7 +215,7 @@ var WEBVIEW_HOST_CAPABILITIES = [
|
|
|
215
215
|
...ALWAYS_AVAILABLE_WEBVIEW_CAPABILITIES
|
|
216
216
|
];
|
|
217
217
|
// package.json
|
|
218
|
-
var version = "0.
|
|
218
|
+
var version = "0.23.0";
|
|
219
219
|
|
|
220
220
|
// src/version.ts
|
|
221
221
|
var SDK_VERSION = version;
|
|
@@ -345,6 +345,180 @@ var defineExtensionView = (definition) => ({
|
|
|
345
345
|
return typeof cleanup === "function" ? cleanup : () => {};
|
|
346
346
|
}
|
|
347
347
|
});
|
|
348
|
+
// src/extensions/event-reference.ts
|
|
349
|
+
var resolveEventReferenceId = (ref, ownerExtensionId) => {
|
|
350
|
+
if (typeof ref === "string")
|
|
351
|
+
return ref;
|
|
352
|
+
const extensionId = ref.extensionId ?? ownerExtensionId;
|
|
353
|
+
if (!extensionId || extensionId === "pstdio")
|
|
354
|
+
return ref.id;
|
|
355
|
+
const lifecycle = /^(command\.(?:requested|started|completed|rejected|failed):)(.+)$/.exec(ref.id);
|
|
356
|
+
if (lifecycle)
|
|
357
|
+
return `${lifecycle[1]}${extensionId}.command.${lifecycle[2]}`;
|
|
358
|
+
return `${extensionId}.event.${ref.id}`;
|
|
359
|
+
};
|
|
360
|
+
// src/extensions/page-resource-codec.ts
|
|
361
|
+
var fromUri = (uri) => {
|
|
362
|
+
try {
|
|
363
|
+
const parsed = new URL(uri);
|
|
364
|
+
if (parsed.protocol !== "pstdio:" || parsed.hostname !== "extension-resource")
|
|
365
|
+
return;
|
|
366
|
+
const [type, id, ...rest] = parsed.pathname.slice(1).split("/");
|
|
367
|
+
if (!type || !id || rest.length > 0)
|
|
368
|
+
return;
|
|
369
|
+
const extensionId = parsed.searchParams.get("extensionId");
|
|
370
|
+
const projectId = parsed.searchParams.get("projectId");
|
|
371
|
+
return {
|
|
372
|
+
type: decodeURIComponent(type),
|
|
373
|
+
id: decodeURIComponent(id),
|
|
374
|
+
...extensionId ? { extensionId } : {},
|
|
375
|
+
...projectId ? { projectId } : {}
|
|
376
|
+
};
|
|
377
|
+
} catch {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
var defaultPageResourceCodec = {
|
|
382
|
+
normalize: (resource) => ({ ...resource }),
|
|
383
|
+
toUri: (resource) => {
|
|
384
|
+
const uri = `pstdio://extension-resource/${encodeURIComponent(resource.type)}/${encodeURIComponent(resource.id)}`;
|
|
385
|
+
const query = new URLSearchParams;
|
|
386
|
+
if (resource.extensionId)
|
|
387
|
+
query.set("extensionId", resource.extensionId);
|
|
388
|
+
if (resource.projectId)
|
|
389
|
+
query.set("projectId", resource.projectId);
|
|
390
|
+
return query.size ? `${uri}?${query}` : uri;
|
|
391
|
+
},
|
|
392
|
+
fromUri
|
|
393
|
+
};
|
|
394
|
+
// src/extensions/page-url.ts
|
|
395
|
+
var hostExtensionId = "pstdio";
|
|
396
|
+
var pageRefKey = (ref) => `${ref.extensionId ?? ""}:page:${ref.id}`;
|
|
397
|
+
var pageForRef = (pages, ref) => pages.find((page) => pageRefKey(page.ref) === pageRefKey(ref));
|
|
398
|
+
var encodePath = (path) => path.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
|
|
399
|
+
var routePath = (projectId, page) => {
|
|
400
|
+
const project = `/projects/${encodeURIComponent(projectId)}`;
|
|
401
|
+
const path = encodePath(page.path);
|
|
402
|
+
if (page.ref.extensionId === hostExtensionId)
|
|
403
|
+
return path ? `${project}/${path}` : project;
|
|
404
|
+
if (!page.ref.extensionId)
|
|
405
|
+
throw new Error(`Page "${page.id}" has no extension id`);
|
|
406
|
+
return `${project}/extensions/${encodeURIComponent(page.ref.extensionId)}/${path}`;
|
|
407
|
+
};
|
|
408
|
+
var normalizedSection = (value) => {
|
|
409
|
+
if (!value || typeof value !== "object" || !Array.isArray(value.anchors))
|
|
410
|
+
return;
|
|
411
|
+
const anchors = value.anchors;
|
|
412
|
+
if (anchors.some((anchor) => !anchor || typeof anchor !== "object" || typeof anchor.id !== "string" || typeof anchor.heading !== "string" || anchor.occurrence !== undefined && (!Number.isInteger(anchor.occurrence) || Number(anchor.occurrence) < 0))) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
anchors: anchors.map((anchor) => {
|
|
417
|
+
const value2 = anchor;
|
|
418
|
+
return {
|
|
419
|
+
id: value2.id,
|
|
420
|
+
heading: value2.heading,
|
|
421
|
+
...value2.occurrence !== undefined ? { occurrence: value2.occurrence } : {}
|
|
422
|
+
};
|
|
423
|
+
})
|
|
424
|
+
};
|
|
425
|
+
};
|
|
426
|
+
var serializeSection = (section) => {
|
|
427
|
+
const normalized = normalizedSection(section);
|
|
428
|
+
if (!normalized)
|
|
429
|
+
throw new Error("Page location has an invalid section");
|
|
430
|
+
return JSON.stringify(normalized);
|
|
431
|
+
};
|
|
432
|
+
var parseSection = (value) => {
|
|
433
|
+
try {
|
|
434
|
+
return normalizedSection(JSON.parse(value));
|
|
435
|
+
} catch {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
var serializeWorkbenchPageUrl = (input) => {
|
|
440
|
+
const page = pageForRef(input.pages, input.location.page);
|
|
441
|
+
if (!page)
|
|
442
|
+
throw new Error(`Unknown page ref: ${pageRefKey(input.location.page)}`);
|
|
443
|
+
const query = new URLSearchParams;
|
|
444
|
+
if (input.location.resource) {
|
|
445
|
+
query.set("resource", input.resources.toUri(input.resources.normalize(input.location.resource)));
|
|
446
|
+
}
|
|
447
|
+
if (input.location.section)
|
|
448
|
+
query.set("section", serializeSection(input.location.section));
|
|
449
|
+
const encoded = query.toString();
|
|
450
|
+
const path = routePath(input.projectId, page);
|
|
451
|
+
return encoded ? `${path}?${encoded}` : path;
|
|
452
|
+
};
|
|
453
|
+
var decodedSegments = (pathname) => {
|
|
454
|
+
try {
|
|
455
|
+
return pathname.split("/").filter(Boolean).map((segment) => decodeURIComponent(segment));
|
|
456
|
+
} catch {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
var isWorkbenchProjectUrl = (urlValue, projectId) => {
|
|
461
|
+
try {
|
|
462
|
+
const url = new URL(urlValue, "http://workbench.local");
|
|
463
|
+
const segments = decodedSegments(url.pathname);
|
|
464
|
+
return Boolean(segments && segments[0] === "projects" && segments[1] === projectId);
|
|
465
|
+
} catch {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
var pageForRoute = (pages, extensionId, path) => pages.find((page) => page.ref.extensionId === extensionId && page.path === path);
|
|
470
|
+
var parseResource = (uri, resources) => {
|
|
471
|
+
try {
|
|
472
|
+
const resource = resources.fromUri(uri);
|
|
473
|
+
return resource ? resources.normalize(resource) : undefined;
|
|
474
|
+
} catch {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
var parseWorkbenchPageUrl = (input) => {
|
|
479
|
+
let url;
|
|
480
|
+
try {
|
|
481
|
+
url = new URL(input.url, "http://workbench.local");
|
|
482
|
+
} catch {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const segments = decodedSegments(url.pathname);
|
|
486
|
+
if (!segments || segments[0] !== "projects" || segments[1] !== input.projectId)
|
|
487
|
+
return;
|
|
488
|
+
const route = segments.slice(2);
|
|
489
|
+
const extensionRoute = route[0] === "extensions";
|
|
490
|
+
const extensionId = extensionRoute ? route[1] : hostExtensionId;
|
|
491
|
+
const path = (extensionRoute ? route.slice(2) : route).join("/");
|
|
492
|
+
if (!extensionId || extensionRoute && !path)
|
|
493
|
+
return;
|
|
494
|
+
const page = pageForRoute(input.pages, extensionId, path);
|
|
495
|
+
if (!page)
|
|
496
|
+
return;
|
|
497
|
+
const resourceValue = url.searchParams.get("resource");
|
|
498
|
+
const resource = resourceValue ? parseResource(resourceValue, input.resources) : undefined;
|
|
499
|
+
if (resourceValue && !resource)
|
|
500
|
+
return;
|
|
501
|
+
const sectionValue = url.searchParams.get("section");
|
|
502
|
+
const section = sectionValue ? parseSection(sectionValue) : undefined;
|
|
503
|
+
if (sectionValue && !section)
|
|
504
|
+
return;
|
|
505
|
+
return {
|
|
506
|
+
pageId: page.id,
|
|
507
|
+
...resource ? { resource } : {},
|
|
508
|
+
...section ? { section } : {}
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
var serializePageUrl = (input) => serializeWorkbenchPageUrl({
|
|
512
|
+
projectId: input.projectId,
|
|
513
|
+
location: { page: input.page.ref, resource: input.resource },
|
|
514
|
+
pages: [input.page],
|
|
515
|
+
resources: defaultPageResourceCodec
|
|
516
|
+
});
|
|
517
|
+
var parsePageUrl = (input) => {
|
|
518
|
+
if (!input.url.startsWith("/") || input.url.startsWith("//"))
|
|
519
|
+
return;
|
|
520
|
+
return parseWorkbenchPageUrl({ ...input, resources: defaultPageResourceCodec });
|
|
521
|
+
};
|
|
348
522
|
// src/extensions/params.ts
|
|
349
523
|
var params = {
|
|
350
524
|
text: (options) => ({ type: "text", ...options }),
|
|
@@ -459,6 +633,19 @@ var createTerminalSessionBridge = (host) => ({
|
|
|
459
633
|
// src/extensions/webview-capabilities.ts
|
|
460
634
|
var artifactMountId = (mount) => typeof mount === "string" ? mount : mount.id;
|
|
461
635
|
var artifactsRead = (mount) => `artifacts.read:${artifactMountId(mount)}`;
|
|
636
|
+
// src/extensions/webview-events.ts
|
|
637
|
+
var EXTENSION_EVENTS_SCOPE = "extension.events";
|
|
638
|
+
var createWebviewEventsClient = (host, extensionId) => ({
|
|
639
|
+
subscribe(event, listener) {
|
|
640
|
+
const id = resolveEventReferenceId(event, extensionId);
|
|
641
|
+
return host.onEvent(EXTENSION_EVENTS_SCOPE, (payload) => {
|
|
642
|
+
const notification = payload;
|
|
643
|
+
if (notification.type === "reset" || notification.type === "changed" && notification.id === id)
|
|
644
|
+
listener();
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
|
|
462
649
|
// src/extensions/webview-client.ts
|
|
463
650
|
var createWebviewClient = (host, options) => {
|
|
464
651
|
const extensionId = options?.extensionId ?? host.extensionId;
|
|
@@ -495,7 +682,8 @@ var createWebviewClient = (host, options) => {
|
|
|
495
682
|
readText: (mount, path) => host.call("artifacts.read", { op: "readText", mount: artifactMountId(mount), path }),
|
|
496
683
|
imageUrl: (mount, path) => host.call("artifacts.read", { op: "imageUrl", mount: artifactMountId(mount), path })
|
|
497
684
|
};
|
|
498
|
-
|
|
685
|
+
const events = createWebviewEventsClient(host, extensionId);
|
|
686
|
+
return { artifacts, commands, events, settings };
|
|
499
687
|
};
|
|
500
688
|
// src/extensions/when.ts
|
|
501
689
|
var matchesResourceWhen = (when, resourceType) => {
|
|
@@ -520,17 +708,23 @@ export {
|
|
|
520
708
|
unwrapCommandOutcome,
|
|
521
709
|
sessionSlots,
|
|
522
710
|
sessionEvents,
|
|
711
|
+
serializeWorkbenchPageUrl,
|
|
712
|
+
serializePageUrl,
|
|
523
713
|
resourceMenuSlotRef2 as resourceMenuSlotRef,
|
|
524
714
|
resourceKey,
|
|
715
|
+
resolveEventReferenceId,
|
|
525
716
|
qualifyRef,
|
|
526
717
|
projectSlots,
|
|
527
718
|
projectEvents,
|
|
719
|
+
parseWorkbenchPageUrl,
|
|
720
|
+
parsePageUrl,
|
|
528
721
|
params,
|
|
529
722
|
packageAsset,
|
|
530
723
|
matchesResourceWhen,
|
|
531
724
|
localContributionIdPattern,
|
|
532
725
|
localContributionIdGrammar,
|
|
533
726
|
l10n,
|
|
727
|
+
isWorkbenchProjectUrl,
|
|
534
728
|
isValidLocalContributionId,
|
|
535
729
|
isLocalizedString,
|
|
536
730
|
gitEvents,
|
|
@@ -569,6 +763,7 @@ export {
|
|
|
569
763
|
defineCommand,
|
|
570
764
|
defineArtifactMount,
|
|
571
765
|
defineActivityItem,
|
|
766
|
+
defaultPageResourceCodec,
|
|
572
767
|
createWebviewClient,
|
|
573
768
|
createTerminalSessionBridge,
|
|
574
769
|
commandRef,
|
|
@@ -580,6 +775,7 @@ export {
|
|
|
580
775
|
WEBVIEW_HOST_CAPABILITIES,
|
|
581
776
|
WEBVIEW_DECLARABLE_CAPABILITIES,
|
|
582
777
|
SDK_VERSION,
|
|
778
|
+
EXTENSION_EVENTS_SCOPE,
|
|
583
779
|
EXTENSION_API_VERSION,
|
|
584
780
|
ALWAYS_AVAILABLE_WEBVIEW_CAPABILITIES
|
|
585
781
|
};
|
package/dist/extensions.d.ts
CHANGED
|
@@ -680,6 +680,9 @@ export declare interface DateControl extends BaseControl {
|
|
|
680
680
|
max?: string;
|
|
681
681
|
}
|
|
682
682
|
|
|
683
|
+
/** Resource URI conversion belongs to route and persistence adapters. */
|
|
684
|
+
export declare const defaultPageResourceCodec: PageResourceCodec;
|
|
685
|
+
|
|
683
686
|
export declare const defineActivityItem: <Definition extends Omit<ActivityItemContribution, "ref">>(definition: Definition) => Definition & ContributionDefinition<"activity-item">;
|
|
684
687
|
|
|
685
688
|
export declare const defineArtifactMount: <Definition extends Omit<ArtifactMountContribution, "ref">>(definition: Definition) => Definition & ContributionDefinition<"artifact-mount">;
|
|
@@ -815,7 +818,7 @@ export declare interface EventRef<TPayload extends Struct = Struct> {
|
|
|
815
818
|
/** Build a typed event reference from separate ownership and local identity. */
|
|
816
819
|
export declare const eventRef: <TPayload extends Struct = Struct>(input: ExternalRefInput) => EventRef<TPayload>;
|
|
817
820
|
|
|
818
|
-
declare type ExactOptions<Definition, Contract> = unknown extends Contract ? Definition : [Contract] extends [Definition] ? Definition : Contract extends unknown ? Definition extends Contract ? Contract extends EventRef ? Definition : Definition extends (...args: never[]) => unknown ? Definition : Definition extends readonly unknown[] ? Contract extends readonly (infer Item)[] ? {
|
|
821
|
+
declare type ExactOptions<Definition, Contract> = unknown extends Contract ? Definition : [Contract] extends [Definition] ? Definition : Contract extends unknown ? Definition extends Contract ? Contract extends EventRef | CommandRef ? Definition : Definition extends (...args: never[]) => unknown ? Definition : Definition extends readonly unknown[] ? Contract extends readonly (infer Item)[] ? {
|
|
819
822
|
[Index in keyof Definition]: ExactOptions<Definition[Index], Item>;
|
|
820
823
|
} : never : Definition extends object ? {
|
|
821
824
|
[Key in keyof Definition]: Key extends keyof Contract ? ExactOptions<Definition[Key], Contract[Key]> : never;
|
|
@@ -824,6 +827,8 @@ declare type ExactOptions<Definition, Contract> = unknown extends Contract ? Def
|
|
|
824
827
|
/** Current host extension API version. `engines.pstdio` in package.json is a semver range checked against this. */
|
|
825
828
|
export declare const EXTENSION_API_VERSION = "1.0.0-alpha.10";
|
|
826
829
|
|
|
830
|
+
export declare const EXTENSION_EVENTS_SCOPE = "extension.events";
|
|
831
|
+
|
|
827
832
|
export declare interface ExtensionActivityApi {
|
|
828
833
|
record(input: {
|
|
829
834
|
message: string;
|
|
@@ -1475,6 +1480,8 @@ export declare const isLocalizedString: (value: unknown) => value is LocalizedSt
|
|
|
1475
1480
|
|
|
1476
1481
|
export declare const isValidLocalContributionId: (id: string) => boolean;
|
|
1477
1482
|
|
|
1483
|
+
export declare const isWorkbenchProjectUrl: (urlValue: string, projectId: string) => boolean;
|
|
1484
|
+
|
|
1478
1485
|
export declare type JsonObject = {
|
|
1479
1486
|
[key: string]: JsonValue;
|
|
1480
1487
|
};
|
|
@@ -2033,6 +2040,12 @@ declare type PagePanelRefs<Slots extends readonly PageSlot[]> = {
|
|
|
2033
2040
|
|
|
2034
2041
|
export declare type PageRef = ContributionRef<"page">;
|
|
2035
2042
|
|
|
2043
|
+
declare interface PageResourceCodec {
|
|
2044
|
+
normalize(resource: ResourceRef): ResourceRef;
|
|
2045
|
+
toUri(resource: ResourceRef): string;
|
|
2046
|
+
fromUri(uri: string): ResourceRef | undefined;
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2036
2049
|
/** A page-owned panel. Main presentation and routed context belong to the page. */
|
|
2037
2050
|
export declare interface PageSlot extends PlacementPresentation {
|
|
2038
2051
|
readonly id: string;
|
|
@@ -2054,6 +2067,12 @@ export declare type PageSlotRegion = ExtensionPanelRegion;
|
|
|
2054
2067
|
|
|
2055
2068
|
export declare type PageSlotRole = "primary" | "auxiliary";
|
|
2056
2069
|
|
|
2070
|
+
export declare interface PageUrlDefinition {
|
|
2071
|
+
id: string;
|
|
2072
|
+
ref: PageRef;
|
|
2073
|
+
path: string;
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2057
2076
|
export declare type PanelRef = PlacementRef | PageSlotRef;
|
|
2058
2077
|
|
|
2059
2078
|
declare type ParamBase<TValue, TRequired extends boolean | undefined = boolean | undefined> = {
|
|
@@ -2139,6 +2158,26 @@ export declare type ParamType = "text" | "longtext" | "markdown" | "number" | "b
|
|
|
2139
2158
|
|
|
2140
2159
|
export declare type ParamValue<TDescriptor extends ParamDescriptor> = TDescriptor extends ParamDescriptor<infer V> ? V : never;
|
|
2141
2160
|
|
|
2161
|
+
export declare interface ParsedWorkbenchPageUrl {
|
|
2162
|
+
pageId: string;
|
|
2163
|
+
resource?: ResourceRef;
|
|
2164
|
+
section?: FileRendererSectionTarget;
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
/** Resolve a dashboard URL against the caller's declared pages and project. */
|
|
2168
|
+
export declare const parsePageUrl: (input: {
|
|
2169
|
+
url: string;
|
|
2170
|
+
projectId: string;
|
|
2171
|
+
pages: readonly PageUrlDefinition[];
|
|
2172
|
+
}) => ParsedWorkbenchPageUrl | undefined;
|
|
2173
|
+
|
|
2174
|
+
export declare const parseWorkbenchPageUrl: (input: {
|
|
2175
|
+
url: string;
|
|
2176
|
+
projectId: string;
|
|
2177
|
+
pages: readonly PageUrlDefinition[];
|
|
2178
|
+
resources: PageResourceCodec;
|
|
2179
|
+
}) => ParsedWorkbenchPageUrl | undefined;
|
|
2180
|
+
|
|
2142
2181
|
export declare type PatchPart = {
|
|
2143
2182
|
type: "patch";
|
|
2144
2183
|
hash?: string;
|
|
@@ -2400,6 +2439,9 @@ declare type RequiredParamKeys<TSchema extends ParamObjectSchema> = {
|
|
|
2400
2439
|
} ? K : never;
|
|
2401
2440
|
}[keyof TSchema];
|
|
2402
2441
|
|
|
2442
|
+
/** Resolve an event ref using the same ownership rules as commands and hooks. */
|
|
2443
|
+
export declare const resolveEventReferenceId: (ref: RendererEventReference, ownerExtensionId?: string) => string;
|
|
2444
|
+
|
|
2403
2445
|
export declare interface ResourceAnchor extends ResourceRef {
|
|
2404
2446
|
role?: ResourceRole;
|
|
2405
2447
|
}
|
|
@@ -2583,6 +2625,20 @@ export declare interface SerializedError {
|
|
|
2583
2625
|
cause?: JsonValue;
|
|
2584
2626
|
}
|
|
2585
2627
|
|
|
2628
|
+
/** Serialize a project page using the same resource encoding as the dashboard. */
|
|
2629
|
+
export declare const serializePageUrl: (input: {
|
|
2630
|
+
projectId: string;
|
|
2631
|
+
page: PageUrlDefinition;
|
|
2632
|
+
resource?: ResourceRef;
|
|
2633
|
+
}) => string;
|
|
2634
|
+
|
|
2635
|
+
export declare const serializeWorkbenchPageUrl: (input: {
|
|
2636
|
+
projectId: string;
|
|
2637
|
+
location: PageLocation;
|
|
2638
|
+
pages: readonly PageUrlDefinition[];
|
|
2639
|
+
resources: PageResourceCodec;
|
|
2640
|
+
}) => string;
|
|
2641
|
+
|
|
2586
2642
|
declare type SessionAttachmentRef = z.infer<typeof sessionAttachmentRefSchema>;
|
|
2587
2643
|
|
|
2588
2644
|
declare const sessionAttachmentRefSchema: z.ZodObject<{
|
|
@@ -3221,6 +3277,7 @@ export declare type WebviewCapabilityDeclaration = WebviewDeclarableCapability |
|
|
|
3221
3277
|
export declare type WebviewClient<TCommands, TSettings = undefined> = {
|
|
3222
3278
|
artifacts: WebviewArtifactsClient;
|
|
3223
3279
|
commands: WebviewCommandsClient<TCommands>;
|
|
3280
|
+
events: WebviewEventsClient;
|
|
3224
3281
|
settings: WebviewSettingsClient<ClientSettingsMap<TSettings>>;
|
|
3225
3282
|
};
|
|
3226
3283
|
|
|
@@ -3249,6 +3306,18 @@ export declare interface WebviewContribution {
|
|
|
3249
3306
|
|
|
3250
3307
|
export declare type WebviewDeclarableCapability = (typeof WEBVIEW_DECLARABLE_CAPABILITIES)[number];
|
|
3251
3308
|
|
|
3309
|
+
export declare interface WebviewEventsClient {
|
|
3310
|
+
/** Refetch on a matching event or host sync reconnect. Returns the unsubscribe function. */
|
|
3311
|
+
subscribe(event: RendererEventReference, listener: () => void): () => void;
|
|
3312
|
+
}
|
|
3313
|
+
|
|
3314
|
+
export declare type WebviewExtensionEvent = {
|
|
3315
|
+
type: "changed";
|
|
3316
|
+
id: string;
|
|
3317
|
+
} | {
|
|
3318
|
+
type: "reset";
|
|
3319
|
+
};
|
|
3320
|
+
|
|
3252
3321
|
export declare interface WebviewExtensionSettingKeyParams {
|
|
3253
3322
|
key: string;
|
|
3254
3323
|
}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1465,6 +1465,7 @@ declare type SseEvent = {
|
|
|
1465
1465
|
};
|
|
1466
1466
|
|
|
1467
1467
|
declare type StartSyncInput = SyncWriterProvider & {
|
|
1468
|
+
/** Called after the initial snapshot, or when a cursor-based connection resumes. */
|
|
1468
1469
|
onConnected?: () => void;
|
|
1469
1470
|
onDisconnected?: () => void;
|
|
1470
1471
|
onConnectionLost?: () => void;
|