Skip to content

Commit

Permalink
new major related to images
Browse files Browse the repository at this point in the history
  • Loading branch information
julianbenegas committed Jun 15, 2024
1 parent 21831a7 commit 706cca6
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 16 deletions.
24 changes: 24 additions & 0 deletions packages/basehub/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# basehub

## 7.0.0

### Major Changes

- Change asset delivery domain from basehub.earth to assets.basehub.com

basehub.earth will still work, but the response from our API will default to the new origin.

This is a breaking change because many developers already allowed basehub.earth as a domain for next/image and not yet assets.basehub.earth

So, why the change?

basehub.earth is the "raw" asset URL (that's stored in cloudflare r2). In order to perform image optimization and improve caching (assets are now cached as immutable), we needed to place a worker in front of r2. This new worker is in assets.basehub.com

Oh, also! We're introducing our next/image loader.

```tsx
import { BaseHubImage, basehubImageLoader } from "basehub/next-image";
```

`BaseHubImage` just returns the regular `next/image` but passes a loader that understands our image optimization cdn. This is great, as you can leverage our cdn instead of needing the asset to pass again via Next.js' optimization pipeline. Also, the URLs will be cleaner.

Enjoy!

## 6.0.7

### Patch Changes
Expand Down
1 change: 1 addition & 0 deletions packages/basehub/next-image.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./dist/next-image";
1 change: 1 addition & 0 deletions packages/basehub/next-image.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./dist/next-image";
6 changes: 4 additions & 2 deletions packages/basehub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "basehub",
"description": "The first AI-native content hub.",
"author": "JB <[email protected]>",
"version": "6.0.7",
"version": "7.0.0",
"license": "MIT",
"repository": "basehub-ai/basehub",
"bugs": "https://github.com/basehub-ai/basehub/issues",
Expand Down Expand Up @@ -33,7 +33,9 @@
"analytics.js",
"analytics.d.ts",
"search.js",
"search.d.ts"
"search.d.ts",
"next-image.js",
"next-image.d.ts"
],
"sideEffects": false,
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions packages/basehub/src/bin/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ R extends Omit<MutationGenqlSelection, "transaction"> & {
"react-search",
"analytics",
"search",
"next-image",
].map((pathsToAlias) => {
// create a file in the output directory that aliases the package to the generated client
fs.writeFileSync(
Expand Down
2 changes: 1 addition & 1 deletion packages/basehub/src/bin/util/get-stuff-from-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { dotenvLoad } from "dotenv-mono";

export const basehubAPIOrigin = "https://api.basehub.com";
const defaultEnvVarPrefix = "BASEHUB";
const DEFAULT_API_VERSION = "1";
const DEFAULT_API_VERSION = "2";

export type Options = {
forceDraft?: boolean;
Expand Down
1 change: 1 addition & 0 deletions packages/basehub/src/next/image/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { BaseHubImage, basehubImageLoader } from "./primitive";
77 changes: 77 additions & 0 deletions packages/basehub/src/next/image/primitive.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import type { ImageLoaderProps, ImageProps } from "next/image";
import Image from "next/image";

const r2URL_deprecated = `https://basehub.earth`;
const assetsURL = `https://assets.basehub.com`;

export const basehubImageLoader = ({
src,
width,
quality,
}: ImageLoaderProps) => {
let url;

try {
url = new URL(src);
} catch (error) {
throw new Error(`Invalid BaseHub Image URL: ${src}
Expected origin to be one of:
- ${r2URL_deprecated} (deprecated)
- ${assetsURL}
`);
}

const params = [`width=${width}`, `quality=${quality || 90}`];

if (url.href.includes(r2URL_deprecated)) {
if (url.pathname.startsWith("/cdn-cgi/image/")) {
// image has existing params. we'll append the extra ones
const [_empty, _cdnThing, _imageThing, currentParams = "", ...rest] =
url.pathname.split("/");
const filteredParams = currentParams.split(",").filter((param) => {
return (
!param.startsWith("width=") &&
!param.startsWith("quality=") &&
!param.startsWith("w=") &&
!param.startsWith("q=")
);
});
let newParams = filteredParams.join(",") + params.join(",");
if (newParams.includes("format=") === false) {
newParams += ",format=auto";
}
url.pathname = `/cdn-cgi/image/${newParams}/${rest.join("/")}`;
} else {
// image has no existing params. we'll append the extra ones
params.push("format=auto");
url.pathname = `/cdn-cgi/image/${params.join(",")}${url.pathname}`;
}
} else if (url.href.includes(assetsURL)) {
// simpler! just append the params
params.forEach((param) => {
const [key, value] = param.split("=");
if (!key || !value) return;
url.searchParams.set(key, value);
});
if (url.searchParams.has("format") === false) {
url.searchParams.set("format", "auto");
}
}

return url.toString();
};

/**
* Uses `next/image` under the hood. Just passes BaseHub's `loader` so that it utilizes BaseHub's Image Optimization.
*
* Literally just returns:
* ```tsx
* <Image {...props} loader={basehubImageLoader} />
* ```
*/
export const BaseHubImage = (props: ImageProps) => {
"use client";
// eslint-disable-next-line jsx-a11y/alt-text
return <Image {...props} loader={basehubImageLoader} />;
};
19 changes: 19 additions & 0 deletions packages/basehub/tsup-client.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { defineConfig, type Options } from "tsup";
import fs from "fs";
import { join } from "path";

export default defineConfig((_options: Options) => {
return {
Expand All @@ -10,7 +12,24 @@ export default defineConfig((_options: Options) => {
"api-transaction": "./src/api-transaction.ts",
analytics: "./src/analytics/index.ts",
search: "./src/search/index.ts",
"next-image": "./src/next/image/index.ts",
},
format: ["esm"],
external: ["react", "react-dom", "next"],
plugins: [
{
name: "use-client-banner",
buildEnd(thing) {
const useClientBannerRgx = /['"]use client['"]\s?;/i;
thing.writtenFiles.forEach((file) => {
const filePath = join(process.cwd(), file.name);
const content = fs.readFileSync(filePath, "utf-8");
if (!useClientBannerRgx.test(content)) return;
const newContents = content.replace(useClientBannerRgx, "");
fs.writeFileSync(filePath, `"use client";\n${newContents}`);
});
},
},
],
};
});
7 changes: 7 additions & 0 deletions playground/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# playground

## 0.0.107

### Patch Changes

- Updated dependencies
- [email protected]

## 0.0.106

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion playground/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const nextConfig = {
swcMinify: true,
experimental: { appDir: true, serverActions: true },
images: {
domains: ["lab.basement.studio"],
domains: ["lab.basement.studio", "assets.basehub.com", "basehub.earth"],
},
};

Expand Down
2 changes: 1 addition & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "playground",
"private": true,
"version": "0.0.106",
"version": "0.0.107",
"scripts": {
"dev": "basehub dev & next dev",
"build": "basehub && next build",
Expand Down
33 changes: 22 additions & 11 deletions playground/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { Pump } from "basehub/react-pump";
import { BaseHubImage } from "basehub/next-image";
import Image from "next/image";

export default async function HomePage() {
return (
<Pump
queries={[
{
blog: {
posts: {
items: {
_title: true,
richText: {
html: true,
},
},
footer: {
someImage: {
url: true,
width: true,
height: true,
alt: true,
},
},
},
Expand All @@ -21,9 +21,20 @@ export default async function HomePage() {
{async ([data]) => {
"use server";
return (
<pre>
<code>{JSON.stringify(data, null, 2)}</code>
</pre>
<div>
<BaseHubImage
src={data.footer.someImage.url}
alt={data.footer.someImage.alt ?? ""}
width={1600 / 2}
height={900 / 2}
/>
<Image
src={data.footer.someImage.url}
alt={data.footer.someImage.alt ?? ""}
width={1600 / 2}
height={900 / 2}
/>
</div>
);
}}
</Pump>
Expand Down

0 comments on commit 706cca6

Please sign in to comment.