From 2fa3e52246c88988aa51f185095bd7108b757a97 Mon Sep 17 00:00:00 2001 From: Jackson Morgan Date: Thu, 20 Mar 2025 15:11:24 -0400 Subject: [PATCH] connected-solid builds --- .../SolidNotificationSubscription.ts | 4 ++- .../Websocket2023NotificationSubscription.ts | 32 +++++++++++-------- .../results/NotificationErrors.ts | 26 +++++++++------ .../src/resources/SolidContainer.ts | 5 ++- .../src/resources/SolidResource.ts | 2 +- packages/connected-solid/src/util/rdfUtils.ts | 3 -- 6 files changed, 42 insertions(+), 30 deletions(-) diff --git a/packages/connected-solid/src/notifications/SolidNotificationSubscription.ts b/packages/connected-solid/src/notifications/SolidNotificationSubscription.ts index 2ceae79..aa03496 100644 --- a/packages/connected-solid/src/notifications/SolidNotificationSubscription.ts +++ b/packages/connected-solid/src/notifications/SolidNotificationSubscription.ts @@ -125,7 +125,9 @@ export abstract class SolidNotificationSubscription { * @internal * onNotificationError */ - protected onNotificationError(message: NotificationCallbackError): void { + protected onNotificationError( + message: NotificationCallbackError, + ): void { Object.values(this.subscriptions).forEach(({ onNotificationError }) => { onNotificationError?.(message); }); diff --git a/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts b/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts index d60f2de..72017c0 100644 --- a/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts +++ b/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts @@ -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, 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 { - 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}.`, ), ); diff --git a/packages/connected-solid/src/notifications/results/NotificationErrors.ts b/packages/connected-solid/src/notifications/results/NotificationErrors.ts index f196c86..494a030 100644 --- a/packages/connected-solid/src/notifications/results/NotificationErrors.ts +++ b/packages/connected-solid/src/notifications/results/NotificationErrors.ts @@ -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 = + | DisconnectedAttemptingReconnectError + | DisconnectedNotAttemptingReconnectError + | UnsupportedNotificationError + | UnexpectedResourceError; /** * 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 { 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 { 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 { readonly type = "disconnectedNotAttemptingReconnectError" as const; } diff --git a/packages/connected-solid/src/resources/SolidContainer.ts b/packages/connected-solid/src/resources/SolidContainer.ts index 0399e95..7e5773c 100644 --- a/packages/connected-solid/src/resources/SolidContainer.ts +++ b/packages/connected-solid/src/resources/SolidContainer.ts @@ -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 => value.isError, + ); if (errors.length > 0) { return new AggregateError(errors); } diff --git a/packages/connected-solid/src/resources/SolidResource.ts b/packages/connected-solid/src/resources/SolidResource.ts index 0c916ae..37d1604 100644 --- a/packages/connected-solid/src/resources/SolidResource.ts +++ b/packages/connected-solid/src/resources/SolidResource.ts @@ -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, ); diff --git a/packages/connected-solid/src/util/rdfUtils.ts b/packages/connected-solid/src/util/rdfUtils.ts index 54eed0e..9f05301 100644 --- a/packages/connected-solid/src/util/rdfUtils.ts +++ b/packages/connected-solid/src/util/rdfUtils.ts @@ -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";