connected-solid builds

main
Jackson Morgan 6 months ago
parent 453ee230f3
commit 2fa3e52246
  1. 4
      packages/connected-solid/src/notifications/SolidNotificationSubscription.ts
  2. 32
      packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts
  3. 26
      packages/connected-solid/src/notifications/results/NotificationErrors.ts
  4. 5
      packages/connected-solid/src/resources/SolidContainer.ts
  5. 2
      packages/connected-solid/src/resources/SolidResource.ts
  6. 3
      packages/connected-solid/src/util/rdfUtils.ts

@ -125,7 +125,9 @@ export abstract class SolidNotificationSubscription {
* @internal
* onNotificationError
*/
protected onNotificationError(message: NotificationCallbackError): void {
protected onNotificationError(
message: NotificationCallbackError<SolidLeaf | SolidContainer>,
): void {
Object.values(this.subscriptions).forEach(({ onNotificationError }) => {
onNotificationError?.(message);
});

@ -1,4 +1,3 @@
import { UnexpectedResourceError } from "../../requester/results/error/ErrorResult";
import { SubscriptionClient } from "@solid-notifications/subscription";
import { WebSocket } from "ws";
import {
@ -6,14 +5,17 @@ import {
DisconnectedNotAttemptingReconnectError,
UnsupportedNotificationError,
} from "./results/NotificationErrors";
import type { NotificationMessage } from "./NotificationMessage";
import type { Resource } from "../Resource";
import type { SolidLdoDatasetContext } from "../../SolidLdoDatasetContext";
import type { SolidNotificationMessage } from "./SolidNotificationMessage";
import { UnexpectedResourceError, type ConnectedContext } from "@ldo/connected";
import type {
ChannelType,
NotificationChannel,
} from "@solid-notifications/types";
import { SolidNotificationSubscription } from "./SolidNotificationSubscription";
import type { SolidConnectedPlugin } from "../SolidConnectedPlugin";
import type { SolidLeaf } from "../resources/SolidLeaf";
import type { SolidContainer } from "../resources/SolidContainer";
import { guaranteeFetch } from "../util/guaranteeFetch";
const CHANNEL_TYPE =
"http://www.w3.org/ns/solid/notifications#WebSocketChannel2023";
@ -33,9 +35,9 @@ export class Websocket2023NotificationSubscription extends SolidNotificationSubs
private maxReconnectAttempts = 6;
constructor(
resource: Resource,
parentSubscription: (message: NotificationMessage) => void,
context: SolidLdoDatasetContext,
resource: SolidLeaf | SolidContainer,
parentSubscription: (message: SolidNotificationMessage) => void,
context: ConnectedContext<SolidConnectedPlugin[]>,
createWebsocket?: (address: string) => WebSocket,
) {
super(resource, parentSubscription, context);
@ -52,11 +54,11 @@ export class Websocket2023NotificationSubscription extends SolidNotificationSubs
err.message.startsWith("Discovery did not succeed")
) {
this.onNotificationError(
new UnsupportedNotificationError(this.resource.uri, err.message),
new UnsupportedNotificationError(this.resource, err.message),
);
} else {
this.onNotificationError(
UnexpectedResourceError.fromThrown(this.resource.uri, err),
UnexpectedResourceError.fromThrown(this.resource, err),
);
}
this.onClose();
@ -64,7 +66,9 @@ export class Websocket2023NotificationSubscription extends SolidNotificationSubs
}
public async discoverNotificationChannel(): Promise<NotificationChannel> {
const client = new SubscriptionClient(this.context.fetch);
const client = new SubscriptionClient(
guaranteeFetch(this.context.solid.fetch),
);
return await client.subscribe(
this.resource.uri,
CHANNEL_TYPE as ChannelType,
@ -86,14 +90,14 @@ export class Websocket2023NotificationSubscription extends SolidNotificationSubs
this.socket.onmessage = (message) => {
const messageData = message.data.toString();
// TODO uncompliant Pod error on misformatted message
this.onNotification(JSON.parse(messageData) as NotificationMessage);
this.onNotification(JSON.parse(messageData) as SolidNotificationMessage);
};
this.socket.onclose = this.onClose.bind(this);
this.socket.onerror = (err) => {
this.onNotificationError(
new UnexpectedResourceError(this.resource.uri, err.error),
new UnexpectedResourceError(this.resource, err.error),
);
};
return;
@ -109,14 +113,14 @@ export class Websocket2023NotificationSubscription extends SolidNotificationSubs
}, this.reconnectInterval);
this.onNotificationError(
new DisconnectedAttemptingReconnectError(
this.resource.uri,
this.resource,
`Attempting to reconnect to Websocket for ${this.resource.uri}.`,
),
);
} else {
this.onNotificationError(
new DisconnectedNotAttemptingReconnectError(
this.resource.uri,
this.resource,
`Lost connection to websocket for ${this.resource.uri}.`,
),
);

@ -1,30 +1,36 @@
import type { UnexpectedResourceError } from "../../../requester/results/error/ErrorResult";
import { ResourceError } from "../../../requester/results/error/ErrorResult";
import type { Resource, UnexpectedResourceError } from "@ldo/connected";
import { ResourceError } from "@ldo/connected";
export type NotificationCallbackError =
| DisconnectedAttemptingReconnectError
| DisconnectedNotAttemptingReconnectError
| UnsupportedNotificationError
| UnexpectedResourceError;
export type NotificationCallbackError<ResourceType extends Resource> =
| DisconnectedAttemptingReconnectError<ResourceType>
| DisconnectedNotAttemptingReconnectError<ResourceType>
| UnsupportedNotificationError<ResourceType>
| UnexpectedResourceError<ResourceType>;
/**
* Indicates that the requested method for receiving notifications is not
* supported by this Pod.
*/
export class UnsupportedNotificationError extends ResourceError {
export class UnsupportedNotificationError<
ResourceType extends Resource,
> extends ResourceError<ResourceType> {
readonly type = "unsupportedNotificationError" as const;
}
/**
* Indicates that the socket has disconnected and is attempting to reconnect.
*/
export class DisconnectedAttemptingReconnectError extends ResourceError {
export class DisconnectedAttemptingReconnectError<
ResourceType extends Resource,
> extends ResourceError<ResourceType> {
readonly type = "disconnectedAttemptingReconnectError" as const;
}
/**
* Indicates that the socket has disconnected and is attempting to reconnect.
*/
export class DisconnectedNotAttemptingReconnectError extends ResourceError {
export class DisconnectedNotAttemptingReconnectError<
ResourceType extends Resource,
> extends ResourceError<ResourceType> {
readonly type = "disconnectedNotAttemptingReconnectError" as const;
}

@ -38,6 +38,7 @@ import {
} from "@ldo/connected";
import type { SolidConnectedPlugin } from "../SolidConnectedPlugin";
import type { SolidLeaf } from "./SolidLeaf";
import type { HttpErrorResultType } from "../requester/results/error/HttpErrorResult";
/**
* Represents the current status of a specific container on a Pod as known by
@ -499,7 +500,9 @@ export class SolidContainer extends SolidResource {
}),
)
).flat();
const errors = results.filter((value) => value.isError);
const errors = results.filter(
(value): value is HttpErrorResultType<this> => value.isError,
);
if (errors.length > 0) {
return new AggregateError(errors);
}

@ -135,7 +135,7 @@ export abstract class SolidResource
super();
this.context = context;
this.notificationSubscription = new Websocket2023NotificationSubscription(
this,
this as unknown as SolidLeaf | SolidContainer,
this.onNotification.bind(this),
this.context,
);

@ -2,9 +2,6 @@ import type { LdoDataset } from "@ldo/ldo";
import { parseRdf } from "@ldo/ldo";
import { namedNode, quad as createQuad } from "@rdfjs/data-model";
import type { Dataset } from "@rdfjs/types";
import type { NoncompliantPodError } from "../requester/results/error/NoncompliantPodError";
import { ErrorResult } from "@ldo/connected";
import { UnexpectedResourceError } from "@ldo/connected";
import type { SolidContainerUri } from "../types";
import { isSolidContainerUri } from "./isSolidUri";

Loading…
Cancel
Save