@boldvideo/bold-js 0.5.0 → 0.6.1

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/index.js ADDED
@@ -0,0 +1,265 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+
41
+ // src/lib/client.ts
42
+ import axios from "axios";
43
+
44
+ // src/lib/fetchers.ts
45
+ function get(client, url) {
46
+ return __async(this, null, function* () {
47
+ try {
48
+ const res = yield client.get(url);
49
+ if (res.status !== 200) {
50
+ throw new Error(`Unexpected response status: ${res.status}`);
51
+ }
52
+ return res.data;
53
+ } catch (error) {
54
+ console.error(`Error fetching data from URL: ${url}`, error);
55
+ throw error;
56
+ }
57
+ });
58
+ }
59
+ function fetchSettings(client) {
60
+ return (videoLimit = 12) => __async(this, null, function* () {
61
+ try {
62
+ return yield get(
63
+ client,
64
+ `settings?limit=${videoLimit}`
65
+ );
66
+ } catch (error) {
67
+ console.error(`Error fetching settings with limit: ${videoLimit}`, error);
68
+ throw error;
69
+ }
70
+ });
71
+ }
72
+ function fetchVideos(client) {
73
+ return (videoLimit = 12) => __async(this, null, function* () {
74
+ try {
75
+ return yield get(
76
+ client,
77
+ `videos/latest?limit=${videoLimit}`
78
+ );
79
+ } catch (error) {
80
+ console.error(`Error fetching videos with limit: ${videoLimit}`, error);
81
+ throw error;
82
+ }
83
+ });
84
+ }
85
+ function searchVideos(client) {
86
+ return (term) => __async(this, null, function* () {
87
+ try {
88
+ return yield get(client, `videos?query=${term}`);
89
+ } catch (error) {
90
+ console.error(`Error searching for videos with term: ${term}`, error);
91
+ throw error;
92
+ }
93
+ });
94
+ }
95
+ function fetchVideo(client) {
96
+ return (id) => __async(this, null, function* () {
97
+ try {
98
+ return yield get(client, `videos/${id}`);
99
+ } catch (error) {
100
+ console.error(`Error fetching video with ID: ${id}`, error);
101
+ throw error;
102
+ }
103
+ });
104
+ }
105
+ function fetchPlaylists(client) {
106
+ return () => __async(this, null, function* () {
107
+ try {
108
+ return yield get(client, "playlists");
109
+ } catch (error) {
110
+ console.error("Error fetching playlists", error);
111
+ throw error;
112
+ }
113
+ });
114
+ }
115
+ function fetchPlaylist(client) {
116
+ return (id) => __async(this, null, function* () {
117
+ try {
118
+ return yield get(client, `playlists/${id}`);
119
+ } catch (error) {
120
+ console.error(`Error fetching playlist with ID: ${id}`, error);
121
+ throw error;
122
+ }
123
+ });
124
+ }
125
+
126
+ // src/util/throttle.ts
127
+ var throttle = (fn, delay) => {
128
+ let wait = false;
129
+ let timeout;
130
+ let cancelled = false;
131
+ return [
132
+ (...args) => {
133
+ if (cancelled)
134
+ return void 0;
135
+ if (wait)
136
+ return void 0;
137
+ const val = fn(...args);
138
+ wait = true;
139
+ timeout = window.setTimeout(() => {
140
+ wait = false;
141
+ }, delay);
142
+ return val;
143
+ },
144
+ () => {
145
+ cancelled = true;
146
+ clearTimeout(timeout);
147
+ }
148
+ ];
149
+ };
150
+
151
+ // src/lib/tracking.ts
152
+ function sendEvent(client, eventName, data, debug) {
153
+ const payload = {
154
+ n: eventName,
155
+ u: data.url,
156
+ usr: data.userId,
157
+ d: data.domain,
158
+ ua: data.userAgent,
159
+ w: data.deviceWidth,
160
+ vid: (data == null ? void 0 : data.videoId) || void 0,
161
+ vt: data.title,
162
+ vdur: (data == null ? void 0 : data.videoDuration) || void 0,
163
+ time: (data == null ? void 0 : data.currentTime) || void 0
164
+ };
165
+ if (debug)
166
+ console.log(`Bold SDK - Logging event '${eventName}'`, payload);
167
+ client.post("/event", payload);
168
+ }
169
+ var [throttledSendEvent] = throttle(sendEvent, 5e3);
170
+ function trackEvent(client, userId, options) {
171
+ return (video, event) => {
172
+ var _a;
173
+ const eventDetails = __spreadProps(__spreadValues({}, basicInfos()), {
174
+ userId,
175
+ videoId: video.id,
176
+ title: video.title,
177
+ videoDuration: video.duration,
178
+ currentTime: ((_a = event.target) == null ? void 0 : _a.currentTime) || 0
179
+ });
180
+ if (event.type == "timeupdate" || event.type == "time-update") {
181
+ throttledSendEvent(
182
+ client,
183
+ getEventName(event),
184
+ eventDetails,
185
+ options.debug
186
+ );
187
+ } else {
188
+ sendEvent(client, getEventName(event), eventDetails, options.debug);
189
+ }
190
+ };
191
+ }
192
+ function trackPageView(client, userId, options) {
193
+ return (title) => {
194
+ const eventDetails = __spreadProps(__spreadValues({}, basicInfos()), {
195
+ userId,
196
+ title
197
+ });
198
+ sendEvent(client, "page_view", eventDetails, options.debug);
199
+ };
200
+ }
201
+ function getEventName(event) {
202
+ switch (event.type) {
203
+ case "pause":
204
+ return "video_pause";
205
+ case "play":
206
+ return "video_resume";
207
+ case "loadedmetadata":
208
+ case "loaded-metadata":
209
+ return "video_load";
210
+ case "time-update":
211
+ case "timeupdate":
212
+ return "video_progress";
213
+ default:
214
+ return "unknown_event";
215
+ }
216
+ }
217
+ function basicInfos() {
218
+ return {
219
+ url: location.href,
220
+ domain: location.hostname,
221
+ referrer: document.referrer || null,
222
+ deviceWidth: window.innerWidth,
223
+ userAgent: navigator.userAgent
224
+ };
225
+ }
226
+
227
+ // src/lib/client.ts
228
+ function createClient(apiKey, options = { debug: false }) {
229
+ var _a;
230
+ if (!apiKey || typeof apiKey !== "string") {
231
+ throw new Error("API key is missing or invalid");
232
+ }
233
+ const { debug } = options;
234
+ const apiClientOptions = {
235
+ baseURL: (_a = options.baseURL) != null ? _a : "https://app.boldvideo.io/api/v1/",
236
+ headers: {
237
+ Authorization: apiKey
238
+ }
239
+ };
240
+ let apiClient;
241
+ try {
242
+ apiClient = axios.create(apiClientOptions);
243
+ } catch (error) {
244
+ console.error("Error creating API client", error);
245
+ throw error;
246
+ }
247
+ const userId = [...Array(30)].map(() => Math.random().toString(36)[2]).join("");
248
+ return {
249
+ settings: fetchSettings(apiClient),
250
+ videos: {
251
+ list: fetchVideos(apiClient),
252
+ get: fetchVideo(apiClient),
253
+ search: searchVideos(apiClient)
254
+ },
255
+ playlists: {
256
+ list: fetchPlaylists(apiClient),
257
+ get: fetchPlaylist(apiClient)
258
+ },
259
+ trackEvent: trackEvent(apiClient, userId, { debug }),
260
+ trackPageView: trackPageView(apiClient, userId, { debug })
261
+ };
262
+ }
263
+ export {
264
+ createClient
265
+ };
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@boldvideo/bold-js",
3
3
  "license": "MIT",
4
- "version": "0.5.0",
4
+ "version": "0.6.1",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "type": "module",
9
+ "engines": {
10
+ "node": ">=20.0.0"
11
+ },
9
12
  "repository": {
10
13
  "type": "git",
11
14
  "url": "https://github.com/boldvideo/bold-js"
@@ -1,8 +0,0 @@
1
- # Changesets
2
-
3
- Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
- with multi-package repos, or single-package repos to help you version and publish your code. You can
5
- find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
-
7
- We have a quick list of common questions to get you started engaging with this project in
8
- [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
3
- "changelog": "@changesets/cli/changelog",
4
- "commit": false,
5
- "fixed": [],
6
- "linked": [],
7
- "access": "restricted",
8
- "baseBranch": "main",
9
- "updateInternalDependencies": "patch",
10
- "ignore": []
11
- }
@@ -1,11 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: "npm"
4
- directory: "/"
5
- schedule:
6
- interval: "weekly"
7
- open-pull-requests-limit: 10
8
- groups:
9
- dependencies:
10
- patterns:
11
- - "*"
@@ -1,21 +0,0 @@
1
- name: CI
2
- on:
3
- push:
4
- branches:
5
- - "**"
6
-
7
- jobs:
8
- build:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - uses: actions/checkout@v3
12
- - uses: pnpm/action-setup@v2
13
- with:
14
- version: 7
15
- - uses: actions/setup-node@v3
16
- with:
17
- node-version: 16.x
18
- cache: "pnpm"
19
-
20
- - run: pnpm install --frozen-lockfile
21
- - run: pnpm run lint && pnpm run build
@@ -1,29 +0,0 @@
1
- name: Publish
2
- on:
3
- push:
4
- branches:
5
- - "main"
6
-
7
- concurrency: ${{ github.workflow }}-${{ github.ref }}
8
-
9
- jobs:
10
- build:
11
- runs-on: ubuntu-latest
12
- steps:
13
- - uses: actions/checkout@v3
14
- - uses: pnpm/action-setup@v2
15
- with:
16
- version: 7
17
- - uses: actions/setup-node@v3
18
- with:
19
- node-version: 16.x
20
- cache: "pnpm"
21
-
22
- - run: pnpm install --frozen-lockfile
23
- - name: Create Release Pull Request or Publish
24
- id: changesets
25
- uses: changesets/action@v1
26
- with:
27
- publish: pnpm run build
28
- env:
29
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1,51 +0,0 @@
1
- name: Changeset Release
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
-
8
- concurrency: ${{ github.workflow }}-${{ github.ref }}
9
-
10
- permissions:
11
- contents: write
12
- pull-requests: write
13
- id-token: write # For npm provenance
14
-
15
- jobs:
16
- release:
17
- name: Release
18
- runs-on: ubuntu-latest
19
- steps:
20
- - name: Checkout code
21
- uses: actions/checkout@v4
22
- with:
23
- fetch-depth: 0
24
-
25
- - name: Install pnpm
26
- uses: pnpm/action-setup@v2
27
- with:
28
- version: 10.12.2
29
-
30
- - name: Setup Node.js
31
- uses: actions/setup-node@v4
32
- with:
33
- node-version: 20.x
34
- cache: 'pnpm'
35
- registry-url: 'https://registry.npmjs.org'
36
-
37
- - name: Install dependencies
38
- run: pnpm install --frozen-lockfile
39
-
40
- - name: Create Release Pull Request or Publish to npm
41
- id: changesets
42
- uses: changesets/action@v1
43
- with:
44
- title: "chore: release package"
45
- commit: "chore: release package"
46
- publish: pnpm changeset publish
47
- createGithubReleases: true
48
- env:
49
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
51
- NPM_CONFIG_PROVENANCE: true
@@ -1,88 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [ main ]
6
- pull_request:
7
- branches: [ main ]
8
-
9
- jobs:
10
- test:
11
- name: Test on Node ${{ matrix.node-version }}
12
- runs-on: ubuntu-latest
13
-
14
- strategy:
15
- matrix:
16
- node-version: [16.x, 18.x, 20.x]
17
-
18
- steps:
19
- - name: Checkout code
20
- uses: actions/checkout@v4
21
-
22
- - name: Install pnpm
23
- uses: pnpm/action-setup@v2
24
- with:
25
- version: 10.12.2
26
-
27
- - name: Use Node.js ${{ matrix.node-version }}
28
- uses: actions/setup-node@v4
29
- with:
30
- node-version: ${{ matrix.node-version }}
31
- cache: 'pnpm'
32
-
33
- - name: Install dependencies
34
- run: pnpm install --frozen-lockfile
35
-
36
- - name: Run linter
37
- run: pnpm run lint
38
-
39
- - name: Build package
40
- run: pnpm run build
41
-
42
- - name: Check package exports
43
- run: |
44
- node -e "const pkg = require('./dist/index.cjs'); console.log('CJS import successful');"
45
- node -e "import('./dist/index.js').then(() => console.log('ESM import successful'));"
46
-
47
- - name: Check TypeScript declarations
48
- run: |
49
- if [ ! -f "dist/index.d.ts" ]; then
50
- echo "TypeScript declarations not found!"
51
- exit 1
52
- fi
53
-
54
- size-check:
55
- name: Bundle Size Check
56
- runs-on: ubuntu-latest
57
-
58
- steps:
59
- - name: Checkout code
60
- uses: actions/checkout@v4
61
-
62
- - name: Install pnpm
63
- uses: pnpm/action-setup@v2
64
- with:
65
- version: 10.12.2
66
-
67
- - name: Use Node.js
68
- uses: actions/setup-node@v4
69
- with:
70
- node-version: 20.x
71
- cache: 'pnpm'
72
-
73
- - name: Install dependencies
74
- run: pnpm install --frozen-lockfile
75
-
76
- - name: Build package
77
- run: pnpm run build
78
-
79
- - name: Check bundle size
80
- run: |
81
- echo "Bundle sizes:"
82
- ls -lh dist/
83
-
84
- # Warn if bundle exceeds 50KB (adjust threshold as needed)
85
- size=$(stat -c%s dist/index.js 2>/dev/null || stat -f%z dist/index.js)
86
- if [ $size -gt 51200 ]; then
87
- echo "⚠️ Warning: Bundle size exceeds 50KB"
88
- fi
@@ -1,83 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- push:
5
- tags:
6
- - 'v*'
7
-
8
- permissions:
9
- contents: read
10
- id-token: write # For npm provenance
11
-
12
- jobs:
13
- release:
14
- name: Release to npm
15
- runs-on: ubuntu-latest
16
-
17
- steps:
18
- - name: Checkout code
19
- uses: actions/checkout@v4
20
- with:
21
- fetch-depth: 0 # Needed for changelog generation
22
-
23
- - name: Install pnpm
24
- uses: pnpm/action-setup@v2
25
- with:
26
- version: 10.12.2
27
-
28
- - name: Setup Node.js
29
- uses: actions/setup-node@v4
30
- with:
31
- node-version: 20.x
32
- cache: 'pnpm'
33
- registry-url: 'https://registry.npmjs.org'
34
-
35
- - name: Install dependencies
36
- run: pnpm install --frozen-lockfile
37
-
38
- - name: Run CI checks
39
- run: |
40
- pnpm run lint
41
- pnpm run build
42
-
43
- - name: Verify version matches tag
44
- run: |
45
- PACKAGE_VERSION="v$(node -p "require('./package.json').version")"
46
- if [ "$PACKAGE_VERSION" != "${{ github.ref_name }}" ]; then
47
- echo "Error: Package version ($PACKAGE_VERSION) doesn't match tag (${{ github.ref_name }})"
48
- exit 1
49
- fi
50
-
51
- - name: Check npm access
52
- run: npm whoami
53
- env:
54
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
55
-
56
- - name: Publish to npm with provenance
57
- run: pnpm publish --access public --no-git-checks
58
- env:
59
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
60
- NPM_CONFIG_PROVENANCE: true
61
-
62
- - name: Create GitHub Release
63
- uses: softprops/action-gh-release@v1
64
- with:
65
- generate_release_notes: true
66
- body: |
67
- ## What's Changed
68
-
69
- See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details.
70
-
71
- ## Installation
72
-
73
- ```bash
74
- npm install @boldvideo/bold-js@${{ github.ref_name }}
75
- ```
76
-
77
- ```bash
78
- pnpm add @boldvideo/bold-js@${{ github.ref_name }}
79
- ```
80
-
81
- ```bash
82
- yarn add @boldvideo/bold-js@${{ github.ref_name }}
83
- ```
package/CLAUDE.md DELETED
@@ -1,76 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- This is the Bold JavaScript SDK (`@boldvideo/bold-js`) - a TypeScript client library for interacting with the Bold Video API. The SDK provides methods for fetching videos, playlists, channel settings, and tracking analytics events.
8
-
9
- ## Common Development Commands
10
-
11
- ```bash
12
- # Install dependencies
13
- pnpm install
14
-
15
- # Build the project (outputs to dist/)
16
- pnpm run build
17
-
18
- # Run type checking/linting
19
- pnpm run lint
20
-
21
- # Publish new version (uses changesets)
22
- pnpm changeset
23
- pnpm changeset version
24
- pnpm changeset publish
25
- ```
26
-
27
- ## Architecture & Key Components
28
-
29
- ### Client Structure
30
- The SDK uses a factory pattern where `createClient(apiKey)` returns an object with namespaced methods:
31
- - `bold.settings()` - Fetch channel settings
32
- - `bold.videos.list()` / `.get(id)` / `.search(query)` - Video operations
33
- - `bold.playlists.list()` / `.get(id)` - Playlist operations
34
- - `bold.trackEvent()` / `bold.trackPageView()` - Analytics tracking
35
-
36
- ### Core Files
37
- - `/src/index.ts` - Main entry point, exports `createClient` and all types
38
- - `/src/lib/client.ts` - Client factory that creates the Bold instance with API key auth
39
- - `/src/lib/fetchers.ts` - Individual API endpoint implementations
40
- - `/src/lib/tracking.ts` - Analytics event tracking with throttling
41
- - `/src/lib/types.ts` - TypeScript interfaces for Video, Playlist, Settings, etc.
42
- - `/src/util/throttle.ts` - Throttling utility for rate-limiting event tracking
43
-
44
- ### Build Configuration
45
- - Uses `tsup` for building TypeScript to both ESM and CommonJS formats
46
- - Outputs to `/dist/` with type declarations
47
- - TypeScript strict mode enabled
48
- - Target: ES2016
49
-
50
- ## Development Workflow
51
-
52
- 1. The project uses GitHub Actions for CI/CD:
53
- - All branches run lint and build checks
54
- - Main branch can publish to npm using changesets
55
-
56
- 2. When making changes:
57
- - Ensure TypeScript types are properly defined
58
- - Run `pnpm run lint` before committing
59
- - The SDK supports both ESM and CommonJS consumers
60
-
61
- 3. API Integration:
62
- - Default base URL: `https://app.boldvideo.io/api/v1/`
63
- - Authentication via API key in Authorization header
64
- - All API methods return promises
65
-
66
- 4. Analytics Tracking:
67
- - Events are throttled to prevent API rate limiting
68
- - User IDs are auto-generated for each client instance
69
- - Debug mode available for development
70
-
71
- ## Important Notes
72
-
73
- - No test framework is currently configured
74
- - The SDK is designed to be lightweight with minimal dependencies (only axios)
75
- - All API responses follow the type definitions in `/src/lib/types.ts`
76
- - The tracking system includes automatic throttling to handle high-frequency events like video progress updates