@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.
@@ -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 };