@maravilla-labs/platform 0.8.1 → 0.9.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.
@@ -1,4 +1,4 @@
1
- import type { KvNamespace, KvListResult, Database, DbDocument, DbFindOptions, Storage, RealtimeService, PresenceService, AuthService, AuthCaller, AuthUser, AuthSession, AuthField, RegisterOptions, LoginOptions, CreateManagedUserOptions, UserListFilter, UserListResponse, UpdateUserOptions, Relation, AddRelationOptions, ListRelationsOptions, PolicyExplain, CanCheck, PolicyService, VectorIndexSpec, VectorIndexDescriptor, VectorQueryWithFilter, VectorSearchHit, IndexSpec, IndexDescriptor, Workflows, WorkflowHandle, WorkflowRun, WorkflowStepRecord } from './types.js';
1
+ import type { KvNamespace, KvListResult, Database, DbDocument, DbFindOptions, Storage, RealtimeService, PresenceService, AuthService, AuthCaller, AuthUser, AuthSession, AuthField, RegisterOptions, LoginOptions, CreateManagedUserOptions, UserListFilter, UserListResponse, UpdateUserOptions, Relation, AddRelationOptions, ListRelationsOptions, PolicyExplain, CanCheck, PolicyService, VectorIndexSpec, VectorIndexDescriptor, VectorQueryWithFilter, VectorSearchHit, IndexSpec, IndexDescriptor, Workflows, WorkflowHandle, WorkflowRun, WorkflowStepRecord, BrowserClient, FramesClient, BrowserJobHandle, ScreenshotRequest, PdfRequest, FramesRenderRequest } from './types.js';
2
2
  import type { TransformsService, TranscodeOpts, ThumbnailOpts, ResizeOpts, OcrOpts, DocToPdfOpts, DocThumbnailOpts, DocConvertOpts, DocToMarkdownOpts, DocToHtmlOpts, DocReplaceImagesOpts, DocInsertQrCodeOpts, DocTemplateMergeOpts, JobHandle, JobStatusResponse, MediaInfo } from './transforms.js';
3
3
  import { RemoteMediaService } from './media.js';
4
4
  import { getRequestAuthHeader } from './request-scope.js';
@@ -1137,11 +1137,16 @@ export function createRemoteClient(baseUrl: string, tenant: string) {
1137
1137
  const policy = new RemotePolicyService();
1138
1138
  const workflows = new RemoteWorkflows(baseUrl, headers);
1139
1139
 
1140
+ const browser = new RemoteBrowserClient(baseUrl, headers);
1141
+ const frames = new RemoteFramesClient(baseUrl, headers);
1142
+
1140
1143
  return {
1141
1144
  env: {
1142
1145
  KV: kvProxy,
1143
1146
  DB: db,
1144
1147
  STORAGE: storage,
1148
+ BROWSER: browser,
1149
+ FRAMES: frames,
1145
1150
  },
1146
1151
  media,
1147
1152
  realtime,
@@ -1151,6 +1156,70 @@ export function createRemoteClient(baseUrl: string, tenant: string) {
1151
1156
  };
1152
1157
  }
1153
1158
 
1159
+ /**
1160
+ * Remote `platform.env.BROWSER` for development. Posts to the dev-server
1161
+ * `/api/media/browser/*` routes and returns the same {@link BrowserJobHandle}
1162
+ * shape the native runtime returns. Phase 1 plumbing — the worker marks
1163
+ * the job `failed("not implemented")` immediately; clients can still
1164
+ * exercise the full request → handle → poll cycle.
1165
+ *
1166
+ * @internal
1167
+ */
1168
+ class RemoteBrowserClient implements BrowserClient {
1169
+ constructor(
1170
+ private baseUrl: string,
1171
+ private headers: Record<string, string>,
1172
+ ) {}
1173
+
1174
+ private async post(path: string, body: unknown): Promise<BrowserJobHandle> {
1175
+ const res = await fetch(`${this.baseUrl}/api/media/browser${path}`, {
1176
+ method: 'POST',
1177
+ headers: { 'Content-Type': 'application/json', ...this.headers, ...getRequestAuthHeader() },
1178
+ body: JSON.stringify(body),
1179
+ });
1180
+ if (!res.ok) {
1181
+ const text = await res.text();
1182
+ throw new Error(`Browser error (${res.status}): ${text}`);
1183
+ }
1184
+ return res.json() as Promise<BrowserJobHandle>;
1185
+ }
1186
+
1187
+ screenshot(request: ScreenshotRequest): Promise<BrowserJobHandle> {
1188
+ return this.post('/screenshot', request);
1189
+ }
1190
+
1191
+ pdf(request: PdfRequest): Promise<BrowserJobHandle> {
1192
+ return this.post('/pdf', request);
1193
+ }
1194
+ }
1195
+
1196
+ /**
1197
+ * Remote `platform.env.FRAMES` for development. Posts to the dev-server
1198
+ * `/api/media/frames/render` route. Same plumbing stub story as
1199
+ * {@link RemoteBrowserClient}.
1200
+ *
1201
+ * @internal
1202
+ */
1203
+ class RemoteFramesClient implements FramesClient {
1204
+ constructor(
1205
+ private baseUrl: string,
1206
+ private headers: Record<string, string>,
1207
+ ) {}
1208
+
1209
+ async render(request: FramesRenderRequest): Promise<BrowserJobHandle> {
1210
+ const res = await fetch(`${this.baseUrl}/api/media/frames/render`, {
1211
+ method: 'POST',
1212
+ headers: { 'Content-Type': 'application/json', ...this.headers, ...getRequestAuthHeader() },
1213
+ body: JSON.stringify(request),
1214
+ });
1215
+ if (!res.ok) {
1216
+ const text = await res.text();
1217
+ throw new Error(`Frames render error (${res.status}): ${text}`);
1218
+ }
1219
+ return res.json() as Promise<BrowserJobHandle>;
1220
+ }
1221
+ }
1222
+
1154
1223
  /**
1155
1224
  * Remote `platform.media.transforms` for development. Each method posts
1156
1225
  * to the dev-server's `/api/media/transforms/*` route and returns the
package/src/transforms.ts CHANGED
@@ -24,6 +24,43 @@
24
24
  // consume this package client-side.
25
25
  import { sha256 } from '@noble/hashes/sha2';
26
26
 
27
+ // ── Headless-browser + frames-render re-exports ─────────────────────────
28
+ //
29
+ // The contract types live in `@maravilla-labs/types` so the runtime crate
30
+ // and downstream packages (adapter-core, app code) consume one canonical
31
+ // shape. We re-export them through this module so app code that already
32
+ // reaches for `@maravilla-labs/platform/transforms` for media-related
33
+ // helpers also gets the browser / frames request types without a second
34
+ // import.
35
+ //
36
+ // The methods themselves — `platform.env.BROWSER.screenshot(...)`,
37
+ // `.pdf(...)`, `platform.env.FRAMES.render(...)` — are injected by the
38
+ // runtime and typed by the `BrowserClient` / `FramesClient` interfaces
39
+ // (declared in `@maravilla-labs/types`, re-exported below). All three
40
+ // return a `BrowserJobHandle` whose `output_key` equals the
41
+ // caller-supplied `target` storage key; poll status with
42
+ // `platform.media.transforms.job(handle.id)`, then read the rendered
43
+ // bytes from `platform.env.STORAGE`. See `BrowserClient.screenshot` /
44
+ // `BrowserClient.pdf` / `FramesClient.render` for per-method JSDoc with
45
+ // runnable examples; see
46
+ // `docs/recipes/{screenshot-public-url,render-animated-title-card,og-image-from-own-page}.md`
47
+ // for full walkthroughs.
48
+ export type {
49
+ BrowserClient,
50
+ BrowserCookie,
51
+ BrowserJobHandle,
52
+ BrowserJobStatus,
53
+ BrowserViewport,
54
+ BrowserWaitFor,
55
+ FramesClient,
56
+ FramesCodec,
57
+ FramesRenderRequest,
58
+ PdfPageFormat,
59
+ PdfRequest,
60
+ ScreenshotFormat,
61
+ ScreenshotRequest,
62
+ } from '@maravilla-labs/types';
63
+
27
64
  // ── Types — mirror `crates/platform/src/media/transforms/types.rs` ──────
28
65
 
29
66
  /** Video container targets supported by v1. */
package/src/types.ts CHANGED
@@ -741,9 +741,9 @@ export interface Storage {
741
741
  * This is the main interface for accessing KV storage, database, and object storage operations.
742
742
  */
743
743
  export interface PlatformEnv {
744
- /**
744
+ /**
745
745
  * Key-Value storage namespaces. Access different KV namespaces by property name.
746
- *
746
+ *
747
747
  * @example
748
748
  * ```typescript
749
749
  * const userCache = platform.env.KV.users;
@@ -755,6 +755,19 @@ export interface PlatformEnv {
755
755
  DB: Database;
756
756
  /** Object/file storage interface */
757
757
  STORAGE: Storage;
758
+ /**
759
+ * Headless-browser screenshot / PDF render. Returns a job handle
760
+ * polled via the shared transforms job ledger. Phase 1 plumbing stub —
761
+ * the worker marks browser jobs `failed("not implemented")` until
762
+ * Task #2 lands the Chromium pipeline.
763
+ */
764
+ BROWSER: BrowserClient;
765
+ /**
766
+ * Deterministic HTML → MP4 / WebM render. Path-only: the renderer hits
767
+ * a route on the tenant's own deployment. Phase 1 plumbing stub —
768
+ * real implementation in Task #3.
769
+ */
770
+ FRAMES: FramesClient;
758
771
  }
759
772
 
760
773
  /**
@@ -805,7 +818,22 @@ export interface PresenceService {
805
818
  //
806
819
  // `AuthService` is also imported (not just re-exported) because the
807
820
  // `Platform` interface below references it within this module's scope.
808
- import type { AuthService } from '@maravilla-labs/types';
821
+ import type { AuthService, BrowserClient, FramesClient } from '@maravilla-labs/types';
822
+ export type {
823
+ BrowserClient,
824
+ FramesClient,
825
+ BrowserCookie,
826
+ BrowserJobHandle,
827
+ BrowserJobStatus,
828
+ BrowserViewport,
829
+ BrowserWaitFor,
830
+ FramesCodec,
831
+ FramesRenderRequest,
832
+ PdfPageFormat,
833
+ PdfRequest,
834
+ ScreenshotFormat,
835
+ ScreenshotRequest,
836
+ } from '@maravilla-labs/types';
809
837
  export type {
810
838
  AuthUser,
811
839
  AuthCaller,
package/tsup.config.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defineConfig } from 'tsup';
2
2
 
3
3
  export default defineConfig({
4
- entry: ['src/index.ts', 'src/config.ts', 'src/push.ts', 'src/events.ts'],
4
+ entry: ['src/index.ts', 'src/config.ts', 'src/push.ts', 'src/events.ts', 'src/mcp.ts'],
5
5
  format: ['esm'],
6
6
  dts: true,
7
7
  splitting: false,