diff --git a/package-lock.json b/package-lock.json index 4f399d7..60b2e3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25710,6 +25710,13 @@ "node": ">=0.10.0" } }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "dev": true, + "license": "MIT" + }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", @@ -26760,13 +26767,18 @@ "cross-fetch": "^3.1.6" }, "devDependencies": { + "@babel/core": "^7.26.10", + "@babel/preset-env": "^7.26.9", "@inrupt/jest-jsdom-polyfills": "^3.2.6", "@ldo/rdf-utils": "^1.0.0-alpha.1", "@rdfjs/types": "^1.0.1", "@testing-library/react": "^14.1.2", + "babel-jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "start-server-and-test": "^2.0.3", - "ts-node": "^10.9.2" + "ts-jest": "^29.3.0", + "ts-node": "^10.9.2", + "whatwg-fetch": "^3.6.20" } }, "packages/solid-type-index": { diff --git a/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts b/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts index 72017c0..2b546ba 100644 --- a/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts +++ b/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts @@ -93,7 +93,9 @@ export class Websocket2023NotificationSubscription extends SolidNotificationSubs this.onNotification(JSON.parse(messageData) as SolidNotificationMessage); }; - this.socket.onclose = this.onClose.bind(this); + this.socket.onclose = () => { + this.onClose(); + }; this.socket.onerror = (err) => { this.onNotificationError( @@ -129,10 +131,12 @@ export class Websocket2023NotificationSubscription extends SolidNotificationSubs } protected async close(): Promise { - this.socket?.terminate(); + this.socket?.close(); } } -function createWebsocketDefault(address: string) { - return new WebSocket(address); +function createWebsocketDefault(address: string): WebSocket { + const WebSocketImpl = + typeof window !== "undefined" ? window.WebSocket : WebSocket; + return new WebSocketImpl(address) as WebSocket; } diff --git a/packages/connected/src/ConnectedLdoDataset.ts b/packages/connected/src/ConnectedLdoDataset.ts index 5cfae20..e743bb8 100644 --- a/packages/connected/src/ConnectedLdoDataset.ts +++ b/packages/connected/src/ConnectedLdoDataset.ts @@ -47,6 +47,26 @@ export class ConnectedLdoDataset< ); } + private getValidPlugin( + uri: string, + pluginName?: string, + ): Plugins[number] | undefined { + // Check for which plugins this uri is valid + const validPlugins = this.plugins + .filter((plugin) => plugin.isUriValid(uri)) + .filter((plugin) => (pluginName ? pluginName === plugin.name : true)); + if (validPlugins.length === 0) { + return undefined; + } else if (validPlugins.length > 1) { + // 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. + throw new Error( + "LDO Connect does not currently support two plugins with overlappng uris", + ); + } + return validPlugins[0]; + } + /** * Retireves a representation of a Resource at the given URI. This resource * represents the current state of the resource: whether it is currently @@ -69,20 +89,8 @@ export class ConnectedLdoDataset< Plugin extends Extract, UriType extends string, >(uri: UriType, pluginName?: Name): GetResourceReturnType { - // Check for which plugins this uri is valid - const validPlugins = this.plugins - .filter((plugin) => plugin.isUriValid(uri)) - .filter((plugin) => (pluginName ? pluginName === plugin.name : true)); - if (validPlugins.length === 0) { - return new InvalidIdentifierResource(uri) as any; - } else if (validPlugins.length > 1) { - // 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. - throw new Error( - "LDO Connect does not currently support two plugins with overlappng uris", - ); - } - const plugin = validPlugins[0]; + const plugin = this.getValidPlugin(uri, pluginName); + if (!plugin) return new InvalidIdentifierResource(uri) as any; const normalizedUri = plugin.normalizeUri?.(uri) ?? uri; let resource = this.resourceMap.get(normalizedUri); @@ -111,6 +119,16 @@ export class ConnectedLdoDataset< return newResourceResult as any; } + forgetResource(uri: string): boolean { + const plugin = this.getValidPlugin(uri); + const normalizedUri = plugin?.normalizeUri?.(uri) ?? uri; + return this.resourceMap.delete(normalizedUri); + } + + forgetAllResources(): void { + this.resourceMap.clear(); + } + /** * Shorthand for solidLdoDataset * .usingType(shapeType) diff --git a/packages/connected/src/ConnectedLdoTransactionDataset.ts b/packages/connected/src/ConnectedLdoTransactionDataset.ts index b1cf8bb..11ca508 100644 --- a/packages/connected/src/ConnectedLdoTransactionDataset.ts +++ b/packages/connected/src/ConnectedLdoTransactionDataset.ts @@ -105,6 +105,13 @@ export class ConnectedLdoTransactionDataset this.context.dataset.setContext(name, context); } + forgetResource(uri: string): boolean { + return this.context.dataset.forgetResource(uri); + } + forgetAllResources(): void { + this.context.dataset.forgetAllResources(); + } + /** * Retireves a representation (either a LeafResource or a ContainerResource) * of a Solid Resource at the given URI. This resource represents the diff --git a/packages/connected/src/IConnectedLdoDataset.ts b/packages/connected/src/IConnectedLdoDataset.ts index 81dcb9b..ba6d503 100644 --- a/packages/connected/src/IConnectedLdoDataset.ts +++ b/packages/connected/src/IConnectedLdoDataset.ts @@ -52,6 +52,10 @@ export interface IConnectedLdoDataset name: Name, ): Promise>; + forgetResource(uri: string): boolean; + + forgetAllResources(): void; + setContext< Name extends Plugins[number]["name"], Plugin extends Extract, diff --git a/packages/solid-react/babel.config.js b/packages/solid-react/babel.config.js new file mode 100644 index 0000000..24d5e76 --- /dev/null +++ b/packages/solid-react/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [["@babel/preset-env", { targets: { node: "current" } }]], +}; diff --git a/packages/solid-react/jest.config.js b/packages/solid-react/jest.config.js index 7557fd2..6644585 100644 --- a/packages/solid-react/jest.config.js +++ b/packages/solid-react/jest.config.js @@ -3,5 +3,15 @@ module.exports = { ...sharedConfig, rootDir: "./", testEnvironment: "jsdom", + transform: { + "^.+\\.(ts|tsx)$": "ts-jest", + "^.+\\.(js|jsx)$": "babel-jest", + }, + transformIgnorePatterns: ["/node_modules/(?!(jose)/)"], + globals: { + "ts-jest": { + isolatedModules: true, + }, + }, setupFiles: ["/jest.setup.ts"], }; diff --git a/packages/solid-react/jest.setup.ts b/packages/solid-react/jest.setup.ts index b0bd26f..dd50f84 100644 --- a/packages/solid-react/jest.setup.ts +++ b/packages/solid-react/jest.setup.ts @@ -1 +1,8 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import "@inrupt/jest-jsdom-polyfills"; + +jest.mock("undici", () => { + return { + fetch: global.fetch, + }; +}); diff --git a/packages/solid-react/package.json b/packages/solid-react/package.json index 96e54b1..a7a0027 100644 --- a/packages/solid-react/package.json +++ b/packages/solid-react/package.json @@ -26,13 +26,18 @@ }, "homepage": "https://github.com/o-development/ldobjects/tree/main/packages/solid-react#readme", "devDependencies": { + "@babel/core": "^7.26.10", + "@babel/preset-env": "^7.26.9", "@inrupt/jest-jsdom-polyfills": "^3.2.6", "@ldo/rdf-utils": "^1.0.0-alpha.1", "@rdfjs/types": "^1.0.1", "@testing-library/react": "^14.1.2", + "babel-jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "start-server-and-test": "^2.0.3", - "ts-node": "^10.9.2" + "ts-jest": "^29.3.0", + "ts-node": "^10.9.2", + "whatwg-fetch": "^3.6.20" }, "dependencies": { "@inrupt/solid-client-authn-browser": "^2.0.0", diff --git a/packages/solid-react/test/Solid-Integration.test.tsx b/packages/solid-react/test/Solid-Integration.test.tsx index 6ea7763..e500871 100644 --- a/packages/solid-react/test/Solid-Integration.test.tsx +++ b/packages/solid-react/test/Solid-Integration.test.tsx @@ -9,6 +9,7 @@ import { } from "./setUpServer"; import { UnauthenticatedSolidLdoProvider } from "../src/UnauthenticatedSolidLdoProvider"; import { + dataset, useLdo, useMatchObject, useMatchSubject, @@ -23,21 +24,14 @@ import type { PostSh } from "./.ldo/post.typings"; // Use an increased timeout, since the CSS server takes too much setup time. jest.setTimeout(40_000); -const oldFetch = global.fetch; -global.fetch = async ( - input: string | Request | URL, - init?: RequestInit | undefined, -): Promise => { - console.log("-------"); - console.log(input, init); - const response = await oldFetch(input, init); - console.log(response.status); - return response; -}; - describe("Integration Tests", () => { setUpServer(); + afterEach(() => { + dataset.forgetAllResources(); + dataset.deleteMatches(undefined, undefined, undefined, undefined); + }); + /** * =========================================================================== * useResource @@ -56,7 +50,6 @@ describe("Integration Tests", () => { , ); await screen.findByText("Loading"); - debug(); const resourceStatus = await screen.findByRole("status"); expect(resourceStatus.innerHTML).toBe("dataReadSuccess"); });