@pushframe/sdk 0.1.1 → 0.1.3

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/package.json CHANGED
@@ -1,24 +1,32 @@
1
1
  {
2
2
  "name": "@pushframe/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Pushframe React Native SDK — Server-Driven UI rendering engine",
5
5
  "main": "./dist/index.js",
6
- "module": "./dist/index.mjs",
6
+ "react-native": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
- "import": "./dist/index.mjs",
12
- "require": "./dist/index.js"
11
+ "react-native": "./dist/index.js",
12
+ "require": "./dist/index.js",
13
+ "default": "./dist/index.js"
13
14
  }
14
15
  },
15
16
  "files": [
16
17
  "dist",
17
18
  "README.md"
18
19
  ],
20
+ "scripts": {
21
+ "build": "tsup",
22
+ "dev": "tsup --watch",
23
+ "typecheck": "tsc --noEmit",
24
+ "lint": "eslint src --ext .ts,.tsx"
25
+ },
19
26
  "peerDependencies": {
20
27
  "react": ">=18.0.0",
21
- "react-native": ">=0.73.0"
28
+ "react-native": ">=0.73.0",
29
+ "react-native-safe-area-context": ">=4.0.0"
22
30
  },
23
31
  "devDependencies": {
24
32
  "@types/react": "^18.2.0",
@@ -32,11 +40,5 @@
32
40
  "sdui",
33
41
  "pushframe"
34
42
  ],
35
- "license": "MIT",
36
- "scripts": {
37
- "build": "tsup",
38
- "dev": "tsup --watch",
39
- "typecheck": "tsc --noEmit",
40
- "lint": "eslint src --ext .ts,.tsx"
41
- }
43
+ "license": "MIT"
42
44
  }
package/dist/index.d.mts DELETED
@@ -1,458 +0,0 @@
1
- import * as React from 'react';
2
- import React__default, { ReactNode, ReactElement } from 'react';
3
- import * as react_native from 'react-native';
4
- import { TextProps, ViewProps, ImageProps, PressableProps, TextInputProps, FlatListProps, ModalProps, ActivityIndicatorProps, SwitchProps, KeyboardAvoidingViewProps, StatusBarProps, ScrollViewProps, ScrollView as ScrollView$1 } from 'react-native';
5
- import * as react_jsx_runtime from 'react/jsx-runtime';
6
-
7
- interface PushFrameProviderProps {
8
- /** Pushframe API key — sent as Authorization header on all fetches. */
9
- apiKey: string;
10
- /**
11
- * Runtime data context. Screens/Components bind to this via {{expressions}}.
12
- * Merged at the Provider level; slot-level context wins on conflict.
13
- */
14
- context?: Record<string, unknown>;
15
- /**
16
- * Base URL of the Pushframe delivery service.
17
- * Defaults to the production endpoint: https://api.pushframe.io
18
- */
19
- baseUrl?: string;
20
- /**
21
- * Semver string appended to fetch paths for schema version targeting.
22
- * e.g. "1.2.3" → GET /screens/home/1.2.3
23
- * When not provided, "null" is sent as the appVersion in the URL.
24
- */
25
- appVersion?: string;
26
- /**
27
- * Developer-registered native components merged into the ComponentRegistry.
28
- * Built-in types cannot be overridden — conflicting keys are warned and skipped.
29
- */
30
- components?: Record<string, React__default.ComponentType<unknown>>;
31
- /** Default loading UI shown while schema is fetching or isLoading=true. */
32
- loadingComponent?: ReactNode;
33
- /** Default fallback UI shown on fetch error or unknown component type. */
34
- fallbackComponent?: ReactNode;
35
- /**
36
- * Global action handler. Receives actions that are not handled as built-ins
37
- * and were not stopped by a slot-level onAction.
38
- */
39
- onAction?: (action: string, payload?: Record<string, unknown>) => void;
40
- /** Called whenever a fetch or render error occurs. */
41
- onError?: (error: Error) => void;
42
- children: ReactNode;
43
- }
44
- /**
45
- * Root provider for the PushFrame SDK.
46
- *
47
- * Wrap your app (or a subtree) in this provider. All PushFrame.Screen and
48
- * PushFrame.Component slots inside will fetch their schemas from the delivery
49
- * service and render them using the shared ComponentRegistry and context.
50
- *
51
- * Also renders the ToastHost and BottomSheetHost overlay hosts at root level
52
- * so any component in the tree can trigger them via built-in actions.
53
- */
54
- declare function PushFrameProvider({ apiKey, context, baseUrl, appVersion, components, loadingComponent, fallbackComponent, onAction, onError, children, }: PushFrameProviderProps): react_jsx_runtime.JSX.Element;
55
-
56
- interface PushFrameSlotProps {
57
- /** ID of the screen/component to fetch from the delivery service. */
58
- id: string;
59
- /**
60
- * Data context local to this slot. Merged with the Provider context;
61
- * local keys win on conflict.
62
- */
63
- context?: Record<string, unknown>;
64
- /**
65
- * External loading signal from the host app. When true, loading UI is shown
66
- * even if the schema has already been fetched.
67
- */
68
- isLoading?: boolean;
69
- /**
70
- * Loading UI shown while isLoading=true OR schema is being fetched.
71
- * Falls back to Provider-level loadingComponent.
72
- */
73
- loadingComponent?: ReactNode;
74
- /**
75
- * Fallback UI shown on fetch error or unresolvable component type.
76
- * Falls back to Provider-level fallbackComponent.
77
- */
78
- fallbackComponent?: ReactNode;
79
- /**
80
- * Slot-level action handler. Return true to stop the action from bubbling
81
- * to the Provider-level onAction.
82
- */
83
- onAction?: (action: string, payload?: Record<string, unknown>) => boolean | void;
84
- }
85
- /**
86
- * Fetches a component schema from GET /components/:id[/:appVersion] on the
87
- * delivery service and renders it inline using RecursiveRenderer.
88
- *
89
- * Context is merged: Provider context → slot context (local wins).
90
- * Actions bubble: slot onAction → Provider onAction.
91
- * Built-in actions (show-toast, show-bottom-sheet, etc.) are handled internally.
92
- */
93
- declare function PushFrameComponent(props: PushFrameSlotProps): react_jsx_runtime.JSX.Element;
94
-
95
- /**
96
- * Fetches a screen schema from GET /screens/:id[/:appVersion] on the delivery
97
- * service and renders it with flex:1 sizing (full-page layout).
98
- *
99
- * Identical to PushFrame.Component in behaviour, but:
100
- * - Fetches from /screens/:id instead of /components/:id
101
- * - Applies flex:1 to its container so it fills the available space
102
- *
103
- * Context is merged: Provider context → slot context (local wins).
104
- * Actions bubble: slot onAction → Provider onAction.
105
- * Built-in actions (show-toast, show-bottom-sheet, etc.) are handled internally.
106
- */
107
- declare function PushFrameScreen(props: PushFrameSlotProps): react_jsx_runtime.JSX.Element;
108
-
109
- /**
110
- * Maps component type strings to React components.
111
- *
112
- * Built-ins are always present and cannot be overridden.
113
- * Developer-registered components are merged on top for non-conflicting types.
114
- */
115
- declare class ComponentRegistry {
116
- private readonly components;
117
- constructor(developerComponents?: Record<string, React__default.ComponentType<unknown>>);
118
- /**
119
- * Resolve a type string to its React component.
120
- * Returns null if no component is registered for the type.
121
- */
122
- resolve(type: string): React__default.ComponentType<Record<string, unknown>> | null;
123
- /**
124
- * Returns all registered type strings (useful for debugging).
125
- */
126
- types(): string[];
127
- }
128
-
129
- interface SchemaNode {
130
- type: string;
131
- props?: Record<string, unknown>;
132
- children?: SchemaNode[];
133
- actions?: Action[];
134
- if?: string;
135
- }
136
- interface FlatListSchemaNode extends SchemaNode {
137
- type: 'flatlist';
138
- renderItem: SchemaNode;
139
- }
140
- interface Action {
141
- trigger: string;
142
- action: string;
143
- payload?: Record<string, unknown>;
144
- }
145
- interface ToastPayload {
146
- message: string;
147
- duration?: number;
148
- type?: 'success' | 'error' | 'info' | 'warning';
149
- }
150
- interface BottomSheetPayload {
151
- schema: SchemaNode;
152
- context?: Record<string, unknown>;
153
- }
154
- interface ScrollToPayload {
155
- x?: number;
156
- y?: number;
157
- animated?: boolean;
158
- }
159
- interface PushFrameContextValue {
160
- apiKey: string;
161
- baseUrl: string;
162
- appVersion?: string;
163
- globalContext: Record<string, unknown>;
164
- registry: ComponentRegistry;
165
- loadingComponent?: React__default.ReactNode;
166
- fallbackComponent?: React__default.ReactNode;
167
- onAction?: (action: string, payload?: Record<string, unknown>) => void;
168
- onError?: (error: Error) => void;
169
- showToast: (payload: ToastPayload) => void;
170
- showBottomSheet: (payload: BottomSheetPayload) => void;
171
- dismissBottomSheet: () => void;
172
- }
173
- declare const PushFrameContext: React__default.Context<PushFrameContextValue | null>;
174
- declare function usePushFrameContext(): PushFrameContextValue;
175
-
176
- interface PushFrameTextProps extends TextProps {
177
- /** Pushframe: hidden by RecursiveRenderer before component renders. */
178
- if?: string;
179
- /** Pushframe: converted to handlers by RecursiveRenderer before component renders. */
180
- actions?: Action[];
181
- /**
182
- * Text content via binding. If provided, takes precedence over children.
183
- * Pushframe-specific — resolved to a string by the time the component renders.
184
- */
185
- value?: string;
186
- }
187
- /**
188
- * Thin wrapper over React Native Text.
189
- * Strips `if`, `actions` before forwarding to RN.
190
- * `value` takes precedence over `children` when both are present.
191
- */
192
- declare function Text({ if: _if, actions: _actions, value, children, ...rest }: PushFrameTextProps): react_jsx_runtime.JSX.Element;
193
-
194
- interface PushFrameViewProps extends ViewProps {
195
- if?: string;
196
- actions?: Action[];
197
- }
198
- /**
199
- * Thin wrapper over React Native View.
200
- * Strips `if`, `actions` before forwarding to RN.
201
- */
202
- declare function View({ if: _if, actions: _actions, ...rest }: PushFrameViewProps): react_jsx_runtime.JSX.Element;
203
-
204
- interface PushFrameImageProps extends Omit<ImageProps, 'source'> {
205
- if?: string;
206
- actions?: Action[];
207
- /**
208
- * URI string for the image source. Maps to RN `source={{ uri: src }}`.
209
- * Takes precedence over the base `source` prop.
210
- */
211
- src?: string;
212
- /** Pass-through for cases where a static require() source is needed. */
213
- source?: ImageProps['source'];
214
- }
215
- /**
216
- * Thin wrapper over React Native Image.
217
- * `src` maps to `source={{ uri: src }}`.
218
- * Strips `if`, `actions`, `src` before forwarding to RN.
219
- */
220
- declare function Image({ if: _if, actions: _actions, src, source, ...rest }: PushFrameImageProps): react_jsx_runtime.JSX.Element;
221
-
222
- interface PushFramePressableProps extends PressableProps {
223
- if?: string;
224
- actions?: Action[];
225
- }
226
- /**
227
- * Thin wrapper over React Native Pressable.
228
- * Actions with trigger "onPress" and "onLongPress" are wired by RecursiveRenderer
229
- * and forwarded through as standard RN props.
230
- * Strips `if`, `actions` before forwarding to RN.
231
- */
232
- declare function Pressable({ if: _if, actions: _actions, ...rest }: PushFramePressableProps): react_jsx_runtime.JSX.Element;
233
-
234
- interface PushFrameTextInputProps extends Omit<TextInputProps, 'onChange'> {
235
- if?: string;
236
- actions?: Action[];
237
- /**
238
- * Schema trigger "onChange" — wired by RecursiveRenderer.
239
- * Mapped to RN `onChangeText` by this component.
240
- */
241
- onChange?: (text: string) => void;
242
- /**
243
- * Schema trigger "onSubmit" — wired by RecursiveRenderer.
244
- * Mapped to RN `onSubmitEditing` by this component.
245
- */
246
- onSubmit?: () => void;
247
- }
248
- /**
249
- * Thin wrapper over React Native TextInput.
250
- * Maps Pushframe schema triggers to RN event props:
251
- * onChange → onChangeText
252
- * onSubmit → onSubmitEditing
253
- * Strips `if`, `actions`, `onChange`, `onSubmit` before forwarding to RN.
254
- */
255
- declare function TextInput({ if: _if, actions: _actions, onChange, onSubmit, ...rest }: PushFrameTextInputProps): react_jsx_runtime.JSX.Element;
256
-
257
- interface PushFrameFlatListProps<T = unknown> extends Omit<FlatListProps<T>, 'data' | 'horizontal'> {
258
- if?: string;
259
- actions?: Action[];
260
- /**
261
- * Resolved array of items. Populated by RecursiveRenderer from the
262
- * `items` binding expression on the schema node.
263
- */
264
- items?: T[];
265
- /**
266
- * "vertical" (default) or "horizontal". Maps to RN `horizontal` boolean.
267
- */
268
- direction?: 'vertical' | 'horizontal';
269
- /**
270
- * Number of columns for grid layouts. Forwarded directly to RN FlatList.
271
- */
272
- numColumns?: number;
273
- }
274
- /**
275
- * Thin wrapper over React Native FlatList.
276
- * RecursiveRenderer handles this type specially — it resolves `items` from
277
- * a binding expression and constructs the `renderItem` per-item context.
278
- *
279
- * This component maps Pushframe props to RN FlatList props and strips
280
- * Pushframe-specific props before forwarding.
281
- */
282
- declare function FlatList<T = unknown>({ if: _if, actions: _actions, items, direction, numColumns, ...rest }: PushFrameFlatListProps<T>): react_jsx_runtime.JSX.Element;
283
-
284
- interface PushFrameModalProps extends ModalProps {
285
- if?: string;
286
- actions?: Action[];
287
- }
288
- /**
289
- * Thin wrapper over React Native Modal.
290
- * Strips `if`, `actions` before forwarding to RN.
291
- */
292
- declare function Modal({ if: _if, actions: _actions, ...rest }: PushFrameModalProps): react_jsx_runtime.JSX.Element;
293
-
294
- interface PushFrameActivityIndicatorProps extends ActivityIndicatorProps {
295
- if?: string;
296
- actions?: Action[];
297
- }
298
- /**
299
- * Thin wrapper over React Native ActivityIndicator.
300
- * Strips `if`, `actions` before forwarding to RN.
301
- */
302
- declare function ActivityIndicator({ if: _if, actions: _actions, ...rest }: PushFrameActivityIndicatorProps): react_jsx_runtime.JSX.Element;
303
-
304
- interface PushFrameSwitchProps extends Omit<SwitchProps, 'onValueChange' | 'onChange'> {
305
- if?: string;
306
- actions?: Action[];
307
- /**
308
- * Schema trigger "onChange" — wired by RecursiveRenderer.
309
- * Mapped to RN `onValueChange` by this component.
310
- */
311
- onChange?: (value: boolean) => void;
312
- }
313
- /**
314
- * Thin wrapper over React Native Switch.
315
- * Maps Pushframe schema trigger to RN event prop:
316
- * onChange → onValueChange
317
- * Strips `if`, `actions`, `onChange` before forwarding to RN.
318
- */
319
- declare function Switch({ if: _if, actions: _actions, onChange, ...rest }: PushFrameSwitchProps): react_jsx_runtime.JSX.Element;
320
-
321
- interface PushFrameKeyboardAvoidingViewProps extends KeyboardAvoidingViewProps {
322
- if?: string;
323
- actions?: Action[];
324
- }
325
- /**
326
- * Thin wrapper over React Native KeyboardAvoidingView.
327
- * Strips `if`, `actions` before forwarding to RN.
328
- */
329
- declare function KeyboardAvoidingView({ if: _if, actions: _actions, ...rest }: PushFrameKeyboardAvoidingViewProps): react_jsx_runtime.JSX.Element;
330
-
331
- interface PushFrameSafeAreaViewProps extends ViewProps {
332
- if?: string;
333
- actions?: Action[];
334
- }
335
- /**
336
- * Thin wrapper over SafeAreaView.
337
- * Uses react-native-safe-area-context when available, RN core otherwise.
338
- * Strips `if`, `actions` before forwarding to the underlying component.
339
- */
340
- declare function SafeAreaView({ if: _if, actions: _actions, ...rest }: PushFrameSafeAreaViewProps): react_jsx_runtime.JSX.Element;
341
-
342
- interface PushFrameStatusBarProps extends StatusBarProps {
343
- if?: string;
344
- actions?: Action[];
345
- }
346
- /**
347
- * Thin wrapper over React Native StatusBar.
348
- * Strips `if`, `actions` before forwarding to RN.
349
- */
350
- declare function StatusBar({ if: _if, actions: _actions, ...rest }: PushFrameStatusBarProps): react_jsx_runtime.JSX.Element;
351
-
352
- interface DispatchAction {
353
- (actionName: string, payload?: Record<string, unknown>): void;
354
- }
355
- interface RecursiveRendererProps {
356
- node: SchemaNode;
357
- /** Current merged data context for binding resolution. */
358
- context: Record<string, unknown>;
359
- registry: ComponentRegistry;
360
- /** Handles all actions — built-ins and host-app bubbling. Provided by the slot component. */
361
- dispatchAction: DispatchAction;
362
- /** Shown when a component type is not found in the registry. */
363
- fallbackComponent?: React__default.ReactNode;
364
- }
365
- /**
366
- * Stateless recursive renderer. Evaluates schema nodes and produces React elements.
367
- *
368
- * - Evaluates `if` expression; returns null when falsy
369
- * - Handles FlatList nodes with per-item context injection
370
- * - Resolves all prop bindings against current context
371
- * - Wires actions to component event handler props
372
- * - Looks up component in registry; renders fallback or null when not found
373
- * - Recurses into children
374
- */
375
- declare function RecursiveRenderer({ node, context, registry, dispatchAction, fallbackComponent, }: RecursiveRendererProps): ReactElement | null;
376
-
377
- /**
378
- * Binding resolver for PushFrame {{expression}} syntax.
379
- *
380
- * Rules:
381
- * - A value that is entirely "{{expr}}" resolves to the bound value (any type)
382
- * - A value with inline bindings "Hello {{user.name}}" resolves to a string
383
- * - Unresolved paths return undefined — never throws
384
- * - Non-string values are returned as-is
385
- */
386
- /**
387
- * Resolve a single prop value against context.
388
- *
389
- * - String values: check for full binding "{{expr}}" or inline bindings "Hello {{name}}"
390
- * - Non-string values: returned as-is
391
- */
392
- declare function resolveValue(value: unknown, context: Record<string, unknown>): unknown;
393
- /**
394
- * Resolve all values in a props map against the context.
395
- * Recursively resolves nested objects and arrays.
396
- */
397
- declare function resolveProps(props: Record<string, unknown> | undefined, context: Record<string, unknown>): Record<string, unknown>;
398
- /**
399
- * Recursively resolve binding expressions in a value (including nested objects/arrays).
400
- */
401
- declare function resolveDeep(value: unknown, context: Record<string, unknown>): unknown;
402
-
403
- /**
404
- * Evaluate the `if` expression of a SchemaNode against the current context.
405
- *
406
- * Returns true → node should render
407
- * Returns false → node (and its entire subtree) should be skipped
408
- *
409
- * Falsy values: false, null, undefined, 0, "" all hide the node.
410
- * When `ifExpr` is undefined the node always renders.
411
- */
412
- declare function evaluateIf(ifExpr: string | undefined, context: Record<string, unknown>): boolean;
413
-
414
- interface PushFrameScrollViewProps extends ScrollViewProps {
415
- if?: string;
416
- actions?: Action[];
417
- }
418
- /**
419
- * Thin wrapper over React Native ScrollView.
420
- * Forwards ref to support programmatic scrolling (e.g. scroll-to action).
421
- * Strips `if`, `actions` before forwarding to RN.
422
- */
423
- declare const ScrollView: React__default.ForwardRefExoticComponent<PushFrameScrollViewProps & React__default.RefAttributes<ScrollView$1>>;
424
-
425
- /**
426
- * The PushFrame namespace. Import this as the single entry-point for the SDK.
427
- *
428
- * Slot components:
429
- * - PushFrame.Provider — wraps the app, initialises registry and context
430
- * - PushFrame.Screen — full-page slot (fetches /screens/:name, applies flex:1)
431
- * - PushFrame.Component — inline slot (fetches /components/:name)
432
- *
433
- * Primitives (used internally by RecursiveRenderer, available for direct use):
434
- * - PushFrame.Text, PushFrame.View, PushFrame.ScrollView, PushFrame.Image
435
- * - PushFrame.Pressable, PushFrame.TextInput, PushFrame.FlatList
436
- * - PushFrame.Modal, PushFrame.ActivityIndicator, PushFrame.Switch
437
- * - PushFrame.KeyboardAvoidingView, PushFrame.SafeAreaView, PushFrame.StatusBar
438
- */
439
- declare const PushFrame: {
440
- readonly Provider: typeof PushFrameProvider;
441
- readonly Screen: typeof PushFrameScreen;
442
- readonly Component: typeof PushFrameComponent;
443
- readonly Text: typeof Text;
444
- readonly View: typeof View;
445
- readonly ScrollView: React.ForwardRefExoticComponent<PushFrameScrollViewProps & React.RefAttributes<react_native.ScrollView>>;
446
- readonly Image: typeof Image;
447
- readonly Pressable: typeof Pressable;
448
- readonly TextInput: typeof TextInput;
449
- readonly FlatList: typeof FlatList;
450
- readonly Modal: typeof Modal;
451
- readonly ActivityIndicator: typeof ActivityIndicator;
452
- readonly Switch: typeof Switch;
453
- readonly KeyboardAvoidingView: typeof KeyboardAvoidingView;
454
- readonly SafeAreaView: typeof SafeAreaView;
455
- readonly StatusBar: typeof StatusBar;
456
- };
457
-
458
- export { type Action, ActivityIndicator, type BottomSheetPayload, ComponentRegistry, type DispatchAction, FlatList, type FlatListSchemaNode, Image, KeyboardAvoidingView, Modal, Pressable, PushFrame, type PushFrameActivityIndicatorProps, PushFrameComponent, PushFrameContext, type PushFrameContextValue, type PushFrameFlatListProps, type PushFrameImageProps, type PushFrameKeyboardAvoidingViewProps, type PushFrameModalProps, type PushFramePressableProps, PushFrameProvider, type PushFrameProviderProps, type PushFrameSafeAreaViewProps, PushFrameScreen, type PushFrameScrollViewProps, type PushFrameSlotProps, type PushFrameStatusBarProps, type PushFrameSwitchProps, type PushFrameTextInputProps, type PushFrameTextProps, type PushFrameViewProps, RecursiveRenderer, type RecursiveRendererProps, SafeAreaView, type SchemaNode, type ScrollToPayload, ScrollView, StatusBar, Switch, Text, TextInput, type ToastPayload, View, evaluateIf, resolveDeep, resolveProps, resolveValue, usePushFrameContext };