@xeonr/renderer-sdk 1.5.2 → 1.6.0
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/dist/react/useRendererClient.d.ts.map +1 -1
- package/dist/react/useRendererClient.js +14 -0
- package/dist/react/useRendererClient.js.map +1 -1
- package/dist/react/worker.d.ts +34 -0
- package/dist/react/worker.d.ts.map +1 -0
- package/dist/react/worker.js +224 -0
- package/dist/react/worker.js.map +1 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/worker-renderer.d.ts +24 -0
- package/dist/worker-renderer.d.ts.map +1 -0
- package/dist/worker-renderer.js +127 -0
- package/dist/worker-renderer.js.map +1 -0
- package/dist/worker.d.ts +110 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +171 -0
- package/dist/worker.js.map +1 -0
- package/package.json +19 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRendererClient.d.ts","sourceRoot":"","sources":["../../src/react/useRendererClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAe,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"useRendererClient.d.ts","sourceRoot":"","sources":["../../src/react/useRendererClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAe,MAAM,aAAa,CAAC;AAGjH,MAAM,WAAW,wBAAyB,SAAQ,qBAAqB;CAAG;AA+E1E,MAAM,WAAW,uBAAuB;IACvC,kDAAkD;IAClD,SAAS,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,2CAA2C;IAC3C,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,4CAA4C;IAC5C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kDAAkD;IAClD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,8BAA8B;IAC9B,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,wDAAwD;IACxD,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,yDAAyD;IACzD,UAAU,EAAE,WAAW,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC1C,qCAAqC;IACrC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0EAA0E;IAC1E,UAAU,EAAE,kBAAkB,CAAC;IAC/B;;;;;;;OAOG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,oGAAoG;IACpG,IAAI,EAAE,MAAM,CAAC;IAEb,kDAAkD;IAClD,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,gDAAgD;IAChD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;IAEtB,+DAA+D;IAC/D,MAAM,EAAE,cAAc,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,uBAAuB,CAqG7F"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState, useEffect, useMemo } from 'react';
|
|
2
2
|
import { RendererClient } from '../client.js';
|
|
3
|
+
import { useWorkerRendererResult } from './worker.js';
|
|
3
4
|
// One RendererClient per page. Multiple `useRendererClient()` calls
|
|
4
5
|
// (different components subscribing to the same state) all share the
|
|
5
6
|
// singleton — previously each call spawned its own client, which
|
|
@@ -95,6 +96,19 @@ function applyThemeToDocument(theme) {
|
|
|
95
96
|
* ```
|
|
96
97
|
*/
|
|
97
98
|
export function useRendererClient(options) {
|
|
99
|
+
// Worker-mode shortcut: when a WorkerRendererProvider is in scope
|
|
100
|
+
// (puppeteer-driven worker.html entry), it publishes a pre-built
|
|
101
|
+
// result via React context. Returning early here lets the same
|
|
102
|
+
// <Renderer /> component code work in both transports.
|
|
103
|
+
//
|
|
104
|
+
// Hooks rule note: useContext is a hook, and we early-return BEFORE
|
|
105
|
+
// any state/effect hooks fire. A given component instance is either
|
|
106
|
+
// always inside the provider (worker entry) or always outside
|
|
107
|
+
// (portal/dashboard) — never both — so the hook set is stable for
|
|
108
|
+
// that instance's lifetime.
|
|
109
|
+
const workerResult = useWorkerRendererResult();
|
|
110
|
+
if (workerResult !== null)
|
|
111
|
+
return workerResult;
|
|
98
112
|
const client = getSharedClient(options);
|
|
99
113
|
// Initial state read directly from the client — handles late
|
|
100
114
|
// subscribers (a second `useRendererClient` mount that happens
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRendererClient.js","sourceRoot":"","sources":["../../src/react/useRendererClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"useRendererClient.js","sourceRoot":"","sources":["../../src/react/useRendererClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { WorkerContext } from '../worker.js';
|
|
3
|
+
import type { UseRendererClientResult } from './useRendererClient.js';
|
|
4
|
+
/** Read the worker-mode result if a WorkerRendererProvider is in scope.
|
|
5
|
+
* `useRendererClient` calls this internally to decide which transport
|
|
6
|
+
* to use. Renderer authors don't call this directly. */
|
|
7
|
+
export declare function useWorkerRendererResult(): UseRendererClientResult | null;
|
|
8
|
+
export interface WorkerRendererProviderProps {
|
|
9
|
+
/** WorkerContext from defineWorker / defineRendererWorker — the
|
|
10
|
+
* source of truth for upload + config + auth in worker mode. */
|
|
11
|
+
ctx: WorkerContext;
|
|
12
|
+
/** Theme for THIS render pass. defineRendererWorker mounts twice
|
|
13
|
+
* (once per theme); each mount passes the relevant value here so
|
|
14
|
+
* useRendererClient's `theme` reflects the active capture pass. */
|
|
15
|
+
theme: 'light' | 'dark';
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Bridges the worker context onto the React tree so the same
|
|
20
|
+
* useRendererClient calls work both inside iframe (portal/dashboard)
|
|
21
|
+
* and inside the worker.html headless mount.
|
|
22
|
+
*
|
|
23
|
+
* Data sources (puppeteer controller is responsible for feeding these
|
|
24
|
+
* via the bridge's exposed `getInput` function):
|
|
25
|
+
* - `upload` → resource (Upload proto JSON)
|
|
26
|
+
* - `config` → RendererConfig (the renderer's config.json)
|
|
27
|
+
* - `__auth_token` → token (step-scoped JWT — Drill-in 3, "Auth
|
|
28
|
+
* tokens for the headless renderer")
|
|
29
|
+
* - `__api_base_url` → apiBaseUrl
|
|
30
|
+
* - `__scope` → RendererScope (precomputed by controller from
|
|
31
|
+
* the upload's bucket + content type)
|
|
32
|
+
*/
|
|
33
|
+
export declare function WorkerRendererProvider({ ctx, theme, children }: WorkerRendererProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/react/worker.tsx"],"names":[],"mappings":"AA0BA,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAQlD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAStE;;wDAEwD;AACxD,wBAAgB,uBAAuB,IAAI,uBAAuB,GAAG,IAAI,CAExE;AAED,MAAM,WAAW,2BAA2B;IAC3C;oEACgE;IAChE,GAAG,EAAE,aAAa,CAAC;IACnB;;uEAEmE;IACnE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,2BAA2B,2CA4C3F"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @xeonr/renderer-sdk/react/worker
|
|
3
|
+
//
|
|
4
|
+
// Worker-mode adapter for `useRendererClient`. Lets renderer authors
|
|
5
|
+
// reuse the SAME <Renderer /> component (which calls useRendererClient
|
|
6
|
+
// internally) in both interactive entries (portal.html / dashboard.html)
|
|
7
|
+
// AND the puppeteer-driven worker entry (worker.html).
|
|
8
|
+
//
|
|
9
|
+
// Mechanism: <WorkerRendererProvider> publishes a synthetic
|
|
10
|
+
// UseRendererClientResult via React context, populated from the
|
|
11
|
+
// worker bridge's getInput() calls. useRendererClient checks the
|
|
12
|
+
// context first; when set, it returns the worker-mode result;
|
|
13
|
+
// otherwise it falls back to the existing iframe-postMessage singleton.
|
|
14
|
+
//
|
|
15
|
+
// Plan reference (Drill-in 3, "SDK-only public API"): the worker entry
|
|
16
|
+
// must not require renderer authors to touch window.* or refactor their
|
|
17
|
+
// Renderer components — the transport is hidden behind the same
|
|
18
|
+
// useRendererClient surface. This provider is the bridge.
|
|
19
|
+
//
|
|
20
|
+
// Authoring shape — typically used through defineRendererWorker which
|
|
21
|
+
// auto-wraps the user's render fn:
|
|
22
|
+
//
|
|
23
|
+
// // src/worker.tsx
|
|
24
|
+
// import { defineRendererWorker } from '@xeonr/renderer-sdk/worker-renderer';
|
|
25
|
+
// import { Renderer } from './Renderer';
|
|
26
|
+
// defineRendererWorker(() => <Renderer />);
|
|
27
|
+
import { createContext, useContext, useEffect, useState } from 'react';
|
|
28
|
+
// Context value: null until the provider has resolved the initial data
|
|
29
|
+
// from the worker bridge. useRendererClient sees null and falls through
|
|
30
|
+
// to its existing singleton path; once non-null, components subscribed
|
|
31
|
+
// to useRendererClient re-render with the worker-backed result.
|
|
32
|
+
const WorkerRendererContext = createContext(null);
|
|
33
|
+
/** Read the worker-mode result if a WorkerRendererProvider is in scope.
|
|
34
|
+
* `useRendererClient` calls this internally to decide which transport
|
|
35
|
+
* to use. Renderer authors don't call this directly. */
|
|
36
|
+
export function useWorkerRendererResult() {
|
|
37
|
+
return useContext(WorkerRendererContext);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Bridges the worker context onto the React tree so the same
|
|
41
|
+
* useRendererClient calls work both inside iframe (portal/dashboard)
|
|
42
|
+
* and inside the worker.html headless mount.
|
|
43
|
+
*
|
|
44
|
+
* Data sources (puppeteer controller is responsible for feeding these
|
|
45
|
+
* via the bridge's exposed `getInput` function):
|
|
46
|
+
* - `upload` → resource (Upload proto JSON)
|
|
47
|
+
* - `config` → RendererConfig (the renderer's config.json)
|
|
48
|
+
* - `__auth_token` → token (step-scoped JWT — Drill-in 3, "Auth
|
|
49
|
+
* tokens for the headless renderer")
|
|
50
|
+
* - `__api_base_url` → apiBaseUrl
|
|
51
|
+
* - `__scope` → RendererScope (precomputed by controller from
|
|
52
|
+
* the upload's bucket + content type)
|
|
53
|
+
*/
|
|
54
|
+
export function WorkerRendererProvider({ ctx, theme, children }) {
|
|
55
|
+
const [result, setResult] = useState(null);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
let cancelled = false;
|
|
58
|
+
(async () => {
|
|
59
|
+
try {
|
|
60
|
+
const [upload, config, token, apiBaseUrl, scope] = await Promise.all([
|
|
61
|
+
ctx.input('upload').catch(() => null),
|
|
62
|
+
ctx.input('config').catch(() => null),
|
|
63
|
+
ctx.input('__auth_token').catch(() => ''),
|
|
64
|
+
ctx.input('__api_base_url').catch(() => ''),
|
|
65
|
+
ctx.input('__scope').catch(() => null),
|
|
66
|
+
]);
|
|
67
|
+
if (cancelled)
|
|
68
|
+
return;
|
|
69
|
+
const built = buildWorkerResult({
|
|
70
|
+
ctx, theme,
|
|
71
|
+
upload,
|
|
72
|
+
config: config ?? defaultConfig(),
|
|
73
|
+
token: token ?? '',
|
|
74
|
+
apiBaseUrl: apiBaseUrl ?? '',
|
|
75
|
+
scope: scope ?? defaultScopeFromUpload(upload),
|
|
76
|
+
});
|
|
77
|
+
setResult(built);
|
|
78
|
+
applyThemeAttribute(theme);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
ctx.log.error('worker-react: provider init failed', { err: String(err) });
|
|
82
|
+
await ctx.fail(`WorkerRendererProvider init: ${String(err)}`);
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
return () => { cancelled = true; };
|
|
86
|
+
}, [ctx, theme]);
|
|
87
|
+
// Re-apply theme attribute when defineRendererWorker swaps theme
|
|
88
|
+
// between capture passes. useEffect above also does it on first
|
|
89
|
+
// resolution; this one handles subsequent passes (provider remounts
|
|
90
|
+
// per theme, so this fires every time).
|
|
91
|
+
useEffect(() => { applyThemeAttribute(theme); }, [theme]);
|
|
92
|
+
return (_jsx(WorkerRendererContext.Provider, { value: result, children: children }));
|
|
93
|
+
}
|
|
94
|
+
function buildWorkerResult(args) {
|
|
95
|
+
const apiAdapter = {
|
|
96
|
+
hostname: args.apiBaseUrl || undefined,
|
|
97
|
+
tokenHelper: async () => args.token || null,
|
|
98
|
+
// Step-scoped JWTs don't refresh — the puppeteer controller
|
|
99
|
+
// mints a single token for the run's duration. If it expires
|
|
100
|
+
// mid-capture the request fails and the step retries on the
|
|
101
|
+
// pipeline coordinator side.
|
|
102
|
+
onAuthenticationExpired: async () => false,
|
|
103
|
+
onAuthenticationFailed: async () => null,
|
|
104
|
+
};
|
|
105
|
+
const stubClient = makeStubClient(args);
|
|
106
|
+
return {
|
|
107
|
+
connected: true,
|
|
108
|
+
scope: args.scope,
|
|
109
|
+
// Worker captures always render as the "preview" variant — same
|
|
110
|
+
// rendering type the dashboard's modal preview uses, which is
|
|
111
|
+
// the closest semantic match for a thumbnail snapshot.
|
|
112
|
+
renderingType: 'preview-modal',
|
|
113
|
+
token: args.token || null,
|
|
114
|
+
// Stub: tokens don't have a known expiry in worker mode (the
|
|
115
|
+
// puppeteer controller mints + holds them). Set to null so
|
|
116
|
+
// renderer code that gates on `tokenExpiresAt` doesn't think
|
|
117
|
+
// the token's about to die.
|
|
118
|
+
tokenExpiresAt: null,
|
|
119
|
+
theme: args.theme,
|
|
120
|
+
config: args.config,
|
|
121
|
+
// Worker has its own entrypoint identity; old enum doesn't
|
|
122
|
+
// include 'worker' so we report null (renderer code that
|
|
123
|
+
// switches on this should treat null + 'worker' equivalently).
|
|
124
|
+
entrypoint: null,
|
|
125
|
+
apiBaseUrl: args.apiBaseUrl || null,
|
|
126
|
+
resource: args.upload,
|
|
127
|
+
path: '/',
|
|
128
|
+
// Methods are mostly no-ops in worker mode (no host frame to
|
|
129
|
+
// receive postMessages). markReady wires to ctx.ready() so the
|
|
130
|
+
// renderer can short-circuit if it knows it's done before
|
|
131
|
+
// defineRendererWorker's settle window expires.
|
|
132
|
+
openUpload: (uploadId) => warnNoOp('openUpload', uploadId),
|
|
133
|
+
requestToken: () => warnNoOp('requestToken'),
|
|
134
|
+
close: () => warnNoOp('close'),
|
|
135
|
+
markReady: () => { void args.ctx.ready(); },
|
|
136
|
+
apiAdapter,
|
|
137
|
+
client: stubClient,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function applyThemeAttribute(theme) {
|
|
141
|
+
if (typeof document === 'undefined')
|
|
142
|
+
return;
|
|
143
|
+
document.documentElement.dataset.theme = theme;
|
|
144
|
+
document.documentElement.style.colorScheme = theme;
|
|
145
|
+
}
|
|
146
|
+
function defaultConfig() {
|
|
147
|
+
// Minimal valid config so renderers that read config.* without
|
|
148
|
+
// optional-chaining don't NPE in worker mode. Matches the
|
|
149
|
+
// most-permissive interactive config (no special perms or sandbox
|
|
150
|
+
// flags — worker mode doesn't care about iframe sandboxing).
|
|
151
|
+
return { version: 1 };
|
|
152
|
+
}
|
|
153
|
+
function defaultScopeFromUpload(upload) {
|
|
154
|
+
if (!upload || typeof upload !== 'object')
|
|
155
|
+
return null;
|
|
156
|
+
const u = upload;
|
|
157
|
+
// Upload proto JSON uses camelCase: uploadId + bucketId
|
|
158
|
+
const uploadId = typeof u.uploadId === 'string' ? u.uploadId : undefined;
|
|
159
|
+
const bucketId = typeof u.bucketId === 'string' ? u.bucketId : undefined;
|
|
160
|
+
if (!uploadId || !bucketId)
|
|
161
|
+
return null;
|
|
162
|
+
return { type: 'upload', uploadId, bucketId };
|
|
163
|
+
}
|
|
164
|
+
function warnNoOp(method, ...extras) {
|
|
165
|
+
// eslint-disable-next-line no-console
|
|
166
|
+
console.warn(`[uplim:worker] ${method}(${extras.map((e) => JSON.stringify(e)).join(', ')}) is a no-op in worker mode (no host frame to receive postMessages)`);
|
|
167
|
+
}
|
|
168
|
+
// Minimal RendererClient stand-in. Renderer code that grabs the raw
|
|
169
|
+
// `client` from useRendererClient and pokes its methods will see
|
|
170
|
+
// warnings + sane defaults rather than crashing.
|
|
171
|
+
function makeStubClient(args) {
|
|
172
|
+
const onInit = (cb) => {
|
|
173
|
+
// Best-effort: fire the init payload synchronously since we
|
|
174
|
+
// already have all the data. Renderer code that subscribes via
|
|
175
|
+
// onInit (rather than useRendererClient's initial state) still works.
|
|
176
|
+
cb({
|
|
177
|
+
version: 1,
|
|
178
|
+
scope: args.scope,
|
|
179
|
+
renderingType: 'preview-modal',
|
|
180
|
+
token: args.token,
|
|
181
|
+
tokenExpiresAt: 0,
|
|
182
|
+
theme: args.theme,
|
|
183
|
+
config: args.config,
|
|
184
|
+
entrypoint: 'portal',
|
|
185
|
+
apiBaseUrl: args.apiBaseUrl,
|
|
186
|
+
resource: args.upload,
|
|
187
|
+
});
|
|
188
|
+
return () => { };
|
|
189
|
+
};
|
|
190
|
+
const noopUnsub = () => () => { };
|
|
191
|
+
const stub = {
|
|
192
|
+
isConnected: () => true,
|
|
193
|
+
getScope: () => args.scope,
|
|
194
|
+
getRenderingType: () => 'preview-modal',
|
|
195
|
+
getToken: () => args.token || null,
|
|
196
|
+
getTokenExpiresAt: () => null,
|
|
197
|
+
getTheme: () => args.theme,
|
|
198
|
+
getConfig: () => args.config,
|
|
199
|
+
getEntrypoint: () => null,
|
|
200
|
+
getApiBaseUrl: () => args.apiBaseUrl || null,
|
|
201
|
+
getResource: () => args.upload,
|
|
202
|
+
getPath: () => '/',
|
|
203
|
+
getApiAdapter: () => ({
|
|
204
|
+
hostname: args.apiBaseUrl || undefined,
|
|
205
|
+
tokenHelper: async () => args.token || null,
|
|
206
|
+
onAuthenticationExpired: async () => false,
|
|
207
|
+
onAuthenticationFailed: async () => null,
|
|
208
|
+
}),
|
|
209
|
+
onInit,
|
|
210
|
+
onThemeChange: noopUnsub,
|
|
211
|
+
onTokenRefresh: noopUnsub,
|
|
212
|
+
onNavigate: noopUnsub,
|
|
213
|
+
openUpload: (uploadId) => warnNoOp('client.openUpload', uploadId),
|
|
214
|
+
requestToken: () => warnNoOp('client.requestToken'),
|
|
215
|
+
close: () => warnNoOp('client.close'),
|
|
216
|
+
signalReady: () => { void args.ctx.ready(); },
|
|
217
|
+
destroy: () => { },
|
|
218
|
+
};
|
|
219
|
+
// Cast through unknown — the stub doesn't extend the concrete class
|
|
220
|
+
// (it'd have to drag too many internals). Renderer code uses the
|
|
221
|
+
// public-facing surface above, which is fully covered.
|
|
222
|
+
return stub;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/react/worker.tsx"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -67,6 +67,24 @@ export interface RendererConfig {
|
|
|
67
67
|
* users behind the overlay.
|
|
68
68
|
*/
|
|
69
69
|
deferReady?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Worker-entry contract declaration. Only meaningful when the
|
|
72
|
+
* renderer ships a `worker.html` entry (the puppeteer-step driver
|
|
73
|
+
* runs it headlessly). Declaring schemas here is the single source
|
|
74
|
+
* of truth a puppeteer step in `upl-im-steps` can cross-check at
|
|
75
|
+
* publish: the step's manifest declares the same input/output names
|
|
76
|
+
* and the registry rejects publish if they don't line up with the
|
|
77
|
+
* renderer's `worker` declarations.
|
|
78
|
+
*
|
|
79
|
+
* Shape:
|
|
80
|
+
* workerInputSchema: Record<input-name, JSON Schema>
|
|
81
|
+
* workerOutputSchema: Record<output-name, JSON Schema>
|
|
82
|
+
*
|
|
83
|
+
* For typical renderers (interactive only, no worker.html), leave
|
|
84
|
+
* unset.
|
|
85
|
+
*/
|
|
86
|
+
workerInputSchema?: Record<string, unknown>;
|
|
87
|
+
workerOutputSchema?: Record<string, unknown>;
|
|
70
88
|
}
|
|
71
89
|
export type RendererPermission = 'createFolder' | 'openUpload';
|
|
72
90
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,CAAC,CAAC;IACX,uDAAuD;IACvD,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE;QACT,qBAAqB;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,oBAAoB;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,wBAAwB;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,2BAA2B;QAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,qBAAqB;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,+BAA+B;QAC/B,oBAAoB,CAAC,EAAE,OAAO,CAAC;QAC/B,2BAA2B;QAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;IACF;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import { type WorkerContext } from './worker.js';
|
|
3
|
+
export interface RendererWorkerOptions {
|
|
4
|
+
/** Rendered container size in CSS pixels. Defaults to 1024×768 —
|
|
5
|
+
* matches what the old default-workers renderer pool drew at and
|
|
6
|
+
* survives downscaling for both card + list-row thumbnails. */
|
|
7
|
+
width?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
/** Devicepixelratio override. 2 = retina-ish. Higher = sharper PNG
|
|
10
|
+
* at proportional cost. Default 2 keeps PNGs under ~1MB at 1024×768. */
|
|
11
|
+
pixelRatio?: number;
|
|
12
|
+
/** Per-theme idle wait (ms) after React commits. Bumps if the
|
|
13
|
+
* renderer kicks off async loads (fonts, wavesurfer decode, react-pdf
|
|
14
|
+
* worker). Default 500. */
|
|
15
|
+
settleMs?: number;
|
|
16
|
+
}
|
|
17
|
+
export type RendererWorkerRenderFn = (args: {
|
|
18
|
+
theme: 'light' | 'dark';
|
|
19
|
+
ctx: WorkerContext;
|
|
20
|
+
}) => ReactElement;
|
|
21
|
+
/** Register a renderer worker entry. Mounts the passed React element
|
|
22
|
+
* twice (light + dark) and ships each capture as a thumbnail. */
|
|
23
|
+
export declare function defineRendererWorker(render: RendererWorkerRenderFn, options?: RendererWorkerOptions): void;
|
|
24
|
+
//# sourceMappingURL=worker-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-renderer.d.ts","sourceRoot":"","sources":["../src/worker-renderer.tsx"],"names":[],"mappings":"AA0BA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG/D,MAAM,WAAW,qBAAqB;IACrC;;mEAE+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;4EACwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;+BAE2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,GAAG,EAAE,aAAa,CAAC;CACnB,KAAK,YAAY,CAAC;AAEnB;iEACiE;AACjE,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,GAAE,qBAA0B,GACjC,IAAI,CAsBN"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// defineRendererWorker — convenience over defineWorker for renderers
|
|
3
|
+
// that want to mount their normal React tree once per theme and ship
|
|
4
|
+
// the captured DOM as common:thumbnail_{light,dark}.
|
|
5
|
+
//
|
|
6
|
+
// Authoring shape (in a renderer's src/worker.tsx):
|
|
7
|
+
//
|
|
8
|
+
// import { defineRendererWorker } from '@xeonr/renderer-sdk/worker-renderer';
|
|
9
|
+
// import { Renderer } from './Renderer';
|
|
10
|
+
//
|
|
11
|
+
// defineRendererWorker(({ theme }) => <Renderer initialTheme={theme} />);
|
|
12
|
+
//
|
|
13
|
+
// Contract — assumed by the puppeteer-kind step manifests in
|
|
14
|
+
// upl-im-default-pipelines:
|
|
15
|
+
// inputs.source blob (the upload bytes; renderer fetches via
|
|
16
|
+
// ctx.inputBlob if it needs direct access)
|
|
17
|
+
// outputs.blobs:
|
|
18
|
+
// common:thumbnail_light image/png (rendered with theme=light)
|
|
19
|
+
// common:thumbnail_dark image/png (rendered with theme=dark)
|
|
20
|
+
//
|
|
21
|
+
// Capture strategy: mount the renderer twice (once per theme) in an
|
|
22
|
+
// offscreen 1024×768 container, wait for two animation frames after
|
|
23
|
+
// React commits + any in-flight images/fonts settle, then html-to-image
|
|
24
|
+
// the container into a PNG. Lazy-imports html-to-image so the SDK
|
|
25
|
+
// doesn't drag it in for non-worker (portal/dashboard) builds.
|
|
26
|
+
import { createRoot } from 'react-dom/client';
|
|
27
|
+
import { StrictMode } from 'react';
|
|
28
|
+
import { defineWorker } from './worker.js';
|
|
29
|
+
import { WorkerRendererProvider } from './react/worker.js';
|
|
30
|
+
/** Register a renderer worker entry. Mounts the passed React element
|
|
31
|
+
* twice (light + dark) and ships each capture as a thumbnail. */
|
|
32
|
+
export function defineRendererWorker(render, options = {}) {
|
|
33
|
+
defineWorker(async (ctx) => {
|
|
34
|
+
const width = options.width ?? 1024;
|
|
35
|
+
const height = options.height ?? 768;
|
|
36
|
+
const pixelRatio = options.pixelRatio ?? 2;
|
|
37
|
+
const settleMs = options.settleMs ?? 500;
|
|
38
|
+
// html-to-image is a 30KB+ dep — lazy-load so portal/dashboard
|
|
39
|
+
// bundles don't pull it.
|
|
40
|
+
const { toPng } = await import('html-to-image');
|
|
41
|
+
for (const theme of ['light', 'dark']) {
|
|
42
|
+
ctx.log.info('render.theme.start', { theme });
|
|
43
|
+
const png = await renderAndCapture({
|
|
44
|
+
render: () => render({ theme, ctx }),
|
|
45
|
+
ctx, theme, width, height, pixelRatio, settleMs, toPng,
|
|
46
|
+
});
|
|
47
|
+
const outputName = theme === 'light' ? 'common:thumbnail_light' : 'common:thumbnail_dark';
|
|
48
|
+
await ctx.outputBlob(outputName, png, 'image/png');
|
|
49
|
+
ctx.log.info('render.theme.done', { theme, bytes: png.byteLength });
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async function renderAndCapture(args) {
|
|
54
|
+
const container = document.createElement('div');
|
|
55
|
+
container.style.width = `${args.width}px`;
|
|
56
|
+
container.style.height = `${args.height}px`;
|
|
57
|
+
container.style.position = 'fixed';
|
|
58
|
+
container.style.top = '0';
|
|
59
|
+
container.style.left = '0';
|
|
60
|
+
container.style.overflow = 'hidden';
|
|
61
|
+
// Stay offscreen-ish so the host page background doesn't bleed.
|
|
62
|
+
container.style.zIndex = '-1';
|
|
63
|
+
// Renderer authors look at data-theme + colorScheme for theme hints.
|
|
64
|
+
container.dataset.theme = args.theme;
|
|
65
|
+
container.style.colorScheme = args.theme;
|
|
66
|
+
document.body.appendChild(container);
|
|
67
|
+
let root = null;
|
|
68
|
+
try {
|
|
69
|
+
root = createRoot(container);
|
|
70
|
+
// Wrap in WorkerRendererProvider so the renderer's useRendererClient
|
|
71
|
+
// calls resolve against the worker bridge (upload / config / token
|
|
72
|
+
// fetched via ctx.input) rather than the iframe postMessage path.
|
|
73
|
+
// This is the "extra export" called out in plan Drill-in 3 — lets
|
|
74
|
+
// the same <Renderer /> component work in portal/dashboard AND
|
|
75
|
+
// worker entries without per-renderer refactoring.
|
|
76
|
+
root.render(_jsx(StrictMode, { children: _jsx(WorkerRendererProvider, { ctx: args.ctx, theme: args.theme, children: args.render() }) }));
|
|
77
|
+
// Let React commit + browsers paint, then wait the renderer-specific
|
|
78
|
+
// settle window for fonts / async images / canvas-based renders.
|
|
79
|
+
await waitForRaf();
|
|
80
|
+
await waitForRaf();
|
|
81
|
+
await new Promise((r) => setTimeout(r, args.settleMs));
|
|
82
|
+
// Wait for any pending image decodes the renderer may have kicked
|
|
83
|
+
// off (font-faces, presigned-URL fetches that turned into <img>s).
|
|
84
|
+
await waitForImages(container);
|
|
85
|
+
const bgColor = args.theme === 'dark' ? '#111111' : '#ffffff';
|
|
86
|
+
const dataUrl = await args.toPng(container, {
|
|
87
|
+
width: args.width,
|
|
88
|
+
height: args.height,
|
|
89
|
+
pixelRatio: args.pixelRatio,
|
|
90
|
+
backgroundColor: bgColor,
|
|
91
|
+
});
|
|
92
|
+
return dataUrlToBytes(dataUrl);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
try {
|
|
96
|
+
root?.unmount();
|
|
97
|
+
}
|
|
98
|
+
catch { /* best-effort cleanup */ }
|
|
99
|
+
container.remove();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function waitForRaf() {
|
|
103
|
+
return new Promise((r) => requestAnimationFrame(() => r()));
|
|
104
|
+
}
|
|
105
|
+
async function waitForImages(root) {
|
|
106
|
+
const imgs = Array.from(root.querySelectorAll('img'));
|
|
107
|
+
await Promise.all(imgs.map((img) => {
|
|
108
|
+
if (img.complete)
|
|
109
|
+
return;
|
|
110
|
+
return new Promise((resolve) => {
|
|
111
|
+
img.addEventListener('load', () => resolve(), { once: true });
|
|
112
|
+
img.addEventListener('error', () => resolve(), { once: true });
|
|
113
|
+
});
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
function dataUrlToBytes(dataUrl) {
|
|
117
|
+
const comma = dataUrl.indexOf(',');
|
|
118
|
+
if (comma < 0)
|
|
119
|
+
throw new Error('defineRendererWorker: capture returned no base64 payload');
|
|
120
|
+
const base64 = dataUrl.slice(comma + 1);
|
|
121
|
+
const bin = atob(base64);
|
|
122
|
+
const out = new Uint8Array(bin.length);
|
|
123
|
+
for (let i = 0; i < bin.length; i++)
|
|
124
|
+
out[i] = bin.charCodeAt(i);
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=worker-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-renderer.js","sourceRoot":"","sources":["../src/worker-renderer.tsx"],"names":[],"mappings":"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"}
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker entry point for renderers used as pipeline steps.
|
|
3
|
+
*
|
|
4
|
+
* A renderer that ships a `worker.html` + `worker.tsx` can be referenced
|
|
5
|
+
* by a `puppeteer`-kind pipeline step. The puppeteer controller launches
|
|
6
|
+
* headless Chrome against the worker entry, exposes a JSON-only bridge
|
|
7
|
+
* via `page.exposeFunction` as `window.__uplWorkerBridge`, and the SDK
|
|
8
|
+
* wraps that bridge with a typed `ctx` so renderer code never touches
|
|
9
|
+
* `window.*` directly.
|
|
10
|
+
*
|
|
11
|
+
* Authoring shape:
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { defineWorker } from '@xeonr/renderer-sdk/worker';
|
|
14
|
+
*
|
|
15
|
+
* defineWorker(async (ctx) => {
|
|
16
|
+
* const upload = await ctx.input<Upload>('upload');
|
|
17
|
+
* const blob = await ctx.inputBlob('source');
|
|
18
|
+
* const png = await renderThumbnail(blob);
|
|
19
|
+
* await ctx.outputBlob('thumbnail', png, 'image/png');
|
|
20
|
+
* await ctx.output('width', upload.width);
|
|
21
|
+
* ctx.log.info('done', { ms: performance.now() });
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* Failure handling: the SDK auto-calls `ctx.fail(...)` on a thrown
|
|
26
|
+
* exception or unhandled rejection inside the handler and `ctx.ready()`
|
|
27
|
+
* on clean resolution. Renderers can call them explicitly to short-
|
|
28
|
+
* circuit (e.g. to fail early with a domain-specific error before any
|
|
29
|
+
* outputs are written).
|
|
30
|
+
*/
|
|
31
|
+
/** Bridge installed by the puppeteer controller via page.exposeFunction.
|
|
32
|
+
* JSON-only by design — blob transport is via presigned URLs. The SDK
|
|
33
|
+
* hides this layer behind ctx; renderers should never reference these
|
|
34
|
+
* names. The dev harness mounts a mock implementation with the same
|
|
35
|
+
* shape so `pnpm dev` runs end-to-end without a controller. */
|
|
36
|
+
interface WorkerBridge {
|
|
37
|
+
getInput(name: string): Promise<unknown>;
|
|
38
|
+
getInputUrl(name: string): Promise<string>;
|
|
39
|
+
getSecret(name: string): Promise<string>;
|
|
40
|
+
setOutput(name: string, value: unknown): Promise<void>;
|
|
41
|
+
/** Mint a presigned PUT URL for a blob output. Worker code then
|
|
42
|
+
* `fetch(url, { method: 'PUT', body })`s the bytes and calls
|
|
43
|
+
* `commitBlobOutput` to record the row. */
|
|
44
|
+
mintBlobOutputUrl(name: string, contentType: string): Promise<string>;
|
|
45
|
+
commitBlobOutput(name: string, contentType: string, sizeBytes: number): Promise<void>;
|
|
46
|
+
log(level: 'info' | 'warn' | 'error', msg: string, attrs?: Record<string, unknown>): Promise<void>;
|
|
47
|
+
ready(): Promise<void>;
|
|
48
|
+
fail(reason: string): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
declare global {
|
|
51
|
+
interface Window {
|
|
52
|
+
__uplWorkerBridge?: WorkerBridge;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export interface WorkerContext {
|
|
56
|
+
/** Read a declared input (JSON value — typed via your manifest schema). */
|
|
57
|
+
input<T = unknown>(name: string): Promise<T>;
|
|
58
|
+
/** Get a presigned GET URL for a blob input. Stream via fetch. */
|
|
59
|
+
inputBlobUrl(name: string): Promise<string>;
|
|
60
|
+
/** Fetch a blob input as bytes. Convenience over inputBlobUrl + fetch. */
|
|
61
|
+
inputBlob(name: string): Promise<Uint8Array>;
|
|
62
|
+
/** Write a JSON output (typed by your manifest's outputs.kv entry,
|
|
63
|
+
* or treated as a manifest-declared structured output). */
|
|
64
|
+
output(name: string, value: unknown): Promise<void>;
|
|
65
|
+
/** Upload a binary output. Streams via presigned PUT to the runs
|
|
66
|
+
* bucket; the controller then commits the UploadMetadata row. */
|
|
67
|
+
outputBlob(name: string, body: BlobPart | Uint8Array, contentType: string): Promise<void>;
|
|
68
|
+
/** Read a secret declared in the step manifest's requiredSecrets. */
|
|
69
|
+
secret(name: string): Promise<string>;
|
|
70
|
+
/** Structured logging — ships to the same per-step log JSONL as
|
|
71
|
+
* stdout/stderr from `js`-kind steps. */
|
|
72
|
+
log: {
|
|
73
|
+
info(msg: string, attrs?: Record<string, unknown>): void;
|
|
74
|
+
warn(msg: string, attrs?: Record<string, unknown>): void;
|
|
75
|
+
error(msg: string, attrs?: Record<string, unknown>): void;
|
|
76
|
+
};
|
|
77
|
+
/** Signal early success — call before resolving the handler if you
|
|
78
|
+
* want to release the run pod before the handler's microtasks settle.
|
|
79
|
+
* Idempotent; the SDK calls it automatically on clean handler exit. */
|
|
80
|
+
ready(): Promise<void>;
|
|
81
|
+
/** Signal failure. The pipeline coordinator records the reason and
|
|
82
|
+
* halts. Idempotent; the SDK calls it on any thrown error. */
|
|
83
|
+
fail(reason: string): Promise<void>;
|
|
84
|
+
}
|
|
85
|
+
interface DefineWorkerOptions {
|
|
86
|
+
/** Override the bridge — only used by the dev harness to inject the
|
|
87
|
+
* mock. Production code never sets this. */
|
|
88
|
+
bridge?: WorkerBridge;
|
|
89
|
+
}
|
|
90
|
+
type WorkerHandler = (ctx: WorkerContext) => Promise<void> | void;
|
|
91
|
+
/** Register the worker handler. Call once at module top level — the SDK
|
|
92
|
+
* waits for the bridge to be ready, runs the handler, captures any
|
|
93
|
+
* thrown error, and reports outcome to the controller. */
|
|
94
|
+
export declare function defineWorker(handler: WorkerHandler, options?: DefineWorkerOptions): void;
|
|
95
|
+
/** Install an in-page mock bridge backed by static fixtures. The Vite
|
|
96
|
+
* plugin injects a `<script>` that calls this before the user's
|
|
97
|
+
* `worker.tsx` loads, so `pnpm dev` runs the handler against
|
|
98
|
+
* fixtures/inputs.json. Production builds never include this path. */
|
|
99
|
+
export interface WorkerDevFixtures {
|
|
100
|
+
inputs?: Record<string, unknown>;
|
|
101
|
+
inputBlobUrls?: Record<string, string>;
|
|
102
|
+
secrets?: Record<string, string>;
|
|
103
|
+
/** Called when handler emits an output (any kind). Defaults to console.log. */
|
|
104
|
+
onOutput?: (kind: 'json' | 'blob', name: string, value: unknown) => void;
|
|
105
|
+
/** Called when handler emits a log line. */
|
|
106
|
+
onLog?: (level: string, msg: string, attrs?: Record<string, unknown>) => void;
|
|
107
|
+
}
|
|
108
|
+
export declare function installDevBridge(fixtures?: WorkerDevFixtures): void;
|
|
109
|
+
export {};
|
|
110
|
+
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker entry point for renderers used as pipeline steps.
|
|
3
|
+
*
|
|
4
|
+
* A renderer that ships a `worker.html` + `worker.tsx` can be referenced
|
|
5
|
+
* by a `puppeteer`-kind pipeline step. The puppeteer controller launches
|
|
6
|
+
* headless Chrome against the worker entry, exposes a JSON-only bridge
|
|
7
|
+
* via `page.exposeFunction` as `window.__uplWorkerBridge`, and the SDK
|
|
8
|
+
* wraps that bridge with a typed `ctx` so renderer code never touches
|
|
9
|
+
* `window.*` directly.
|
|
10
|
+
*
|
|
11
|
+
* Authoring shape:
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { defineWorker } from '@xeonr/renderer-sdk/worker';
|
|
14
|
+
*
|
|
15
|
+
* defineWorker(async (ctx) => {
|
|
16
|
+
* const upload = await ctx.input<Upload>('upload');
|
|
17
|
+
* const blob = await ctx.inputBlob('source');
|
|
18
|
+
* const png = await renderThumbnail(blob);
|
|
19
|
+
* await ctx.outputBlob('thumbnail', png, 'image/png');
|
|
20
|
+
* await ctx.output('width', upload.width);
|
|
21
|
+
* ctx.log.info('done', { ms: performance.now() });
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* Failure handling: the SDK auto-calls `ctx.fail(...)` on a thrown
|
|
26
|
+
* exception or unhandled rejection inside the handler and `ctx.ready()`
|
|
27
|
+
* on clean resolution. Renderers can call them explicitly to short-
|
|
28
|
+
* circuit (e.g. to fail early with a domain-specific error before any
|
|
29
|
+
* outputs are written).
|
|
30
|
+
*/
|
|
31
|
+
let installed = false;
|
|
32
|
+
/** Register the worker handler. Call once at module top level — the SDK
|
|
33
|
+
* waits for the bridge to be ready, runs the handler, captures any
|
|
34
|
+
* thrown error, and reports outcome to the controller. */
|
|
35
|
+
export function defineWorker(handler, options = {}) {
|
|
36
|
+
if (installed) {
|
|
37
|
+
throw new Error('[uplim:worker] defineWorker called twice — only one handler per worker entry.');
|
|
38
|
+
}
|
|
39
|
+
installed = true;
|
|
40
|
+
if (typeof window === 'undefined') {
|
|
41
|
+
// Worker entry imported in a non-browser context (SSR test, type
|
|
42
|
+
// resolution). Skip registration silently — the handler will
|
|
43
|
+
// re-register when the bundle actually loads in headless Chrome.
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
void runWorker(handler, options);
|
|
47
|
+
}
|
|
48
|
+
async function runWorker(handler, options) {
|
|
49
|
+
const bridge = options.bridge ?? (await waitForBridge());
|
|
50
|
+
if (!bridge) {
|
|
51
|
+
console.error('[uplim:worker] No bridge available. In production this means the puppeteer controller never connected; in dev, install the Vite worker harness.');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const ctx = makeContext(bridge);
|
|
55
|
+
// Surface uncaught errors as fail() so a malformed handler doesn't
|
|
56
|
+
// leave the controller waiting on a ready that never comes.
|
|
57
|
+
const onError = (ev) => {
|
|
58
|
+
void bridge.fail(`uncaught: ${ev.message}`);
|
|
59
|
+
};
|
|
60
|
+
const onRejection = (ev) => {
|
|
61
|
+
void bridge.fail(`unhandled-rejection: ${stringify(ev.reason)}`);
|
|
62
|
+
};
|
|
63
|
+
window.addEventListener('error', onError);
|
|
64
|
+
window.addEventListener('unhandledrejection', onRejection);
|
|
65
|
+
try {
|
|
66
|
+
await handler(ctx);
|
|
67
|
+
await bridge.ready();
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
await bridge.fail(stringify(e));
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
window.removeEventListener('error', onError);
|
|
74
|
+
window.removeEventListener('unhandledrejection', onRejection);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Poll for `window.__uplWorkerBridge` (the controller installs it via
|
|
78
|
+
* page.exposeFunction during page navigation, which races handler load).
|
|
79
|
+
* Bounded to 30s — beyond that something is wrong with the controller. */
|
|
80
|
+
async function waitForBridge() {
|
|
81
|
+
const deadline = Date.now() + 30_000;
|
|
82
|
+
while (Date.now() < deadline) {
|
|
83
|
+
if (window.__uplWorkerBridge)
|
|
84
|
+
return window.__uplWorkerBridge;
|
|
85
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
function makeContext(bridge) {
|
|
90
|
+
return {
|
|
91
|
+
input: (name) => bridge.getInput(name),
|
|
92
|
+
inputBlobUrl: (name) => bridge.getInputUrl(name),
|
|
93
|
+
inputBlob: async (name) => {
|
|
94
|
+
const url = await bridge.getInputUrl(name);
|
|
95
|
+
const res = await fetch(url);
|
|
96
|
+
if (!res.ok)
|
|
97
|
+
throw new Error(`inputBlob(${name}): ${res.status}`);
|
|
98
|
+
const buf = await res.arrayBuffer();
|
|
99
|
+
return new Uint8Array(buf);
|
|
100
|
+
},
|
|
101
|
+
output: (name, value) => bridge.setOutput(name, value),
|
|
102
|
+
outputBlob: async (name, body, contentType) => {
|
|
103
|
+
const url = await bridge.mintBlobOutputUrl(name, contentType);
|
|
104
|
+
const blob = body instanceof Uint8Array
|
|
105
|
+
? new Blob([body.buffer], { type: contentType })
|
|
106
|
+
: (body instanceof Blob ? body : new Blob([body], { type: contentType }));
|
|
107
|
+
const res = await fetch(url, {
|
|
108
|
+
method: 'PUT',
|
|
109
|
+
headers: { 'Content-Type': contentType },
|
|
110
|
+
body: blob,
|
|
111
|
+
});
|
|
112
|
+
if (!res.ok)
|
|
113
|
+
throw new Error(`outputBlob(${name}): ${res.status}`);
|
|
114
|
+
await bridge.commitBlobOutput(name, contentType, blob.size);
|
|
115
|
+
},
|
|
116
|
+
secret: (name) => bridge.getSecret(name),
|
|
117
|
+
log: {
|
|
118
|
+
info: (msg, attrs) => void bridge.log('info', msg, attrs),
|
|
119
|
+
warn: (msg, attrs) => void bridge.log('warn', msg, attrs),
|
|
120
|
+
error: (msg, attrs) => void bridge.log('error', msg, attrs),
|
|
121
|
+
},
|
|
122
|
+
ready: () => bridge.ready(),
|
|
123
|
+
fail: (reason) => bridge.fail(reason),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function stringify(e) {
|
|
127
|
+
if (e instanceof Error)
|
|
128
|
+
return `${e.name}: ${e.message}\n${e.stack ?? ''}`;
|
|
129
|
+
try {
|
|
130
|
+
return JSON.stringify(e);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return String(e);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export function installDevBridge(fixtures = {}) {
|
|
137
|
+
if (typeof window === 'undefined')
|
|
138
|
+
return;
|
|
139
|
+
const outputs = {};
|
|
140
|
+
const onOut = fixtures.onOutput ?? ((kind, name, v) => console.log(`[worker dev] output(${kind}, ${name})`, v));
|
|
141
|
+
const onLog = fixtures.onLog ?? ((level, msg, attrs) => console.log(`[worker dev] ${level}: ${msg}`, attrs ?? ''));
|
|
142
|
+
const mock = {
|
|
143
|
+
getInput: async (name) => fixtures.inputs?.[name],
|
|
144
|
+
getInputUrl: async (name) => {
|
|
145
|
+
const url = fixtures.inputBlobUrls?.[name];
|
|
146
|
+
if (!url)
|
|
147
|
+
throw new Error(`[worker dev] no fixture URL for blob input "${name}"`);
|
|
148
|
+
return url;
|
|
149
|
+
},
|
|
150
|
+
getSecret: async (name) => fixtures.secrets?.[name] ?? '',
|
|
151
|
+
setOutput: async (name, value) => {
|
|
152
|
+
outputs[name] = value;
|
|
153
|
+
onOut('json', name, value);
|
|
154
|
+
},
|
|
155
|
+
mintBlobOutputUrl: async (name) => {
|
|
156
|
+
// Dev: blob outputs PUT to a synthetic data: URL via fetch
|
|
157
|
+
// won't work — return a placeholder and the controller-less
|
|
158
|
+
// path is short-circuited in outputBlob. The dev path captures
|
|
159
|
+
// the blob bytes locally for inspection.
|
|
160
|
+
return `data:dev-stub/${encodeURIComponent(name)},`;
|
|
161
|
+
},
|
|
162
|
+
commitBlobOutput: async (name, contentType, size) => {
|
|
163
|
+
onOut('blob', name, { contentType, size });
|
|
164
|
+
},
|
|
165
|
+
log: async (level, msg, attrs) => onLog(level, msg, attrs),
|
|
166
|
+
ready: async () => onLog('info', '[worker dev] ready()'),
|
|
167
|
+
fail: async (reason) => onLog('error', `[worker dev] fail(${reason})`),
|
|
168
|
+
};
|
|
169
|
+
window.__uplWorkerBridge = mock;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xeonr/renderer-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"description": "SDK for building custom renderers for upl.im integrations",
|
|
@@ -23,10 +23,22 @@
|
|
|
23
23
|
"default": "./dist/react/dom.js",
|
|
24
24
|
"types": "./dist/react/dom.d.ts"
|
|
25
25
|
},
|
|
26
|
+
"./react/worker": {
|
|
27
|
+
"default": "./dist/react/worker.js",
|
|
28
|
+
"types": "./dist/react/worker.d.ts"
|
|
29
|
+
},
|
|
26
30
|
"./protocol": {
|
|
27
31
|
"default": "./dist/protocol.js",
|
|
28
32
|
"types": "./dist/protocol.d.ts"
|
|
29
33
|
},
|
|
34
|
+
"./worker": {
|
|
35
|
+
"default": "./dist/worker.js",
|
|
36
|
+
"types": "./dist/worker.d.ts"
|
|
37
|
+
},
|
|
38
|
+
"./worker-renderer": {
|
|
39
|
+
"default": "./dist/worker-renderer.js",
|
|
40
|
+
"types": "./dist/worker-renderer.d.ts"
|
|
41
|
+
},
|
|
30
42
|
"./renderer.css": "./renderer.css",
|
|
31
43
|
"./*": {
|
|
32
44
|
"default": "./dist/*.js",
|
|
@@ -38,7 +50,8 @@
|
|
|
38
50
|
"react-dom": ">=18.0.0",
|
|
39
51
|
"@bufbuild/protobuf": ">=2.0.0",
|
|
40
52
|
"@xeonr/uploads-protocol": "*",
|
|
41
|
-
"@xeonr/uploads-sdk": "*"
|
|
53
|
+
"@xeonr/uploads-sdk": "*",
|
|
54
|
+
"html-to-image": "^1.11.13"
|
|
42
55
|
},
|
|
43
56
|
"peerDependenciesMeta": {
|
|
44
57
|
"react": {
|
|
@@ -55,12 +68,16 @@
|
|
|
55
68
|
},
|
|
56
69
|
"@xeonr/uploads-sdk": {
|
|
57
70
|
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"html-to-image": {
|
|
73
|
+
"optional": true
|
|
58
74
|
}
|
|
59
75
|
},
|
|
60
76
|
"devDependencies": {
|
|
61
77
|
"@types/react": "^19.0.0",
|
|
62
78
|
"@types/react-dom": "^19.0.0",
|
|
63
79
|
"@bufbuild/protobuf": "^2.0.0",
|
|
80
|
+
"html-to-image": "^1.11.13",
|
|
64
81
|
"react": "^19.0.0",
|
|
65
82
|
"react-dom": "^19.0.0",
|
|
66
83
|
"typescript": "^5.8.3",
|