Skip to content

Commit 4f1bbd2

Browse files
authored
@gitbook/adaptive (#808)
* WIP * put in devdeps * client folder * review * simplify * remove export * package version * changeset
1 parent 49e3ad1 commit 4f1bbd2

File tree

9 files changed

+266
-24
lines changed

9 files changed

+266
-24
lines changed

.changeset/solid-wasps-switch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@gitbook/adaptive': patch
3+
---
4+
5+
Initial version of @gitbook/adaptive

bun.lock

Lines changed: 112 additions & 24 deletions
Large diffs are not rendered by default.

packages/adaptive/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist

packages/adaptive/esbuild.config.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const esbuild = require('esbuild');
2+
3+
// Common settings
4+
const commonSettings = {
5+
entryPoints: ['src/index.ts'],
6+
bundle: true,
7+
minify: true,
8+
sourcemap: true,
9+
target: ['es2020', 'chrome70', 'firefox70', 'safari12', 'edge79'],
10+
plugins: [],
11+
logLevel: 'info',
12+
};
13+
14+
// Build ESM module
15+
esbuild
16+
.build({
17+
...commonSettings,
18+
outfile: 'dist/index.js',
19+
format: 'esm',
20+
})
21+
.catch(() => process.exit(1));
22+
23+
// Build CommonJS module
24+
esbuild
25+
.build({
26+
...commonSettings,
27+
outfile: 'dist/index.cjs',
28+
format: 'cjs',
29+
})
30+
.catch(() => process.exit(1));

packages/adaptive/package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "@gitbook/adaptive",
3+
"description": "Utility to use adaptive content in GitBook",
4+
"type": "module",
5+
"version": "0.0.0",
6+
"sideEffects": false,
7+
"files": [
8+
"README.md",
9+
"dist/**"
10+
],
11+
"dependencies": {
12+
"js-cookie": "^3.0.5"
13+
},
14+
"devDependencies": {
15+
"@gitbook/tsconfig": "*",
16+
"typescript": "^5.6.2",
17+
"@bucketco/browser-sdk": "^3.1.2",
18+
"@types/js-cookie": "^3.0.6",
19+
"esbuild": "^0.25.3"
20+
},
21+
"scripts": {
22+
"build": "bun esbuild.config.js && tsc --emitDeclarationOnly",
23+
"typecheck": "tsc --noEmit"
24+
},
25+
"exports": {
26+
".": {
27+
"import": "./dist/index.js",
28+
"default": "./dist/index.cjs",
29+
"require": "./dist/index.cjs",
30+
"types": "./dist/index.d.ts"
31+
},
32+
"./package.json": "./package.json"
33+
}
34+
}

packages/adaptive/src/bucket.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { BucketClient } from '@bucketco/browser-sdk';
2+
import { writeGitBookVisitorCookie } from './utils';
3+
4+
/**
5+
* Sets a client-side session cookie with the features enabled in the bucket client.
6+
*/
7+
export function withBucket(client: BucketClient): () => void {
8+
const handler = () => {
9+
const features: Record<string, boolean> = {};
10+
// Check features enabled in the client
11+
for (const [key, value] of Object.entries(client.getFeatures())) {
12+
const enabled =
13+
typeof value.isEnabledOverride === 'boolean'
14+
? value.isEnabledOverride
15+
: value.isEnabled;
16+
features[key] = enabled;
17+
}
18+
19+
writeGitBookVisitorCookie('bucket', features);
20+
};
21+
22+
// Determine if we're in a browser environment
23+
const isBrowser = typeof window !== 'undefined';
24+
25+
if (!isBrowser) {
26+
console.warn('withBucket was called in a non-browser environment');
27+
return () => {};
28+
}
29+
30+
const cleanup: Array<() => void> = [];
31+
32+
// Add event listener for when the DOM is ready
33+
if (document.readyState === 'interactive' || document.readyState === 'complete') {
34+
handler();
35+
} else {
36+
document.addEventListener('DOMContentLoaded', handler);
37+
cleanup.push(() => {
38+
document.removeEventListener('DOMContentLoaded', handler);
39+
});
40+
}
41+
// Add event listeners for feature updates
42+
cleanup.push(client.on('featuresUpdated', handler));
43+
44+
// Return cleanup function
45+
return () => {
46+
cleanup.forEach((fn) => fn());
47+
};
48+
}

packages/adaptive/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './bucket';
2+
export { writeGitBookVisitorCookie } from './utils';

packages/adaptive/src/utils.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Cookies from 'js-cookie';
2+
3+
const GITBOOK_VISITOR_PUBLIC_PREFIX = 'gitbook-visitor-public' as const;
4+
5+
/**
6+
* Write a client-side cookie for the GitBook visitor.
7+
*/
8+
export function writeGitBookVisitorCookie(name: string, value: unknown) {
9+
const COOKIE_NAME = `${GITBOOK_VISITOR_PUBLIC_PREFIX}-${name}`;
10+
const COOKIE_VALUE = (() => {
11+
try {
12+
return typeof value === 'string' ? value : JSON.stringify(value);
13+
} catch (e) {
14+
console.error('Error serializing value for cookie: ', e);
15+
throw e;
16+
}
17+
})();
18+
19+
Cookies.set(COOKIE_NAME, COOKIE_VALUE, {
20+
secure: true,
21+
});
22+
}

packages/adaptive/tsconfig.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "@gitbook/tsconfig/base.json",
3+
"include": ["src/**/*"],
4+
"rootDir": "./src",
5+
"compilerOptions": {
6+
"outDir": "./dist",
7+
"baseUrl": "./src",
8+
"allowImportingTsExtensions": false,
9+
"noEmit": false,
10+
"declaration": true
11+
}
12+
}

0 commit comments

Comments
 (0)