Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-nagy committed Dec 15, 2023
1 parent 1d6006b commit f5e6b55
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 8 deletions.
4 changes: 4 additions & 0 deletions packages/core/src/Injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ export function provide<
getOwnPropertyDescriptor(target, prop) {
if (prop === inject) return { configurable: true };
return Reflect.getOwnPropertyDescriptor(target, prop);
},
has(target, prop) {
if (prop === inject) return true;
return Reflect.has(target, prop);
}
}) as InjectableFunction<Func, Tags>;
}
2 changes: 1 addition & 1 deletion packages/core/src/JsObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export function has<Prop extends PropertyKey>(
value: object,
property: Prop
): value is Record<Prop, unknown> {
return Object.hasOwn(value, property);
return property in value;
}

/**
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/JsPromise.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { expect, test } from "bun:test";

import * as JsPromise from "./JsPromise.js";

test("checking if a promise is a promise", () => {
expect(JsPromise.isPromise(Promise.resolve("👌"))).toBe(true);
});

test("checking if a value with a then method is a promise", () => {
expect(JsPromise.isPromise({ then() {} })).toBe(true);
});
8 changes: 8 additions & 0 deletions packages/core/src/Protocol/ClientAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ export class ClientAgent extends Fiber.t {
return Reflect.getOwnPropertyDescriptor(target, property);
}
},
has(target, property) {
switch (property) {
case Metadata.symbol:
return true;
default:
return Reflect.has(target, property);
}
},
ownKeys(_target) {
// Prevents enumeration of the proxy. Attempting to enumerate the proxy
// will throw a `TypeError`, this includes using the rest syntax when
Expand Down
12 changes: 10 additions & 2 deletions packages/core/src/Protocol/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ export class ServerSession<Value> extends Session {
* type safety.
*/
type Subprotocol<Value> = Subprotocol.t<
JsFunction.Input<ExtractFunctions<Value>>,
JsFunction.Output<ExtractFunctions<Value>>
JsFunction.Input<OmitDependencies<ExtractFunctions<Value>>>,
Awaited<JsFunction.Output<OmitDependencies<ExtractFunctions<Value>>>>
>;

interface Options<Value> {
Expand Down Expand Up @@ -316,6 +316,14 @@ type Local<T> = T extends (...args: infer Args) => infer Return
*/
type MaybePromise<T> = Awaited<T> | Promise<Awaited<T>>;

/**
* Distributes over a union of function types and omits their injected
* dependencies.
*/
type OmitDependencies<T> = T extends Injector.InjectableFunction
? Injector.InjectedFunction<T>
: T;

/**
* Represents a remote value. A remote value is the inverse of a local value.
*/
Expand Down
30 changes: 25 additions & 5 deletions packages/core/src/Protocol/Session.typetest.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as Injector from '../Injector.js';
import * as Json from '../Json.js';
import * as Proxy from '../Proxy.js';
import * as Session from './Session.js';
import * as Subprotocol from './Subprotocol.js';
import * as Injector from "../Injector.js";
import * as Json from "../Json.js";
import * as Proxy from "../Proxy.js";
import * as Session from "./Session.js";
import * as Subprotocol from "./Subprotocol.js";

const protocol = Subprotocol.init({
connectionMode: Subprotocol.ConnectionMode.ConnectionOriented,
Expand Down Expand Up @@ -48,6 +48,12 @@ test("remote function returning object", () => {
// ^? const _proxy: RemoteFunction<() => {}>
});

test("remote function returning a promise", () => {
const session = Session.client<() => Promise<{ cat: "🐈" }>>({ protocol });
const _proxy = session.createProxy();
// ^? const _proxy: RemoteFunction<() => Promise<{ cat: "🐈"; }>>
});

test("remote function returning function", async () => {
const session = Session.client<() => () => null>({ protocol });
const proxy = session.createProxy();
Expand Down Expand Up @@ -272,6 +278,20 @@ test("an injected dependency is removed from the call signature", () => {
// ^? const _proxy: RemoteFunction<(a: boolean) => null>
});

test("an injected dependency is excluded from protocol type checking", () => {
type Context = { clientId: string };

const session = Session.client<
Injector.InjectableFunction<
(context: Context | undefined, a: boolean) => null,
[Injector.Tag<Context>]
>
>({ protocol });

const _proxy = session.createProxy();
// ^? const _proxy: RemoteFunction<(a: boolean) => null>
});

test("returning a proxy from a function", () => {
class Foo {
a!: number;
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/Proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export function proxy<T extends object>(value: T) {
getOwnPropertyDescriptor(target, prop) {
if (prop === symbol) return { configurable: true };
return Reflect.getOwnPropertyDescriptor(target, prop);
},
has(target, prop) {
if (prop === symbol) return true;
return Reflect.has(target, prop);
}
}) as Proxy<T>;
}
Expand Down

0 comments on commit f5e6b55

Please sign in to comment.