connected library builds

main
Jackson Morgan 6 months ago
parent 778d49ef85
commit 356ecf8c67
  1. 13
      packages/connected-solid/src/SolidConnectedPlugin.ts
  2. 127
      packages/connected-solid/src/resources/SolidResource.ts
  3. 7
      packages/connected/src/ConnectedContext.ts
  4. 62
      packages/connected/src/ConnectedLdoDataset.ts
  5. 26
      packages/connected/src/ConnectedPlugin.ts
  6. 6
      packages/connected/src/InvalidIdentifierResource.ts
  7. 8
      packages/connected/src/Resource.ts
  8. 5
      packages/connected/src/index.ts
  9. 10
      packages/connected/src/notifications/NotificationMessage.ts
  10. 144
      packages/connected/src/notifications/NotificationSubscription.ts
  11. 13
      packages/connected/src/results/error/NotificationErrors.ts
  12. 19
      packages/connected/src/results/success/CheckRootContainerSuccess.ts
  13. 13
      packages/connected/src/results/success/CreateSuccess.ts
  14. 14
      packages/connected/src/results/success/DeleteSuccess.ts
  15. 71
      packages/connected/src/results/success/ReadSuccess.ts
  16. 24
      packages/connected/src/results/success/UpdateSuccess.ts

@ -9,6 +9,12 @@ export interface SolidConnectedPlugin extends ConnectedPlugin {
getResource: getResource:
| ((uri: SolidLeafUri) => SolidLeaf) | ((uri: SolidLeafUri) => SolidLeaf)
| ((uri: SolidContainerUri) => SolidContainer); | ((uri: SolidContainerUri) => SolidContainer);
createResource(): Promise<SolidLeaf>;
isUriValid(uri: string): uri is SolidLeafUri | SolidContainerUri;
normalizeUri?: (uri: string) => SolidLeafUri | SolidContainerUri;
context: {
fetch?: typeof fetch;
};
} }
export const solidConnectedPlugin: SolidConnectedPlugin = { export const solidConnectedPlugin: SolidConnectedPlugin = {
@ -17,4 +23,11 @@ export const solidConnectedPlugin: SolidConnectedPlugin = {
getResource(_uri: SolidUri): SolidContainer | SolidLeaf { getResource(_uri: SolidUri): SolidContainer | SolidLeaf {
throw new Error("Not Implemented"); throw new Error("Not Implemented");
}, },
createResource: function (): Promise<SolidLeaf> {
throw new Error("Function not implemented.");
},
isUriValid: function (uri: string): uri is SolidLeafUri | SolidContainerUri {
throw new Error("Function not implemented.");
},
context: {},
}; };

@ -1,3 +1,126 @@
import type { Resource } from "@ldo/connected"; import type {
ConnectedResult,
Resource,
ResourceResult,
SubscriptionCallbacks,
} from "@ldo/connected";
import type { SolidContainerUri, SolidLeafUri } from "../types";
export class SolidResource implements Resource {} export class SolidResource
implements Resource<SolidLeafUri | SolidContainerUri>
{
uri: SolidLeafUri | SolidContainerUri;
type: string;
status: ConnectedResult;
isLoading(): boolean {
throw new Error("Method not implemented.");
}
isFetched(): boolean {
throw new Error("Method not implemented.");
}
isUnfetched(): boolean {
throw new Error("Method not implemented.");
}
isDoingInitialFetch(): boolean {
throw new Error("Method not implemented.");
}
isPresent(): boolean {
throw new Error("Method not implemented.");
}
isAbsent(): boolean {
throw new Error("Method not implemented.");
}
isSubscribedToNotifications(): boolean {
throw new Error("Method not implemented.");
}
read(): Promise<ResourceResult<this>> {
throw new Error("Method not implemented.");
}
readIfAbsent(): Promise<ResourceResult<this>> {
throw new Error("Method not implemented.");
}
subscribeToNotifications(callbacks?: SubscriptionCallbacks): Promise<string> {
throw new Error("Method not implemented.");
}
unsubscribeFromNotifications(subscriptionId: string): Promise<void> {
throw new Error("Method not implemented.");
}
unsubscribeFromAllNotifications(): Promise<void> {
throw new Error("Method not implemented.");
}
addListener<E extends "update" | "notification">(
event: E,
listener: { update: () => void; notification: () => void }[E],
): this {
throw new Error("Method not implemented.");
}
on<E extends "update" | "notification">(
event: E,
listener: { update: () => void; notification: () => void }[E],
): this {
throw new Error("Method not implemented.");
}
once<E extends "update" | "notification">(
event: E,
listener: { update: () => void; notification: () => void }[E],
): this {
throw new Error("Method not implemented.");
}
prependListener<E extends "update" | "notification">(
event: E,
listener: { update: () => void; notification: () => void }[E],
): this {
throw new Error("Method not implemented.");
}
prependOnceListener<E extends "update" | "notification">(
event: E,
listener: { update: () => void; notification: () => void }[E],
): this {
throw new Error("Method not implemented.");
}
off<E extends "update" | "notification">(
event: E,
listener: { update: () => void; notification: () => void }[E],
): this {
throw new Error("Method not implemented.");
}
removeAllListeners<E extends "update" | "notification">(
event?: E | undefined,
): this {
throw new Error("Method not implemented.");
}
removeListener<E extends "update" | "notification">(
event: E,
listener: { update: () => void; notification: () => void }[E],
): this {
throw new Error("Method not implemented.");
}
emit<E extends "update" | "notification">(
event: E,
...args: Parameters<{ update: () => void; notification: () => void }[E]>
): boolean {
throw new Error("Method not implemented.");
}
eventNames(): (string | symbol)[] {
throw new Error("Method not implemented.");
}
rawListeners<E extends "update" | "notification">(
event: E,
): { update: () => void; notification: () => void }[E][] {
throw new Error("Method not implemented.");
}
listeners<E extends "update" | "notification">(
event: E,
): { update: () => void; notification: () => void }[E][] {
throw new Error("Method not implemented.");
}
listenerCount<E extends "update" | "notification">(event: E): number {
throw new Error("Method not implemented.");
}
getMaxListeners(): number {
throw new Error("Method not implemented.");
}
setMaxListeners(maxListeners: number): this {
throw new Error("Method not implemented.");
}
}

@ -1,8 +1,11 @@
import type { ConnectedLdoDataset } from "./ConnectedLdoDataset"; import type { ConnectedLdoDataset } from "./ConnectedLdoDataset";
import type { ConnectedPlugin } from "./ConnectedPlugin"; import type { ConnectedPlugin } from "./ConnectedPlugin";
export type ConnectedContext<Plugins extends ConnectedPlugin[]> = { export type ConnectedContext<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Plugins extends ConnectedPlugin<any, any, any, any>[],
> = {
dataset: ConnectedLdoDataset<Plugins>; dataset: ConnectedLdoDataset<Plugins>;
} & { } & {
[P in Plugins[number] as P["name"]]: P["context"]; [P in Plugins[number] as P["name"]]: P["types"]["context"];
}; };

@ -1,22 +1,17 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { LdoDataset } from "@ldo/ldo"; import { LdoDataset } from "@ldo/ldo";
import type { ConnectedPlugin } from "./ConnectedPlugin"; import type { ConnectedPlugin } from "./ConnectedPlugin";
import type { Dataset, DatasetFactory, Quad } from "@rdfjs/types"; import type { Dataset, DatasetFactory, Quad } from "@rdfjs/types";
import type { ITransactionDatasetFactory } from "@ldo/subscribable-dataset"; import type { ITransactionDatasetFactory } from "@ldo/subscribable-dataset";
import { InvalidIdentifierResource } from "./InvalidIdentifierResource"; import { InvalidIdentifierResource } from "./InvalidIdentifierResource";
import type { ConnectedContext } from "./ConnectedContext";
type ReturnTypeFromArgs<T, Arg> = T extends (arg: Arg) => infer R ? R : never; type ReturnTypeFromArgs<Func, Arg> = Func extends (arg: Arg) => infer R
type ResourceTypes<Plugins extends ConnectedPlugin[]> = ? R
| ReturnType<Plugins[number]["getResource"]> : never;
| InvalidIdentifierResource;
type GetResourceReturn<
Plugin extends ConnectedPlugin,
UriType extends string,
> = UriType extends Parameters<Plugin["getResource"]>[0]
? ReturnTypeFromArgs<Plugin["getResource"], UriType>
: ResourceTypes<[Plugin]>;
export class ConnectedLdoDataset< export class ConnectedLdoDataset<
Plugins extends ConnectedPlugin[], Plugins extends ConnectedPlugin<any, any, any, any>[],
> extends LdoDataset { > extends LdoDataset {
private plugins: Plugins; private plugins: Plugins;
/** /**
@ -24,7 +19,8 @@ export class ConnectedLdoDataset<
* *
* A mapping between a resource URI and a Solid resource * A mapping between a resource URI and a Solid resource
*/ */
protected resourceMap: Map<string, ResourceTypes<Plugins>>; protected resourceMap: Map<string, Plugins[number]["types"]["resource"]>;
protected context: ConnectedContext<Plugins>;
constructor( constructor(
plugins: Plugins, plugins: Plugins,
@ -35,6 +31,12 @@ export class ConnectedLdoDataset<
super(datasetFactory, transactionDatasetFactory, initialDataset); super(datasetFactory, transactionDatasetFactory, initialDataset);
this.plugins = plugins; this.plugins = plugins;
this.resourceMap = new Map(); this.resourceMap = new Map();
this.context = {
dataset: this,
};
this.plugins.forEach(
(plugin) => (this.context[plugin.name] = plugin.initialContext),
);
} }
/** /**
@ -58,16 +60,18 @@ export class ConnectedLdoDataset<
Name extends Plugins[number]["name"], Name extends Plugins[number]["name"],
Plugin extends Extract<Plugins[number], { name: Name }>, Plugin extends Extract<Plugins[number], { name: Name }>,
UriType extends string, UriType extends string,
>(uri: UriType, pluginName?: Name): GetResourceReturn<Plugin, UriType> { >(
uri: UriType,
pluginName?: Name,
): UriType extends Plugin["types"]["uri"]
? ReturnTypeFromArgs<Plugin["getResource"], UriType>
: ReturnType<Plugin["getResource"]> | InvalidIdentifierResource {
// Check for which plugins this uri is valid // Check for which plugins this uri is valid
const validPlugins = this.plugins const validPlugins = this.plugins
.filter((plugin) => plugin.isUriValid(uri)) .filter((plugin) => plugin.isUriValid(uri))
.filter((plugin) => (pluginName ? pluginName === plugin.name : true)); .filter((plugin) => (pluginName ? pluginName === plugin.name : true));
if (validPlugins.length === 0) { if (validPlugins.length === 0) {
return new InvalidIdentifierResource(uri) as GetResourceReturn< return new InvalidIdentifierResource(uri) as any;
Plugin,
UriType
>;
} else if (validPlugins.length > 1) { } else if (validPlugins.length > 1) {
// TODO: LDO is currently not architected to have an ID valid in multiple // TODO: LDO is currently not architected to have an ID valid in multiple
// protocols. This will need to be refactored if this is ever the case. // protocols. This will need to be refactored if this is ever the case.
@ -80,9 +84,29 @@ export class ConnectedLdoDataset<
let resource = this.resourceMap.get(normalizedUri); let resource = this.resourceMap.get(normalizedUri);
if (!resource) { if (!resource) {
resource = plugin.getResource(uri) as ResourceTypes<Plugins>; resource = plugin.getResource(uri, this.context);
this.resourceMap.set(normalizedUri, resource); this.resourceMap.set(normalizedUri, resource);
} }
return resource as GetResourceReturn<Plugin, UriType>; return resource as any;
}
async createResource<
Name extends Plugins[number]["name"],
Plugin extends Extract<Plugins[number], { name: Name }>,
>(name: Name): Promise<ReturnType<Plugin["createResource"]>> {
const validPlugin = this.plugins.find((plugin) => name === plugin.name)!;
const newResourceResult = await validPlugin.createResource(this.context);
if (newResourceResult.isError) return newResourceResult;
this.resourceMap.set(newResourceResult.uri, newResourceResult);
return newResourceResult;
}
setContext<
Name extends Plugins[number]["name"],
Plugin extends Extract<Plugins[number], { name: Name }>,
>(name: Name, context: Plugin["types"]["context"]) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.context[name] = context;
} }
} }

@ -1,9 +1,23 @@
import type { Resource } from "./Resource"; import type { Resource } from "./Resource";
import type { ErrorResult } from "./results/error/ErrorResult";
export interface ConnectedPlugin { export interface ConnectedPlugin<
name: string; Name extends string,
getResource(uri: string): Resource; UriType extends string,
createResource(): Promise<Resource>; ResourceType extends Resource<UriType>,
isUriValid(uri: string): boolean; ContextType,
normalizeUri?: (uri: string) => string; > {
name: Name;
getResource(uri: UriType, context: ContextType): ResourceType | ErrorResult;
createResource(context: ContextType): Promise<ResourceType | ErrorResult>;
isUriValid(uri: UriType): boolean;
normalizeUri?: (uri: UriType) => UriType;
initialContext: ContextType;
// This object exists to transfer typescript types. It does not need to be
// filled out in an actual instance.
types: {
uri: UriType;
context: ContextType;
resource: ResourceType;
};
} }

@ -1,7 +1,6 @@
import EventEmitter from "events"; import EventEmitter from "events";
import type { Resource, ResourceEventEmitter } from "./Resource"; import type { Resource, ResourceEventEmitter } from "./Resource";
import { InvalidUriError } from "./results/error/InvalidUriError"; import { InvalidUriError } from "./results/error/InvalidUriError";
import type { SubscriptionCallbacks } from "./notifications/NotificationSubscription";
export class InvalidIdentifierResource export class InvalidIdentifierResource
extends (EventEmitter as new () => ResourceEventEmitter) extends (EventEmitter as new () => ResourceEventEmitter)
@ -10,6 +9,7 @@ export class InvalidIdentifierResource
public readonly uri: string; public readonly uri: string;
public readonly type = "InvalidIdentifierResouce" as const; public readonly type = "InvalidIdentifierResouce" as const;
public status: InvalidUriError<this>; public status: InvalidUriError<this>;
public readonly isError = false as const;
constructor(uri: string) { constructor(uri: string) {
super(); super();
@ -50,9 +50,7 @@ export class InvalidIdentifierResource
async createIfAbsent(): Promise<InvalidUriError<this>> { async createIfAbsent(): Promise<InvalidUriError<this>> {
return this.status; return this.status;
} }
async subscribeToNotifications( async subscribeToNotifications(_callbacks): Promise<string> {
_callbacks?: SubscriptionCallbacks,
): Promise<string> {
throw new Error("Cannot subscribe to an invalid resource."); throw new Error("Cannot subscribe to an invalid resource.");
} }
async unsubscribeFromNotifications(_subscriptionId: string): Promise<void> { async unsubscribeFromNotifications(_subscriptionId: string): Promise<void> {

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type TypedEmitter from "typed-emitter"; import type TypedEmitter from "typed-emitter";
import type { ConnectedResult } from "./results/ConnectedResult"; import type { ConnectedResult } from "./results/ConnectedResult";
import type { ResourceResult } from "./results/ResourceResult"; import type { ResourceResult } from "./results/ResourceResult";
import type { SubscriptionCallbacks } from "./notifications/NotificationSubscription";
export type ResourceEventEmitter = TypedEmitter<{ export type ResourceEventEmitter = TypedEmitter<{
update: () => void; update: () => void;
@ -10,6 +10,7 @@ export type ResourceEventEmitter = TypedEmitter<{
export interface Resource<UriType extends string = string> export interface Resource<UriType extends string = string>
extends ResourceEventEmitter { extends ResourceEventEmitter {
readonly isError: false;
readonly uri: UriType; readonly uri: UriType;
readonly type: string; readonly type: string;
status: ConnectedResult; status: ConnectedResult;
@ -22,7 +23,10 @@ export interface Resource<UriType extends string = string>
isSubscribedToNotifications(): boolean; isSubscribedToNotifications(): boolean;
read(): Promise<ResourceResult<this>>; read(): Promise<ResourceResult<this>>;
readIfAbsent(): Promise<ResourceResult<this>>; readIfAbsent(): Promise<ResourceResult<this>>;
subscribeToNotifications(callbacks?: SubscriptionCallbacks): Promise<string>; subscribeToNotifications(callbacks?: {
onNotification: (message: any) => void;
onNotificationError: (err: Error) => void;
}): Promise<string>;
unsubscribeFromNotifications(subscriptionId: string): Promise<void>; unsubscribeFromNotifications(subscriptionId: string): Promise<void>;
unsubscribeFromAllNotifications(): Promise<void>; unsubscribeFromAllNotifications(): Promise<void>;
} }

@ -4,11 +4,10 @@ export * from "./Resource";
export * from "./InvalidIdentifierResource"; export * from "./InvalidIdentifierResource";
export * from "./ConnectedContext"; export * from "./ConnectedContext";
export * from "./notifications/NotificationMessage";
export * from "./notifications/NotificationSubscription";
export * from "./results/ConnectedResult"; export * from "./results/ConnectedResult";
export * from "./results/ResourceResult"; export * from "./results/ResourceResult";
export * from "./results/error/ErrorResult"; export * from "./results/error/ErrorResult";
export * from "./results/error/InvalidUriError";
export * from "./results/error/NotificationErrors";
export * from "./results/success/SuccessResult"; export * from "./results/success/SuccessResult";
export * from "./results/success/Unfetched"; export * from "./results/success/Unfetched";

@ -1,10 +0,0 @@
/**
* A message sent from the Pod as a notification
*/
export interface NotificationMessage {
"@context": string | string[];
id: string;
type: "Update" | "Delete" | "Remove" | "Add";
object: string;
published: string;
}

@ -1,144 +0,0 @@
import type { SolidLdoDatasetContext } from "../../SolidLdoDatasetContext";
import type { Resource } from "../Resource";
import type { NotificationMessage } from "./NotificationMessage";
import type { NotificationCallbackError } from "./results/NotificationErrors";
import { v4 } from "uuid";
export interface SubscriptionCallbacks {
onNotification?: (message: NotificationMessage) => void;
// TODO: make notification errors more specific
onNotificationError?: (error: Error) => void;
}
/**
* @internal
* Abstract class for notification subscription methods.
*/
export abstract class NotificationSubscription {
protected resource: Resource;
protected parentSubscription: (message: NotificationMessage) => void;
protected context: SolidLdoDatasetContext;
protected subscriptions: Record<string, SubscriptionCallbacks> = {};
private isOpen: boolean = false;
constructor(
resource: Resource,
parentSubscription: (message: NotificationMessage) => void,
context: SolidLdoDatasetContext,
) {
this.resource = resource;
this.parentSubscription = parentSubscription;
this.context = context;
}
public isSubscribedToNotifications(): boolean {
return this.isOpen;
}
/**
* ===========================================================================
* PUBLIC
* ===========================================================================
*/
/**
* @internal
* subscribeToNotifications
*/
async subscribeToNotifications(
subscriptionCallbacks?: SubscriptionCallbacks,
): Promise<string> {
const subscriptionId = v4();
this.subscriptions[subscriptionId] = subscriptionCallbacks ?? {};
if (!this.isOpen) {
await this.open();
this.setIsOpen(true);
}
return subscriptionId;
}
/**
* @internal
* unsubscribeFromNotification
*/
async unsubscribeFromNotification(subscriptionId: string): Promise<void> {
if (
!!this.subscriptions[subscriptionId] &&
Object.keys(this.subscriptions).length === 1
) {
await this.close();
this.setIsOpen(false);
}
delete this.subscriptions[subscriptionId];
}
/**
* @internal
* unsubscribeFromAllNotifications
*/
async unsubscribeFromAllNotifications(): Promise<void> {
await Promise.all(
Object.keys(this.subscriptions).map((id) =>
this.unsubscribeFromNotification(id),
),
);
}
/**
* ===========================================================================
* HELPERS
* ===========================================================================
*/
/**
* @internal
* Opens the subscription
*/
protected abstract open(): Promise<void>;
/**
* @internal
* Closes the subscription
*/
protected abstract close(): Promise<void>;
/**
* ===========================================================================
* CALLBACKS
* ===========================================================================
*/
/**
* @internal
* onNotification
*/
protected onNotification(message: NotificationMessage): void {
this.parentSubscription(message);
Object.values(this.subscriptions).forEach(({ onNotification }) => {
onNotification?.(message);
});
}
/**
* @internal
* onNotificationError
*/
protected onNotificationError(message: NotificationCallbackError): void {
Object.values(this.subscriptions).forEach(({ onNotificationError }) => {
onNotificationError?.(message);
});
if (message.type === "disconnectedNotAttemptingReconnectError") {
this.setIsOpen(false);
}
}
/**
* @internal
* setIsOpen
*/
protected setIsOpen(status: boolean) {
const shouldUpdate = status !== this.isOpen;
this.isOpen = status;
if (shouldUpdate) this.resource.emit("update");
}
}

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

@ -1,19 +0,0 @@
import type { Container } from "../../../resource/Container";
import type { ResourceSuccess, SuccessResult } from "./SuccessResult";
/**
* Indicates that the request to check if a resource is the root container was
* a success.
*/
export interface CheckRootContainerSuccess extends ResourceSuccess {
type: "checkRootContainerSuccess";
/**
* True if this resoure is the root container
*/
isRootContainer: boolean;
}
export interface GetStorageContainerFromWebIdSuccess extends SuccessResult {
type: "getStorageContainerFromWebIdSuccess";
storageContainers: Container[];
}

@ -1,13 +0,0 @@
import type { ResourceSuccess } from "./SuccessResult";
/**
* Indicates that the request to create the resource was a success.
*/
export interface CreateSuccess extends ResourceSuccess {
type: "createSuccess";
/**
* True if there was a resource that existed before at the given URI that was
* overwritten
*/
didOverwrite: boolean;
}

@ -1,14 +0,0 @@
import type { ResourceSuccess } from "./SuccessResult";
/**
* Indicates that the request to delete a resource was a success.
*/
export interface DeleteSuccess extends ResourceSuccess {
type: "deleteSuccess";
/**
* True if there was a resource at the provided URI that was deleted. False if
* a resource didn't exist.
*/
resourceExisted: boolean;
}

@ -1,71 +0,0 @@
import type { ResourceSuccess, SuccessResult } from "./SuccessResult";
/**
* Indicates that the request to read a resource was a success
*/
export interface ReadSuccess extends ResourceSuccess {
/**
* True if the resource was recalled from local memory rather than a recent
* request
*/
recalledFromMemory: boolean;
}
/**
* Indicates that the read request was successful and that the resource
* retrieved was a binary resource.
*/
export interface BinaryReadSuccess extends ReadSuccess {
type: "binaryReadSuccess";
/**
* The raw data for the binary resource
*/
blob: Blob;
/**
* The mime type of the binary resource
*/
mimeType: string;
}
/**
* Indicates that the read request was successful and that the resource
* retrieved was a data (RDF) resource.
*/
export interface DataReadSuccess extends ReadSuccess {
type: "dataReadSuccess";
}
/**
* Indicates that the read request was successful and that the resource
* retrieved was a container resource.
*/
export interface ContainerReadSuccess extends ReadSuccess {
type: "containerReadSuccess";
/**
* True if this container is a root container
*/
isRootContainer: boolean;
}
/**
* Indicates that the read request was successful, but no resource exists at
* the provided URI.
*/
export interface AbsentReadSuccess extends ReadSuccess {
type: "absentReadSuccess";
}
/**
* A helper function that checks to see if a result is a ReadSuccess result
*
* @param result - the result to check
* @returns true if the result is a ReadSuccessResult result
*/
export function isReadSuccess(result: SuccessResult): result is ReadSuccess {
return (
result.type === "binaryReadSuccess" ||
result.type === "dataReadSuccess" ||
result.type === "absentReadSuccess" ||
result.type === "containerReadSuccess"
);
}

@ -1,24 +0,0 @@
import type { ResourceSuccess } from "./SuccessResult";
/**
* Indicates that an update request to a resource was successful
*/
export interface UpdateSuccess extends ResourceSuccess {
type: "updateSuccess";
}
/**
* Indicates that an update request to the default graph was successful. This
* data was not written to a Pod. It was only written locally.
*/
export interface UpdateDefaultGraphSuccess extends ResourceSuccess {
type: "updateDefaultGraphSuccess";
}
/**
* Indicates that LDO ignored an invalid update (usually because a container
* attempted an update)
*/
export interface IgnoredInvalidUpdateSuccess extends ResourceSuccess {
type: "ignoredInvalidUpdateSuccess";
}
Loading…
Cancel
Save