summaryrefslogtreecommitdiffhomepage
path: root/packages/surface-registry/src
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-26 22:03:19 +0900
committerAdam Malczewski <[email protected]>2026-06-26 22:23:39 +0900
commit727c98c9dae516a2070eb950410314380a20c974 (patch)
tree52aa1022c54f11770be7e4e2a324f0a8b8b8deec /packages/surface-registry/src
parente59dc11f63b1df51142259bb2c406af8c9c8c2bb (diff)
downloaddispatch-727c98c9dae516a2070eb950410314380a20c974.tar.gz
dispatch-727c98c9dae516a2070eb950410314380a20c974.zip
style: switch from tabs to 2-space indentation
Diffstat (limited to 'packages/surface-registry/src')
-rw-r--r--packages/surface-registry/src/extension.ts28
-rw-r--r--packages/surface-registry/src/registry.test.ts224
-rw-r--r--packages/surface-registry/src/registry.ts100
3 files changed, 176 insertions, 176 deletions
diff --git a/packages/surface-registry/src/extension.ts b/packages/surface-registry/src/extension.ts
index 6d0ce22..2e0c038 100644
--- a/packages/surface-registry/src/extension.ts
+++ b/packages/surface-registry/src/extension.ts
@@ -3,21 +3,21 @@ import { createSurfaceRegistry } from "./registry.js";
import { surfaceRegistryHandle } from "./service.js";
export const manifest: Manifest = {
- id: "surface-registry",
- name: "Surface Registry",
- version: "0.0.0",
- apiVersion: "^0.1.0",
- trust: "bundled",
- activation: "eager",
- contributes: { services: ["surface-registry/registry"] },
+ id: "surface-registry",
+ name: "Surface Registry",
+ version: "0.0.0",
+ apiVersion: "^0.1.0",
+ trust: "bundled",
+ activation: "eager",
+ contributes: { services: ["surface-registry/registry"] },
};
export function createSurfaceRegistryExtension(): Extension {
- return {
- manifest,
- activate(host) {
- const registry = createSurfaceRegistry();
- host.provideService(surfaceRegistryHandle, registry);
- },
- };
+ return {
+ manifest,
+ activate(host) {
+ const registry = createSurfaceRegistry();
+ host.provideService(surfaceRegistryHandle, registry);
+ },
+ };
}
diff --git a/packages/surface-registry/src/registry.test.ts b/packages/surface-registry/src/registry.test.ts
index c47c979..151e449 100644
--- a/packages/surface-registry/src/registry.test.ts
+++ b/packages/surface-registry/src/registry.test.ts
@@ -4,119 +4,119 @@ import type { SurfaceProvider } from "./registry.js";
import { createSurfaceRegistry } from "./registry.js";
function fakeProvider(id: string, title?: string): SurfaceProvider {
- const catalogEntry: SurfaceCatalogEntry = {
- id,
- region: "default",
- title: title ?? `Surface ${id}`,
- };
- return {
- catalogEntry,
- getSpec(): SurfaceSpec {
- return {
- id,
- region: "default",
- title: catalogEntry.title,
- fields: [],
- };
- },
- invoke() {},
- };
+ const catalogEntry: SurfaceCatalogEntry = {
+ id,
+ region: "default",
+ title: title ?? `Surface ${id}`,
+ };
+ return {
+ catalogEntry,
+ getSpec(): SurfaceSpec {
+ return {
+ id,
+ region: "default",
+ title: catalogEntry.title,
+ fields: [],
+ };
+ },
+ invoke() {},
+ };
}
describe("createSurfaceRegistry", () => {
- describe("register + getCatalog", () => {
- it("returns the entry after registration", () => {
- const registry = createSurfaceRegistry();
- registry.register(fakeProvider("a", "Surface A"));
-
- const catalog = registry.getCatalog();
- expect(catalog).toHaveLength(1);
- expect(catalog[0]).toEqual({
- id: "a",
- region: "default",
- title: "Surface A",
- });
- });
-
- it("returns entries for multiple providers", () => {
- const registry = createSurfaceRegistry();
- registry.register(fakeProvider("a"));
- registry.register(fakeProvider("b"));
-
- const catalog = registry.getCatalog();
- expect(catalog).toHaveLength(2);
- expect(catalog.map((e) => e.id)).toEqual(["a", "b"]);
- });
- });
-
- describe("getSurface", () => {
- it("returns the provider for a known id", () => {
- const registry = createSurfaceRegistry();
- const provider = fakeProvider("x");
- registry.register(provider);
-
- expect(registry.getSurface("x")).toBe(provider);
- });
-
- it("returns undefined for an unknown id", () => {
- const registry = createSurfaceRegistry();
- expect(registry.getSurface("nonexistent")).toBeUndefined();
- });
- });
-
- describe("disposer", () => {
- it("removes the provider from catalog and lookup", () => {
- const registry = createSurfaceRegistry();
- const dispose = registry.register(fakeProvider("a"));
-
- expect(registry.getCatalog()).toHaveLength(1);
- expect(registry.getSurface("a")).toBeDefined();
-
- dispose();
-
- expect(registry.getCatalog()).toHaveLength(0);
- expect(registry.getSurface("a")).toBeUndefined();
- });
-
- it("is idempotent — calling dispose twice is safe", () => {
- const registry = createSurfaceRegistry();
- const dispose = registry.register(fakeProvider("a"));
-
- dispose();
- dispose();
-
- expect(registry.getCatalog()).toHaveLength(0);
- });
-
- it("does not remove a replacement provider with the same id", () => {
- const registry = createSurfaceRegistry();
- const first = fakeProvider("a", "First");
- const second = fakeProvider("a", "Second");
-
- const disposeFirst = registry.register(first);
- registry.register(second);
-
- disposeFirst();
-
- // The second provider should still be registered
- expect(registry.getSurface("a")).toBe(second);
- expect(registry.getCatalog()).toHaveLength(1);
- expect(registry.getCatalog()[0]?.title).toBe("Second");
- });
- });
-
- describe("duplicate-id behavior (last-wins)", () => {
- it("replaces an existing provider when registering the same id", () => {
- const registry = createSurfaceRegistry();
- const first = fakeProvider("a", "First");
- const second = fakeProvider("a", "Second");
-
- registry.register(first);
- registry.register(second);
-
- expect(registry.getSurface("a")).toBe(second);
- expect(registry.getCatalog()).toHaveLength(1);
- expect(registry.getCatalog()[0]?.title).toBe("Second");
- });
- });
+ describe("register + getCatalog", () => {
+ it("returns the entry after registration", () => {
+ const registry = createSurfaceRegistry();
+ registry.register(fakeProvider("a", "Surface A"));
+
+ const catalog = registry.getCatalog();
+ expect(catalog).toHaveLength(1);
+ expect(catalog[0]).toEqual({
+ id: "a",
+ region: "default",
+ title: "Surface A",
+ });
+ });
+
+ it("returns entries for multiple providers", () => {
+ const registry = createSurfaceRegistry();
+ registry.register(fakeProvider("a"));
+ registry.register(fakeProvider("b"));
+
+ const catalog = registry.getCatalog();
+ expect(catalog).toHaveLength(2);
+ expect(catalog.map((e) => e.id)).toEqual(["a", "b"]);
+ });
+ });
+
+ describe("getSurface", () => {
+ it("returns the provider for a known id", () => {
+ const registry = createSurfaceRegistry();
+ const provider = fakeProvider("x");
+ registry.register(provider);
+
+ expect(registry.getSurface("x")).toBe(provider);
+ });
+
+ it("returns undefined for an unknown id", () => {
+ const registry = createSurfaceRegistry();
+ expect(registry.getSurface("nonexistent")).toBeUndefined();
+ });
+ });
+
+ describe("disposer", () => {
+ it("removes the provider from catalog and lookup", () => {
+ const registry = createSurfaceRegistry();
+ const dispose = registry.register(fakeProvider("a"));
+
+ expect(registry.getCatalog()).toHaveLength(1);
+ expect(registry.getSurface("a")).toBeDefined();
+
+ dispose();
+
+ expect(registry.getCatalog()).toHaveLength(0);
+ expect(registry.getSurface("a")).toBeUndefined();
+ });
+
+ it("is idempotent — calling dispose twice is safe", () => {
+ const registry = createSurfaceRegistry();
+ const dispose = registry.register(fakeProvider("a"));
+
+ dispose();
+ dispose();
+
+ expect(registry.getCatalog()).toHaveLength(0);
+ });
+
+ it("does not remove a replacement provider with the same id", () => {
+ const registry = createSurfaceRegistry();
+ const first = fakeProvider("a", "First");
+ const second = fakeProvider("a", "Second");
+
+ const disposeFirst = registry.register(first);
+ registry.register(second);
+
+ disposeFirst();
+
+ // The second provider should still be registered
+ expect(registry.getSurface("a")).toBe(second);
+ expect(registry.getCatalog()).toHaveLength(1);
+ expect(registry.getCatalog()[0]?.title).toBe("Second");
+ });
+ });
+
+ describe("duplicate-id behavior (last-wins)", () => {
+ it("replaces an existing provider when registering the same id", () => {
+ const registry = createSurfaceRegistry();
+ const first = fakeProvider("a", "First");
+ const second = fakeProvider("a", "Second");
+
+ registry.register(first);
+ registry.register(second);
+
+ expect(registry.getSurface("a")).toBe(second);
+ expect(registry.getCatalog()).toHaveLength(1);
+ expect(registry.getCatalog()[0]?.title).toBe("Second");
+ });
+ });
});
diff --git a/packages/surface-registry/src/registry.ts b/packages/surface-registry/src/registry.ts
index 5780910..840ef5a 100644
--- a/packages/surface-registry/src/registry.ts
+++ b/packages/surface-registry/src/registry.ts
@@ -6,7 +6,7 @@ import type { SurfaceCatalog, SurfaceCatalogEntry, SurfaceSpec } from "@dispatch
* the default/global behaviour.
*/
export interface SurfaceContext {
- readonly conversationId?: string;
+ readonly conversationId?: string;
}
/**
@@ -14,20 +14,20 @@ export interface SurfaceContext {
* Each provider owns one surface identified by its catalog entry id.
*/
export interface SurfaceProvider {
- /** Discovery metadata for the surface catalog. */
- readonly catalogEntry: SurfaceCatalogEntry;
+ /** Discovery metadata for the surface catalog. */
+ readonly catalogEntry: SurfaceCatalogEntry;
- /** Build the current surface spec (may be async for dynamic surfaces). */
- getSpec(context?: SurfaceContext): SurfaceSpec | Promise<SurfaceSpec>;
+ /** Build the current surface spec (may be async for dynamic surfaces). */
+ getSpec(context?: SurfaceContext): SurfaceSpec | Promise<SurfaceSpec>;
- /** Run a backend action by id with an optional payload. */
- invoke(actionId: string, payload?: unknown, context?: SurfaceContext): void | Promise<void>;
+ /** Run a backend action by id with an optional payload. */
+ invoke(actionId: string, payload?: unknown, context?: SurfaceContext): void | Promise<void>;
- /**
- * Optional: subscribe to spec changes. Returns an unsubscribe disposer.
- * When the spec changes, the caller should re-fetch via getSpec() and push.
- */
- subscribe?(onChange: () => void): () => void;
+ /**
+ * Optional: subscribe to spec changes. Returns an unsubscribe disposer.
+ * When the spec changes, the caller should re-fetch via getSpec() and push.
+ */
+ subscribe?(onChange: () => void): () => void;
}
/**
@@ -35,18 +35,18 @@ export interface SurfaceProvider {
* `host.getService(surfaceRegistryHandle)`.
*/
export interface SurfaceRegistry {
- /**
- * Register a surface provider. Returns an unregister disposer.
- * If a provider with the same id is already registered, the new one
- * replaces it (last-wins semantics).
- */
- register(provider: SurfaceProvider): () => void;
+ /**
+ * Register a surface provider. Returns an unregister disposer.
+ * If a provider with the same id is already registered, the new one
+ * replaces it (last-wins semantics).
+ */
+ register(provider: SurfaceProvider): () => void;
- /** Return discovery metadata for all currently registered providers. */
- getCatalog(): SurfaceCatalog;
+ /** Return discovery metadata for all currently registered providers. */
+ getCatalog(): SurfaceCatalog;
- /** Look up a provider by its surface id. */
- getSurface(id: string): SurfaceProvider | undefined;
+ /** Look up a provider by its surface id. */
+ getSurface(id: string): SurfaceProvider | undefined;
}
/**
@@ -54,36 +54,36 @@ export interface SurfaceRegistry {
* the decision logic is a plain Map behind the SurfaceRegistry interface.
*/
export function createSurfaceRegistry(): SurfaceRegistry {
- const providers = new Map<string, SurfaceProvider>();
+ const providers = new Map<string, SurfaceProvider>();
- return {
- register(provider: SurfaceProvider): () => void {
- const id = provider.catalogEntry.id;
- providers.set(id, provider);
+ return {
+ register(provider: SurfaceProvider): () => void {
+ const id = provider.catalogEntry.id;
+ providers.set(id, provider);
- let disposed = false;
- return () => {
- if (!disposed) {
- disposed = true;
- // Only delete if the current entry is still this provider
- // (another register with the same id may have replaced it).
- if (providers.get(id) === provider) {
- providers.delete(id);
- }
- }
- };
- },
+ let disposed = false;
+ return () => {
+ if (!disposed) {
+ disposed = true;
+ // Only delete if the current entry is still this provider
+ // (another register with the same id may have replaced it).
+ if (providers.get(id) === provider) {
+ providers.delete(id);
+ }
+ }
+ };
+ },
- getCatalog(): SurfaceCatalog {
- const entries: SurfaceCatalogEntry[] = [];
- for (const provider of providers.values()) {
- entries.push(provider.catalogEntry);
- }
- return entries;
- },
+ getCatalog(): SurfaceCatalog {
+ const entries: SurfaceCatalogEntry[] = [];
+ for (const provider of providers.values()) {
+ entries.push(provider.catalogEntry);
+ }
+ return entries;
+ },
- getSurface(id: string): SurfaceProvider | undefined {
- return providers.get(id);
- },
- };
+ getSurface(id: string): SurfaceProvider | undefined {
+ return providers.get(id);
+ },
+ };
}