Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7c534a3
feat(extension): Add distributed object capability programming
rekmarks Aug 16, 2024
14ad89c
test(extension): Manually envelope messages mocked directly through p…
grypez Sep 3, 2024
7e0d182
types(extension): Distinguish VatId and MessageId with type aliases.
grypez Sep 3, 2024
ea7c2d5
feat(extension): Add generator for vat unresolved messages.
grypez Sep 3, 2024
20616ef
chore(extension): The types are well again.
grypez Sep 3, 2024
a5aafd3
test(extension): Prevent an unlikely future headache.
grypez Sep 3, 2024
87112df
refactor(extension,streams): Generify StreamPair to allow MessagePort…
grypez Sep 5, 2024
979b9b3
test(extension): Add capTp frangooly unit test.
grypez Sep 9, 2024
c01440c
chore: Update @endo/eventual-send@^1.2.4
grypez Sep 11, 2024
324c051
types(extension): Strengthen message and envelope types.
grypez Sep 11, 2024
9496c1b
test(extension): Test cover capTp usage errors.
grypez Sep 11, 2024
0006d3a
test(extension): Add dev-console tests.
grypez Sep 11, 2024
ccf3c1e
refactor(extension): Avert a name collision with design doc.
grypez Sep 11, 2024
19f16cb
feat(extension): Give vats individual message counters.
grypez Sep 11, 2024
c32f62b
refactor(extension): Use ExtensionTarget enum.
grypez Sep 11, 2024
f566a66
docs(extension): Flatten a transitive explanation.
grypez Sep 11, 2024
5b595ae
chore(packages): Remove unused @endo/lockdown dependency.
grypez Sep 11, 2024
bf7be4b
chore: Remove unused code.
grypez Sep 11, 2024
7dd0cbc
fix(extension): Organize dev-console priority in trusted-prelude.
grypez Sep 12, 2024
ad535fa
refactor: Label command envelopes 'command'.
grypez Sep 12, 2024
f430c10
test: Use it.each for multi-case test.
grypez Sep 12, 2024
447acf9
docs: Clarify explanation for ts-ignore statements.
grypez Sep 12, 2024
5074743
refactor: Move unresolved messages into VatRecord.
grypez Sep 12, 2024
c55469c
refactor: s/ExtensionTarget/ExtensionMessageTarget/g
grypez Sep 12, 2024
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
3 changes: 3 additions & 0 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
"test:watch": "vitest --config vitest.config.ts"
},
"dependencies": {
"@endo/captp": "^4.2.2",
"@endo/eventual-send": "^1.2.4",
"@endo/exo": "^1.5.2",
"@endo/patterns": "^1.4.2",
"@endo/promise-kit": "^1.1.4",
"@metamask/snaps-utils": "^7.8.0",
"@metamask/utils": "^9.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/extension/src/background-trusted-prelude.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
import './dev-console.js';
import './endoify.js';
import './dev-console.js';
43 changes: 23 additions & 20 deletions packages/extension/src/background.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import type { Json } from '@metamask/utils';

import './background-trusted-prelude.js';
import type { ExtensionMessage } from './shared.js';
import { Command, makeHandledCallback } from './shared.js';
import type { ExtensionMessage } from './message.js';
import { Command, ExtensionMessageTarget } from './message.js';
import { makeHandledCallback } from './shared.js';

// globalThis.kernel will exist due to dev-console.js
// globalThis.kernel will exist due to dev-console.js in background-trusted-prelude.js
Object.defineProperties(globalThis.kernel, {
sendMessage: {
value: sendMessage,
capTpCall: {
value: async (method: string, params: Json[]) =>
sendMessage(Command.CapTpCall, { method, params }),
},
capTpInit: {
value: async () => sendMessage(Command.CapTpInit),
},
evaluate: {
value: async (source: string) => sendMessage(Command.Evaluate, source),
},
ping: {
value: async () => sendMessage(Command.Ping),
},
sendMessage: {
value: sendMessage,
},
});
harden(globalThis.kernel);

const OFFSCREEN_DOCUMENT_PATH = '/offscreen.html';

Expand All @@ -29,12 +40,12 @@ chrome.action.onClicked.addListener(() => {
* @param data - The message data.
* @param data.name - The name to include in the message.
*/
async function sendMessage(type: string, data?: string): Promise<void> {
async function sendMessage(type: string, data?: Json): Promise<void> {
await provideOffScreenDocument();

await chrome.runtime.sendMessage({
type,
target: 'offscreen',
target: ExtensionMessageTarget.Offscreen,
data: data ?? null,
});
}
Expand All @@ -54,8 +65,8 @@ async function provideOffScreenDocument(): Promise<void> {

// Handle replies from the offscreen document
chrome.runtime.onMessage.addListener(
makeHandledCallback(async (message: ExtensionMessage<Command, string>) => {
if (message.target !== 'background') {
makeHandledCallback(async (message: ExtensionMessage) => {
if (message.target !== ExtensionMessageTarget.Background) {
console.warn(
`Background received message with unexpected target: "${message.target}"`,
);
Expand All @@ -64,25 +75,17 @@ chrome.runtime.onMessage.addListener(

switch (message.type) {
case Command.Evaluate:
case Command.CapTpCall:
case Command.CapTpInit:
case Command.Ping:
console.log(message.data);
await closeOffscreenDocument();
break;
default:
console.error(
// @ts-expect-error The type of `message` is `never`, but this could happen at runtime.
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Background received unexpected message type: "${message.type}"`,
);
}
}),
);

/**
* Close the offscreen document if it exists.
*/
async function closeOffscreenDocument(): Promise<void> {
if (!(await chrome.offscreen.hasDocument())) {
return;
}
await chrome.offscreen.closeDocument();
}
21 changes: 21 additions & 0 deletions packages/extension/src/dev-console.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { describe, it, expect } from 'vitest';
import '@ocap/shims/endoify';
import './dev-console.js';

describe('vat-console', () => {
describe('kernel', () => {
it('is available on globalThis', async () => {
expect(kernel).toBeDefined();
});

it('has expected property descriptors', async () => {
expect(
Object.getOwnPropertyDescriptor(globalThis, 'kernel'),
).toMatchObject({
configurable: false,
enumerable: true,
writable: false,
});
});
});
});
22 changes: 22 additions & 0 deletions packages/extension/src/envelope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { isObject } from '@metamask/utils';

import type { WrappedIframeMessage } from './message.js';
import { isWrappedIframeMessage } from './message.js';

export enum EnvelopeLabel {
Command = 'command',
CapTp = 'capTp',
}

export type StreamEnvelope =
| {
label: EnvelopeLabel.Command;
content: WrappedIframeMessage;
}
| { label: EnvelopeLabel.CapTp; content: unknown };

export const isStreamEnvelope = (value: unknown): value is StreamEnvelope =>
isObject(value) &&
(value.label === EnvelopeLabel.CapTp ||
(value.label === EnvelopeLabel.Command &&
isWrappedIframeMessage(value.content)));
Loading