@pugpigbolt/bridge 0.1.0 → 0.1.2

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 CHANGED
@@ -2,13 +2,15 @@
2
2
 
3
3
  Communication layer between Bolt web apps and the native Pugpig shell. Provides a reactive bridge object that syncs native state (stories, auth, timelines, locale) into the web layer and exposes action methods for triggering native behaviour.
4
4
 
5
+ [![npm](https://img.shields.io/npm/v/@pugpigbolt/bridge)](https://www.npmjs.com/package/@pugpigbolt/bridge)
6
+
5
7
  ## Installation
6
8
 
7
9
  ```bash
8
10
  npm install @pugpigbolt/bridge
9
11
  ```
10
12
 
11
- Vue is an optional peer dependency only needed when using `@pugpigbolt/bridge/vue`.
13
+ `vue >= 3` is an optional peer dependency, only needed when using `@pugpigbolt/bridge/vue`.
12
14
 
13
15
  ## Usage
14
16
 
@@ -17,10 +19,8 @@ Vue is an optional peer dependency — only needed when using `@pugpigbolt/bridg
17
19
  ```ts
18
20
  import { globalBridge } from '@pugpigbolt/bridge'
19
21
 
20
- // Read state
21
22
  console.log(globalBridge.stories)
22
23
 
23
- // Listen for changes
24
24
  globalBridge.$on('change:stories', (stories) => {
25
25
  console.log('stories updated', stories)
26
26
  })
@@ -36,7 +36,6 @@ import { BoltBridgeVue } from '@pugpigbolt/bridge/vue'
36
36
 
37
37
  const app = createApp(App)
38
38
  app.use(BoltBridgeVue, () => {
39
- // optional callback — called once the bridge is ready
40
39
  app.mount('#app')
41
40
  })
42
41
  ```
@@ -49,29 +48,6 @@ import { useBridge } from '@pugpigbolt/bridge/vue'
49
48
  const { stories, openArticle, sendAnalytics } = useBridge()
50
49
  ```
51
50
 
52
- `useBridge()` returns Vue refs for all reactive state (individually reactive via `toRefs`) plus bound outgoing action methods.
53
-
54
- ## Exports
55
-
56
- ### `@pugpigbolt/bridge`
57
-
58
- | Export | Description |
59
- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
60
- | `globalBridge` | Proxy-wrapped bridge singleton for non-Vue contexts. Fires `change:<prop>` and `change` events on writes. |
61
- | `bootstrap(options?)` | Framework-agnostic entry-point init. Handles scroll restoration, pugpigUpdate sequence, theme CSS, feed classes, and `timelineIsReady`. Returns a cleanup function. |
62
- | `createPugpigBridgeService(config)` | Factory for a mock `window.pugpigBridgeService` — used in local development to simulate the native shell. |
63
- | All types | `Story`, `StoryEntry`, `BridgeService`, `RemoteConfig`, `Timeline`, `Feed`, `AuthorisationStatus`, `BootstrapOptions`, etc. |
64
-
65
- ### `@pugpigbolt/bridge/vue`
66
-
67
- | Export | Description |
68
- | ------------------ | ------------------------------------------------------------------------------------------------------------------------ |
69
- | `BoltBridgeVue` | Vue plugin. Sets `$bridge` on `globalProperties`, installs tooltip directive, lazy-loads dev overlay in `?preview` mode. |
70
- | `useBridge()` | Composable returning reactive state refs + bound action methods. |
71
- | `globalBridge` | `reactive(rawBridge)` — Vue-reactive bridge, also set as `window.boltBridge`. |
72
- | `isDebug` | `true` when `window.location.search` includes `'preview'`. |
73
- | `registerToolTips` | Registers tooltip definitions for the native tooltip directive. |
74
-
75
51
  ## Local development (mock bridge)
76
52
 
77
53
  When running outside the native shell, install a mock service to simulate native responses:
@@ -81,15 +57,9 @@ import { createPugpigBridgeService } from '@pugpigbolt/bridge'
81
57
 
82
58
  window.pugpigBridgeService = createPugpigBridgeService({
83
59
  live_domain: 'https://example.com',
84
- stories: [...], // StoryEntry[]
85
- timelines: [...], // Timeline[]
60
+ stories: [...],
61
+ timelines: [...],
86
62
  timeline: { id: 'main' },
87
63
  debugLogs: true,
88
64
  })
89
65
  ```
90
-
91
- ## How it works
92
-
93
- The native Pugpig shell calls `window.pugpigUpdate(method, payload)` to push state into the web view. `@pugpigbolt/bridge` registers this global and dispatches calls to internal handlers that update the reactive store. The store is exposed via `globalBridge` / `useBridge()`.
94
-
95
- Outgoing calls (open article, share, analytics, etc.) invoke `window.pugpigBridgeService[method](jsonPayload)` — the native shell implements this interface.
@@ -174,6 +174,7 @@ const analytics = {
174
174
  },
175
175
  sendAnalytics(type, story, index = 0, dimensions = {}) {
176
176
  const pathName = getPathName();
177
+ const baseUrl = story?.originalBaseURL || story?.baseURL;
177
178
  const overrides = typeof type === "object" && type !== null ? type : {};
178
179
  const payload = {
179
180
  type,
@@ -183,14 +184,19 @@ const analytics = {
183
184
  dimensions,
184
185
  ...overrides
185
186
  };
187
+ let paramName = payload.paramName || "pugpigEditionID";
188
+ const category = this.timelineType === "SavedTimeline" ? "/SavedTimeline" : "/Timeline";
186
189
  payload.dimensions.pugpigEventOrigin = pathName;
187
- if (pathName !== "Bolt Timeline") return analytics.sendAnalyticsEvent(payload.type, "/Timeline", payload.param, payload.dimensions, payload.story?.entry, payload.story?.feedid, payload.index);
188
- return dispatchBridgeAction("trackAnalyticsEvent", payload);
190
+ if (!payload.paramName && payload?.param === payload?.story?.entry.title) paramName = "pugpigPageName";
191
+ if (payload?.story?.entry.url && baseUrl) payload.story.entry.url = new URL(payload.story.entry.url, baseUrl).href;
192
+ if (payload?.story?.entry.shareurl && baseUrl) payload.story.entry.shareurl = new URL(payload.story.entry.shareurl, baseUrl).href;
193
+ return analytics.sendAnalyticsEvent(payload.type, category, payload.param, paramName, payload.dimensions, payload.story?.entry, payload.story?.feedid, payload.index);
189
194
  },
190
- sendAnalyticsEvent(name, category, param = "", dimensions = {}, storyEntry, feedid, index) {
195
+ sendAnalyticsEvent(name, category, param = "", paramName = "", dimensions = {}, storyEntry, feedid, index) {
191
196
  const payload = {
192
197
  name,
193
198
  category,
199
+ paramName,
194
200
  feedid,
195
201
  storyEntry,
196
202
  index,
@@ -480,8 +486,8 @@ const BOOTSTRAP_METHODS = [
480
486
  "actionProviderNames",
481
487
  "stories"
482
488
  ];
483
- function triggerPugpigUpdateSequence() {
484
- for (const method of BOOTSTRAP_METHODS) window.pugpigUpdate(method);
489
+ function triggerPugpigUpdateSequence(methods = BOOTSTRAP_METHODS) {
490
+ for (const method of methods) window.pugpigUpdate(method);
485
491
  }
486
492
  function bootstrap(bridge, options = {}) {
487
493
  const { rootSelector = "#app", readyTimeout = 4e3 } = options;
@@ -402,6 +402,7 @@ interface AnalyticsContext {
402
402
  feed?: {
403
403
  id?: string;
404
404
  };
405
+ timelineType?: string;
405
406
  }
406
407
  interface AnalyticsDimensions {
407
408
  pugpigEventOrigin?: string;
@@ -487,7 +488,7 @@ declare const rawBridge: {
487
488
  openImageGallery(images: StoryImage[] | undefined, initialImage?: number): Promise<unknown>;
488
489
  logInfo(this: AnalyticsContext, logLevel: string, payload: string): void;
489
490
  sendAnalytics(this: AnalyticsContext, type: string | Record<string, unknown>, story: Story, index?: number, dimensions?: AnalyticsDimensions): Promise<unknown>;
490
- sendAnalyticsEvent(name: string, category: string, param?: string, dimensions?: AnalyticsDimensions, storyEntry?: StoryEntry, feedid?: string, index?: number): Promise<unknown>;
491
+ sendAnalyticsEvent(name: string, category: string, param?: string, paramName?: string, dimensions?: AnalyticsDimensions, storyEntry?: StoryEntry, feedid?: string, index?: number): Promise<unknown>;
491
492
  openArticle(story: Story, index: number): Promise<unknown>;
492
493
  openEdition(editionId: string, defaultPartition?: string, skipTimeline?: boolean, autoDownload?: boolean): Promise<unknown>;
493
494
  shouldViewWidget(story: Story, index: number): Promise<unknown>;
@@ -581,6 +582,10 @@ declare function createPugpigBridgeService(config: BridgeServiceConfig): {
581
582
  setRead(payload?: string): any;
582
583
  };
583
584
  //#endregion
585
+ //#region src/core/bootstrap.d.ts
586
+ declare const BOOTSTRAP_METHODS: readonly ["localeInfo", "timelineInfo", "authorisationStatus", "savedStories", "readStories", "updateTime", "actionProviderNames", "stories"];
587
+ declare function triggerPugpigUpdateSequence(methods?: readonly string[]): void;
588
+ //#endregion
584
589
  //#region src/index.d.ts
585
590
  /**
586
591
  * @signature globalBridge: GlobalBridge
@@ -593,4 +598,4 @@ declare const globalBridge: GlobalBridge;
593
598
  */
594
599
  declare function bootstrap(options?: BootstrapOptions): () => void;
595
600
  //#endregion
596
- export { UpdateTimePayload as A, Theme as C, TimelineMetadata as D, TimelineInfoPayload as E, TimelineState as O, StoryImage as S, TimelineArgs as T, RemoteConfig as _, AdSize as a, Story as b, AuthorisationStatus as c, BridgeService as d, Feed as f, ReadStoriesPayload as g, PugpigBridgeService as h, GlobalBridge as i, WebviewInfoPayload as j, TimelinesInfoPayload as k, BoltBridgePlugin as l, LocaleInfoPayload as m, globalBridge as n, AnalyticsContext as o, IssueAuthorisationStatus as p, createPugpigBridgeService as r, AnalyticsDimensions as s, bootstrap as t, BootstrapOptions as u, SavedStoriesPayload as v, Timeline as w, StoryEntry as x, StoriesPayload as y };
601
+ export { TimelineState as A, StoryEntry as C, TimelineArgs as D, Timeline as E, UpdateTimePayload as M, WebviewInfoPayload as N, TimelineInfoPayload as O, Story as S, Theme as T, PugpigBridgeService as _, createPugpigBridgeService as a, SavedStoriesPayload as b, AnalyticsContext as c, BoltBridgePlugin as d, BootstrapOptions as f, LocaleInfoPayload as g, IssueAuthorisationStatus as h, triggerPugpigUpdateSequence as i, TimelinesInfoPayload as j, TimelineMetadata as k, AnalyticsDimensions as l, Feed as m, globalBridge as n, GlobalBridge as o, BridgeService as p, BOOTSTRAP_METHODS as r, AdSize as s, bootstrap as t, AuthorisationStatus as u, ReadStoriesPayload as v, StoryImage as w, StoriesPayload as x, RemoteConfig as y };
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as UpdateTimePayload, C as Theme, D as TimelineMetadata, E as TimelineInfoPayload, O as TimelineState, S as StoryImage, T as TimelineArgs, _ as RemoteConfig, a as AdSize, b as Story, c as AuthorisationStatus, d as BridgeService, f as Feed, g as ReadStoriesPayload, h as PugpigBridgeService, i as GlobalBridge, j as WebviewInfoPayload, k as TimelinesInfoPayload, l as BoltBridgePlugin, m as LocaleInfoPayload, n as globalBridge, o as AnalyticsContext, p as IssueAuthorisationStatus, r as createPugpigBridgeService, s as AnalyticsDimensions, t as bootstrap, u as BootstrapOptions, v as SavedStoriesPayload, w as Timeline, x as StoryEntry, y as StoriesPayload } from "./index-D5X9A3Gj.mjs";
2
- export { AdSize, AnalyticsContext, AnalyticsDimensions, AuthorisationStatus, BoltBridgePlugin, BootstrapOptions, BridgeService, Feed, GlobalBridge, IssueAuthorisationStatus, LocaleInfoPayload, PugpigBridgeService, ReadStoriesPayload, RemoteConfig, SavedStoriesPayload, StoriesPayload, Story, StoryEntry, StoryImage, Theme, Timeline, TimelineArgs, TimelineInfoPayload, TimelineMetadata, TimelineState, TimelinesInfoPayload, UpdateTimePayload, WebviewInfoPayload, bootstrap, createPugpigBridgeService, globalBridge };
1
+ import { A as TimelineState, C as StoryEntry, D as TimelineArgs, E as Timeline, M as UpdateTimePayload, N as WebviewInfoPayload, O as TimelineInfoPayload, S as Story, T as Theme, _ as PugpigBridgeService, a as createPugpigBridgeService, b as SavedStoriesPayload, c as AnalyticsContext, d as BoltBridgePlugin, f as BootstrapOptions, g as LocaleInfoPayload, h as IssueAuthorisationStatus, i as triggerPugpigUpdateSequence, j as TimelinesInfoPayload, k as TimelineMetadata, l as AnalyticsDimensions, m as Feed, n as globalBridge, o as GlobalBridge, p as BridgeService, r as BOOTSTRAP_METHODS, s as AdSize, t as bootstrap, u as AuthorisationStatus, v as ReadStoriesPayload, w as StoryImage, x as StoriesPayload, y as RemoteConfig } from "./index-BjDhZ_q5.mjs";
2
+ export { AdSize, AnalyticsContext, AnalyticsDimensions, AuthorisationStatus, BOOTSTRAP_METHODS, BoltBridgePlugin, BootstrapOptions, BridgeService, Feed, GlobalBridge, IssueAuthorisationStatus, LocaleInfoPayload, PugpigBridgeService, ReadStoriesPayload, RemoteConfig, SavedStoriesPayload, StoriesPayload, Story, StoryEntry, StoryImage, Theme, Timeline, TimelineArgs, TimelineInfoPayload, TimelineMetadata, TimelineState, TimelinesInfoPayload, UpdateTimePayload, WebviewInfoPayload, bootstrap, createPugpigBridgeService, globalBridge, triggerPugpigUpdateSequence };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as makeProxyBridge, i as setupPugpigUpdate, n as bootstrap$1, o as rawBridge } from "./bootstrap-DnSyt3hZ.mjs";
1
+ import { a as makeProxyBridge, i as setupPugpigUpdate, n as bootstrap$1, o as rawBridge, r as triggerPugpigUpdateSequence, t as BOOTSTRAP_METHODS } from "./bootstrap-DQyoNFue.mjs";
2
2
  import { t as createPugpigBridgeService } from "./mockBridgeService-vnaAIjCu.mjs";
3
3
  //#region src/index.ts
4
4
  /**
@@ -16,4 +16,4 @@ function bootstrap(options) {
16
16
  return bootstrap$1(globalBridge, options);
17
17
  }
18
18
  //#endregion
19
- export { bootstrap, createPugpigBridgeService, globalBridge };
19
+ export { BOOTSTRAP_METHODS, bootstrap, createPugpigBridgeService, globalBridge, triggerPugpigUpdateSequence };
package/dist/vue.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as UpdateTimePayload, C as Theme, D as TimelineMetadata, E as TimelineInfoPayload, O as TimelineState, S as StoryImage, T as TimelineArgs, _ as RemoteConfig, a as AdSize, b as Story, c as AuthorisationStatus, d as BridgeService, f as Feed, g as ReadStoriesPayload, h as PugpigBridgeService, i as GlobalBridge, j as WebviewInfoPayload, k as TimelinesInfoPayload, l as BoltBridgePlugin, m as LocaleInfoPayload, o as AnalyticsContext, p as IssueAuthorisationStatus, s as AnalyticsDimensions, u as BootstrapOptions, v as SavedStoriesPayload, w as Timeline, x as StoryEntry, y as StoriesPayload } from "./index-D5X9A3Gj.mjs";
1
+ import { A as TimelineState, C as StoryEntry, D as TimelineArgs, E as Timeline, M as UpdateTimePayload, N as WebviewInfoPayload, O as TimelineInfoPayload, S as Story, T as Theme, _ as PugpigBridgeService, b as SavedStoriesPayload, c as AnalyticsContext, d as BoltBridgePlugin, f as BootstrapOptions, g as LocaleInfoPayload, h as IssueAuthorisationStatus, i as triggerPugpigUpdateSequence, j as TimelinesInfoPayload, k as TimelineMetadata, l as AnalyticsDimensions, m as Feed, o as GlobalBridge, p as BridgeService, r as BOOTSTRAP_METHODS, s as AdSize, u as AuthorisationStatus, v as ReadStoriesPayload, w as StoryImage, x as StoriesPayload, y as RemoteConfig } from "./index-BjDhZ_q5.mjs";
2
2
  import * as _$vue from "vue";
3
3
  import { App } from "vue";
4
4
 
@@ -69,7 +69,7 @@ declare function useBridge(): {
69
69
  openImageGallery(images: StoryImage[] | undefined, initialImage?: number): Promise<unknown>;
70
70
  logInfo(this: AnalyticsContext, logLevel: string, payload: string): void;
71
71
  sendAnalytics(this: AnalyticsContext, type: string | Record<string, unknown>, story: Story, index?: number, dimensions?: AnalyticsDimensions): Promise<unknown>;
72
- sendAnalyticsEvent(name: string, category: string, param?: string, dimensions?: AnalyticsDimensions, storyEntry?: StoryEntry, feedid?: string, index?: number): Promise<unknown>;
72
+ sendAnalyticsEvent(name: string, category: string, param?: string, paramName?: string, dimensions?: AnalyticsDimensions, storyEntry?: StoryEntry, feedid?: string, index?: number): Promise<unknown>;
73
73
  openArticle(story: Story, index: number): Promise<unknown>;
74
74
  openEdition(editionId: string, defaultPartition?: string, skipTimeline?: boolean, autoDownload?: boolean): Promise<unknown>;
75
75
  shouldViewWidget(story: Story, index: number): Promise<unknown>;
@@ -106,10 +106,6 @@ declare function useBridge(): {
106
106
  };
107
107
  type UseBridgeReturn = ReturnType<typeof useBridge>;
108
108
  //#endregion
109
- //#region src/core/bootstrap.d.ts
110
- declare const BOOTSTRAP_METHODS: readonly ["localeInfo", "timelineInfo", "authorisationStatus", "savedStories", "readStories", "updateTime", "actionProviderNames", "stories"];
111
- declare function triggerPugpigUpdateSequence(): void;
112
- //#endregion
113
109
  //#region src/vue/bootstrap.d.ts
114
110
  declare function useBootstrap(options?: BootstrapOptions): void;
115
111
  declare function injectThemeAndWait(readyTimeout?: number): void;
package/dist/vue.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { i as setupPugpigUpdate, o as rawBridge, r as triggerPugpigUpdateSequence, s as outgoingActions, t as BOOTSTRAP_METHODS } from "./bootstrap-DnSyt3hZ.mjs";
1
+ import { i as setupPugpigUpdate, o as rawBridge, r as triggerPugpigUpdateSequence, s as outgoingActions, t as BOOTSTRAP_METHODS } from "./bootstrap-DQyoNFue.mjs";
2
2
  import { onUnmounted, reactive, ref, toRefs, watchEffect } from "vue";
3
3
  //#region src/vue/tooltip.ts
4
4
  const tooltipsQueue = ref([]);
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@pugpigbolt/bridge",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
+ "license": "MIT",
4
5
  "files": [
5
6
  "dist"
6
7
  ],