@polymorfa/browser 0.1.0-dev.20260922094209
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +248 -0
- package/dist/calls/api.d.ts +22 -0
- package/dist/calls/api.d.ts.map +1 -0
- package/dist/calls/api.js +104 -0
- package/dist/calls/api.js.map +1 -0
- package/dist/calls/backend.d.ts +85 -0
- package/dist/calls/backend.d.ts.map +1 -0
- package/dist/calls/backend.js +141 -0
- package/dist/calls/backend.js.map +1 -0
- package/dist/calls/client.d.ts +56 -0
- package/dist/calls/client.d.ts.map +1 -0
- package/dist/calls/client.js +260 -0
- package/dist/calls/client.js.map +1 -0
- package/dist/calls/controller.d.ts +329 -0
- package/dist/calls/controller.d.ts.map +1 -0
- package/dist/calls/controller.js +1328 -0
- package/dist/calls/controller.js.map +1 -0
- package/dist/calls/diagnostics.d.ts +52 -0
- package/dist/calls/diagnostics.d.ts.map +1 -0
- package/dist/calls/diagnostics.js +188 -0
- package/dist/calls/diagnostics.js.map +1 -0
- package/dist/calls/index.d.ts +3 -0
- package/dist/calls/index.d.ts.map +1 -0
- package/dist/calls/index.js +5 -0
- package/dist/calls/index.js.map +1 -0
- package/dist/calls/internal.d.ts +8 -0
- package/dist/calls/internal.d.ts.map +1 -0
- package/dist/calls/internal.js +8 -0
- package/dist/calls/internal.js.map +1 -0
- package/dist/calls/media.d.ts +144 -0
- package/dist/calls/media.d.ts.map +1 -0
- package/dist/calls/media.js +512 -0
- package/dist/calls/media.js.map +1 -0
- package/dist/calls/signaling.d.ts +74 -0
- package/dist/calls/signaling.d.ts.map +1 -0
- package/dist/calls/signaling.js +169 -0
- package/dist/calls/signaling.js.map +1 -0
- package/dist/calls/socket.d.ts +95 -0
- package/dist/calls/socket.d.ts.map +1 -0
- package/dist/calls/socket.js +267 -0
- package/dist/calls/socket.js.map +1 -0
- package/dist/chat/composer.d.ts +59 -0
- package/dist/chat/composer.d.ts.map +1 -0
- package/dist/chat/composer.js +217 -0
- package/dist/chat/composer.js.map +1 -0
- package/dist/chat/conversation.d.ts +71 -0
- package/dist/chat/conversation.d.ts.map +1 -0
- package/dist/chat/conversation.js +204 -0
- package/dist/chat/conversation.js.map +1 -0
- package/dist/chat/index.d.ts +4 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +4 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/voice-recorder.d.ts +75 -0
- package/dist/chat/voice-recorder.d.ts.map +1 -0
- package/dist/chat/voice-recorder.js +346 -0
- package/dist/chat/voice-recorder.js.map +1 -0
- package/dist/controller.d.ts +16 -0
- package/dist/controller.d.ts.map +1 -0
- package/dist/controller.js +50 -0
- package/dist/controller.js.map +1 -0
- package/dist/diagnostics.d.ts +27 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +2 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/dropin/client.d.ts +82 -0
- package/dist/dropin/client.d.ts.map +1 -0
- package/dist/dropin/client.js +314 -0
- package/dist/dropin/client.js.map +1 -0
- package/dist/dropin/connect.d.ts +23 -0
- package/dist/dropin/connect.d.ts.map +1 -0
- package/dist/dropin/connect.js +54 -0
- package/dist/dropin/connect.js.map +1 -0
- package/dist/dropin/inbox.d.ts +131 -0
- package/dist/dropin/inbox.d.ts.map +1 -0
- package/dist/dropin/inbox.js +406 -0
- package/dist/dropin/inbox.js.map +1 -0
- package/dist/dropin/index.d.ts +5 -0
- package/dist/dropin/index.d.ts.map +1 -0
- package/dist/dropin/index.js +5 -0
- package/dist/dropin/index.js.map +1 -0
- package/dist/dropin/permissions.d.ts +29 -0
- package/dist/dropin/permissions.d.ts.map +1 -0
- package/dist/dropin/permissions.js +53 -0
- package/dist/dropin/permissions.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +12 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +13 -0
- package/dist/internal.js.map +1 -0
- package/dist/messaging/client.d.ts +54 -0
- package/dist/messaging/client.d.ts.map +1 -0
- package/dist/messaging/client.js +153 -0
- package/dist/messaging/client.js.map +1 -0
- package/dist/messaging/composer.d.ts +12 -0
- package/dist/messaging/composer.d.ts.map +1 -0
- package/dist/messaging/composer.js +36 -0
- package/dist/messaging/composer.js.map +1 -0
- package/dist/messaging/index.d.ts +4 -0
- package/dist/messaging/index.d.ts.map +1 -0
- package/dist/messaging/index.js +3 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/messaging/types.d.ts +209 -0
- package/dist/messaging/types.d.ts.map +1 -0
- package/dist/messaging/types.js +2 -0
- package/dist/messaging/types.js.map +1 -0
- package/dist/templates/controller.d.ts +45 -0
- package/dist/templates/controller.d.ts.map +1 -0
- package/dist/templates/controller.js +298 -0
- package/dist/templates/controller.js.map +1 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +3 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/transport.d.ts +7 -0
- package/dist/templates/transport.d.ts.map +1 -0
- package/dist/templates/transport.js +124 -0
- package/dist/templates/transport.js.map +1 -0
- package/dist/templates/types.d.ts +141 -0
- package/dist/templates/types.d.ts.map +1 -0
- package/dist/templates/types.js +2 -0
- package/dist/templates/types.js.map +1 -0
- package/dist/token.d.ts +37 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +152 -0
- package/dist/token.js.map +1 -0
- package/dist/transport.d.ts +53 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +328 -0
- package/dist/transport.js.map +1 -0
- package/package.json +45 -0
package/dist/token.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface ClientToken {
|
|
2
|
+
readonly value: string;
|
|
3
|
+
readonly audience: "browser";
|
|
4
|
+
readonly expiresAt: number;
|
|
5
|
+
readonly scopes?: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
export type ClientTokenProvider = () => Promise<string | ClientToken>;
|
|
8
|
+
export interface ClientTokenProviderOptions {
|
|
9
|
+
readonly path?: string;
|
|
10
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
11
|
+
}
|
|
12
|
+
export declare function createClientTokenProvider(options?: ClientTokenProviderOptions): ClientTokenProvider;
|
|
13
|
+
export interface ClientTokenManagerOptions {
|
|
14
|
+
readonly now?: () => number;
|
|
15
|
+
readonly expirySkewMs?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class ClientTokenManager {
|
|
18
|
+
#private;
|
|
19
|
+
constructor(provider: ClientTokenProvider, options?: ClientTokenManagerOptions);
|
|
20
|
+
get(): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* The current token with its expiry when the provider supplied one.
|
|
23
|
+
* `refresh: true` discards the cached token first.
|
|
24
|
+
*/
|
|
25
|
+
token(options?: {
|
|
26
|
+
readonly refresh?: boolean;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
readonly value: string;
|
|
29
|
+
readonly expiresAt?: number;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* Drop the cached token. A provider call already in flight may return the
|
|
33
|
+
* refused token: it neither answers later requests nor replaces the cache.
|
|
34
|
+
*/
|
|
35
|
+
invalidate(): void;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;AAEtE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAC1C;AAED,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,mBAAmB,CA8DrB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,qBAAa,kBAAkB;;gBAU3B,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,GAAE,yBAA8B;IAczC,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;IAItB;;;OAGG;IACG,KAAK,CACT,OAAO,GAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO,GAC3C,OAAO,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAQnE;;;OAGG;IACH,UAAU,IAAI,IAAI;CAyDnB"}
|
package/dist/token.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { BrowserConfigurationError, BrowserHttpError } from "./errors.js";
|
|
2
|
+
export function createClientTokenProvider(options = {}) {
|
|
3
|
+
const path = options.path ?? "/api/polymorfa/token";
|
|
4
|
+
if (!path.startsWith("/") ||
|
|
5
|
+
path.startsWith("//") ||
|
|
6
|
+
path.includes("\\") ||
|
|
7
|
+
URL.canParse(path)) {
|
|
8
|
+
throw new BrowserConfigurationError("Client token route must be a same-origin relative path.", "invalid_token_route");
|
|
9
|
+
}
|
|
10
|
+
const fetch = options.fetch ?? globalThis.fetch;
|
|
11
|
+
if (typeof fetch !== "function") {
|
|
12
|
+
throw new BrowserConfigurationError("A fetch implementation is required for the client token route.", "missing_fetch");
|
|
13
|
+
}
|
|
14
|
+
return async () => {
|
|
15
|
+
const response = await fetch(path, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
credentials: "same-origin",
|
|
18
|
+
headers: { accept: "application/json" },
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
throw new BrowserHttpError(`Client token route failed with status ${response.status}.`, {
|
|
22
|
+
category: response.status >= 500 ? "server" : "http",
|
|
23
|
+
status: response.status,
|
|
24
|
+
code: "client_token_route_failed",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
let value;
|
|
28
|
+
try {
|
|
29
|
+
value = await response.json();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
throw new BrowserConfigurationError("Client token route returned an invalid response.", "invalid_token_response");
|
|
33
|
+
}
|
|
34
|
+
if (!isClientToken(value)) {
|
|
35
|
+
throw new BrowserConfigurationError("Client token route returned invalid browser claims.", "invalid_token_response");
|
|
36
|
+
}
|
|
37
|
+
return Object.freeze({
|
|
38
|
+
value: value.value,
|
|
39
|
+
audience: "browser",
|
|
40
|
+
expiresAt: value.expiresAt,
|
|
41
|
+
...(value.scopes === undefined
|
|
42
|
+
? {}
|
|
43
|
+
: { scopes: Object.freeze([...value.scopes]) }),
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export class ClientTokenManager {
|
|
48
|
+
#provider;
|
|
49
|
+
#now;
|
|
50
|
+
#expirySkewMs;
|
|
51
|
+
#cached;
|
|
52
|
+
#pending;
|
|
53
|
+
// Only the latest provider call may replace the cached token.
|
|
54
|
+
#fetchGeneration = 0;
|
|
55
|
+
constructor(provider, options = {}) {
|
|
56
|
+
if (typeof provider !== "function")
|
|
57
|
+
throw new BrowserConfigurationError("getClientToken must be a function.");
|
|
58
|
+
this.#provider = provider;
|
|
59
|
+
this.#now = options.now ?? Date.now;
|
|
60
|
+
this.#expirySkewMs = options.expirySkewMs ?? 30_000;
|
|
61
|
+
if (!Number.isFinite(this.#expirySkewMs) || this.#expirySkewMs < 0) {
|
|
62
|
+
throw new BrowserConfigurationError("expirySkewMs must be a non-negative number.");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
get() {
|
|
66
|
+
return this.#get(false);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The current token with its expiry when the provider supplied one.
|
|
70
|
+
* `refresh: true` discards the cached token first.
|
|
71
|
+
*/
|
|
72
|
+
async token(options = {}) {
|
|
73
|
+
const value = await this.#get(options.refresh === true);
|
|
74
|
+
const cached = this.#cached;
|
|
75
|
+
return cached !== undefined && cached.value === value
|
|
76
|
+
? { value, expiresAt: cached.expiresAt }
|
|
77
|
+
: { value };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Drop the cached token. A provider call already in flight may return the
|
|
81
|
+
* refused token: it neither answers later requests nor replaces the cache.
|
|
82
|
+
*/
|
|
83
|
+
invalidate() {
|
|
84
|
+
this.#cached = undefined;
|
|
85
|
+
this.#pending = undefined;
|
|
86
|
+
this.#fetchGeneration += 1;
|
|
87
|
+
}
|
|
88
|
+
#get(refresh) {
|
|
89
|
+
if (!refresh &&
|
|
90
|
+
this.#cached !== undefined &&
|
|
91
|
+
this.#cached.expiresAt - this.#expirySkewMs > this.#now()) {
|
|
92
|
+
return Promise.resolve(this.#cached.value);
|
|
93
|
+
}
|
|
94
|
+
// A forced refresh never takes the result of a provider call that started
|
|
95
|
+
// before it was requested: that call may return the refused token.
|
|
96
|
+
if (refresh)
|
|
97
|
+
this.invalidate();
|
|
98
|
+
if (this.#pending !== undefined)
|
|
99
|
+
return this.#pending;
|
|
100
|
+
const generation = ++this.#fetchGeneration;
|
|
101
|
+
const promise = this.#refresh(generation).finally(() => {
|
|
102
|
+
if (this.#pending === promise)
|
|
103
|
+
this.#pending = undefined;
|
|
104
|
+
});
|
|
105
|
+
this.#pending = promise;
|
|
106
|
+
return promise;
|
|
107
|
+
}
|
|
108
|
+
async #refresh(generation) {
|
|
109
|
+
const supplied = await this.#provider();
|
|
110
|
+
if (typeof supplied === "string") {
|
|
111
|
+
validatePrefix(supplied);
|
|
112
|
+
return supplied;
|
|
113
|
+
}
|
|
114
|
+
validatePrefix(supplied.value);
|
|
115
|
+
if (supplied.audience !== "browser") {
|
|
116
|
+
throw new BrowserConfigurationError("Client token audience must be browser.", "invalid_token_audience");
|
|
117
|
+
}
|
|
118
|
+
if (!Number.isFinite(supplied.expiresAt) ||
|
|
119
|
+
supplied.expiresAt <= this.#now()) {
|
|
120
|
+
throw new BrowserConfigurationError("Client token is expired or has an invalid expiry.", "expired_client_token");
|
|
121
|
+
}
|
|
122
|
+
if (generation !== this.#fetchGeneration)
|
|
123
|
+
return supplied.value;
|
|
124
|
+
this.#cached = Object.freeze({
|
|
125
|
+
...supplied,
|
|
126
|
+
...(supplied.scopes === undefined
|
|
127
|
+
? {}
|
|
128
|
+
: { scopes: Object.freeze([...supplied.scopes]) }),
|
|
129
|
+
});
|
|
130
|
+
return supplied.value;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function validatePrefix(value) {
|
|
134
|
+
if (!value.startsWith("pmfa_ct_") || value.length <= "pmfa_ct_".length) {
|
|
135
|
+
throw new BrowserConfigurationError("Browser client token must use the pmfa_ct_ prefix.", "invalid_client_token");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function isClientToken(value) {
|
|
139
|
+
if (typeof value !== "object" || value === null)
|
|
140
|
+
return false;
|
|
141
|
+
const token = value;
|
|
142
|
+
return (typeof token.value === "string" &&
|
|
143
|
+
token.value.startsWith("pmfa_ct_") &&
|
|
144
|
+
token.value.length > "pmfa_ct_".length &&
|
|
145
|
+
token.audience === "browser" &&
|
|
146
|
+
typeof token.expiresAt === "number" &&
|
|
147
|
+
Number.isFinite(token.expiresAt) &&
|
|
148
|
+
(token.scopes === undefined ||
|
|
149
|
+
(Array.isArray(token.scopes) &&
|
|
150
|
+
token.scopes.every((scope) => typeof scope === "string"))));
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { BrowserDiagnosticSink } from "./diagnostics.js";
|
|
2
|
+
import { type ClientTokenProvider } from "./token.js";
|
|
3
|
+
export type BrowserHttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
|
|
4
|
+
export interface BrowserRequest {
|
|
5
|
+
readonly method: BrowserHttpMethod;
|
|
6
|
+
readonly path: string;
|
|
7
|
+
readonly query?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
8
|
+
readonly body?: unknown;
|
|
9
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
10
|
+
readonly idempotencyKey?: string;
|
|
11
|
+
readonly signal?: AbortSignal;
|
|
12
|
+
readonly timeoutMs?: number;
|
|
13
|
+
readonly maxNetworkRetries?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface BrowserResponseMetadata {
|
|
16
|
+
readonly status: number;
|
|
17
|
+
readonly requestId?: string;
|
|
18
|
+
readonly attempts: number;
|
|
19
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
20
|
+
}
|
|
21
|
+
export interface BrowserResponse<T> {
|
|
22
|
+
readonly data: T;
|
|
23
|
+
readonly metadata: BrowserResponseMetadata;
|
|
24
|
+
}
|
|
25
|
+
export interface BrowserTransportOptions {
|
|
26
|
+
readonly getClientToken: ClientTokenProvider;
|
|
27
|
+
readonly baseUrl?: string;
|
|
28
|
+
readonly timeoutMs?: number;
|
|
29
|
+
readonly maxNetworkRetries?: number;
|
|
30
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
31
|
+
readonly sleep?: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
|
|
32
|
+
readonly random?: () => number;
|
|
33
|
+
readonly now?: () => number;
|
|
34
|
+
readonly onDiagnostic?: BrowserDiagnosticSink;
|
|
35
|
+
}
|
|
36
|
+
export declare class BrowserTransport {
|
|
37
|
+
#private;
|
|
38
|
+
/** The API origin requests are resolved against (no trailing slash). */
|
|
39
|
+
get baseUrl(): string;
|
|
40
|
+
constructor(options: BrowserTransportOptions);
|
|
41
|
+
/**
|
|
42
|
+
* The client token requests use, for authenticating sockets. `refresh: true`
|
|
43
|
+
* asks the token provider for a new token.
|
|
44
|
+
*/
|
|
45
|
+
token(options?: {
|
|
46
|
+
readonly refresh?: boolean;
|
|
47
|
+
}): Promise<{
|
|
48
|
+
readonly value: string;
|
|
49
|
+
readonly expiresAt?: number;
|
|
50
|
+
}>;
|
|
51
|
+
request<T = unknown>(request: BrowserRequest): Promise<BrowserResponse<T>>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAAsB,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E,MAAM,MAAM,iBAAiB,GAC3B,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CACvB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAC7D,CAAC;IACF,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAC;CAC5C;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,CACf,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,WAAW,KACjB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,qBAAqB,CAAC;CAC/C;AAID,qBAAa,gBAAgB;;IAc3B,wEAAwE;IACxE,IAAI,OAAO,IAAI,MAAM,CAEpB;gBAEW,OAAO,EAAE,uBAAuB;IAuB5C;;;OAGG;IACH,KAAK,CACH,OAAO,GAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO,GAC3C,OAAO,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAI7D,OAAO,CAAC,CAAC,GAAG,OAAO,EACvB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;CAkI/B"}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { BrowserCancelledError, BrowserConnectionError, BrowserError, BrowserHttpError, BrowserTimeoutError, BrowserValidationError, } from "./errors.js";
|
|
2
|
+
import { ClientTokenManager } from "./token.js";
|
|
3
|
+
const SAFE_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
|
|
4
|
+
export class BrowserTransport {
|
|
5
|
+
#baseUrl;
|
|
6
|
+
#tokens;
|
|
7
|
+
#timeoutMs;
|
|
8
|
+
#maxNetworkRetries;
|
|
9
|
+
#fetch;
|
|
10
|
+
#sleep;
|
|
11
|
+
#random;
|
|
12
|
+
#now;
|
|
13
|
+
#onDiagnostic;
|
|
14
|
+
/** The API origin requests are resolved against (no trailing slash). */
|
|
15
|
+
get baseUrl() {
|
|
16
|
+
return this.#baseUrl;
|
|
17
|
+
}
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.#baseUrl = (options.baseUrl ?? "https://api.polymorfa.com").replace(/\/+$/, "");
|
|
20
|
+
this.#tokens = new ClientTokenManager(options.getClientToken);
|
|
21
|
+
this.#timeoutMs = positiveInteger(options.timeoutMs ?? 15_000, "timeoutMs", false);
|
|
22
|
+
this.#maxNetworkRetries = positiveInteger(options.maxNetworkRetries ?? 2, "maxNetworkRetries", true);
|
|
23
|
+
this.#fetch = options.fetch ?? globalThis.fetch;
|
|
24
|
+
this.#sleep = options.sleep ?? defaultSleep;
|
|
25
|
+
this.#random = options.random ?? Math.random;
|
|
26
|
+
this.#now = options.now ?? Date.now;
|
|
27
|
+
this.#onDiagnostic = options.onDiagnostic;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The client token requests use, for authenticating sockets. `refresh: true`
|
|
31
|
+
* asks the token provider for a new token.
|
|
32
|
+
*/
|
|
33
|
+
token(options = {}) {
|
|
34
|
+
return this.#tokens.token(options);
|
|
35
|
+
}
|
|
36
|
+
async request(request) {
|
|
37
|
+
validatePath(request.path);
|
|
38
|
+
const retries = positiveInteger(request.maxNetworkRetries ?? this.#maxNetworkRetries, "maxNetworkRetries", true);
|
|
39
|
+
const retryableMethod = SAFE_METHODS.has(request.method) || Boolean(request.idempotencyKey);
|
|
40
|
+
let attempt = 0;
|
|
41
|
+
while (true) {
|
|
42
|
+
attempt += 1;
|
|
43
|
+
const startedAt = this.#now();
|
|
44
|
+
this.#emit({
|
|
45
|
+
type: "request.started",
|
|
46
|
+
timestamp: startedAt,
|
|
47
|
+
method: request.method,
|
|
48
|
+
path: request.path,
|
|
49
|
+
attempt,
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
const response = await this.#perform(request);
|
|
53
|
+
const data = await decodeBody(response);
|
|
54
|
+
const metadata = responseMetadata(response, attempt);
|
|
55
|
+
if (response.ok) {
|
|
56
|
+
this.#emit({
|
|
57
|
+
type: "request.completed",
|
|
58
|
+
timestamp: this.#now(),
|
|
59
|
+
method: request.method,
|
|
60
|
+
path: request.path,
|
|
61
|
+
attempt,
|
|
62
|
+
status: response.status,
|
|
63
|
+
durationMs: Math.max(this.#now() - startedAt, 0),
|
|
64
|
+
...(metadata.requestId === undefined
|
|
65
|
+
? {}
|
|
66
|
+
: { requestId: metadata.requestId }),
|
|
67
|
+
});
|
|
68
|
+
return Object.freeze({ data: data, metadata });
|
|
69
|
+
}
|
|
70
|
+
if (retryableMethod &&
|
|
71
|
+
attempt <= retries &&
|
|
72
|
+
isRetryableStatus(response.status) &&
|
|
73
|
+
!isIdempotentReplay(response)) {
|
|
74
|
+
await this.#sleep(retryDelay(response, attempt, this.#random), request.signal);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
throw httpError(response, data, metadata);
|
|
78
|
+
}
|
|
79
|
+
catch (cause) {
|
|
80
|
+
const error = classifyFailure(cause, request.signal);
|
|
81
|
+
if ((error instanceof BrowserConnectionError ||
|
|
82
|
+
error instanceof BrowserTimeoutError) &&
|
|
83
|
+
retryableMethod &&
|
|
84
|
+
attempt <= retries) {
|
|
85
|
+
await this.#sleep(retryDelay(undefined, attempt, this.#random), request.signal);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
this.#emit({
|
|
89
|
+
type: "request.failed",
|
|
90
|
+
timestamp: this.#now(),
|
|
91
|
+
method: request.method,
|
|
92
|
+
path: request.path,
|
|
93
|
+
attempt,
|
|
94
|
+
durationMs: Math.max(this.#now() - startedAt, 0),
|
|
95
|
+
category: error.category,
|
|
96
|
+
...(error.status === undefined ? {} : { status: error.status }),
|
|
97
|
+
...(error.requestId === undefined
|
|
98
|
+
? {}
|
|
99
|
+
: { requestId: error.requestId }),
|
|
100
|
+
});
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async #perform(request) {
|
|
106
|
+
throwIfAborted(request.signal);
|
|
107
|
+
const token = await this.#tokens.get();
|
|
108
|
+
throwIfAborted(request.signal);
|
|
109
|
+
const headers = new Headers(request.headers);
|
|
110
|
+
headers.set("accept", "application/json");
|
|
111
|
+
headers.set("authorization", `Bearer ${token}`);
|
|
112
|
+
headers.set("x-polymorfa-client", "browser/0.1.0-dev.0");
|
|
113
|
+
if (request.idempotencyKey !== undefined)
|
|
114
|
+
headers.set("idempotency-key", request.idempotencyKey);
|
|
115
|
+
const body = request.body === undefined ? undefined : JSON.stringify(request.body);
|
|
116
|
+
if (body !== undefined)
|
|
117
|
+
headers.set("content-type", "application/json");
|
|
118
|
+
const timeoutMs = positiveInteger(request.timeoutMs ?? this.#timeoutMs, "timeoutMs", false);
|
|
119
|
+
const controller = new AbortController();
|
|
120
|
+
let timedOut = false;
|
|
121
|
+
const timer = setTimeout(() => {
|
|
122
|
+
timedOut = true;
|
|
123
|
+
controller.abort();
|
|
124
|
+
}, timeoutMs);
|
|
125
|
+
const cancel = () => controller.abort(request.signal?.reason);
|
|
126
|
+
request.signal?.addEventListener("abort", cancel, { once: true });
|
|
127
|
+
try {
|
|
128
|
+
return await this.#fetch(requestUrl(this.#baseUrl, request), {
|
|
129
|
+
method: request.method,
|
|
130
|
+
headers,
|
|
131
|
+
...(body === undefined ? {} : { body }),
|
|
132
|
+
signal: controller.signal,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
catch (cause) {
|
|
136
|
+
if (timedOut)
|
|
137
|
+
throw new RequestTimeout(timeoutMs, cause);
|
|
138
|
+
throw cause;
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
clearTimeout(timer);
|
|
142
|
+
request.signal?.removeEventListener("abort", cancel);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
#emit(event) {
|
|
146
|
+
this.#onDiagnostic?.(Object.freeze(event));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
class RequestTimeout extends Error {
|
|
150
|
+
timeoutMs;
|
|
151
|
+
constructor(timeoutMs, cause) {
|
|
152
|
+
super("Request timed out.", { cause });
|
|
153
|
+
this.timeoutMs = timeoutMs;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function validatePath(path) {
|
|
157
|
+
if (!path.startsWith("/") ||
|
|
158
|
+
path.startsWith("//") ||
|
|
159
|
+
path.includes("\\") ||
|
|
160
|
+
URL.canParse(path)) {
|
|
161
|
+
throw new BrowserValidationError("Browser request paths must be relative and begin with one slash.", "invalid_path");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function requestUrl(baseUrl, request) {
|
|
165
|
+
const url = new URL(request.path, `${baseUrl}/`);
|
|
166
|
+
for (const [key, value] of Object.entries(request.query ?? {})) {
|
|
167
|
+
if (value !== undefined && value !== null)
|
|
168
|
+
url.searchParams.append(key, String(value));
|
|
169
|
+
}
|
|
170
|
+
return url;
|
|
171
|
+
}
|
|
172
|
+
async function decodeBody(response) {
|
|
173
|
+
if (response.status === 204)
|
|
174
|
+
return undefined;
|
|
175
|
+
const text = await response.text();
|
|
176
|
+
if (text.length === 0)
|
|
177
|
+
return undefined;
|
|
178
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
179
|
+
if (!contentType.includes("json"))
|
|
180
|
+
return text;
|
|
181
|
+
try {
|
|
182
|
+
return JSON.parse(text);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return text;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function responseMetadata(response, attempts) {
|
|
189
|
+
const headers = {};
|
|
190
|
+
response.headers.forEach((value, key) => {
|
|
191
|
+
headers[key] = value;
|
|
192
|
+
});
|
|
193
|
+
const requestId = response.headers.get("x-request-id") ??
|
|
194
|
+
response.headers.get("request-id") ??
|
|
195
|
+
undefined;
|
|
196
|
+
return Object.freeze({
|
|
197
|
+
status: response.status,
|
|
198
|
+
attempts,
|
|
199
|
+
headers: Object.freeze(headers),
|
|
200
|
+
...(requestId === undefined ? {} : { requestId }),
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function httpError(response, details, metadata) {
|
|
204
|
+
const category = response.status === 401
|
|
205
|
+
? "authentication"
|
|
206
|
+
: response.status === 403
|
|
207
|
+
? "authorization"
|
|
208
|
+
: response.status === 404
|
|
209
|
+
? "not_found"
|
|
210
|
+
: response.status === 409
|
|
211
|
+
? "conflict"
|
|
212
|
+
: response.status === 429
|
|
213
|
+
? "rate_limit"
|
|
214
|
+
: response.status >= 500
|
|
215
|
+
? "server"
|
|
216
|
+
: "http";
|
|
217
|
+
const fields = errorFields(details);
|
|
218
|
+
// Cross-origin callers cannot always read X-Request-Id; the body repeats it.
|
|
219
|
+
const requestId = fields.requestId ?? metadata.requestId;
|
|
220
|
+
return new BrowserHttpError(errorMessage(details, response.status), {
|
|
221
|
+
category,
|
|
222
|
+
status: response.status,
|
|
223
|
+
details,
|
|
224
|
+
metadata,
|
|
225
|
+
...(fields.code === undefined ? {} : { code: fields.code }),
|
|
226
|
+
...(requestId === undefined ? {} : { requestId }),
|
|
227
|
+
...(fields.docUrl === undefined ? {} : { docUrl: fields.docUrl }),
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function errorFields(details) {
|
|
231
|
+
if (typeof details !== "object" || details === null)
|
|
232
|
+
return {};
|
|
233
|
+
const record = details;
|
|
234
|
+
const error = typeof record.error === "object" && record.error !== null
|
|
235
|
+
? record.error
|
|
236
|
+
: undefined;
|
|
237
|
+
const text = (value) => typeof value === "string" && value.length > 0 ? value : undefined;
|
|
238
|
+
const code = text(error ? error.code : record.code);
|
|
239
|
+
const requestId = text(error?.request_id);
|
|
240
|
+
const docUrl = text(record.docs);
|
|
241
|
+
return {
|
|
242
|
+
...(code === undefined ? {} : { code }),
|
|
243
|
+
...(requestId === undefined ? {} : { requestId }),
|
|
244
|
+
...(docUrl === undefined ? {} : { docUrl }),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function errorMessage(details, status) {
|
|
248
|
+
if (typeof details === "object" && details !== null) {
|
|
249
|
+
const record = details;
|
|
250
|
+
if (typeof record.error === "object" && record.error !== null) {
|
|
251
|
+
const message = record.error.message;
|
|
252
|
+
if (typeof message === "string")
|
|
253
|
+
return message;
|
|
254
|
+
}
|
|
255
|
+
if (typeof record.message === "string")
|
|
256
|
+
return record.message;
|
|
257
|
+
if (typeof record.error === "string")
|
|
258
|
+
return record.error;
|
|
259
|
+
}
|
|
260
|
+
return `Polymorfa browser request failed with status ${status}.`;
|
|
261
|
+
}
|
|
262
|
+
function classifyFailure(cause, signal) {
|
|
263
|
+
if (cause instanceof BrowserError)
|
|
264
|
+
return cause;
|
|
265
|
+
if (signal?.aborted === true) {
|
|
266
|
+
return new BrowserCancelledError("The browser request was cancelled.", {
|
|
267
|
+
category: "cancelled",
|
|
268
|
+
cause,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
if (cause instanceof RequestTimeout) {
|
|
272
|
+
return new BrowserTimeoutError(`The browser request exceeded its ${cause.timeoutMs}ms timeout.`, {
|
|
273
|
+
category: "timeout",
|
|
274
|
+
cause,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return new BrowserConnectionError("The browser request could not reach the Polymorfa API.", {
|
|
278
|
+
category: "connection",
|
|
279
|
+
cause,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* A replayed Idempotency-Key result is final: retrying returns the same
|
|
284
|
+
* recorded response, so a replayed failure is surfaced immediately.
|
|
285
|
+
*/
|
|
286
|
+
function isIdempotentReplay(response) {
|
|
287
|
+
return response.headers.get("idempotent-replayed") === "true";
|
|
288
|
+
}
|
|
289
|
+
function isRetryableStatus(status) {
|
|
290
|
+
return status === 408 || status === 409 || status === 429 || status >= 500;
|
|
291
|
+
}
|
|
292
|
+
function retryDelay(response, attempt, random) {
|
|
293
|
+
const retryAfter = response?.headers.get("retry-after");
|
|
294
|
+
if (retryAfter !== undefined && retryAfter !== null) {
|
|
295
|
+
const seconds = Number(retryAfter);
|
|
296
|
+
if (Number.isFinite(seconds) && seconds >= 0)
|
|
297
|
+
return Math.min(seconds * 1_000, 30_000);
|
|
298
|
+
}
|
|
299
|
+
const ceiling = Math.min(250 * 2 ** Math.max(attempt - 1, 0), 3_000);
|
|
300
|
+
return Math.floor(ceiling * (0.5 + random() * 0.5));
|
|
301
|
+
}
|
|
302
|
+
async function defaultSleep(milliseconds, signal) {
|
|
303
|
+
if (signal?.aborted === true)
|
|
304
|
+
throw signal.reason;
|
|
305
|
+
await new Promise((resolve, reject) => {
|
|
306
|
+
const finish = () => {
|
|
307
|
+
signal?.removeEventListener("abort", abort);
|
|
308
|
+
resolve();
|
|
309
|
+
};
|
|
310
|
+
const timer = setTimeout(finish, milliseconds);
|
|
311
|
+
const abort = () => {
|
|
312
|
+
clearTimeout(timer);
|
|
313
|
+
reject(signal?.reason);
|
|
314
|
+
};
|
|
315
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
function positiveInteger(value, field, allowZero) {
|
|
319
|
+
if (!Number.isInteger(value) || value < 0 || (!allowZero && value === 0)) {
|
|
320
|
+
throw new BrowserValidationError(`${field} must be ${allowZero ? "a non-negative" : "a positive"} integer.`);
|
|
321
|
+
}
|
|
322
|
+
return value;
|
|
323
|
+
}
|
|
324
|
+
function throwIfAborted(signal) {
|
|
325
|
+
if (signal?.aborted === true)
|
|
326
|
+
throw signal.reason;
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@polymorfa/browser",
|
|
3
|
+
"version": "0.1.0-dev.20260922094209",
|
|
4
|
+
"description": "Framework-neutral Polymorfa browser transport and product controllers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/polymorfa/sdks.git",
|
|
10
|
+
"directory": "packages/browser"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/polymorfa/sdks/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/polymorfa/sdks#readme",
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@polymorfa/sdk": "0.1.0-dev.20260922094209"
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./internal": {
|
|
28
|
+
"types": "./dist/internal.d.ts",
|
|
29
|
+
"import": "./dist/internal.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsc -p tsconfig.build.json",
|
|
39
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public",
|
|
43
|
+
"provenance": true
|
|
44
|
+
}
|
|
45
|
+
}
|