Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
53af412
feat: Implement support for browser requests.
kinyoklion Sep 10, 2024
bf164dd
feat: Add support for conditional event source capabilities.
kinyoklion Sep 10, 2024
8307b03
Add more comments.
kinyoklion Sep 10, 2024
c23bf45
Implement for edge SDKs.
kinyoklion Sep 10, 2024
a084b9a
Lint
kinyoklion Sep 10, 2024
6acc5f4
Add getEventSourceCapabilities to mocks.
kinyoklion Sep 10, 2024
b89e14e
Test updates.
kinyoklion Sep 10, 2024
5becb5b
More test updates.
kinyoklion Sep 10, 2024
8f63e45
More tests.
kinyoklion Sep 10, 2024
1c5450f
More test updates.
kinyoklion Sep 10, 2024
f0a51c6
feat: Implement browser platform.
kinyoklion Sep 10, 2024
39355b8
Merge branch 'rlamb/sc-254415/support-event-source-capabilities' into…
kinyoklion Sep 10, 2024
d259791
Rename browser event source.
kinyoklion Sep 10, 2024
679b813
Add backoff tests.
kinyoklion Sep 10, 2024
0434103
Enable encoding.
kinyoklion Sep 10, 2024
7c66b7b
Move to rollup.
kinyoklion Sep 11, 2024
a9ae9ac
Merge branch 'main' into rlamb/sc-254415/implement-browser-requests
kinyoklion Sep 11, 2024
fd8d7d6
Validate package.json imports.
kinyoklion Sep 11, 2024
61a3631
Configurable reset time.
kinyoklion Sep 11, 2024
0cb22bf
feat: Scaffold browser client.
kinyoklion Sep 11, 2024
af341cb
Implements platform.
kinyoklion Sep 11, 2024
f70e901
Merge branch 'rlamb/sc-254415/implement-browser-requests' into rlamb/…
kinyoklion Sep 11, 2024
3900a13
feat: Scaffold browser client.
kinyoklion Sep 11, 2024
ff1dc23
Correct fetch.
kinyoklion Sep 11, 2024
e64cc34
Merge branch 'rlamb/sc-254415/implement-browser-requests' into rlamb/…
kinyoklion Sep 11, 2024
a1ad827
feat: Allow using custom user-agent name.
kinyoklion Sep 12, 2024
cf3abae
Merge branch 'main' into rlamb/sc-255716/support-x-launchdarkly-user-…
kinyoklion Sep 12, 2024
745e994
Remove unused imports.
kinyoklion Sep 12, 2024
5126f93
Event processor should use the default headers.
kinyoklion Sep 12, 2024
b58fc09
Merge branch 'rlamb/sc-255716/support-x-launchdarkly-user-agent' into…
kinyoklion Sep 12, 2024
a6e1126
Set user agent header name.
kinyoklion Sep 12, 2024
6fafb33
feat: Add initial contract test support.
kinyoklion Sep 13, 2024
44c8d7b
Cleanup.
kinyoklion Sep 13, 2024
49d292b
Refinements.
kinyoklion Sep 13, 2024
210d79b
Improvements.
kinyoklion Sep 13, 2024
a2db3ac
Move capabilities to the browser-side implementation.
kinyoklion Sep 13, 2024
4ad9aa4
Add typed evaluation tests.
kinyoklion Sep 13, 2024
e947304
Use typed enums.
kinyoklion Sep 13, 2024
73f6ae5
Revert shared changes.
kinyoklion Sep 13, 2024
f1b254e
Merge branch 'main' into rlamb/sc-254697/browser-contract-tests
kinyoklion Sep 13, 2024
90ed3e7
Project configuratin updates.
kinyoklion Sep 13, 2024
861cb20
Lint and lint structure.
kinyoklion Sep 13, 2024
b69a5b4
Lint
kinyoklion Sep 13, 2024
2897452
Exclude contract tests from the browser SDK build configuration.
kinyoklion Sep 13, 2024
3f02658
Package script adjustments.
kinyoklion Sep 13, 2024
f75a6e2
Improve logging. Automatically open browser.
kinyoklion Sep 13, 2024
db0f41f
Add description.
kinyoklion Sep 13, 2024
2be0b60
Change title.
kinyoklion Sep 13, 2024
d2e7bdd
Remove vite logo.
kinyoklion Sep 13, 2024
9d929fe
Typo
kinyoklion Sep 13, 2024
8eb02f3
Suppress less.
kinyoklion Sep 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"packages/store/node-server-sdk-dynamodb",
"packages/telemetry/node-server-sdk-otel",
"packages/tooling/jest",
"packages/sdk/browser"
"packages/sdk/browser",
"packages/sdk/browser/contract-tests/entity",
"packages/sdk/browser/contract-tests/adapter"
],
"private": true,
"scripts": {
Expand Down
40 changes: 40 additions & 0 deletions packages/sdk/browser/contract-tests/adapter/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "browser-contract-test-adapter",
"version": "1.0.0",
"description": "Adapts REST interface to a websocket for use in browsers.",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"start": "yarn build && node dist/index.js",
"lint": "eslint ./src",
"prettier": "prettier --write '**/*.@(js|ts|tsx|json|css)' --ignore-path ../../../../.prettierignore"
},
"author": "",
"license": "UNLICENSED",
"dependencies": {
"body-parser": "^1.20.3",
"cors": "^2.8.5",
"express": "^4.21.0",
"ws": "^8.18.0"
},
"devDependencies": {
"@eslint/js": "^9.10.0",
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/ws": "^8.5.12",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",
"eslint": "^8.45.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jest": "^27.6.3",
"eslint-plugin-prettier": "^5.0.0",
"globals": "^15.9.0",
"prettier": "^3.0.0",
"typescript": "^5.6.2",
"typescript-eslint": "^8.5.0"
}
}
112 changes: 112 additions & 0 deletions packages/sdk/browser/contract-tests/adapter/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* eslint-disable no-console */

/* eslint-disable @typescript-eslint/no-explicit-any */
import bodyParser from 'body-parser';
import cors from 'cors';
import { randomUUID } from 'crypto';
import express from 'express';
import http from 'node:http';
import util from 'node:util';
import { WebSocketServer } from 'ws';

let server: http.Server | undefined;

async function main() {
const wss = new WebSocketServer({ port: 8001 });
const waiters: Record<string, (data: unknown) => void> = {};

console.log('Running contract test harness adapter.');
wss.on('connection', async (ws) => {
ws.on('error', console.error);

ws.on('message', (stringData: string) => {
const data = JSON.parse(stringData);
if (Object.prototype.hasOwnProperty.call(waiters, data.reqId)) {
waiters[data.reqId](data);
delete waiters[data.reqId];
} else {
console.error('Did not find outstanding request', data.reqId);
}
});

const send = (data: { [key: string]: unknown; reqId: string }): Promise<any> => {
let resolver: (data: unknown) => void;
const waiter = new Promise((resolve) => {
resolver = resolve;
});
// @ts-expect-error The body of the above assignment runs sequentially.
waiters[data.reqId] = resolver;
ws.send(JSON.stringify(data));
return waiter;
};

if (server) {
await util.promisify(server.close).call(server);
server = undefined;
}

const app = express();

const port = 8000;

app.use(
cors({
origin: '*',
allowedHeaders: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
}),
);
app.use(bodyParser.json());

app.get('/', async (_req, res) => {
const commandResult = await send({ command: 'getCapabilities', reqId: randomUUID() });
res.header('Content-Type', 'application/json');
res.json(commandResult);
});

app.delete('/', () => {
process.exit();
});

app.post('/', async (req, res) => {
const commandResult = await send({
command: 'createClient',
body: req.body,
reqId: randomUUID(),
});
if (commandResult.resourceUrl) {
res.set('Location', commandResult.resourceUrl);
}
if (commandResult.status) {
res.status(commandResult.status);
}
res.send();
});

app.post('/clients/:id', async (req, res) => {
const commandResult = await send({
command: 'runCommand',
id: req.params.id,
body: req.body,
reqId: randomUUID(),
});
if (commandResult.status) {
res.status(commandResult.status);
}
if (commandResult.body) {
res.write(JSON.stringify(commandResult.body));
}
res.send();
});

app.delete('/clients/:id', async (req, res) => {
await send({ command: 'deleteClient', id: req.params.id, reqId: randomUUID() });
res.send();
});

server = app.listen(port, () => {
console.log('Listening on port %d', port);
});
});
}
main();
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "./tsconfig.json",
"include": ["/**/*.ts"],
"exclude": ["node_modules"]
}
14 changes: 14 additions & 0 deletions packages/sdk/browser/contract-tests/adapter/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"moduleResolution": "node",
"outDir": "dist",
"sourceMap": true
},
"lib": ["ES6"],
"exclude": ["**/*.test.ts", "dist", "node_modules"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"include": ["src/**/*", "package.json"],
"compilerOptions": {
"composite": true
}
}
13 changes: 13 additions & 0 deletions packages/sdk/browser/contract-tests/entity/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SDK Contract Test Service</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
30 changes: 30 additions & 0 deletions packages/sdk/browser/contract-tests/entity/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "browser-contract-test-service",
"private": true,
"version": "0.0.0",
"type": "module",
"description": "Contract test service implementation for @launchdarkly/js-client-sdk",
"scripts": {
"start": "vite --open=true",
"lint": "eslint ./src",
"prettier": "prettier --write '**/*.@(js|ts|tsx|json|css)' --ignore-path ../../../../.prettierignore"
},
"dependencies": {
"@launchdarkly/js-client-sdk": "0.0.0"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",
"eslint": "^8.45.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jest": "^27.6.3",
"eslint-plugin-prettier": "^5.0.0",
"prettier": "^3.0.0",
"typescript": "^5.5.3",
"vite": "^5.4.1"
}
}
Loading