@xhub-reels/sdk 0.1.7
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/README.md +186 -0
- package/dist/index.cjs +2891 -0
- package/dist/index.d.cts +1075 -0
- package/dist/index.d.ts +1075 -0
- package/dist/index.js +2845 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# @xhub-reels/sdk
|
|
2
|
+
|
|
3
|
+
High-performance Short Video / Reels SDK for React — optimized for Flutter WebView.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@xhub-reels/sdk)
|
|
6
|
+
[](https://bundlephobia.com/package/@xhub-reels/sdk)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
## Why?
|
|
10
|
+
|
|
11
|
+
Built as a leaner, faster alternative focused on solving real-world WebView performance issues:
|
|
12
|
+
|
|
13
|
+
| Problem | Solution |
|
|
14
|
+
|---|---|
|
|
15
|
+
| React state updates during drag → jank | Pointer Events + direct DOM, zero React during drag |
|
|
16
|
+
| `querySelectorAll` per animation frame | MutationObserver slot cache, O(1) lookup |
|
|
17
|
+
| `setTimeout` polling for sync | Single `store.subscribe` |
|
|
18
|
+
| CSS transitions interrupted by React renders | Web Animations API (imperative, cancellable) |
|
|
19
|
+
| Static class-level global cache | Instance-scoped prefetch cache |
|
|
20
|
+
| 1153-line Feed component | Split into focused, testable units |
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @xhub-reels/sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Peer dependencies:**
|
|
29
|
+
```bash
|
|
30
|
+
npm install react react-dom # >=18.0.0
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import {
|
|
37
|
+
ReelsProvider,
|
|
38
|
+
MockDataSource,
|
|
39
|
+
MockInteraction,
|
|
40
|
+
} from '@xhub-reels/sdk';
|
|
41
|
+
import { MyFeed } from './MyFeed';
|
|
42
|
+
|
|
43
|
+
export function App() {
|
|
44
|
+
return (
|
|
45
|
+
<ReelsProvider
|
|
46
|
+
adapters={{
|
|
47
|
+
dataSource: new MockDataSource(),
|
|
48
|
+
interaction: new MockInteraction(),
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
<MyFeed />
|
|
52
|
+
</ReelsProvider>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## With Your Own Data Source
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import type { IDataSource, FeedPage } from '@xhub-reels/sdk';
|
|
61
|
+
|
|
62
|
+
class MyAPIDataSource implements IDataSource {
|
|
63
|
+
async fetchFeed(cursor?: string | null): Promise<FeedPage> {
|
|
64
|
+
const res = await fetch(`/api/feed?cursor=${cursor ?? ''}`);
|
|
65
|
+
const data = await res.json();
|
|
66
|
+
return {
|
|
67
|
+
items: data.videos,
|
|
68
|
+
nextCursor: data.nextCursor,
|
|
69
|
+
hasMore: data.hasMore,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Hooks
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { useFeed, usePlayer, useResource } from '@xhub-reels/sdk';
|
|
79
|
+
|
|
80
|
+
function MyFeed() {
|
|
81
|
+
const { items, loading, loadInitial, loadMore } = useFeed();
|
|
82
|
+
const { focusedIndex, setFocusedIndex, shouldRenderVideo } = useResource();
|
|
83
|
+
const { isPlaying, togglePlay, handlers } = usePlayer();
|
|
84
|
+
|
|
85
|
+
// ...
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Gesture Engine
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { usePointerGesture, useSnapAnimation } from '@xhub-reels/sdk';
|
|
93
|
+
|
|
94
|
+
function SwipeableFeed() {
|
|
95
|
+
const { animateSnap, animateBounceBack } = useSnapAnimation();
|
|
96
|
+
|
|
97
|
+
const { bind } = usePointerGesture({
|
|
98
|
+
onDragOffset: (offset) => {
|
|
99
|
+
// Direct DOM — zero React state during drag
|
|
100
|
+
containerRef.current!.style.transform = `translateY(${offset}px)`;
|
|
101
|
+
},
|
|
102
|
+
onSnap: (direction) => {
|
|
103
|
+
const next = direction === 'forward' ? index + 1 : index - 1;
|
|
104
|
+
goToIndex(next);
|
|
105
|
+
animateSnap(targets);
|
|
106
|
+
},
|
|
107
|
+
onBounceBack: () => animateBounceBack(targets),
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return <div {...bind} style={{ touchAction: 'none' }}>...</div>;
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Architecture
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
@xhub-reels/sdk
|
|
118
|
+
├── types/ ← Pure TypeScript interfaces (no deps)
|
|
119
|
+
├── domain/ ← Business logic (zustand/vanilla, no React)
|
|
120
|
+
│ ├── PlayerEngine — State machine + Circuit Breaker
|
|
121
|
+
│ ├── FeedManager — Pagination, LRU, SWR, dedup
|
|
122
|
+
│ ├── OptimisticManager — Debounced like/follow + rollback
|
|
123
|
+
│ └── ResourceGovernor — Max 3 video DOM nodes
|
|
124
|
+
├── gesture/ ← Pointer Events + Web Animations API
|
|
125
|
+
│ ├── usePointerGesture — Zero React during drag
|
|
126
|
+
│ └── useSnapAnimation — Cancellable snap animation
|
|
127
|
+
├── components/ ← React components
|
|
128
|
+
│ └── ReelsProvider — Context + DI container
|
|
129
|
+
├── hooks/ ← useSyncExternalStore-based hooks
|
|
130
|
+
│ ├── useFeed
|
|
131
|
+
│ ├── usePlayer
|
|
132
|
+
│ └── useResource
|
|
133
|
+
└── adapters/mock/ ← Development mocks
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Performance Targets
|
|
137
|
+
|
|
138
|
+
| Metric | Target |
|
|
139
|
+
|---|---|
|
|
140
|
+
| Bundle size | < 35KB gzip |
|
|
141
|
+
| First video load | < 1s on WiFi |
|
|
142
|
+
| Scroll FPS | 60fps |
|
|
143
|
+
| Max video DOM nodes | 3 |
|
|
144
|
+
| React renders per swipe | 1 (on snap only) |
|
|
145
|
+
|
|
146
|
+
## Bundle Size Limits
|
|
147
|
+
|
|
148
|
+
| Package | Limit |
|
|
149
|
+
|---|---|
|
|
150
|
+
| `@xhub-reels/sdk` | 35KB gzip |
|
|
151
|
+
|
|
152
|
+
## Development
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Install
|
|
156
|
+
npm install
|
|
157
|
+
|
|
158
|
+
# Build package
|
|
159
|
+
npm run build
|
|
160
|
+
|
|
161
|
+
# Run demo app
|
|
162
|
+
npm run dev
|
|
163
|
+
|
|
164
|
+
# Tests
|
|
165
|
+
npm run test
|
|
166
|
+
|
|
167
|
+
# Type check
|
|
168
|
+
npm run typecheck
|
|
169
|
+
|
|
170
|
+
# Lint + format
|
|
171
|
+
npm run lint:fix
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Release
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Bump version
|
|
178
|
+
npm version patch # or minor / major
|
|
179
|
+
|
|
180
|
+
# Tag and push (triggers GitHub Actions publish)
|
|
181
|
+
git tag v0.1.1 && git push --tags
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT
|