Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ JavaScript SDK for integrating with an [Optable Data Connectivity Node (DCN)](ht
- [Rules](#rules)
- [Return Value](#return-value)
- [Input Type](#input-type)
- [Geotargeting](#geotargeting)
- [Geo-routing](#geo-routing)
- [Demo Pages](#demo-pages)

## Installing
Expand Down Expand Up @@ -1175,27 +1175,27 @@ type NodeTargetingRule = {
};
```

## Geotargeting
## Geo-routing

The geotargeting addon maps a visitor's geo (country code) to the Optable host and node that should serve them, so that a single SDK bundle can route traffic to region-specific DCNs.
The geo-routing addon maps a visitor's region code to the Optable edge host that should serve them, so that a single SDK bundle can route traffic to the right regional edge.

```typescript
import { getGeoConfig } from "@optable/web-sdk/lib/dist/addons/geotargeting";
import { getGeoRouting } from "@optable/web-sdk/lib/dist/addons/geo-routing";

const geoConfig = getGeoConfig("acme", visitorGeo); // e.g. { host: "na.edge.optable.co", node: "acme" } for "US"
const host = getGeoRouting(visitorRegion); // e.g. "na.edge.optable.co" for "NA"

if (geoConfig) {
if (host) {
const sdk = new OptableSDK({
host: geoConfig.host,
node: geoConfig.node,
host,
node: "my-node",
site: "my-site",
});
}
```

The first argument is the node name: the tenant name, optionally with an `-auth` suffix to select the auth variant of the node (e.g. `"acme-auth"`). `getGeoConfig` returns `null` when the geo is not supported, in which case region-specific initialization should be skipped. For geos served by a dedicated cloud host rather than a regional edge host, `node` is `undefined` and the host's default node is used.
`getGeoRouting` returns `null` when the region is not supported, in which case region-specific initialization should be skipped. The default `GeoMap` supports the `NA`, `CA`, `EU` and `AU` region codes, each mapped to its regional edge host; pass a custom `GeoMap` as the second argument for other regions.

The default `GeoMap` supports the `US`, `CA`, `GB`, `UK` and `AU` geos and reflects a specific provisioning shape: regional edge nodes in US/CA and dedicated per-tenant cloud hosts (`<name>.cloud.<region>.optable.co`) in AU and the EU. The dedicated hosts only exist for tenants provisioned that way — pass a custom `GeoMap` as the third argument when your topology differs; see `lib/addons/geotargeting.ts` for the entry format.
Keys are region codes, not country codes. Translating a visitor's country code to a region code (for example `GB`/`UK``EU`) is the caller's responsibility — the addon deliberately knows only regions. The caller also supplies the SDK `node`/`site`; this addon only resolves the host.

## Demo Pages

Expand Down
42 changes: 42 additions & 0 deletions lib/addons/geo-routing.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { getGeoRouting, DEFAULT_GEO_MAP } from "./geo-routing.ts";

describe("getGeoRouting", () => {
test("resolves the edge host for each supported region", () => {
expect(getGeoRouting("NA")).toBe("na.edge.optable.co");
expect(getGeoRouting("CA")).toBe("ca.edge.optable.co");
expect(getGeoRouting("EU")).toBe("eu.edge.optable.co");
expect(getGeoRouting("AU")).toBe("au.edge.optable.co");
});

test("returns null for an unsupported region", () => {
expect(getGeoRouting("SA")).toBeNull();
});

test("returns null for a missing region", () => {
expect(getGeoRouting("")).toBeNull();
expect(getGeoRouting(undefined)).toBeNull();
});

test("returns null for regions inherited from Object.prototype", () => {
expect(getGeoRouting("constructor")).toBeNull();
expect(getGeoRouting("__proto__")).toBeNull();
expect(getGeoRouting("toString")).toBeNull();
});

test("is case-sensitive on the region key", () => {
expect(getGeoRouting("na")).toBeNull();
});

test("accepts a custom geo map", () => {
const geoMap = { SA: "sa.edge.optable.co" };
expect(getGeoRouting("SA", geoMap)).toBe("sa.edge.optable.co");
expect(getGeoRouting("NA", geoMap)).toBeNull();
});

test("exposes the default geo map", () => {
expect(DEFAULT_GEO_MAP.NA).toBe("na.edge.optable.co");
expect(DEFAULT_GEO_MAP.CA).toBe("ca.edge.optable.co");
expect(DEFAULT_GEO_MAP.EU).toBe("eu.edge.optable.co");
expect(DEFAULT_GEO_MAP.AU).toBe("au.edge.optable.co");
});
});
35 changes: 35 additions & 0 deletions lib/addons/geo-routing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* The geo-routing addon maps a visitor's region code to the Optable edge host
* that should serve them, so a single SDK bundle can route traffic to the
* regional edge closest to (and provisioned for) the visitor.
*
* Keys are region codes (not country codes) that map 1:1 to Optable edge hosts.
* Translating a visitor's country code to a region code is the caller's
* responsibility — the addon deliberately knows only regions, not the full
* country-to-region table. The caller also supplies the SDK `node`/`site`;
* this addon only resolves the host.
*/

export type GeoMap = Record<string, string>;

export const DEFAULT_GEO_MAP: GeoMap = {
AU: "au.edge.optable.co",
CA: "ca.edge.optable.co",
EU: "eu.edge.optable.co",
NA: "na.edge.optable.co",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be US: "na.edge.optable.co" instead of NA: "na.edge.optable.co". We could support both though.

};

/*
* getGeoRouting() resolves the Optable edge host for a given region code.
*
* Returns null when the region is missing or not present in the map, in which
* case the caller should skip region-specific initialization.
*/
export function getGeoRouting(region: string | undefined, geoMap: GeoMap = DEFAULT_GEO_MAP): string | null {
// hasOwnProperty guards against inherited Object.prototype members being
// picked up when an unexpected region like "constructor" is looked up.
if (region === undefined || !Object.prototype.hasOwnProperty.call(geoMap, region)) {
return null;
}
return geoMap[region];
}
94 changes: 0 additions & 94 deletions lib/addons/geotargeting.test.js

This file was deleted.

72 changes: 0 additions & 72 deletions lib/addons/geotargeting.ts

This file was deleted.

Loading