@genex-ai/embed-sdk 0.17.0 → 0.21.1

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.
@@ -0,0 +1,249 @@
1
+ // ../embed-protocol/src/constants.ts
2
+ var NATIVE_CHANNEL = "genex-native";
3
+ var NATIVE_PROTOCOL_VERSION = 1;
4
+ var NATIVE_MARKER_PARAM = "genex_native";
5
+ var NATIVE_MARKER_VALUE = "1";
6
+ var NATIVE_PROTOCOL_PARAM = "genex_protocol";
7
+ var NATIVE_ATTEMPT_PARAM = "genex_attempt";
8
+ var NATIVE_NONCE_PARAM = "genex_nonce";
9
+ var NATIVE_RECEIVER = "__genexNative";
10
+ var MAX_BRIDGE_MESSAGE_BYTES = 4096;
11
+ var BRIDGE_ID_RE = /^[0-9a-f]{32}$/;
12
+ var SLUG_RE = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
13
+ function isBridgeId(value) {
14
+ return typeof value === "string" && BRIDGE_ID_RE.test(value);
15
+ }
16
+ function isBridgeSlug(value) {
17
+ return typeof value === "string" && SLUG_RE.test(value);
18
+ }
19
+
20
+ // ../embed-protocol/src/base64url.ts
21
+ var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
22
+ var LOOKUP = (() => {
23
+ const table = new Array(128).fill(-1);
24
+ for (let i = 0; i < ALPHABET.length; i++) table[ALPHABET.charCodeAt(i)] = i;
25
+ return table;
26
+ })();
27
+ function utf8Bytes(text) {
28
+ const out = [];
29
+ for (let i = 0; i < text.length; i++) {
30
+ let code = text.charCodeAt(i);
31
+ if (code >= 55296 && code <= 56319) {
32
+ const next = i + 1 < text.length ? text.charCodeAt(i + 1) : 0;
33
+ if (next >= 56320 && next <= 57343) {
34
+ code = 65536 + (code - 55296 << 10) + (next - 56320);
35
+ i++;
36
+ } else {
37
+ code = 65533;
38
+ }
39
+ } else if (code >= 56320 && code <= 57343) {
40
+ code = 65533;
41
+ }
42
+ if (code < 128) out.push(code);
43
+ else if (code < 2048) out.push(192 | code >> 6, 128 | code & 63);
44
+ else if (code < 65536) {
45
+ out.push(224 | code >> 12, 128 | code >> 6 & 63, 128 | code & 63);
46
+ } else {
47
+ out.push(
48
+ 240 | code >> 18,
49
+ 128 | code >> 12 & 63,
50
+ 128 | code >> 6 & 63,
51
+ 128 | code & 63
52
+ );
53
+ }
54
+ }
55
+ return out;
56
+ }
57
+ function utf8Text(bytes) {
58
+ let out = "";
59
+ for (let i = 0; i < bytes.length; ) {
60
+ const b0 = bytes[i];
61
+ let code;
62
+ let size;
63
+ if (b0 < 128) {
64
+ code = b0;
65
+ size = 1;
66
+ } else if ((b0 & 224) === 192) {
67
+ code = b0 & 31;
68
+ size = 2;
69
+ } else if ((b0 & 240) === 224) {
70
+ code = b0 & 15;
71
+ size = 3;
72
+ } else if ((b0 & 248) === 240) {
73
+ code = b0 & 7;
74
+ size = 4;
75
+ } else return null;
76
+ if (i + size > bytes.length) return null;
77
+ for (let k = 1; k < size; k++) {
78
+ const b = bytes[i + k];
79
+ if ((b & 192) !== 128) return null;
80
+ code = code << 6 | b & 63;
81
+ }
82
+ if (size === 2 && code < 128) return null;
83
+ if (size === 3 && (code < 2048 || code >= 55296 && code <= 57343)) return null;
84
+ if (size === 4 && (code < 65536 || code > 1114111)) return null;
85
+ if (code > 65535) {
86
+ const v = code - 65536;
87
+ out += String.fromCharCode(55296 + (v >> 10), 56320 + (v & 1023));
88
+ } else {
89
+ out += String.fromCharCode(code);
90
+ }
91
+ i += size;
92
+ }
93
+ return out;
94
+ }
95
+ function utf8ByteLength(text) {
96
+ return utf8Bytes(text).length;
97
+ }
98
+ function encodeBase64UrlJson(value) {
99
+ const bytes = utf8Bytes(JSON.stringify(value));
100
+ let out = "";
101
+ for (let i = 0; i < bytes.length; i += 3) {
102
+ const b0 = bytes[i];
103
+ const b1 = bytes[i + 1];
104
+ const b2 = bytes[i + 2];
105
+ out += ALPHABET[b0 >> 2];
106
+ out += ALPHABET[(b0 & 3) << 4 | (b1 ?? 0) >> 4];
107
+ if (b1 === void 0) break;
108
+ out += ALPHABET[(b1 & 15) << 2 | (b2 ?? 0) >> 6];
109
+ if (b2 === void 0) break;
110
+ out += ALPHABET[b2 & 63];
111
+ }
112
+ return out;
113
+ }
114
+ function decodeBase64UrlJson(encoded) {
115
+ if (encoded.length % 4 === 1) return void 0;
116
+ const bytes = [];
117
+ let buffer = 0;
118
+ let bits = 0;
119
+ for (let i = 0; i < encoded.length; i++) {
120
+ const code = encoded.charCodeAt(i);
121
+ const value = code < 128 ? LOOKUP[code] : -1;
122
+ if (value < 0) return void 0;
123
+ buffer = buffer << 6 | value;
124
+ bits += 6;
125
+ if (bits >= 8) {
126
+ bits -= 8;
127
+ bytes.push(buffer >> bits & 255);
128
+ }
129
+ }
130
+ if (bits > 0 && (buffer & (1 << bits) - 1) !== 0) return void 0;
131
+ const text = utf8Text(bytes);
132
+ if (text === null) return void 0;
133
+ try {
134
+ return JSON.parse(text);
135
+ } catch {
136
+ return void 0;
137
+ }
138
+ }
139
+
140
+ // ../embed-protocol/src/messages.ts
141
+ var MAX_TICKET_LENGTH = 2048;
142
+ var MAX_EXPIRES_AT_LENGTH = 32;
143
+ var ISO_INSTANT_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?Z$/;
144
+ function isRecord(value) {
145
+ return typeof value === "object" && value !== null && !Array.isArray(value);
146
+ }
147
+ function hasExactKeys(value, keys) {
148
+ const own = Object.keys(value);
149
+ if (own.length !== keys.length) return false;
150
+ for (const key of keys) {
151
+ if (!Object.prototype.hasOwnProperty.call(value, key)) return false;
152
+ }
153
+ return true;
154
+ }
155
+ var BASE_KEYS = ["channel", "v", "type", "slug", "attemptId", "nonce"];
156
+ function envelopeBaseIsValid(value) {
157
+ return value.channel === NATIVE_CHANNEL && value.v === NATIVE_PROTOCOL_VERSION && isBridgeSlug(value.slug) && isBridgeId(value.attemptId) && isBridgeId(value.nonce);
158
+ }
159
+ function parseBridgeNativeCommand(value) {
160
+ if (!isRecord(value) || !envelopeBaseIsValid(value)) return void 0;
161
+ switch (value.type) {
162
+ case "ticket":
163
+ if (!hasExactKeys(value, [...BASE_KEYS, "ticket", "expiresAt"])) return void 0;
164
+ if (typeof value.ticket !== "string" || value.ticket.length === 0 || value.ticket.length > MAX_TICKET_LENGTH) {
165
+ return void 0;
166
+ }
167
+ if (typeof value.expiresAt !== "string" || value.expiresAt.length > MAX_EXPIRES_AT_LENGTH || !ISO_INSTANT_RE.test(value.expiresAt)) {
168
+ return void 0;
169
+ }
170
+ return value;
171
+ case "guest":
172
+ case "cancel":
173
+ if (!hasExactKeys(value, BASE_KEYS)) return void 0;
174
+ return value;
175
+ case "foreground":
176
+ if (!hasExactKeys(value, [...BASE_KEYS, "active"])) return void 0;
177
+ if (typeof value.active !== "boolean") return void 0;
178
+ return value;
179
+ case "network":
180
+ if (!hasExactKeys(value, [...BASE_KEYS, "online"])) return void 0;
181
+ if (typeof value.online !== "boolean") return void 0;
182
+ return value;
183
+ default:
184
+ return void 0;
185
+ }
186
+ }
187
+
188
+ // ../embed-protocol/src/transport.ts
189
+ function read(raw, parse) {
190
+ if (typeof raw !== "string" || raw.length === 0) return { ok: false, reason: "undecodable" };
191
+ if (utf8ByteLength(raw) > MAX_BRIDGE_MESSAGE_BYTES) return { ok: false, reason: "too-large" };
192
+ const decoded = decodeBase64UrlJson(raw);
193
+ if (decoded === void 0) return { ok: false, reason: "undecodable" };
194
+ const message = parse(decoded);
195
+ if (message === void 0) return { ok: false, reason: "invalid" };
196
+ return { ok: true, message };
197
+ }
198
+ function readBridgeNativeCommand(raw) {
199
+ return read(raw, parseBridgeNativeCommand);
200
+ }
201
+ function encodeBridgeMessage(message) {
202
+ const encoded = encodeBase64UrlJson(message);
203
+ if (encoded.length > MAX_BRIDGE_MESSAGE_BYTES) return void 0;
204
+ return encoded;
205
+ }
206
+
207
+ // ../embed-protocol/src/entry-url.ts
208
+ function readParam(search, key) {
209
+ const query = search.charAt(0) === "?" ? search.slice(1) : search;
210
+ if (query.length === 0) return null;
211
+ for (const pair of query.split("&")) {
212
+ const eq = pair.indexOf("=");
213
+ if (eq === -1) continue;
214
+ if (pair.slice(0, eq) === key) return pair.slice(eq + 1);
215
+ }
216
+ return null;
217
+ }
218
+ function hasNativeMarker(search) {
219
+ return readParam(search, NATIVE_MARKER_PARAM) === NATIVE_MARKER_VALUE;
220
+ }
221
+ function readNativeEntry(search) {
222
+ if (!hasNativeMarker(search)) return null;
223
+ const attemptId = readParam(search, NATIVE_ATTEMPT_PARAM);
224
+ const nonce = readParam(search, NATIVE_NONCE_PARAM);
225
+ const protocol = Number(readParam(search, NATIVE_PROTOCOL_PARAM));
226
+ if (!isBridgeId(attemptId) || !isBridgeId(nonce)) return null;
227
+ if (protocol !== NATIVE_PROTOCOL_VERSION) return null;
228
+ return { attemptId, nonce, protocol };
229
+ }
230
+
231
+ // ../embed-protocol/src/runtime-generation.ts
232
+ function isGenerationId(value) {
233
+ return typeof value === "string" && /^[A-Za-z0-9_-]{1,128}$/.test(value);
234
+ }
235
+ function isGenerationTerminal(status) {
236
+ return ["succeeded", "failed", "unknown", "canceled", "expired"].includes(status);
237
+ }
238
+
239
+ export {
240
+ NATIVE_CHANNEL,
241
+ NATIVE_PROTOCOL_VERSION,
242
+ NATIVE_RECEIVER,
243
+ readBridgeNativeCommand,
244
+ encodeBridgeMessage,
245
+ hasNativeMarker,
246
+ readNativeEntry,
247
+ isGenerationId,
248
+ isGenerationTerminal
249
+ };
@@ -0,0 +1,44 @@
1
+ import { RuntimeWorkflowInput, RuntimeGenerationView } from '@genex/embed-protocol';
2
+
3
+ /** Server-only benchmarks spend the authenticated creator's own coin wallet. */
4
+
5
+ interface DevelopmentGenerationConfig {
6
+ apiUrl: string;
7
+ /** Full creator bearer credential, kept only in your server or local script. */
8
+ creatorToken: string;
9
+ projectId: string;
10
+ }
11
+ interface DevelopmentGenerationOptions extends DevelopmentGenerationConfig {
12
+ /** Explicit maximum reservation in your own coins. Actual usage is charged. */
13
+ maxCoins: number;
14
+ request: {
15
+ modelId: string;
16
+ prompt: string;
17
+ outputFormat: 'text' | 'json';
18
+ schema?: Record<string, unknown>;
19
+ idempotencyKey?: string;
20
+ };
21
+ /** Waiting time only; timeout returns the last server view without canceling. */
22
+ timeoutMs?: number;
23
+ }
24
+ interface DevelopmentWorkflowOptions extends DevelopmentGenerationConfig {
25
+ workflowId: string;
26
+ maxCoins: number;
27
+ request: {
28
+ offeringId: string;
29
+ input: RuntimeWorkflowInput;
30
+ idempotencyKey?: string;
31
+ };
32
+ }
33
+ /** Create a generic benchmark and wait for execution and its actual-usage receipt. */
34
+ declare function developmentGenerate(options: DevelopmentGenerationOptions): Promise<RuntimeGenerationView>;
35
+ /** Returns the accepted workflow so its trusted executor can enqueue before waiting. */
36
+ declare function developmentRequestWorkflow(options: DevelopmentWorkflowOptions): Promise<RuntimeGenerationView>;
37
+ /** Recover a benchmark with the same creator and project; no play token is used. */
38
+ declare function getDevelopmentGeneration(config: DevelopmentGenerationConfig, generationId: string): Promise<RuntimeGenerationView>;
39
+ /** Acknowledges cancellation; the returned receipt determines the charge or remaining hold. */
40
+ declare function cancelDevelopmentGeneration(config: DevelopmentGenerationConfig, generationId: string): Promise<RuntimeGenerationView>;
41
+ /** Wait for execution and final billing; timeout preserves the latest pending receipt. */
42
+ declare function waitForDevelopmentGeneration(config: DevelopmentGenerationConfig, generationId: string, timeoutMs?: number): Promise<RuntimeGenerationView>;
43
+
44
+ export { type DevelopmentGenerationConfig, type DevelopmentGenerationOptions, type DevelopmentWorkflowOptions, cancelDevelopmentGeneration, developmentGenerate, developmentRequestWorkflow, getDevelopmentGeneration, waitForDevelopmentGeneration };
@@ -0,0 +1,99 @@
1
+ import {
2
+ isGenerationId,
3
+ isGenerationTerminal
4
+ } from "./chunk-Q476GJHI.js";
5
+
6
+ // src/development.ts
7
+ function assertIdentifier(value) {
8
+ if (!/^[A-Za-z0-9_.:-]{1,120}$/.test(value) || value === "." || value === "..") throw new Error("invalid_development_identifier");
9
+ }
10
+ function baseUrl(config) {
11
+ if (typeof window !== "undefined") throw new Error("development_server_only");
12
+ assertIdentifier(config.projectId);
13
+ if (!config.creatorToken || /\s/.test(config.creatorToken)) throw new Error("creator_token_required");
14
+ const url = new URL(config.apiUrl);
15
+ if (url.username || url.password || url.search || url.hash || url.pathname !== "/" || url.protocol !== "https:" && !(url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))) {
16
+ throw new Error("invalid_api_url");
17
+ }
18
+ return url.origin + "/api/runtime/development/projects/" + encodeURIComponent(config.projectId);
19
+ }
20
+ function validateMaximum(maxCoins) {
21
+ if (!Number.isSafeInteger(maxCoins) || maxCoins <= 0 || maxCoins > 1e6) throw new Error("invalid_max_coins");
22
+ }
23
+ async function request(config, path, body) {
24
+ const response = await fetch(baseUrl(config) + path, {
25
+ method: body === void 0 ? "GET" : "POST",
26
+ credentials: "omit",
27
+ cache: "no-store",
28
+ redirect: "error",
29
+ headers: { Authorization: "Bearer " + config.creatorToken, ...body === void 0 ? {} : { "Content-Type": "application/json" } },
30
+ ...body === void 0 ? {} : { body: JSON.stringify(body) }
31
+ });
32
+ const result = await response.json().catch(() => ({}));
33
+ if (!response.ok) throw new Error(typeof result.error === "string" ? result.error : "development_generation_unavailable");
34
+ const view = result;
35
+ if (!isGenerationId(view.id) || view.projectId !== config.projectId || view.development !== true || view.quote?.billingPolicy !== "consumed-v1" || view.funding !== "coins") throw new Error("invalid_development_response");
36
+ return view;
37
+ }
38
+ async function developmentGenerate(options) {
39
+ validateMaximum(options.maxCoins);
40
+ if (options.timeoutMs !== void 0 && (!Number.isFinite(options.timeoutMs) || options.timeoutMs < 0)) throw new Error("invalid_timeout");
41
+ const input = options.request;
42
+ const view = await request(options, "/generations", { maxCoins: options.maxCoins, request: {
43
+ modelId: input.modelId,
44
+ prompt: input.prompt,
45
+ outputFormat: input.outputFormat,
46
+ ...input.schema === void 0 ? {} : { schema: input.schema },
47
+ idempotencyKey: input.idempotencyKey ?? crypto.randomUUID()
48
+ } });
49
+ return wait(options, view, options.timeoutMs ?? 6e5);
50
+ }
51
+ async function developmentRequestWorkflow(options) {
52
+ validateMaximum(options.maxCoins);
53
+ assertIdentifier(options.workflowId);
54
+ assertIdentifier(options.request.offeringId);
55
+ const view = await request(options, "/workflows/" + encodeURIComponent(options.workflowId) + "/requests", {
56
+ maxCoins: options.maxCoins,
57
+ request: {
58
+ offeringId: options.request.offeringId,
59
+ input: options.request.input,
60
+ idempotencyKey: options.request.idempotencyKey ?? crypto.randomUUID()
61
+ }
62
+ });
63
+ if (view.kind !== "workflow" || view.workflow?.id !== options.workflowId || view.workflow.offeringId !== options.request.offeringId) {
64
+ throw new Error("invalid_development_response");
65
+ }
66
+ return view;
67
+ }
68
+ async function getDevelopmentGeneration(config, generationId) {
69
+ if (!isGenerationId(generationId)) throw new Error("invalid_generation_id");
70
+ const view = await request(config, "/generations/" + encodeURIComponent(generationId));
71
+ if (view.id !== generationId) throw new Error("invalid_development_response");
72
+ return view;
73
+ }
74
+ async function cancelDevelopmentGeneration(config, generationId) {
75
+ if (!isGenerationId(generationId)) throw new Error("invalid_generation_id");
76
+ const view = await request(config, "/generations/" + encodeURIComponent(generationId) + "/cancel", {});
77
+ if (view.id !== generationId) throw new Error("invalid_development_response");
78
+ return view;
79
+ }
80
+ async function wait(config, initial, timeoutMs) {
81
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0) throw new Error("invalid_timeout");
82
+ const deadline = Date.now() + timeoutMs;
83
+ let view = initial;
84
+ while (!(isGenerationTerminal(view.status) && view.billingStatus === "final") && Date.now() < deadline) {
85
+ await new Promise((resolve) => setTimeout(resolve, Math.min(750, deadline - Date.now())));
86
+ view = await getDevelopmentGeneration(config, view.id);
87
+ }
88
+ return view;
89
+ }
90
+ async function waitForDevelopmentGeneration(config, generationId, timeoutMs = 6e5) {
91
+ return wait(config, await getDevelopmentGeneration(config, generationId), timeoutMs);
92
+ }
93
+ export {
94
+ cancelDevelopmentGeneration,
95
+ developmentGenerate,
96
+ developmentRequestWorkflow,
97
+ getDevelopmentGeneration,
98
+ waitForDevelopmentGeneration
99
+ };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { RuntimeWorkflowInput, RuntimeGenerationBilling, RuntimeGenerationFunding, RuntimeGenerationView, RuntimeGenerationModels, RuntimeWorkflowOfferings } from '@genex/embed-protocol';
2
+ export { RuntimeBillingPolicy, RuntimeExternalProvider, RuntimeGenerationBilling, RuntimeGenerationFunding, RuntimeGenerationModels, RuntimeGenerationStatus, RuntimeGenerationView, RuntimeWorkflowInput, RuntimeWorkflowOfferings } from '@genex/embed-protocol';
3
+
1
4
  /** A thing the game sells. Resolved server-side; the game never sets a price. */
2
5
  interface ShopItem {
3
6
  id: string;
@@ -118,6 +121,75 @@ declare function buy(opts: {
118
121
  timeoutMs?: number;
119
122
  }): Promise<PurchaseResult>;
120
123
 
124
+ interface GenerateOptions {
125
+ /** Fixed coin price of a started attempt. Zero is accepted only for server-authorized free options. */
126
+ estimateCoins: number;
127
+ modelId: string;
128
+ prompt: string;
129
+ outputFormat: 'text' | 'json';
130
+ schema?: Record<string, unknown>;
131
+ /** Allow player-supplied results through their own configured Claude or ChatGPT account. Defaults off. */
132
+ allowExternal?: boolean;
133
+ /** Reuse for retries of the same operation, including after a game reload. */
134
+ idempotencyKey?: string;
135
+ /** Waiting time only. Reaching it does not cancel an accepted generation. */
136
+ timeoutMs?: number;
137
+ }
138
+ interface RuntimeGenerationResult extends RuntimeGenerationBilling {
139
+ status: 'succeeded' | 'failed' | 'unknown' | 'canceled' | 'expired' | 'pending';
140
+ generationId?: string;
141
+ output?: unknown;
142
+ /** External output is user-supplied; never use it as authority for rewards or money. */
143
+ source?: 'openrouter' | 'external';
144
+ modelProvenance?: 'unverified';
145
+ error?: string;
146
+ }
147
+ interface RequestWorkflowOptions {
148
+ /** Fixed coin price of a started attempt, including failed or canceled work. */
149
+ estimateCoins: number;
150
+ /** Offer configured personal Claude/ChatGPT funding on the same quote. Defaults off. */
151
+ allowExternal?: boolean;
152
+ workflowId: string;
153
+ offeringId: string;
154
+ input: RuntimeWorkflowInput;
155
+ /** Reuse for the exact same operation after sign-in, cancellation or reload. */
156
+ idempotencyKey?: string;
157
+ /** Approval waiting time only. A timeout does not cancel an accepted request. */
158
+ timeoutMs?: number;
159
+ }
160
+ interface RuntimeWorkflowAuthorization extends RuntimeGenerationBilling {
161
+ status: 'authorized' | 'canceled' | 'expired' | 'failed' | 'pending';
162
+ generationId?: string;
163
+ funding?: RuntimeGenerationFunding;
164
+ error?: string;
165
+ }
166
+ /** Available models and pricing; the confirmation always uses a fresh server quote. */
167
+ declare function getGenerationModels(): Promise<RuntimeGenerationModels>;
168
+ /** Server-owned estimates, reservation maxima and availability. Confirmation seals the quote. */
169
+ declare function getWorkflowOfferings(workflowId: string): Promise<RuntimeWorkflowOfferings>;
170
+ /** Recover an operation by ID after a reload. Scoped to this player AND this game. */
171
+ declare function getGeneration(generationId: string): Promise<RuntimeGenerationView>;
172
+ /** Resume waiting for execution. A terminal result can still carry pending billing; read getGeneration() for settlement. */
173
+ declare function waitForGeneration(generationId: string, timeoutMs?: number): Promise<RuntimeGenerationResult>;
174
+ /**
175
+ * Call directly from a click handler. The trusted popup is reserved BEFORE any
176
+ * asynchronous work, so standalone games retain the browser's user gesture.
177
+ * The player approves on Genex. Cancellation resolves normally; only API state
178
+ * can return an output. Store generationId to recover a pending result on boot.
179
+ */
180
+ declare function generate(options: GenerateOptions): Promise<RuntimeGenerationResult>;
181
+ /**
182
+ * Call directly from the player's click, before awaiting anything. Returns when
183
+ * Genex authorizes the entire workflow, so the game can enqueue its executor.
184
+ * Personal-provider instructions stay open after authorization. Store the ID;
185
+ * getGeneration()/waitForGeneration() recover the eventual result without a new charge.
186
+ */
187
+ declare function requestWorkflow(options: RequestWorkflowOptions): Promise<RuntimeWorkflowAuthorization>;
188
+ /** Reopen a saved approval without repricing or submitting a new request. Call directly from a click. */
189
+ declare function resumeWorkflow(generationId: string, options?: {
190
+ timeoutMs?: number;
191
+ }): Promise<RuntimeWorkflowAuthorization>;
192
+
121
193
  interface EmbedConfig {
122
194
  /** This game's own slug (GENEX.slug) — identifies the project to /play/authorize. */
123
195
  slug: string;
@@ -357,4 +429,4 @@ declare function __resetForTests(overrides?: {
357
429
  heartbeatIntervalMs?: number;
358
430
  }): void;
359
431
 
360
- export { type AuthState, type EmbedConfig, type EmbedEvent, type EmbedUser, type Entitlement, type Leaderboard, type LeaderboardEntry, type PlayerStateResult, type PurchaseResult, type PurchaseStatus, type SaveStateResult, type ShopItem, type SubmitScoreResult, type WorldStateResult, __resetForTests, _stashTicketFromUrl, buy, consumeEntitlement, getAuthState, getColyseusAuth, getColyseusUrls, getEmbedToken, getEntitlements, getLeaderboard, getShop, getUser, initEmbed, isEmbedded, loadPlayerState, loadWorldState, on, savePlayerState, saveWorldState, submitScore, waitForAuth, waitForPlayer };
432
+ export { type AuthState, type EmbedConfig, type EmbedEvent, type EmbedUser, type Entitlement, type GenerateOptions, type Leaderboard, type LeaderboardEntry, type PlayerStateResult, type PurchaseResult, type PurchaseStatus, type RequestWorkflowOptions, type RuntimeGenerationResult, type RuntimeWorkflowAuthorization, type SaveStateResult, type ShopItem, type SubmitScoreResult, type WorldStateResult, __resetForTests, _stashTicketFromUrl, buy, consumeEntitlement, generate, getAuthState, getColyseusAuth, getColyseusUrls, getEmbedToken, getEntitlements, getGeneration, getGenerationModels, getLeaderboard, getShop, getUser, getWorkflowOfferings, initEmbed, isEmbedded, loadPlayerState, loadWorldState, on, requestWorkflow, resumeWorkflow, savePlayerState, saveWorldState, submitScore, waitForAuth, waitForGeneration, waitForPlayer };
package/dist/index.js CHANGED
@@ -3,46 +3,61 @@ import {
3
3
  _stashTicketFromUrl,
4
4
  buy,
5
5
  consumeEntitlement,
6
+ generate,
6
7
  getAuthState,
7
8
  getColyseusAuth,
8
9
  getColyseusUrls,
9
10
  getEmbedToken,
10
11
  getEntitlements,
12
+ getGeneration,
13
+ getGenerationModels,
11
14
  getLeaderboard,
12
15
  getShop,
13
16
  getUser,
17
+ getWorkflowOfferings,
14
18
  initEmbed,
15
19
  isEmbedded,
16
20
  loadPlayerState,
17
21
  loadWorldState,
18
22
  on,
23
+ requestWorkflow,
24
+ resumeWorkflow,
19
25
  savePlayerState,
20
26
  saveWorldState,
21
27
  submitScore,
22
28
  waitForAuth,
29
+ waitForGeneration,
23
30
  waitForPlayer
24
- } from "./chunk-DNLXNEPL.js";
31
+ } from "./chunk-CKFZQ7AP.js";
32
+ import "./chunk-Q476GJHI.js";
25
33
  export {
26
34
  __resetForTests,
27
35
  _stashTicketFromUrl,
28
36
  buy,
29
37
  consumeEntitlement,
38
+ generate,
30
39
  getAuthState,
31
40
  getColyseusAuth,
32
41
  getColyseusUrls,
33
42
  getEmbedToken,
34
43
  getEntitlements,
44
+ getGeneration,
45
+ getGenerationModels,
35
46
  getLeaderboard,
36
47
  getShop,
37
48
  getUser,
49
+ getWorkflowOfferings,
38
50
  initEmbed,
39
51
  isEmbedded,
40
52
  loadPlayerState,
41
53
  loadWorldState,
42
54
  on,
55
+ requestWorkflow,
56
+ resumeWorkflow,
43
57
  savePlayerState,
44
58
  saveWorldState,
45
59
  submitScore,
46
60
  waitForAuth,
61
+ waitForGeneration,
47
62
  waitForPlayer
48
63
  };
package/dist/sentry.js CHANGED
@@ -2,7 +2,8 @@ import {
2
2
  _stashTicketFromUrl,
3
3
  getUser,
4
4
  on
5
- } from "./chunk-DNLXNEPL.js";
5
+ } from "./chunk-CKFZQ7AP.js";
6
+ import "./chunk-Q476GJHI.js";
6
7
 
7
8
  // src/sentry.ts
8
9
  import * as Sentry from "@sentry/browser";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genex-ai/embed-sdk",
3
- "version": "0.17.0",
4
- "description": "Player identity + durable game state for genex games \u2014 signed-in or guest play, per-player save slots, shared world state, and soft-trust leaderboards.",
3
+ "version": "0.21.1",
4
+ "description": "Player identity + durable game state for genex games signed-in or guest play, per-player save slots, shared world state, and soft-trust leaderboards.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -15,6 +15,12 @@
15
15
  "@genex-ai/source": "./src/sentry.ts",
16
16
  "types": "./dist/sentry.d.ts",
17
17
  "import": "./dist/sentry.js"
18
+ },
19
+ "./development": {
20
+ "types": "./dist/development.d.ts",
21
+ "browser": null,
22
+ "@genex-ai/source": "./src/development.ts",
23
+ "import": "./dist/development.js"
18
24
  }
19
25
  },
20
26
  "files": [