@pugpigbolt/bridge 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/README.md +2 -2
- package/dist/chunks/bootstrap-B7Gwb_jl.mjs +1 -0
- package/dist/chunks/development-CzUmtUQR.mjs +1 -0
- package/dist/{index-BAapL0vP.d.mts → chunks/index-B2cNakTH.d.mts} +7 -108
- package/dist/chunks/mockBridgeService-M_48ewQL.mjs +27 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -19
- package/dist/vue.d.mts +9 -50
- package/dist/vue.mjs +1 -213
- package/package.json +2 -1
- package/dist/bootstrap-BzOJNz7-.mjs +0 -530
- package/dist/development-Bl8-5E3g.mjs +0 -56
- package/dist/mockBridgeService-vnaAIjCu.mjs +0 -272
|
@@ -1,530 +0,0 @@
|
|
|
1
|
-
//#region src/core/access.ts
|
|
2
|
-
function resolveIssueAccess(story, issueAuthorisationStatus) {
|
|
3
|
-
let { paywall_locked: locked, entitlements = [] } = story.entry;
|
|
4
|
-
if (locked && entitlements.length <= 0) entitlements = story.feedid ? [story.feedid] : [];
|
|
5
|
-
const hasAccess = story.feedid ? issueAuthorisationStatus[story.feedid] : false;
|
|
6
|
-
const hasArticleAccess = entitlements.length > 0 ? entitlements.find((e) => issueAuthorisationStatus[e]) : true;
|
|
7
|
-
return !hasAccess && !hasArticleAccess;
|
|
8
|
-
}
|
|
9
|
-
//#endregion
|
|
10
|
-
//#region src/core/store.ts
|
|
11
|
-
const SAVE_TIMELINE_KEY = "SavedTimeline";
|
|
12
|
-
const COLLECTION_KEY = "collection_type-edition";
|
|
13
|
-
const store = {
|
|
14
|
-
feed: {},
|
|
15
|
-
rawStories: [],
|
|
16
|
-
timelines: [],
|
|
17
|
-
timelinesStates: {},
|
|
18
|
-
themeURL: [],
|
|
19
|
-
theme: {},
|
|
20
|
-
darkTheme: {},
|
|
21
|
-
timelineMode: "Single",
|
|
22
|
-
timelineType: "Timeline",
|
|
23
|
-
sourceURL: null,
|
|
24
|
-
baseUrl: "",
|
|
25
|
-
metadataLoaded: false,
|
|
26
|
-
initialBatchSize: 0,
|
|
27
|
-
filter: {},
|
|
28
|
-
positionOverrides: [],
|
|
29
|
-
debugLogs: false,
|
|
30
|
-
actionProviderNames: [],
|
|
31
|
-
authorisationStatus: {},
|
|
32
|
-
issueAuthorisationStatus: {},
|
|
33
|
-
read: /* @__PURE__ */ new Set(),
|
|
34
|
-
saved: /* @__PURE__ */ new Set(),
|
|
35
|
-
get stories() {
|
|
36
|
-
return deriveStories(this.rawStories, this.saved, this.read, this.authorisationStatus, this.issueAuthorisationStatus);
|
|
37
|
-
},
|
|
38
|
-
get themeFileNames() {
|
|
39
|
-
return this.themeURL?.map((file) => file.split("/").pop() ?? "") ?? [];
|
|
40
|
-
},
|
|
41
|
-
get isSavedTimeline() {
|
|
42
|
-
return this.timelineType === SAVE_TIMELINE_KEY;
|
|
43
|
-
},
|
|
44
|
-
get isCollection() {
|
|
45
|
-
return this.feed?.classes?.includes(COLLECTION_KEY) ?? false;
|
|
46
|
-
},
|
|
47
|
-
isTimelineStyleVersion(version) {
|
|
48
|
-
return window.timelineStyleVersion === version;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
function deriveStories(stories, saved, read, authorisationStatus, issueAuthorisationStatus) {
|
|
52
|
-
const hasIssueAuth = !!(window.parent?.pugpigBridgeService)?.issueAuthorisationStatus;
|
|
53
|
-
return stories.map((story, index) => {
|
|
54
|
-
story.locked = hasIssueAuth ? resolveIssueAccess(story, issueAuthorisationStatus) : resolveSubscriptionAccess(story, authorisationStatus);
|
|
55
|
-
story.hidden = resolveVisibility(story, authorisationStatus);
|
|
56
|
-
story.saved = saved.has(story.entry.id);
|
|
57
|
-
story.read = read.has(`${story.feedid}::::${story.entry.id}`);
|
|
58
|
-
story.originalIndex = index;
|
|
59
|
-
return story;
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
function resolveSubscriptionAccess(story, authorisationStatus) {
|
|
63
|
-
const { state } = authorisationStatus;
|
|
64
|
-
const { paywall_locked: locked = false } = story.entry;
|
|
65
|
-
return state !== "active" && locked;
|
|
66
|
-
}
|
|
67
|
-
function resolveVisibility(story, authorisationStatus) {
|
|
68
|
-
const { state } = authorisationStatus;
|
|
69
|
-
const { visibility, categories, hidden } = story.entry;
|
|
70
|
-
const pugpigAttributes = categories?.find(({ scheme }) => scheme === "http://schema.pugpig.com/attributes");
|
|
71
|
-
if (visibility) return visibility === "marketing" && state !== "inactive" || visibility === "private" && !!story.locked;
|
|
72
|
-
if (pugpigAttributes) return pugpigAttributes.term === "marketing" && state !== "inactive" || pugpigAttributes.term === "private" && state !== "inactive";
|
|
73
|
-
return !!hidden;
|
|
74
|
-
}
|
|
75
|
-
//#endregion
|
|
76
|
-
//#region src/handlers/outgoing/dispatch.ts
|
|
77
|
-
async function safeAwait(promise) {
|
|
78
|
-
try {
|
|
79
|
-
const response = await promise;
|
|
80
|
-
return { data: response ? JSON.parse(response) : void 0 };
|
|
81
|
-
} catch (error) {
|
|
82
|
-
return { error };
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
async function dispatchBridgeAction(action, payload) {
|
|
86
|
-
const bridgeService = window.parent?.pugpigBridgeService;
|
|
87
|
-
const hasBridgeServiceAction = bridgeService && bridgeService[action];
|
|
88
|
-
const payloadString = payload ? JSON.stringify(payload) : void 0;
|
|
89
|
-
if (hasBridgeServiceAction) {
|
|
90
|
-
const { data, error } = await safeAwait(Promise.resolve(payloadString ? bridgeService[action](payloadString) : bridgeService[action]()));
|
|
91
|
-
if (error) throw new Error(error instanceof Error ? error.message : JSON.stringify(error));
|
|
92
|
-
return data;
|
|
93
|
-
}
|
|
94
|
-
window.parent?.postMessage({
|
|
95
|
-
bolt: "up",
|
|
96
|
-
action,
|
|
97
|
-
payload: JSON.parse(payloadString ?? "{}")
|
|
98
|
-
}, "*");
|
|
99
|
-
}
|
|
100
|
-
function getPathName() {
|
|
101
|
-
return (window.location.pathname.split("/").pop()?.replace(".html", "") ?? "").split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
102
|
-
}
|
|
103
|
-
function debounce(func, wait) {
|
|
104
|
-
let timeout;
|
|
105
|
-
return function(...args) {
|
|
106
|
-
clearTimeout(timeout);
|
|
107
|
-
timeout = setTimeout(() => func.apply(this, args), wait);
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
//#endregion
|
|
111
|
-
//#region src/handlers/outgoing/articles.ts
|
|
112
|
-
const articles = {
|
|
113
|
-
openArticle(story, index) {
|
|
114
|
-
return dispatchBridgeAction("viewArticle", {
|
|
115
|
-
...story,
|
|
116
|
-
story,
|
|
117
|
-
index
|
|
118
|
-
});
|
|
119
|
-
},
|
|
120
|
-
openEdition(editionId, defaultPartition, skipTimeline = false, autoDownload = true) {
|
|
121
|
-
const payload = {
|
|
122
|
-
editionId,
|
|
123
|
-
skipTimeline,
|
|
124
|
-
autoDownload
|
|
125
|
-
};
|
|
126
|
-
if (defaultPartition) payload.partition = defaultPartition;
|
|
127
|
-
return dispatchBridgeAction("openEdition", payload);
|
|
128
|
-
},
|
|
129
|
-
shouldViewWidget(story, index) {
|
|
130
|
-
return dispatchBridgeAction("shouldViewWidget", {
|
|
131
|
-
...story,
|
|
132
|
-
story,
|
|
133
|
-
index
|
|
134
|
-
});
|
|
135
|
-
},
|
|
136
|
-
setSaved(story, index, saved) {
|
|
137
|
-
return dispatchBridgeAction("setSaved", {
|
|
138
|
-
story,
|
|
139
|
-
index,
|
|
140
|
-
saved
|
|
141
|
-
});
|
|
142
|
-
},
|
|
143
|
-
setRead(story, index) {
|
|
144
|
-
return dispatchBridgeAction("setRead", {
|
|
145
|
-
story,
|
|
146
|
-
index
|
|
147
|
-
});
|
|
148
|
-
},
|
|
149
|
-
shareStory(story, index) {
|
|
150
|
-
return dispatchBridgeAction("shareStory", {
|
|
151
|
-
story,
|
|
152
|
-
index
|
|
153
|
-
});
|
|
154
|
-
},
|
|
155
|
-
addToCalendar(story, index) {
|
|
156
|
-
return dispatchBridgeAction("addToCalendar", {
|
|
157
|
-
story,
|
|
158
|
-
index
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region src/handlers/outgoing/analytics.ts
|
|
164
|
-
const analytics = {
|
|
165
|
-
/**
|
|
166
|
-
* Sends a log message to native.
|
|
167
|
-
* `'debug'` level messages are silently suppressed unless `store.debugLogs` is true.
|
|
168
|
-
* Use `'global'` for logs that should always appear regardless of debug mode.
|
|
169
|
-
*/
|
|
170
|
-
logInfo(logLevel, payload) {
|
|
171
|
-
if (logLevel === "debug" && !this.debugLogs) return;
|
|
172
|
-
const feedId = this.feed?.id ? ` [${this.feed.id}]` : "";
|
|
173
|
-
dispatchBridgeAction("logInfo", `[${document.title || "Bolt Timeline"}]${feedId} ${payload}`);
|
|
174
|
-
},
|
|
175
|
-
sendAnalytics(type, story, index = 0, dimensions = {}) {
|
|
176
|
-
const pathName = getPathName();
|
|
177
|
-
const baseUrl = story?.originalBaseURL || story?.baseURL;
|
|
178
|
-
const overrides = typeof type === "object" && type !== null ? type : {};
|
|
179
|
-
const payload = {
|
|
180
|
-
type,
|
|
181
|
-
story,
|
|
182
|
-
index,
|
|
183
|
-
param: story?.feedid,
|
|
184
|
-
dimensions,
|
|
185
|
-
...overrides
|
|
186
|
-
};
|
|
187
|
-
let paramName = payload.paramName || "pugpigEditionID";
|
|
188
|
-
const category = this.timelineType === "SavedTimeline" ? "/SavedTimeline" : "/Timeline";
|
|
189
|
-
payload.dimensions.pugpigEventOrigin = pathName;
|
|
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);
|
|
194
|
-
},
|
|
195
|
-
sendAnalyticsEvent(name, category, param = "", paramName = "", dimensions = {}, storyEntry, feedid, index) {
|
|
196
|
-
const payload = {
|
|
197
|
-
name,
|
|
198
|
-
category,
|
|
199
|
-
paramName,
|
|
200
|
-
feedid,
|
|
201
|
-
storyEntry,
|
|
202
|
-
index,
|
|
203
|
-
dimensions
|
|
204
|
-
};
|
|
205
|
-
if (param && param !== "") payload.param = typeof param !== "string" ? JSON.stringify(param) : param;
|
|
206
|
-
payload.dimensions = {
|
|
207
|
-
...dimensions,
|
|
208
|
-
pugpigEventOrigin: getPathName()
|
|
209
|
-
};
|
|
210
|
-
return dispatchBridgeAction("trackAnalyticsEvent", payload);
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
//#endregion
|
|
214
|
-
//#region src/handlers/outgoing/media.ts
|
|
215
|
-
const media = {
|
|
216
|
-
openAudio(story, fallback, index) {
|
|
217
|
-
return dispatchBridgeAction("playAudio", {
|
|
218
|
-
story,
|
|
219
|
-
index,
|
|
220
|
-
...fallback
|
|
221
|
-
});
|
|
222
|
-
},
|
|
223
|
-
openImageGallery(images, initialImage = 0) {
|
|
224
|
-
return dispatchBridgeAction("openImageGallery", {
|
|
225
|
-
images,
|
|
226
|
-
initialImage
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
//#endregion
|
|
231
|
-
//#region src/handlers/outgoing/ui.ts
|
|
232
|
-
const ui = {
|
|
233
|
-
fireToast(type, action) {
|
|
234
|
-
return dispatchBridgeAction("fireToast", {
|
|
235
|
-
type,
|
|
236
|
-
action
|
|
237
|
-
});
|
|
238
|
-
},
|
|
239
|
-
clearForwardTouchesWithin() {
|
|
240
|
-
return dispatchBridgeAction("clearForwardTouchesWithin");
|
|
241
|
-
},
|
|
242
|
-
/**
|
|
243
|
-
* Debounced 300ms.
|
|
244
|
-
* Automatically calls `clearForwardTouchesWithin` before each dispatch to reset the touch region.
|
|
245
|
-
* Do not call `clearForwardTouchesWithin` manually alongside this.
|
|
246
|
-
*/
|
|
247
|
-
forwardTouchesWithin: debounce(async function(payload) {
|
|
248
|
-
await this.clearForwardTouchesWithin();
|
|
249
|
-
return dispatchBridgeAction("forwardTouchesWithin", payload ? Object.values(payload) : payload);
|
|
250
|
-
}, 300)
|
|
251
|
-
};
|
|
252
|
-
//#endregion
|
|
253
|
-
//#region src/handlers/outgoing/lifecycle.ts
|
|
254
|
-
const lifecycle = {
|
|
255
|
-
call(action, payload) {
|
|
256
|
-
return dispatchBridgeAction(action, payload);
|
|
257
|
-
},
|
|
258
|
-
/**
|
|
259
|
-
* Call once after the Vue app has mounted.
|
|
260
|
-
* Sends the git version to native and logs startup timing.
|
|
261
|
-
* Calling more than once is a no-op in native but will produce duplicate log entries.
|
|
262
|
-
*/
|
|
263
|
-
timelineIsReady() {
|
|
264
|
-
const version = import.meta.env.VITE_GIT_VERSION;
|
|
265
|
-
dispatchBridgeAction("timelineIsReady", { version });
|
|
266
|
-
this.logInfo("global", `timelineIsReady took ${performance.now()}ms`);
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
//#endregion
|
|
270
|
-
//#region src/handlers/outgoing/index.ts
|
|
271
|
-
const outgoingActions = {
|
|
272
|
-
...articles,
|
|
273
|
-
...analytics,
|
|
274
|
-
...media,
|
|
275
|
-
...ui,
|
|
276
|
-
...lifecycle
|
|
277
|
-
};
|
|
278
|
-
//#endregion
|
|
279
|
-
//#region src/core/eventEmitter.ts
|
|
280
|
-
const eventEmitter = {
|
|
281
|
-
events: {},
|
|
282
|
-
debounceTimers: {},
|
|
283
|
-
$on(event, listener) {
|
|
284
|
-
if (!Array.isArray(this.events[event])) this.events[event] = [];
|
|
285
|
-
this.events[event].push(listener);
|
|
286
|
-
return () => this.removeListener(event, listener);
|
|
287
|
-
},
|
|
288
|
-
removeListener(event, listener) {
|
|
289
|
-
if (Array.isArray(this.events[event])) {
|
|
290
|
-
const idx = this.events[event].indexOf(listener);
|
|
291
|
-
if (idx > -1) this.events[event].splice(idx, 1);
|
|
292
|
-
}
|
|
293
|
-
},
|
|
294
|
-
$off(event, listener) {
|
|
295
|
-
this.removeListener(event, listener);
|
|
296
|
-
},
|
|
297
|
-
$emit(event, ...args) {
|
|
298
|
-
const debounce = (args?.[0])?.debounce;
|
|
299
|
-
const filterBy = (str) => new RegExp("^" + str.replace(/\*/g, ".*") + "$").test(event);
|
|
300
|
-
const eventMatches = Object.keys(this.events).filter(filterBy);
|
|
301
|
-
if (!eventMatches || eventMatches.length <= 0) return;
|
|
302
|
-
eventMatches.forEach((eventName) => {
|
|
303
|
-
if (debounce) {
|
|
304
|
-
if (this.debounceTimers[eventName]) clearTimeout(this.debounceTimers[eventName]);
|
|
305
|
-
this.debounceTimers[eventName] = setTimeout(() => {
|
|
306
|
-
this.events[eventName].forEach((listener) => listener.apply(this, args));
|
|
307
|
-
}, debounce);
|
|
308
|
-
} else this.events[eventName].forEach((listener) => listener.apply(this, args));
|
|
309
|
-
});
|
|
310
|
-
},
|
|
311
|
-
$once(event, listener) {
|
|
312
|
-
const remove = this.$on(event, (...args) => {
|
|
313
|
-
remove();
|
|
314
|
-
listener.apply(this, args);
|
|
315
|
-
});
|
|
316
|
-
},
|
|
317
|
-
subscribe(cb) {
|
|
318
|
-
cb(this);
|
|
319
|
-
return this.$on("change", () => cb(this));
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
//#endregion
|
|
323
|
-
//#region src/core/bridge.ts
|
|
324
|
-
const rawBridge = Object.assign(store, {
|
|
325
|
-
...outgoingActions,
|
|
326
|
-
resolveIssueAccess: (story) => resolveIssueAccess(story, store.issueAuthorisationStatus)
|
|
327
|
-
}, eventEmitter);
|
|
328
|
-
function makeProxyBridge(raw) {
|
|
329
|
-
return new Proxy(raw, { set(target, prop, value, receiver) {
|
|
330
|
-
const result = Reflect.set(target, prop, value, receiver);
|
|
331
|
-
if (typeof prop !== "string") return result;
|
|
332
|
-
raw.$emit(`change:${prop}`, value);
|
|
333
|
-
raw.$emit("change", prop, value);
|
|
334
|
-
return result;
|
|
335
|
-
} });
|
|
336
|
-
}
|
|
337
|
-
//#endregion
|
|
338
|
-
//#region src/core/utils.ts
|
|
339
|
-
function compareStoriesObj(oldObj, newObj) {
|
|
340
|
-
if (oldObj.length !== newObj.length) return true;
|
|
341
|
-
for (let i = 0; i < oldObj.length; i++) {
|
|
342
|
-
const { entry: { id: oldId, updated: oldUpdated } } = oldObj[i];
|
|
343
|
-
const { entry: { id: newId, updated: newUpdated } } = newObj[i];
|
|
344
|
-
if (oldId !== newId || oldUpdated !== newUpdated) return true;
|
|
345
|
-
}
|
|
346
|
-
return false;
|
|
347
|
-
}
|
|
348
|
-
//#endregion
|
|
349
|
-
//#region src/handlers/incoming.ts
|
|
350
|
-
async function fetchWithHooks(method, data) {
|
|
351
|
-
const bridgeService = window.parent?.pugpigBridgeService;
|
|
352
|
-
const payload = data ? await Promise.resolve(bridgeService?.[method](data)) : await Promise.resolve(bridgeService?.[method]());
|
|
353
|
-
let payloadJson = JSON.parse(payload);
|
|
354
|
-
const hookTransform = window.parent?.pugpig?.timelineHooks?.transforms?.bridge;
|
|
355
|
-
if (hookTransform) payloadJson = await hookTransform({
|
|
356
|
-
method,
|
|
357
|
-
payload: payloadJson
|
|
358
|
-
});
|
|
359
|
-
return payloadJson;
|
|
360
|
-
}
|
|
361
|
-
//#endregion
|
|
362
|
-
//#region src/core/pugpigUpdate.ts
|
|
363
|
-
const handlers = {
|
|
364
|
-
stories: async function({ updateAction } = {}) {
|
|
365
|
-
const { stories } = await fetchWithHooks("stories");
|
|
366
|
-
const oldStories = this.rawStories;
|
|
367
|
-
const feedUpdated = compareStoriesObj(oldStories, stories);
|
|
368
|
-
this.rawStories = stories;
|
|
369
|
-
if (feedUpdated) {
|
|
370
|
-
window.pugpigUpdate("issueAuthorisationStatus");
|
|
371
|
-
window.pugpigUpdate("timelineInfo");
|
|
372
|
-
}
|
|
373
|
-
if (oldStories.length > 0) this.$emit("stories-updated", {
|
|
374
|
-
feedUpdated,
|
|
375
|
-
updateAction
|
|
376
|
-
});
|
|
377
|
-
},
|
|
378
|
-
timelines: async function() {
|
|
379
|
-
this.timelines = await fetchWithHooks("timelines", JSON.stringify(this.filter));
|
|
380
|
-
},
|
|
381
|
-
timelineInfo: async function() {
|
|
382
|
-
const { themeURL, timelineType, debugLogs, sourceURL, timelineMode, metadata, feedReference } = await fetchWithHooks("timelineInfo");
|
|
383
|
-
this.themeURL = themeURL;
|
|
384
|
-
this.sourceURL = sourceURL;
|
|
385
|
-
this.theme = metadata?.configuration?.theme ?? {};
|
|
386
|
-
this.darkTheme = metadata?.configuration?.darkTheme ?? this.theme;
|
|
387
|
-
this.feed = feedReference;
|
|
388
|
-
this.timelineType = timelineType;
|
|
389
|
-
this.timelineMode = timelineMode;
|
|
390
|
-
if (metadata) this.metadataLoaded = true;
|
|
391
|
-
this.initialBatchSize = metadata?.configuration?.timeline_initial_batch_size ?? metadata?.timeline_initial_batch_size ?? Math.floor(screen.height / 150);
|
|
392
|
-
if (window.useTimelineGrid) this.positionOverrides = window.timelinePositionOverrides ?? metadata?.configuration?.position_overrides ?? metadata?.position_overrides ?? [];
|
|
393
|
-
this.debugLogs = debugLogs;
|
|
394
|
-
},
|
|
395
|
-
timeline: async function({ editionId, progress, state, downloadError }) {
|
|
396
|
-
const index = this.timelines.findIndex((x) => x.id === editionId);
|
|
397
|
-
if (!this.timelines || this.timelines.length <= 0 || !this.timelines[index]) return;
|
|
398
|
-
if (!this.timelinesStates[editionId]) this.timelinesStates[editionId] = {};
|
|
399
|
-
this.timelinesStates[editionId].progress = progress;
|
|
400
|
-
this.timelinesStates[editionId].state = state;
|
|
401
|
-
this.timelinesStates[editionId].downloadError = downloadError;
|
|
402
|
-
},
|
|
403
|
-
timelinesInfo: async function() {
|
|
404
|
-
const { baseurl, debugLogs, filter, css = [], theme = {}, darkTheme } = await fetchWithHooks("timelinesInfo");
|
|
405
|
-
this.theme = theme;
|
|
406
|
-
this.darkTheme = darkTheme ?? theme;
|
|
407
|
-
this.themeURL = css;
|
|
408
|
-
this.baseUrl = baseurl;
|
|
409
|
-
this.filter = filter;
|
|
410
|
-
this.debugLogs = debugLogs;
|
|
411
|
-
},
|
|
412
|
-
localeInfo: async function() {
|
|
413
|
-
const { locale = "en-GB", direction = "ltr" } = await fetchWithHooks("localeInfo");
|
|
414
|
-
if (document.documentElement.lang !== locale) document.documentElement.lang = locale?.replace(/_/g, "-");
|
|
415
|
-
if (document.documentElement.dir !== direction) document.documentElement.dir = direction;
|
|
416
|
-
},
|
|
417
|
-
issueAuthorisationStatus: async function() {
|
|
418
|
-
const feedids = [...new Set(this.rawStories.flatMap(({ feedid, entry }) => [feedid, ...entry.entitlements ?? []]))];
|
|
419
|
-
this.issueAuthorisationStatus = await fetchWithHooks("issueAuthorisationStatus", JSON.stringify(feedids));
|
|
420
|
-
},
|
|
421
|
-
authorisationStatus: async function() {
|
|
422
|
-
this.authorisationStatus = await fetchWithHooks("authorisationStatus");
|
|
423
|
-
},
|
|
424
|
-
actionProviderNames: async function() {
|
|
425
|
-
this.actionProviderNames = await fetchWithHooks("actionProviderNames");
|
|
426
|
-
},
|
|
427
|
-
readStories: async function() {
|
|
428
|
-
const { readStories } = await fetchWithHooks("readStories");
|
|
429
|
-
this.read = new Set(readStories.map((story) => story.join("::::")));
|
|
430
|
-
},
|
|
431
|
-
savedStories: async function() {
|
|
432
|
-
const { savedStories } = await fetchWithHooks("savedStories");
|
|
433
|
-
this.saved = new Set(savedStories.map((story) => story?.[1]));
|
|
434
|
-
},
|
|
435
|
-
updateTime: async function() {
|
|
436
|
-
const { dateTime, lastCheckedDateTime } = await fetchWithHooks("updateTime");
|
|
437
|
-
this.$emit("time-updated", {
|
|
438
|
-
dateTime,
|
|
439
|
-
lastCheckedDateTime
|
|
440
|
-
});
|
|
441
|
-
},
|
|
442
|
-
storeGet: async function({ key }) {
|
|
443
|
-
this.$emit("store-updated", { key });
|
|
444
|
-
},
|
|
445
|
-
webviewInfo: async function() {
|
|
446
|
-
const { themeURL } = await fetchWithHooks("webviewInfo");
|
|
447
|
-
this.themeURL = themeURL;
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
function isDispatcher(fn) {
|
|
451
|
-
return typeof fn === "function" && "__boltHandlers" in fn;
|
|
452
|
-
}
|
|
453
|
-
function getRegistry() {
|
|
454
|
-
if (isDispatcher(window.pugpigUpdate)) return window.pugpigUpdate.__boltHandlers;
|
|
455
|
-
const registry = window.pugpigUpdate ? [window.pugpigUpdate] : [];
|
|
456
|
-
const dispatcher = Object.assign((method, args = {}) => registry.forEach((h) => h(method, args)), { __boltHandlers: registry });
|
|
457
|
-
window.pugpigUpdate = dispatcher;
|
|
458
|
-
return registry;
|
|
459
|
-
}
|
|
460
|
-
const bridgeHandlers = /* @__PURE__ */ new WeakMap();
|
|
461
|
-
function setupPugpigUpdate(globalBridge) {
|
|
462
|
-
const registry = getRegistry();
|
|
463
|
-
if (!bridgeHandlers.has(globalBridge)) bridgeHandlers.set(globalBridge, (method, args = {}) => {
|
|
464
|
-
if (window.parent?.pugpigBridgeService?.[method]) {
|
|
465
|
-
document.querySelectorAll("iframe").forEach((iframe) => {
|
|
466
|
-
try {
|
|
467
|
-
iframe.contentWindow?.pugpigUpdate?.(method, args);
|
|
468
|
-
} catch (_e) {}
|
|
469
|
-
});
|
|
470
|
-
return handlers[method]?.call(globalBridge, args);
|
|
471
|
-
}
|
|
472
|
-
console.info(`Bolt Timeline Bridge: '${method}' not available on this platform.`);
|
|
473
|
-
});
|
|
474
|
-
const handler = bridgeHandlers.get(globalBridge);
|
|
475
|
-
if (!registry.includes(handler)) registry.push(handler);
|
|
476
|
-
}
|
|
477
|
-
//#endregion
|
|
478
|
-
//#region src/core/bootstrap.ts
|
|
479
|
-
const BOOTSTRAP_METHODS = [
|
|
480
|
-
"localeInfo",
|
|
481
|
-
"timelineInfo",
|
|
482
|
-
"authorisationStatus",
|
|
483
|
-
"savedStories",
|
|
484
|
-
"readStories",
|
|
485
|
-
"updateTime",
|
|
486
|
-
"actionProviderNames",
|
|
487
|
-
"stories"
|
|
488
|
-
];
|
|
489
|
-
function triggerPugpigUpdateSequence() {
|
|
490
|
-
for (const method of BOOTSTRAP_METHODS) window.pugpigUpdate(method);
|
|
491
|
-
}
|
|
492
|
-
function bootstrap(bridge, options = {}) {
|
|
493
|
-
const { rootSelector = "#app", readyTimeout = 4e3 } = options;
|
|
494
|
-
if ("scrollRestoration" in history) history.scrollRestoration = "manual";
|
|
495
|
-
triggerPugpigUpdateSequence();
|
|
496
|
-
const rootEl = document.querySelector(rootSelector);
|
|
497
|
-
const loaded = [];
|
|
498
|
-
const forceReady = setTimeout(() => {
|
|
499
|
-
bridge.logInfo("debug", `${readyTimeout}ms have passed, forcing timelineIsReady`);
|
|
500
|
-
bridge.timelineIsReady();
|
|
501
|
-
}, readyTimeout);
|
|
502
|
-
function onDepLoaded(name) {
|
|
503
|
-
loaded.push(name);
|
|
504
|
-
if (!["renderedRequiredStyles", ...bridge.themeFileNames ?? []].every((dep) => loaded.includes(dep))) return;
|
|
505
|
-
clearTimeout(forceReady);
|
|
506
|
-
document.fonts.ready.then(() => bridge.timelineIsReady());
|
|
507
|
-
}
|
|
508
|
-
for (const url of bridge.themeURL ?? []) {
|
|
509
|
-
const link = document.createElement("link");
|
|
510
|
-
link.rel = "stylesheet";
|
|
511
|
-
link.href = url;
|
|
512
|
-
link.onload = () => onDepLoaded(url);
|
|
513
|
-
link.onerror = () => onDepLoaded(url);
|
|
514
|
-
document.head.appendChild(link);
|
|
515
|
-
}
|
|
516
|
-
onDepLoaded("renderedRequiredStyles");
|
|
517
|
-
function applyFeedClasses() {
|
|
518
|
-
const classes = [...bridge.feed?.classes ?? []];
|
|
519
|
-
if (bridge.isSavedTimeline) classes.push("saved-timeline");
|
|
520
|
-
if (rootEl && classes.length) rootEl.classList.add(...classes);
|
|
521
|
-
}
|
|
522
|
-
applyFeedClasses();
|
|
523
|
-
const stopFeed = bridge.$on("change:feed", applyFeedClasses);
|
|
524
|
-
return () => {
|
|
525
|
-
clearTimeout(forceReady);
|
|
526
|
-
stopFeed();
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
//#endregion
|
|
530
|
-
export { makeProxyBridge as a, setupPugpigUpdate as i, bootstrap as n, rawBridge as o, triggerPugpigUpdateSequence as r, outgoingActions as s, BOOTSTRAP_METHODS as t };
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { n as createPugpigBridgeServiceProxy, r as fetchJson } from "./mockBridgeService-vnaAIjCu.mjs";
|
|
2
|
-
//#region src/development/devConfig.ts
|
|
3
|
-
function resolveUrl(url) {
|
|
4
|
-
if (url === "origin") url = window.location.origin;
|
|
5
|
-
if (!/^https?:\/\//i.test(url)) url = "https://" + url;
|
|
6
|
-
return url;
|
|
7
|
-
}
|
|
8
|
-
async function resolveUrlParams(config) {
|
|
9
|
-
const timelinesEndpoint = `${config.live_domain}/timelines.json`;
|
|
10
|
-
const timelinesJson = await fetchJson(timelinesEndpoint);
|
|
11
|
-
const timelinesCurrent = timelinesJson.timelines?.find((timeline) => timeline.id === config.edition) ?? timelinesJson.timelines[0];
|
|
12
|
-
const timelineEndpoint = new URL(timelinesCurrent?.feed ?? "", timelinesEndpoint).href;
|
|
13
|
-
const timelineJson = await fetchJson(config?.stories || timelineEndpoint);
|
|
14
|
-
return Object.assign(config, {
|
|
15
|
-
live_domain: config.live_domain,
|
|
16
|
-
timelines: timelinesJson.timelines,
|
|
17
|
-
timeline: timelinesCurrent,
|
|
18
|
-
stories: timelineJson.stories,
|
|
19
|
-
metadata: timelineJson.metadata
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
async function resolveConfigParams(config) {
|
|
23
|
-
const platformName = config.platform ?? "web";
|
|
24
|
-
const configVersion = (await fetchJson(`${config.live_domain}/bolt_properties.json`))?.[`${config.config}_version`] ?? "latest_version";
|
|
25
|
-
const configUrl = `${config.live_domain}/bolt/config/${configVersion}/web/config.json`;
|
|
26
|
-
const themeUrls = (config.config ? await fetchJson(configUrl) : void 0)?.timeline_css.map((pathname) => `${config.live_domain}/bolt/config/${configVersion}/${platformName}/${pathname}`);
|
|
27
|
-
return Object.assign(config, { themeUrl: themeUrls });
|
|
28
|
-
}
|
|
29
|
-
async function fetchRemoteConfig(_ctx, _callback) {
|
|
30
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
31
|
-
const paramsObj = Object.fromEntries(urlParams.entries());
|
|
32
|
-
if (paramsObj.useStorage) {
|
|
33
|
-
const cached = localStorage.getItem("config");
|
|
34
|
-
if (cached) return JSON.parse(cached);
|
|
35
|
-
}
|
|
36
|
-
let mergedConfig = {
|
|
37
|
-
...window.__TIMELINE_LOCAL_CONFIG__,
|
|
38
|
-
...paramsObj,
|
|
39
|
-
debugLogs: paramsObj.debugLogs === "true"
|
|
40
|
-
};
|
|
41
|
-
if (mergedConfig.live_domain) {
|
|
42
|
-
mergedConfig.live_domain = resolveUrl(mergedConfig.live_domain);
|
|
43
|
-
mergedConfig = await resolveUrlParams(mergedConfig);
|
|
44
|
-
mergedConfig = await resolveConfigParams(mergedConfig);
|
|
45
|
-
}
|
|
46
|
-
localStorage.setItem("config", JSON.stringify(mergedConfig));
|
|
47
|
-
return mergedConfig;
|
|
48
|
-
}
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/development/index.ts
|
|
51
|
-
async function injectBridge(app, callback) {
|
|
52
|
-
window.config = await fetchRemoteConfig(app, callback);
|
|
53
|
-
window.pugpigBridgeService = createPugpigBridgeServiceProxy(window.config);
|
|
54
|
-
}
|
|
55
|
-
//#endregion
|
|
56
|
-
export { injectBridge };
|