@bitbitpress/client 1.1.3 → 1.1.4

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.
Files changed (46) hide show
  1. package/dist/generated/openapi.d.ts +420 -0
  2. package/dist/react/index.d.ts +76 -2
  3. package/dist/react/index.d.ts.map +1 -1
  4. package/dist/react/index.js +110 -3
  5. package/dist/react/index.js.map +1 -1
  6. package/dist/react-native-expo/BitBitPiece.d.ts +64 -0
  7. package/dist/react-native-expo/BitBitPiece.d.ts.map +1 -0
  8. package/dist/react-native-expo/BitBitPiece.js +164 -0
  9. package/dist/react-native-expo/BitBitPiece.js.map +1 -0
  10. package/dist/react-native-expo/bootstrapHtml.d.ts +13 -0
  11. package/dist/react-native-expo/bootstrapHtml.d.ts.map +1 -1
  12. package/dist/react-native-expo/bootstrapHtml.js +108 -12
  13. package/dist/react-native-expo/bootstrapHtml.js.map +1 -1
  14. package/dist/react-native-expo/index.d.ts +1 -0
  15. package/dist/react-native-expo/index.d.ts.map +1 -1
  16. package/dist/react-native-expo/index.js +1 -0
  17. package/dist/react-native-expo/index.js.map +1 -1
  18. package/dist/runtime/index.d.ts +32 -0
  19. package/dist/runtime/index.d.ts.map +1 -1
  20. package/dist/runtime/index.js +68 -2
  21. package/dist/runtime/index.js.map +1 -1
  22. package/dist/studio/BitBitMobilePreview.d.ts +33 -0
  23. package/dist/studio/BitBitMobilePreview.d.ts.map +1 -0
  24. package/dist/studio/BitBitMobilePreview.js +120 -0
  25. package/dist/studio/BitBitMobilePreview.js.map +1 -0
  26. package/dist/studio/index.d.ts +7 -0
  27. package/dist/studio/index.d.ts.map +1 -0
  28. package/dist/studio/index.js +7 -0
  29. package/dist/studio/index.js.map +1 -0
  30. package/dist/user/index.d.ts +27 -0
  31. package/dist/user/index.d.ts.map +1 -1
  32. package/dist/user/index.js +6 -1
  33. package/dist/user/index.js.map +1 -1
  34. package/dist/user/synthesisPiece.d.ts +38 -0
  35. package/dist/user/synthesisPiece.d.ts.map +1 -0
  36. package/dist/user/synthesisPiece.js +58 -0
  37. package/dist/user/synthesisPiece.js.map +1 -0
  38. package/dist/user/track-batch-manager.d.ts +10 -4
  39. package/dist/user/track-batch-manager.d.ts.map +1 -1
  40. package/dist/user/track-batch-manager.js +6 -5
  41. package/dist/user/track-batch-manager.js.map +1 -1
  42. package/dist/user/track.d.ts +9 -0
  43. package/dist/user/track.d.ts.map +1 -1
  44. package/dist/user/track.js +17 -0
  45. package/dist/user/track.js.map +1 -1
  46. package/package.json +5 -1
@@ -1,5 +1,5 @@
1
- import { createElement, useEffect, useRef } from 'react';
2
- import { loadGeneratedModule, mountGeneratedView, } from '../runtime/index.js';
1
+ import { createElement, useCallback, useEffect, useRef, useState } from 'react';
2
+ import { attachHlsMedia, loadGeneratedModule, mountGeneratedView, } from '../runtime/index.js';
3
3
  import { useBitBitContext } from '../synthesisUi/context.js';
4
4
  export { BitBitProvider } from '../synthesisUi/context.js';
5
5
  const noop = () => { };
@@ -12,7 +12,7 @@ const noop = () => { };
12
12
  * `mobile` preview in the light DOM). Native delivery renders the same mobile
13
13
  * bundle in a WebView via the `react-native-expo` entry.
14
14
  */
15
- export function BitBitView({ client: clientProp, keyName, platform = 'web', onTrack, onEvent, onNavigate, inputs, output, searchOptionsOverrides, synthesisHistoryLimit, }) {
15
+ export function BitBitView({ client: clientProp, keyName, platform = 'web', onTrack, onEvent, onNavigate, onTts, inputs, output, searchOptionsOverrides, synthesisHistoryLimit, }) {
16
16
  const contextClient = useBitBitContext()?.client;
17
17
  const client = clientProp ?? contextClient;
18
18
  const hostRef = useRef(null);
@@ -39,6 +39,8 @@ export function BitBitView({ client: clientProp, keyName, platform = 'web', onTr
39
39
  },
40
40
  onEvent: onEvent ?? noop,
41
41
  navigate: onNavigate,
42
+ tts: onTts,
43
+ playMedia: attachHlsMedia,
42
44
  });
43
45
  void (async () => {
44
46
  const stream = await client.user.synthesizeUi({
@@ -90,6 +92,7 @@ export function BitBitView({ client: clientProp, keyName, platform = 'web', onTr
90
92
  onTrack,
91
93
  onEvent,
92
94
  onNavigate,
95
+ onTts,
93
96
  inputs,
94
97
  output,
95
98
  searchOptionsOverrides,
@@ -97,4 +100,108 @@ export function BitBitView({ client: clientProp, keyName, platform = 'web', onTr
97
100
  ]);
98
101
  return createElement('div', { ref: hostRef, style: { height: '100%' } });
99
102
  }
103
+ /**
104
+ * Render a generated piece bundle (its `uiWebCode`). Two modes:
105
+ * - **Direct** (`code` + `data`): mounts the module from source in hand — editor
106
+ * previews where code and data are already available (the piece studio).
107
+ * - **Embed** (`keyName` + `client`): resolves the piece's bundle, field values
108
+ * (incl. pre-generated `audioData.url`s), and theme by `keyName` through the
109
+ * client (like `<BitBitView keyName>`).
110
+ *
111
+ * Either way the module mounts on the host (web: Shadow DOM) and `data` is pushed
112
+ * in, re-rendering in place when it changes.
113
+ */
114
+ export function BitBitPiece(props) {
115
+ const { theme, platform = 'web', colorScheme, onTrack, onEvent, onNavigate, onTts, remountToken, } = props;
116
+ const keyName = 'keyName' in props ? props.keyName : undefined;
117
+ const contextClient = useBitBitContext()?.client;
118
+ const client = ('client' in props ? props.client : undefined) ?? contextClient;
119
+ // In embed mode, the resolved bundle/data/theme are fetched by keyName.
120
+ const [fetched, setFetched] = useState(null);
121
+ useEffect(() => {
122
+ if (keyName == null || !client)
123
+ return;
124
+ let cancelled = false;
125
+ void (async () => {
126
+ const payload = await client.user.getSynthesisPiece(keyName);
127
+ if (cancelled)
128
+ return;
129
+ setFetched({ code: payload.uiWebCode, data: payload.fields, theme: payload.theme });
130
+ })();
131
+ return () => {
132
+ cancelled = true;
133
+ };
134
+ }, [keyName, client]);
135
+ const code = keyName != null ? (fetched?.code ?? null) : props.code;
136
+ const data = keyName != null ? fetched?.data : props.data;
137
+ const resolvedTheme = (keyName != null ? fetched?.theme : undefined) ?? theme;
138
+ // Embed mode wires audio playback through the client automatically; an explicit `onTts`
139
+ // (or direct `code` mode) always wins. The client-backed URL captures the piece's keyName.
140
+ const clientTtsUrl = client?.user.synthesisPieceTtsUrl;
141
+ const resolvedOnTts = onTts ??
142
+ (keyName != null && clientTtsUrl
143
+ ? (ref) => clientTtsUrl(keyName, ref)
144
+ : undefined);
145
+ const hostRef = useRef(null);
146
+ const handleRef = useRef(undefined);
147
+ // Latest props, read at mount/update without re-mounting on identity changes.
148
+ const propsRef = useRef({
149
+ data,
150
+ theme: resolvedTheme,
151
+ colorScheme,
152
+ onTrack,
153
+ onEvent,
154
+ onNavigate,
155
+ onTts: resolvedOnTts,
156
+ });
157
+ propsRef.current = {
158
+ data,
159
+ theme: resolvedTheme,
160
+ colorScheme,
161
+ onTrack,
162
+ onEvent,
163
+ onNavigate,
164
+ onTts: resolvedOnTts,
165
+ };
166
+ const makeCtx = useCallback(() => {
167
+ const p = propsRef.current;
168
+ return {
169
+ theme: p.theme ?? {},
170
+ ...(p.colorScheme && { colorScheme: p.colorScheme }),
171
+ track: p.onTrack ?? noop,
172
+ onEvent: p.onEvent ?? noop,
173
+ navigate: p.onNavigate,
174
+ tts: p.onTts,
175
+ playMedia: attachHlsMedia,
176
+ };
177
+ }, []);
178
+ // Mount when the bundle source changes (in embed mode, once it has resolved).
179
+ // biome-ignore lint/correctness/useExhaustiveDependencies: remountToken is a deliberate remount trigger — bumping it re-runs the teardown/mount even though the body never reads it.
180
+ useEffect(() => {
181
+ const host = hostRef.current;
182
+ if (!host || !code)
183
+ return;
184
+ let cancelled = false;
185
+ void (async () => {
186
+ const mod = await loadGeneratedModule(code);
187
+ if (cancelled || !hostRef.current)
188
+ return;
189
+ handleRef.current = mountGeneratedView(hostRef.current, mod, { data: propsRef.current.data, ctx: makeCtx() }, { isolateStyles: platform !== 'mobile' });
190
+ })();
191
+ return () => {
192
+ cancelled = true;
193
+ handleRef.current?.unmount();
194
+ handleRef.current = undefined;
195
+ };
196
+ // `remountToken` re-runs this to tear down + re-mount cleanly (module is cached).
197
+ }, [code, platform, makeCtx, remountToken]);
198
+ // Push fresh data (and ctx) into the mounted view. `colorScheme` is included so a
199
+ // light/dark toggle re-pushes ctx — `makeCtx` reads props from a ref (stable identity),
200
+ // so without it a scheme change would sit unflushed until `data` changed.
201
+ // biome-ignore lint/correctness/useExhaustiveDependencies: colorScheme is a deliberate re-push trigger — makeCtx reads it through a stable ref, so it must stay in deps to flush a scheme toggle.
202
+ useEffect(() => {
203
+ handleRef.current?.update({ data, ctx: makeCtx() });
204
+ }, [data, makeCtx, colorScheme]);
205
+ return createElement('div', { ref: hostRef, style: { height: '100%' } });
206
+ }
100
207
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { WebView } from 'react-native-webview';
2
+ /** What the native `<BitBitPiece keyName>` needs from a client: resolve a
3
+ * published piece for embedding. A full `BitBitPressClient` satisfies this. */
4
+ export interface BitBitPieceFetcher {
5
+ user: {
6
+ getSynthesisPiece(keyName: string): Promise<{
7
+ uiWebCode: string;
8
+ fields: unknown;
9
+ theme?: Record<string, string>;
10
+ }>;
11
+ trackPieceItem?(e: {
12
+ keyName: string;
13
+ type: 'VIEW' | 'CLICK';
14
+ name?: string;
15
+ payload?: unknown;
16
+ }): Promise<unknown>;
17
+ /** Mint an on-demand streaming audio URL for referenced piece content — wired into the
18
+ * view's `ctx.tts` so audio players play without host setup. */
19
+ synthesisPieceTtsUrl?(keyName: string, ref?: {
20
+ field?: string;
21
+ index?: number;
22
+ }): Promise<string>;
23
+ };
24
+ }
25
+ export interface BitBitPieceProps {
26
+ /** Client to resolve the piece through. Optional when a `<BitBitProvider
27
+ * client>` is in scope. */
28
+ client?: BitBitPieceFetcher;
29
+ keyName: string;
30
+ /** Brand analytics / link tracking. */
31
+ onTrack?: (event: string, payload?: unknown) => void;
32
+ /** Host slot callbacks (developer-supplied event handlers). */
33
+ onEvent?: (name: string, payload?: unknown) => void;
34
+ /** Navigate a link the view requested (the WebView never navigates itself). */
35
+ onNavigate?: (href: string) => void;
36
+ /** Called when the piece fails to resolve, load, or render. Defaults to
37
+ * `console.warn` so failures are never silent. */
38
+ onError?: (message: string) => void;
39
+ /** Fill the host's height (`flex: 1`) instead of sizing to the piece's own
40
+ * content height. Use for a full-screen piece; defaults to false so the piece
41
+ * renders at its natural height inside a scrolling host (a feed tile). */
42
+ fillHeight?: boolean;
43
+ /** Height (px) to reserve before the content reports its own — avoids a layout
44
+ * jump. Ignored when `fillHeight`. Defaults to 240. */
45
+ initialHeight?: number;
46
+ /** Force the rendered scheme. Defaults to the device appearance
47
+ * (`useColorScheme`) — the WebView can't read it itself, so it's passed in. */
48
+ colorScheme?: 'light' | 'dark';
49
+ /** Style for the hosting WebView. */
50
+ style?: Record<string, unknown>;
51
+ }
52
+ /**
53
+ * React Native view for a published SynthesisPiece — the native counterpart of
54
+ * the web `<BitBitPiece keyName>`. Resolves the piece's generated web bundle
55
+ * (`uiWebCode`), current field values (`fields`), and deployment `theme` by
56
+ * `keyName`, hosts the bundle (plain DOM: Preact + htm) in a `WebView`, pushes
57
+ * `fields` in as its data, and relays the view's `track`/`onEvent`/`navigate`
58
+ * back out (plus auto-beaconing when `client` is a full `BitBitPressClient`).
59
+ *
60
+ * Unlike `<BitBitView>` there is no stream — a piece is a single resolved
61
+ * snapshot, so the data is pushed once the WebView signals `ready`.
62
+ */
63
+ export declare function BitBitPiece({ client: clientProp, keyName, onTrack, onEvent, onNavigate, onError, fillHeight, initialHeight, colorScheme, style, }: BitBitPieceProps): import("react").CElement<import("react-native-webview").WebViewProps, WebView> | null;
64
+ //# sourceMappingURL=BitBitPiece.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BitBitPiece.d.ts","sourceRoot":"","sources":["../../src/react-native-expo/BitBitPiece.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAA4B,MAAM,sBAAsB,CAAC;AAIzE;gFACgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE;QACJ,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;YAC1C,SAAS,EAAE,MAAM,CAAC;YAClB,MAAM,EAAE,OAAO,CAAC;YAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAChC,CAAC,CAAC;QAIH,cAAc,CAAC,CAAC,CAAC,EAAE;YACjB,OAAO,EAAE,MAAM,CAAC;YAChB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;YACvB,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,OAAO,CAAC;SACnB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACrB;yEACiE;QACjE,oBAAoB,CAAC,CACnB,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,GACvC,OAAO,CAAC,MAAM,CAAC,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B;gCAC4B;IAC5B,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC;uDACmD;IACnD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC;;+EAE2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;4DACwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;oFACgF;IAChF,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EAAE,UAAU,EAClB,OAAO,EACP,OAAO,EACP,OAAO,EACP,UAAU,EACV,OAAO,EACP,UAAkB,EAClB,aAAmB,EACnB,WAAW,EACX,KAAK,GACN,EAAE,gBAAgB,yFAqKlB"}
@@ -0,0 +1,164 @@
1
+ import { createElement, useCallback, useEffect, useRef, useState } from 'react';
2
+ import { useColorScheme } from 'react-native';
3
+ import { WebView } from 'react-native-webview';
4
+ import { useBitBitContext } from '../synthesisUi/context.js';
5
+ import { buildBootstrapHtml } from './bootstrapHtml.js';
6
+ /**
7
+ * React Native view for a published SynthesisPiece — the native counterpart of
8
+ * the web `<BitBitPiece keyName>`. Resolves the piece's generated web bundle
9
+ * (`uiWebCode`), current field values (`fields`), and deployment `theme` by
10
+ * `keyName`, hosts the bundle (plain DOM: Preact + htm) in a `WebView`, pushes
11
+ * `fields` in as its data, and relays the view's `track`/`onEvent`/`navigate`
12
+ * back out (plus auto-beaconing when `client` is a full `BitBitPressClient`).
13
+ *
14
+ * Unlike `<BitBitView>` there is no stream — a piece is a single resolved
15
+ * snapshot, so the data is pushed once the WebView signals `ready`.
16
+ */
17
+ export function BitBitPiece({ client: clientProp, keyName, onTrack, onEvent, onNavigate, onError, fillHeight = false, initialHeight = 240, colorScheme, style, }) {
18
+ const contextClient = useBitBitContext()?.client;
19
+ const client = clientProp ?? contextClient;
20
+ // The WebView can't read the OS appearance, so resolve it here and pass it in.
21
+ const osScheme = useColorScheme();
22
+ const scheme = colorScheme ?? (osScheme === 'dark' ? 'dark' : 'light');
23
+ // Read at (re)build time without making it a build dependency — scheme changes
24
+ // are pushed live below instead of rebuilding (which would reload the WebView).
25
+ const schemeRef = useRef(scheme);
26
+ schemeRef.current = scheme;
27
+ const reportError = useCallback((message) => {
28
+ if (onError)
29
+ onError(message);
30
+ else
31
+ console.warn(`[BitBitPiece] ${message}`);
32
+ }, [onError]);
33
+ const webRef = useRef(null);
34
+ const [html, setHtml] = useState(null);
35
+ // Content height reported by the bundle (auto-height mode); null until first report.
36
+ const [contentHeight, setContentHeight] = useState(null);
37
+ // Resolved field values + whether the WebView has loaded the bundle and can
38
+ // receive them. Refs (not state) so the bridge round-trip doesn't churn renders.
39
+ const dataRef = useRef(undefined);
40
+ const readyRef = useRef(false);
41
+ // A `BitBitPressClient` may be a retry Proxy whose method getters return a NEW
42
+ // function on every access, so we depend on this stable boolean — never the
43
+ // function identities — and read the methods fresh from `client` when calling.
44
+ const hasTts = typeof client?.user.synthesisPieceTtsUrl === 'function';
45
+ const beacon = useCallback((type, name, payload) => {
46
+ client?.user
47
+ .trackPieceItem?.({ keyName, type, ...(name != null && { name }), payload })
48
+ ?.catch?.(() => { });
49
+ }, [client, keyName]);
50
+ const pushData = useCallback((data) => {
51
+ webRef.current?.injectJavaScript(`window.__bb && window.__bb.update(${JSON.stringify(data)}); true;`);
52
+ }, []);
53
+ // Resolve the piece and build the WebView document. Pushes the fields in
54
+ // immediately if the WebView has already signalled `ready`.
55
+ useEffect(() => {
56
+ if (!client)
57
+ return;
58
+ let cancelled = false;
59
+ readyRef.current = false;
60
+ dataRef.current = undefined;
61
+ setHtml(null);
62
+ void (async () => {
63
+ try {
64
+ const piece = await client.user.getSynthesisPiece(keyName);
65
+ if (cancelled)
66
+ return;
67
+ dataRef.current = piece.fields;
68
+ setHtml(buildBootstrapHtml({
69
+ bundle: piece.uiWebCode,
70
+ theme: piece.theme ?? {},
71
+ autoHeight: !fillHeight,
72
+ enableTts: hasTts,
73
+ colorScheme: schemeRef.current,
74
+ }));
75
+ if (readyRef.current)
76
+ pushData(piece.fields);
77
+ }
78
+ catch (err) {
79
+ if (!cancelled)
80
+ reportError(err instanceof Error ? err.message : String(err));
81
+ }
82
+ })();
83
+ return () => {
84
+ cancelled = true;
85
+ };
86
+ }, [client, keyName, pushData, fillHeight, hasTts, reportError]);
87
+ // Push OS appearance changes into the loaded WebView (no reload) so a dual-mode
88
+ // piece recolors live when the device switches light/dark.
89
+ useEffect(() => {
90
+ webRef.current?.injectJavaScript(`window.__bb && window.__bb.setColorScheme(${JSON.stringify(scheme)}); true;`);
91
+ }, [scheme]);
92
+ const onMessage = useCallback((e) => {
93
+ let msg;
94
+ try {
95
+ msg = JSON.parse(e.nativeEvent.data);
96
+ }
97
+ catch {
98
+ return;
99
+ }
100
+ switch (msg.kind) {
101
+ case 'ready':
102
+ readyRef.current = true;
103
+ if (dataRef.current !== undefined)
104
+ pushData(dataRef.current);
105
+ break;
106
+ case 'height':
107
+ if (!fillHeight && msg.px > 0)
108
+ setContentHeight(msg.px);
109
+ break;
110
+ case 'error':
111
+ reportError(msg.message);
112
+ break;
113
+ case 'tts': {
114
+ const { id, ref } = msg;
115
+ const resolve = (url, error) => webRef.current?.injectJavaScript(`window.__bb && window.__bb.resolveTts(${id}, ${JSON.stringify(url)}, ${JSON.stringify(error ?? null)}); true;`);
116
+ const ttsUrl = client?.user.synthesisPieceTtsUrl;
117
+ if (!ttsUrl) {
118
+ resolve(null, 'Could not load audio');
119
+ break;
120
+ }
121
+ ttsUrl(keyName, ref)
122
+ .then((url) => resolve(url))
123
+ .catch((err) => resolve(null, err instanceof Error ? err.message : 'Could not load audio'));
124
+ break;
125
+ }
126
+ case 'view':
127
+ beacon('VIEW');
128
+ break;
129
+ case 'track':
130
+ onTrack?.(msg.event, msg.payload);
131
+ beacon('CLICK', msg.event, msg.payload);
132
+ break;
133
+ case 'event':
134
+ onEvent?.(msg.name, msg.payload);
135
+ break;
136
+ case 'navigate':
137
+ onNavigate?.(msg.href);
138
+ break;
139
+ }
140
+ }, [beacon, onTrack, onEvent, onNavigate, pushData, fillHeight, client, keyName, reportError]);
141
+ if (!html)
142
+ return null;
143
+ // Auto-height: the host feed scrolls, so the WebView sizes to the piece's
144
+ // reported content height and never scrolls itself. Fill mode fills the parent.
145
+ const sizeStyle = fillHeight
146
+ ? { flex: 1 }
147
+ : { width: '100%', height: contentHeight ?? initialHeight };
148
+ return createElement(WebView, {
149
+ ref: webRef,
150
+ source: { html, baseUrl: 'https://localhost/' },
151
+ originWhitelist: ['*'],
152
+ onMessage,
153
+ onError: () => reportError('WebView failed to load'),
154
+ scrollEnabled: fillHeight,
155
+ javaScriptEnabled: true,
156
+ domStorageEnabled: true,
157
+ allowsInlineMediaPlayback: true,
158
+ mediaPlaybackRequiresUserAction: false,
159
+ // Links go to `onNavigate`, never in-WebView navigation.
160
+ onShouldStartLoadWithRequest: (request) => request.url === 'https://localhost/' || request.url.startsWith('about:'),
161
+ style: style ?? { backgroundColor: 'transparent', ...sizeStyle },
162
+ });
163
+ }
164
+ //# sourceMappingURL=BitBitPiece.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BitBitPiece.js","sourceRoot":"","sources":["../../src/react-native-expo/BitBitPiece.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,OAAO,EAA4B,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAoExD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,MAAM,EAAE,UAAU,EAClB,OAAO,EACP,OAAO,EACP,OAAO,EACP,UAAU,EACV,OAAO,EACP,UAAU,GAAG,KAAK,EAClB,aAAa,GAAG,GAAG,EACnB,WAAW,EACX,KAAK,GACY;IACjB,MAAM,aAAa,GAAG,gBAAgB,EAAE,EAAE,MAAwC,CAAC;IACnF,MAAM,MAAM,GAAG,UAAU,IAAI,aAAa,CAAC;IAE3C,+EAA+E;IAC/E,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,MAAM,MAAM,GAAqB,WAAW,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACzF,+EAA+E;IAC/E,gFAAgF;IAChF,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;IAE3B,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,OAAe,EAAE,EAAE;QAClB,IAAI,OAAO;YAAE,OAAO,CAAC,OAAO,CAAC,CAAC;;YACzB,OAAO,CAAC,IAAI,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC5C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACtD,qFAAqF;IACrF,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxE,4EAA4E;IAC5E,iFAAiF;IACjF,MAAM,OAAO,GAAG,MAAM,CAAU,SAAS,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE/B,+EAA+E;IAC/E,4EAA4E;IAC5E,+EAA+E;IAC/E,MAAM,MAAM,GAAG,OAAO,MAAM,EAAE,IAAI,CAAC,oBAAoB,KAAK,UAAU,CAAC;IACvE,MAAM,MAAM,GAAG,WAAW,CACxB,CAAC,IAAsB,EAAE,IAAa,EAAE,OAAiB,EAAE,EAAE;QAC3D,MAAM,EAAE,IAAI;aACT,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;YAC5E,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxB,CAAC,EACD,CAAC,MAAM,EAAE,OAAO,CAAC,CAClB,CAAC;IAEF,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,IAAa,EAAE,EAAE;QAC7C,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAC9B,qCAAqC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CACpE,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,yEAAyE;IACzE,4DAA4D;IAC5D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;QACzB,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;gBAC3D,IAAI,SAAS;oBAAE,OAAO;gBACtB,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC/B,OAAO,CACL,kBAAkB,CAAC;oBACjB,MAAM,EAAE,KAAK,CAAC,SAAS;oBACvB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;oBACxB,UAAU,EAAE,CAAC,UAAU;oBACvB,SAAS,EAAE,MAAM;oBACjB,WAAW,EAAE,SAAS,CAAC,OAAO;iBAC/B,CAAC,CACH,CAAC;gBACF,IAAI,QAAQ,CAAC,OAAO;oBAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,SAAS;oBAAE,WAAW,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAChF,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAEjE,gFAAgF;IAChF,2DAA2D;IAC3D,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAC9B,6CAA6C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAC9E,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,CAAsB,EAAE,EAAE;QACzB,IAAI,GAAkB,CAAC;QACvB,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAkB,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,OAAO;gBACV,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;gBACxB,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;oBAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC7D,MAAM;YACR,KAAK,QAAQ;gBACX,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,GAAG,CAAC;oBAAE,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACxD,MAAM;YACR,KAAK,OAAO;gBACV,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACzB,MAAM;YACR,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;gBACxB,MAAM,OAAO,GAAG,CAAC,GAAkB,EAAE,KAAc,EAAE,EAAE,CACrD,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAC9B,yCAAyC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAChH,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC;gBACjD,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;oBACtC,MAAM;gBACR,CAAC;gBACD,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;qBACjB,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;qBAC3B,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CACtB,OAAO,CAAC,IAAI,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAC3E,CAAC;gBACJ,MAAM;YACR,CAAC;YACD,KAAK,MAAM;gBACT,MAAM,CAAC,MAAM,CAAC,CAAC;gBACf,MAAM;YACR,KAAK,OAAO;gBACV,OAAO,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBAClC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBACxC,MAAM;YACR,KAAK,OAAO;gBACV,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBACjC,MAAM;YACR,KAAK,UAAU;gBACb,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACvB,MAAM;QACV,CAAC;IACH,CAAC,EACD,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAC3F,CAAC;IAEF,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,0EAA0E;IAC1E,gFAAgF;IAChF,MAAM,SAAS,GAAG,UAAU;QAC1B,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;QACb,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,IAAI,aAAa,EAAE,CAAC;IAC9D,OAAO,aAAa,CAAC,OAAO,EAAE;QAC5B,GAAG,EAAE,MAAM;QACX,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE;QAC/C,eAAe,EAAE,CAAC,GAAG,CAAC;QACtB,SAAS;QACT,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,wBAAwB,CAAC;QACpD,aAAa,EAAE,UAAU;QACzB,iBAAiB,EAAE,IAAI;QACvB,iBAAiB,EAAE,IAAI;QACvB,yBAAyB,EAAE,IAAI;QAC/B,+BAA+B,EAAE,KAAK;QACtC,yDAAyD;QACzD,4BAA4B,EAAE,CAAC,OAAwB,EAAE,EAAE,CACzD,OAAO,CAAC,GAAG,KAAK,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;QAC1E,KAAK,EAAE,KAAK,IAAI,EAAE,eAAe,EAAE,aAAa,EAAE,GAAG,SAAS,EAAE;KACjE,CAAC,CAAC;AACL,CAAC"}
@@ -16,5 +16,18 @@
16
16
  export declare function buildBootstrapHtml(params: {
17
17
  bundle: string;
18
18
  theme: Record<string, string>;
19
+ /** Report content height to native (`{ kind: 'height', px }`) and lay the app
20
+ * out at its natural height instead of filling the viewport — for embedding a
21
+ * piece at its own size inside a scrolling host (a feed tile). Defaults to
22
+ * false: fill the WebView height (a full-screen `<BitBitView>`). */
23
+ autoHeight?: boolean;
24
+ /** Expose `ctx.tts(ref)` to the bundle: an audio player calls it on play to mint a streaming
25
+ * URL for the referenced piece content. Requests round-trip to native (`{ kind: 'tts', id,
26
+ * ref }`) and resolve when native injects `window.__bb.resolveTts(id, …)`. Defaults to false —
27
+ * without it `ctx.tts` is undefined and players stay idle. */
28
+ enableTts?: boolean;
29
+ /** The color scheme to render in (`ctx.colorScheme`). The WebView can't read the
30
+ * OS appearance reliably, so native passes it explicitly. Omit for none. */
31
+ colorScheme?: 'light' | 'dark';
19
32
  }): string;
20
33
  //# sourceMappingURL=bootstrapHtml.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrapHtml.d.ts","sourceRoot":"","sources":["../../src/react-native-expo/bootstrapHtml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,GAAG,MAAM,CA8DT"}
1
+ {"version":3,"file":"bootstrapHtml.d.ts","sourceRoot":"","sources":["../../src/react-native-expo/bootstrapHtml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;yEAGqE;IACrE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;mEAG+D;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;iFAC6E;IAC7E,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC,GAAG,MAAM,CA8JT"}
@@ -16,14 +16,12 @@
16
16
  export function buildBootstrapHtml(params) {
17
17
  const bundle = JSON.stringify(params.bundle);
18
18
  const theme = JSON.stringify(params.theme);
19
- return `<!doctype html>
20
- <html>
21
- <head>
22
- <meta charset="utf-8">
23
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover">
24
- <style>
25
- html, body { margin: 0; padding: 0; }
26
- /* Viewport units (not %) so the app fills the WebView height without a
19
+ const autoHeight = params.autoHeight ?? false;
20
+ const enableTts = params.enableTts ?? false;
21
+ const colorScheme = JSON.stringify(params.colorScheme ?? null);
22
+ const rootLayout = autoHeight
23
+ ? `#bb-root { display: flex; flex-direction: column; }`
24
+ : `/* Viewport units (not %) so the app fills the WebView height without a
27
25
  definite parent-height chain, which collapses in a WebView. */
28
26
  body { min-height: 100vh; min-height: 100dvh; }
29
27
  #bb-root {
@@ -33,7 +31,30 @@ export function buildBootstrapHtml(params) {
33
31
  flex-direction: column;
34
32
  }
35
33
  /* Let the mounted app grow to fill the height (still scrolls when taller). */
36
- #bb-root > * { flex: 1 0 auto; }
34
+ #bb-root > * { flex: 1 0 auto; }`;
35
+ // In auto-height mode, mirror the streamed content's size out to native so the
36
+ // host tile can size to it (the app's standard embed-sizing contract).
37
+ const heightReporter = autoHeight
38
+ ? `
39
+ const root = document.getElementById('bb-root');
40
+ let lastHeight = 0;
41
+ const reportHeight = () => {
42
+ const px = Math.ceil(root.getBoundingClientRect().height);
43
+ if (px > 0 && Math.abs(px - lastHeight) >= 2) { lastHeight = px; post({ kind: 'height', px }); }
44
+ };
45
+ if (typeof ResizeObserver !== 'undefined') new ResizeObserver(reportHeight).observe(root);
46
+ if (typeof MutationObserver !== 'undefined')
47
+ new MutationObserver(reportHeight).observe(root, { childList: true, subtree: true, attributes: true });
48
+ [0, 150, 300, 750, 1500].forEach((d) => setTimeout(reportHeight, d));`
49
+ : '';
50
+ return `<!doctype html>
51
+ <html>
52
+ <head>
53
+ <meta charset="utf-8">
54
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover">
55
+ <style>
56
+ html, body { margin: 0; padding: 0; }
57
+ ${rootLayout}
37
58
  * { box-sizing: border-box; }
38
59
  :root { -webkit-tap-highlight-color: transparent; }
39
60
  </style>
@@ -41,18 +62,60 @@ export function buildBootstrapHtml(params) {
41
62
  <body>
42
63
  <div id="bb-root"></div>
43
64
  <script type="module">
44
- const post = (m) => { try { window.ReactNativeWebView.postMessage(JSON.stringify(m)); } catch (e) {} };
45
- const bb = (window.__bb = { theme: ${theme}, mod: null, handle: null, pending: null, viewed: false });
65
+ // Transport out: React Native WebView when hosted natively, else the parent window
66
+ // (a web <iframe> preview). Same message shapes both ways.
67
+ const post = (m) => {
68
+ try { if (window.ReactNativeWebView) { window.ReactNativeWebView.postMessage(JSON.stringify(m)); return; } } catch (e) {}
69
+ try { if (window.parent && window.parent !== window) window.parent.postMessage(m, '*'); } catch (e) {}
70
+ };
71
+ const bb = (window.__bb = { theme: ${theme}, colorScheme: ${colorScheme}, mod: null, handle: null, pending: null, data: undefined, history: undefined, viewed: false, tts: {}, ttsSeq: 0 });
46
72
  const wrap = (h) => (typeof h === 'function' ? { update() {}, unmount: h } : h);
73
+ const applyColorScheme = () => { if (bb.colorScheme) document.documentElement.style.colorScheme = bb.colorScheme; };
74
+ applyColorScheme();
75
+ // An audio player calls ctx.tts(ref) on play; the request round-trips to the host, which mints
76
+ // a streaming URL for the referenced piece content and injects it back via resolveTts.
77
+ const requestTts = (ref) => new Promise((resolve, reject) => {
78
+ const id = ++bb.ttsSeq;
79
+ bb.tts[id] = { resolve, reject };
80
+ post({ kind: 'tts', id, ref });
81
+ });
82
+ bb.resolveTts = (id, url, error) => {
83
+ const p = bb.tts[id];
84
+ if (!p) return;
85
+ delete bb.tts[id];
86
+ if (error || !url) p.reject(new Error(error || 'Could not load audio'));
87
+ else p.resolve(url);
88
+ };
89
+ // Play an HLS URL on every platform: native HLS where the WebView supports it (iOS), else
90
+ // hls.js loaded on demand (Android). Handed to the bundle as ctx.playMedia — a plain <audio src>
91
+ // of an HLS playlist only works on iOS.
92
+ const playMedia = (el, url) => {
93
+ if (el.canPlayType('application/vnd.apple.mpegurl')) {
94
+ el.src = url;
95
+ return () => { el.removeAttribute('src'); el.load(); };
96
+ }
97
+ let destroyed = false; let hls = null;
98
+ import('https://esm.sh/hls.js@1').then((m) => {
99
+ if (destroyed) return;
100
+ const H = m.default || m;
101
+ if (!H || !H.isSupported()) { el.src = url; return; }
102
+ hls = new H(); hls.loadSource(url); hls.attachMedia(el);
103
+ }).catch(() => { if (!destroyed) el.src = url; });
104
+ return () => { destroyed = true; if (hls) { try { hls.destroy(); } catch (e) {} } };
105
+ };
47
106
  const ctx = () => ({
48
107
  theme: bb.theme,
108
+ ...(bb.colorScheme ? { colorScheme: bb.colorScheme } : {}),
49
109
  track: (event, payload) => post({ kind: 'track', event, payload }),
50
110
  onEvent: (name, payload) => post({ kind: 'event', name, payload }),
51
111
  navigate: (href) => post({ kind: 'navigate', href }),
112
+ playMedia,
113
+ ${enableTts ? 'tts: requestTts,' : ''}
52
114
  });
53
115
  // Called by native (injectJavaScript) with each streamed data payload (+ the
54
116
  // optional history array, forwarded into the view's props).
55
117
  bb.update = (data, history) => {
118
+ bb.data = data; bb.history = history;
56
119
  if (!bb.mod) { bb.pending = { data, history }; return; }
57
120
  const el = document.getElementById('bb-root');
58
121
  const props = { data, history, ctx: ctx() };
@@ -60,6 +123,22 @@ bb.update = (data, history) => {
60
123
  bb.handle = wrap(bb.mod.mount(el, props));
61
124
  if (!bb.viewed) { bb.viewed = true; post({ kind: 'view' }); }
62
125
  };
126
+ // Native pushes OS appearance changes here; re-render the mounted view with the
127
+ // new scheme so a dual-mode piece recolors live.
128
+ bb.setColorScheme = (scheme) => {
129
+ bb.colorScheme = scheme || null;
130
+ applyColorScheme();
131
+ if (bb.handle && bb.data !== undefined) bb.handle.update({ data: bb.data, history: bb.history, ctx: ctx() });
132
+ };
133
+ // Transport in for a web <iframe> host (native drives these via injectJavaScript instead).
134
+ window.addEventListener('message', (e) => {
135
+ const m = e.data;
136
+ if (!m || typeof m !== 'object') return;
137
+ if (m.kind === 'update') bb.update(m.data, m.history);
138
+ else if (m.kind === 'setColorScheme') bb.setColorScheme(m.scheme);
139
+ else if (m.kind === 'resolveTts') bb.resolveTts(m.id, m.url, m.error);
140
+ });
141
+ ${heightReporter}
63
142
  (async () => {
64
143
  try {
65
144
  const src = ${bundle};
@@ -70,8 +149,25 @@ bb.update = (data, history) => {
70
149
  if (typeof bb.mod.mount !== 'function') throw new Error('generated bundle has no mount()');
71
150
  post({ kind: 'ready' });
72
151
  if (bb.pending != null) bb.update(bb.pending.data, bb.pending.history);
73
- } catch (e) {}
152
+ } catch (e) {
153
+ post({ kind: 'error', message: (e && e.message) ? e.message : String(e) });
154
+ }
74
155
  })();
156
+ // Surface uncaught errors so native can log them (otherwise the WebView fails
157
+ // silently). Capture phase (3rd arg true) so it also catches media element
158
+ // errors (<audio>/<video> load/decode failures), which don't bubble.
159
+ const MEDIA_ERR = ['', 'ABORTED', 'NETWORK', 'DECODE', 'SRC_NOT_SUPPORTED'];
160
+ window.addEventListener('error', (e) => {
161
+ const t = e.target;
162
+ if (t && (t.tagName === 'AUDIO' || t.tagName === 'VIDEO')) {
163
+ const code = t.error && t.error.code;
164
+ post({ kind: 'error', message: 'media ' + (MEDIA_ERR[code] || 'error') + ' loading ' + (t.currentSrc || t.src || '') });
165
+ return;
166
+ }
167
+ post({ kind: 'error', message: e.message || 'script error' });
168
+ }, true);
169
+ window.addEventListener('unhandledrejection', (e) =>
170
+ post({ kind: 'error', message: (e.reason && e.reason.message) || String(e.reason) }));
75
171
  </script>
76
172
  </body>
77
173
  </html>`;
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrapHtml.js","sourceRoot":"","sources":["../../src/react-native-expo/bootstrapHtml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAGlC;IACC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;qCA0B4B,KAAK;;;;;;;;;;;;;;;;;;;;kBAoBxB,MAAM;;;;;;;;;;;;QAYhB,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"bootstrapHtml.js","sourceRoot":"","sources":["../../src/react-native-expo/bootstrapHtml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAgBlC;IACC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC;IAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,UAAU;QAC3B,CAAC,CAAC,qDAAqD;QACvD,CAAC,CAAC;;;;;;;;;;mCAU6B,CAAC;IAClC,+EAA+E;IAC/E,uEAAuE;IACvE,MAAM,cAAc,GAAG,UAAU;QAC/B,CAAC,CAAC;;;;;;;;;;sEAUgE;QAClE,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;;;;;;;IAOL,UAAU;;;;;;;;;;;;;;qCAcuB,KAAK,kBAAkB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0CnE,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BrC,cAAc;;;kBAGE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6BhB,CAAC;AACT,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export { type BitBitContextValue, BitBitProvider } from '../synthesisUi/context.js';
2
2
  export type { SynthesisUiPlatform, SynthesisUiStreamEvent, SynthesizeUiFetcher, } from '../synthesisUi/types.js';
3
+ export { BitBitPiece, type BitBitPieceFetcher, type BitBitPieceProps, } from './BitBitPiece.js';
3
4
  export { BitBitView, type BitBitViewProps } from './BitBitView.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react-native-expo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpF,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react-native-expo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpF,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export { BitBitProvider } from '../synthesisUi/context.js';
2
+ export { BitBitPiece, } from './BitBitPiece.js';
2
3
  export { BitBitView } from './BitBitView.js';
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react-native-expo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMpF,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react-native-expo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMpF,OAAO,EACL,WAAW,GAGZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAC"}