Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions packages/extension/src/kernel-integration/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ import {
} from './execute-db-query.ts';
import { getStatusHandler, getStatusSpec } from './get-status.ts';
import { launchVatHandler, launchVatSpec } from './launch-vat.ts';
import { queueMessageHandler, queueMessageSpec } from './queue-message.ts';
import { reloadConfigHandler, reloadConfigSpec } from './reload-config.ts';
import { restartVatHandler, restartVatSpec } from './restart-vat.ts';
import {
sendVatCommandHandler,
sendVatCommandSpec,
} from './send-vat-command.ts';
import {
terminateAllVatsHandler,
terminateAllVatsSpec,
Expand All @@ -35,7 +32,7 @@ export const handlers = {
launchVat: launchVatHandler,
reload: reloadConfigHandler,
restartVat: restartVatHandler,
sendVatCommand: sendVatCommandHandler,
queueMessage: queueMessageHandler,
terminateAllVats: terminateAllVatsHandler,
collectGarbage: collectGarbageHandler,
terminateVat: terminateVatHandler,
Expand All @@ -52,7 +49,7 @@ export const methodSpecs = {
launchVat: launchVatSpec,
reload: reloadConfigSpec,
restartVat: restartVatSpec,
sendVatCommand: sendVatCommandSpec,
queueMessage: queueMessageSpec,
terminateAllVats: terminateAllVatsSpec,
collectGarbage: collectGarbageSpec,
terminateVat: terminateVatSpec,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type { CapData } from '@endo/marshal';
import type { Kernel } from '@metamask/ocap-kernel';
import { describe, it, expect, vi, beforeEach } from 'vitest';

import { queueMessageSpec, queueMessageHandler } from './queue-message.ts';

describe('queueMessageSpec', () => {
it('should define the correct method name', () => {
expect(queueMessageSpec.method).toBe('queueMessage');
});

it('should define the correct parameter structure', () => {
// Valid parameters should pass validation
const validParams = [
'target123',
'methodName',
[1, 'string', { key: 'value' }],
];
expect(() => queueMessageSpec.params.create(validParams)).not.toThrow();

// Invalid parameters should fail validation
const invalidParams = ['target123', 123, [1, 'string']];
expect(() => queueMessageSpec.params.create(invalidParams)).toThrow(
'Expected a string',
);
});

it('should define the correct result structure', () => {
// Valid result should pass validation
const validResult: CapData<string> = { body: 'result', slots: [] };
expect(() => queueMessageSpec.result.create(validResult)).not.toThrow();

// Invalid result should fail validation
const invalidResult = 'not a CapData object';
expect(() => queueMessageSpec.result.create(invalidResult)).toThrow(
'Expected an object',
);
});
});

describe('queueMessageHandler', () => {
let mockKernel: Pick<Kernel, 'queueMessage'>;

beforeEach(() => {
mockKernel = {
queueMessage: vi.fn(),
};
});

it('should correctly forward arguments to kernel.queueMessage', async () => {
const target = 'targetId';
const method = 'methodName';
const args = [1, 'string', { key: 'value' }];
const expectedResult: CapData<string> = { body: 'result', slots: [] };

vi.mocked(mockKernel.queueMessage).mockResolvedValueOnce(expectedResult);

const result = await queueMessageHandler.implementation(
{ kernel: mockKernel },
[target, method, args],
);

expect(mockKernel.queueMessage).toHaveBeenCalledWith(target, method, args);
expect(result).toStrictEqual(expectedResult);
});

it('should propagate errors from kernel.queueMessage', async () => {
const error = new Error('Queue message failed');
vi.mocked(mockKernel.queueMessage).mockRejectedValueOnce(error);

await expect(
queueMessageHandler.implementation({ kernel: mockKernel }, [
'target',
'method',
[],
]),
).rejects.toThrow('Queue message failed');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { CapData } from '@endo/marshal';
import type { MethodSpec, Handler } from '@metamask/kernel-rpc-methods';
import type { Kernel } from '@metamask/ocap-kernel';
import { CapDataStruct } from '@metamask/ocap-kernel';
import { tuple, string, array } from '@metamask/superstruct';
import { UnsafeJsonStruct } from '@metamask/utils';
import type { Json } from '@metamask/utils';

/**
* Enqueue a message to a vat via the kernel's crank queue.
*/
export const queueMessageSpec: MethodSpec<
'queueMessage',
[string, string, Json[]],
CapData<string>
> = {
method: 'queueMessage',
params: tuple([string(), string(), array(UnsafeJsonStruct)]),
result: CapDataStruct,
};

export type QueueMessageHooks = {
kernel: Pick<Kernel, 'queueMessage'>;
};

export const queueMessageHandler: Handler<
'queueMessage',
[string, string, Json[]],
Promise<CapData<string>>,
QueueMessageHooks
> = {
...queueMessageSpec,
hooks: { kernel: true },
implementation: async (
{ kernel }: QueueMessageHooks,
[target, method, args],
): Promise<CapData<string>> => {
return kernel.queueMessage(target, method, args);
},
};

This file was deleted.

This file was deleted.

68 changes: 60 additions & 8 deletions packages/extension/src/ui/App.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ body > div {
box-sizing: border-box;
}

h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 600;
}

pre {
word-break: break-word;
white-space: normal;
line-height: 1.5;
}

/* Panel container */
.panel {
padding: var(--spacing-xl);
Expand All @@ -65,8 +80,10 @@ body > div {
}

/* Common form elements */
input,
.input,
.button,
select,
.select {
height: var(--input-height);
padding: 0 var(--spacing-lg);
Expand Down Expand Up @@ -156,6 +173,11 @@ select,
color: var(--color-white);
}

.buttonBlack:hover:not(:disabled) {
background-color: var(--color-gray-600);
color: var(--color-white);
}

.textButton {
padding: 0;
border: 0;
Expand Down Expand Up @@ -200,12 +222,6 @@ select,
margin-bottom: var(--spacing-sm);
}

.messageInputRow {
display: flex;
gap: var(--spacing-sm);
margin-bottom: var(--spacing-sm);
}

.messageContent {
composes: input;
flex: 1;
Expand Down Expand Up @@ -338,16 +354,45 @@ div + .sent {
}

.messageInputSection {
border-top: 1px solid var(--color-gray-300);
border: 1px solid var(--color-gray-300);
padding: var(--spacing-md);
background: var(--color-gray-200);
border-radius: var(--border-radius);
margin-bottom: var(--spacing-xl);
}

.messageInputSection h3 {
margin: 0 0 var(--spacing-md);
}

.messageInputRow {
.horizontalForm {
display: flex;
gap: var(--spacing-sm);
}

.horizontalForm > div {
display: flex;
flex-direction: column;
flex: 1;
}

.horizontalForm > div > label {
margin-bottom: var(--spacing-xs);
}

.messageResponse {
font-family: monospace;
font-size: var(--font-size-xs);
}

.messageResponse h4 {
margin: var(--spacing-md) 0 var(--spacing-sm);
}

.messageResponse pre {
margin: 0;
}

.table {
width: 100%;
border: 1px solid var(--color-gray-300);
Expand Down Expand Up @@ -598,3 +643,10 @@ table.table {
font-weight: 400;
margin-left: var(--spacing-xs);
}

@media (min-width: 1200px) {
.horizontalForm .formFieldTarget {
width: 150px;
flex: none;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const mockUsePanelContext = {
setMessageContent: vi.fn(),
setSelectedVatId: vi.fn(),
status: mockStatus,
objectRegistry: null,
setObjectRegistry: vi.fn(),
};

vi.mock('../hooks/useKernelActions.ts', () => ({
Expand Down Expand Up @@ -70,7 +72,6 @@ describe('ConfigEditor Component', () => {
vi.mocked(useKernelActions).mockReturnValue({
updateClusterConfig: mockUpdateClusterConfig,
reload: mockReload,
sendKernelCommand: vi.fn(),
terminateAllVats: vi.fn(),
clearState: vi.fn(),
launchVat: vi.fn(),
Expand Down
Loading
Loading