@reidelsaltres/pureper 0.2.26 → 0.2.28
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/out/foundation/Theme.d.ts +39 -0
- package/out/foundation/Theme.d.ts.map +1 -1
- package/out/foundation/Theme.js +94 -0
- package/out/foundation/Theme.js.map +1 -1
- package/out/foundation/worker/ServiceWorker.d.ts +10 -0
- package/out/foundation/worker/ServiceWorker.d.ts.map +1 -1
- package/out/foundation/worker/ServiceWorker.js +14 -0
- package/out/foundation/worker/ServiceWorker.js.map +1 -1
- package/out/index.d.ts +1 -1
- package/out/index.d.ts.map +1 -1
- package/out/index.js.map +1 -1
- package/package.json +1 -1
- package/src/foundation/Theme.ts +127 -0
- package/src/foundation/worker/ServiceWorker.ts +21 -0
- package/src/foundation/worker/serviceworker.js +78 -1
- package/src/index.ts +1 -1
|
@@ -1,6 +1,45 @@
|
|
|
1
|
+
import Observable from "./api/Observer.js";
|
|
1
2
|
export declare let ACTIVE_THEME_KEY: string;
|
|
2
3
|
export declare function loadTheme(name: string): Promise<string>;
|
|
3
4
|
export declare function loadThemeAsInstant(name: string): Promise<CSSStyleSheet>;
|
|
4
5
|
export declare function init(): Promise<void>;
|
|
5
6
|
export declare function setTheme(name: string): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* AppTheme descriptor — combines a color palette with optional
|
|
9
|
+
* component implementation switches and lifecycle callbacks.
|
|
10
|
+
*/
|
|
11
|
+
export interface AppThemeConfig {
|
|
12
|
+
/** Name of the theme */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Color palette CSS file name (without .theme.css extension), e.g. "Winter" */
|
|
15
|
+
palette: string;
|
|
16
|
+
/** Map of placeholder name → implementation name to switch when theme activates */
|
|
17
|
+
implementations?: Map<string, string>;
|
|
18
|
+
/** Called when theme is activated — use for effects (e.g., snow animation) */
|
|
19
|
+
onActivate?: () => void;
|
|
20
|
+
/** Called when theme is deactivated — use to clean up effects */
|
|
21
|
+
onDeactivate?: () => void;
|
|
22
|
+
}
|
|
23
|
+
/** Currently active AppTheme, or null if only a color palette is active */
|
|
24
|
+
export declare const activeAppTheme: Observable<AppThemeConfig | null>;
|
|
25
|
+
/** Register an AppTheme so it can be activated by name */
|
|
26
|
+
export declare function registerAppTheme(config: AppThemeConfig): void;
|
|
27
|
+
/** Get a registered AppTheme by name */
|
|
28
|
+
export declare function getAppTheme(name: string): AppThemeConfig | undefined;
|
|
29
|
+
/** Get all registered AppTheme names */
|
|
30
|
+
export declare function getAppThemeNames(): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Activate an AppTheme by name.
|
|
33
|
+
* - Applies its color palette
|
|
34
|
+
* - Switches component implementations listed in the config
|
|
35
|
+
* - Calls onActivate callback
|
|
36
|
+
*/
|
|
37
|
+
export declare function activateAppTheme(name: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Deactivate the currently active AppTheme.
|
|
40
|
+
* - Calls onDeactivate callback
|
|
41
|
+
* - Reverts implementations to defaults
|
|
42
|
+
* - Does NOT change the color palette (that's separate)
|
|
43
|
+
*/
|
|
44
|
+
export declare function deactivateAppTheme(): Promise<void>;
|
|
6
45
|
//# sourceMappingURL=Theme.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Theme.d.ts","sourceRoot":"","sources":["../../src/foundation/Theme.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Theme.d.ts","sourceRoot":"","sources":["../../src/foundation/Theme.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAE3C,eAAO,IAAI,gBAAgB,QAAU,CAAC;AAItC,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7D;AACD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAK7E;AACD,wBAAsB,IAAI,kBAOzB;AACD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,iBA0B1C;AAID;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,2EAA2E;AAC3E,eAAO,MAAM,cAAc,EAAE,UAAU,CAAC,cAAc,GAAG,IAAI,CAA+C,CAAC;AAK7G,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAE7D;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEpE;AAED,wCAAwC;AACxC,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkClE;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CA2BxD"}
|
package/out/foundation/Theme.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import Fetcher from "./Fetcher.js";
|
|
2
|
+
import Observable from "./api/Observer.js";
|
|
2
3
|
export let ACTIVE_THEME_KEY = "Empty";
|
|
3
4
|
let activeThemeSheet = null;
|
|
5
|
+
let _internalThemeSwitch = false;
|
|
4
6
|
export async function loadTheme(name) {
|
|
5
7
|
// Use hosting-root absolute path so GitHub Pages subfolder deployments (e.g. /Hellper/) keep the subfolder.
|
|
6
8
|
return Fetcher.fetchText(`/resources/${name}.theme.css`);
|
|
@@ -21,6 +23,13 @@ export async function init() {
|
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
export async function setTheme(name) {
|
|
26
|
+
// Deactivate AppTheme when switching to a plain palette (but not when called from activateAppTheme)
|
|
27
|
+
if (!_internalThemeSwitch && activeAppTheme.getObject()) {
|
|
28
|
+
const current = activeAppTheme.getObject();
|
|
29
|
+
current.onDeactivate?.();
|
|
30
|
+
activeAppTheme.setObject(null);
|
|
31
|
+
localStorage.removeItem('appTheme');
|
|
32
|
+
}
|
|
24
33
|
let theme = await loadTheme(name);
|
|
25
34
|
theme = theme.replace(/\.[\w-]+-theme/g, ":root");
|
|
26
35
|
const sheet = new CSSStyleSheet();
|
|
@@ -41,4 +50,89 @@ export async function setTheme(name) {
|
|
|
41
50
|
}
|
|
42
51
|
activeThemeSheet = sheet;
|
|
43
52
|
}
|
|
53
|
+
/** Currently active AppTheme, or null if only a color palette is active */
|
|
54
|
+
export const activeAppTheme = new Observable(null);
|
|
55
|
+
/** Registry of all registered AppThemes */
|
|
56
|
+
const appThemeRegistry = new Map();
|
|
57
|
+
/** Register an AppTheme so it can be activated by name */
|
|
58
|
+
export function registerAppTheme(config) {
|
|
59
|
+
appThemeRegistry.set(config.name, config);
|
|
60
|
+
}
|
|
61
|
+
/** Get a registered AppTheme by name */
|
|
62
|
+
export function getAppTheme(name) {
|
|
63
|
+
return appThemeRegistry.get(name);
|
|
64
|
+
}
|
|
65
|
+
/** Get all registered AppTheme names */
|
|
66
|
+
export function getAppThemeNames() {
|
|
67
|
+
return Array.from(appThemeRegistry.keys());
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Activate an AppTheme by name.
|
|
71
|
+
* - Applies its color palette
|
|
72
|
+
* - Switches component implementations listed in the config
|
|
73
|
+
* - Calls onActivate callback
|
|
74
|
+
*/
|
|
75
|
+
export async function activateAppTheme(name) {
|
|
76
|
+
const config = appThemeRegistry.get(name);
|
|
77
|
+
if (!config)
|
|
78
|
+
throw new Error(`[Theme]: AppTheme "${name}" not registered`);
|
|
79
|
+
// Deactivate current AppTheme if any
|
|
80
|
+
await deactivateAppTheme();
|
|
81
|
+
// Apply palette (guarded to avoid deactivation inside setTheme)
|
|
82
|
+
_internalThemeSwitch = true;
|
|
83
|
+
await setTheme(config.palette);
|
|
84
|
+
_internalThemeSwitch = false;
|
|
85
|
+
ACTIVE_THEME_KEY = config.palette;
|
|
86
|
+
// Switch implementations
|
|
87
|
+
if (config.implementations) {
|
|
88
|
+
// Dynamic import to avoid circular dependency
|
|
89
|
+
const { Placeholder } = await import('./Injection.js');
|
|
90
|
+
for (const [placeholder, impl] of config.implementations) {
|
|
91
|
+
try {
|
|
92
|
+
await Placeholder.switchTo(placeholder, impl);
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
console.warn(`[Theme]: Failed to switch "${placeholder}" to "${impl}":`, e);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Set active
|
|
100
|
+
activeAppTheme.setObject(config);
|
|
101
|
+
localStorage.setItem('appTheme', name);
|
|
102
|
+
// Call activate callback
|
|
103
|
+
config.onActivate?.();
|
|
104
|
+
console.info(`[Theme]: AppTheme "${name}" activated`);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Deactivate the currently active AppTheme.
|
|
108
|
+
* - Calls onDeactivate callback
|
|
109
|
+
* - Reverts implementations to defaults
|
|
110
|
+
* - Does NOT change the color palette (that's separate)
|
|
111
|
+
*/
|
|
112
|
+
export async function deactivateAppTheme() {
|
|
113
|
+
const current = activeAppTheme.getObject();
|
|
114
|
+
if (!current)
|
|
115
|
+
return;
|
|
116
|
+
// Call deactivate callback
|
|
117
|
+
current.onDeactivate?.();
|
|
118
|
+
// Revert implementations to defaults
|
|
119
|
+
if (current.implementations) {
|
|
120
|
+
const { Placeholder } = await import('./Injection.js');
|
|
121
|
+
for (const [placeholder] of current.implementations) {
|
|
122
|
+
try {
|
|
123
|
+
const p = Placeholder.get(placeholder);
|
|
124
|
+
const firstImpl = p.implementations.entries().next().value;
|
|
125
|
+
if (firstImpl) {
|
|
126
|
+
await Placeholder.switchTo(placeholder, firstImpl[0]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (e) {
|
|
130
|
+
console.warn(`[Theme]: Failed to revert "${placeholder}":`, e);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
activeAppTheme.setObject(null);
|
|
135
|
+
localStorage.removeItem('appTheme');
|
|
136
|
+
console.info(`[Theme]: AppTheme "${current.name}" deactivated`);
|
|
137
|
+
}
|
|
44
138
|
//# sourceMappingURL=Theme.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Theme.js","sourceRoot":"","sources":["../../src/foundation/Theme.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Theme.js","sourceRoot":"","sources":["../../src/foundation/Theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,8 @@ export interface FetchActivityItem {
|
|
|
14
14
|
error?: string;
|
|
15
15
|
}
|
|
16
16
|
export type PageSourceType = 'cache' | 'network' | 'unknown';
|
|
17
|
+
export type CacheStrategy = 'cache-first' | 'network-first';
|
|
18
|
+
export type PrecacheMode = 'precache' | 'normal' | 'disabled';
|
|
17
19
|
/**
|
|
18
20
|
* Client-side Service Worker manager for Purper SPA.
|
|
19
21
|
*
|
|
@@ -36,6 +38,8 @@ export default class ServiceWorker {
|
|
|
36
38
|
static readonly online: Observable<boolean>;
|
|
37
39
|
static readonly fetchActivities: Observable<FetchActivityItem[]>;
|
|
38
40
|
static readonly pageSource: Observable<PageSourceType>;
|
|
41
|
+
static readonly cacheStrategy: Observable<CacheStrategy>;
|
|
42
|
+
static readonly precacheMode: Observable<PrecacheMode>;
|
|
39
43
|
private static _fetchTrackingEnabled;
|
|
40
44
|
private static _fetchListenerBound;
|
|
41
45
|
private static _connectivityBound;
|
|
@@ -55,6 +59,12 @@ export default class ServiceWorker {
|
|
|
55
59
|
static clearCache(): Promise<boolean>;
|
|
56
60
|
/** Check whether a URL exists in the SW cache. */
|
|
57
61
|
static isCached(url: string): Promise<boolean>;
|
|
62
|
+
static setCacheStrategy(strategy: CacheStrategy): void;
|
|
63
|
+
static setPrecacheMode(mode: PrecacheMode): void;
|
|
64
|
+
static getConfig(): Promise<{
|
|
65
|
+
strategy: CacheStrategy;
|
|
66
|
+
precacheMode: PrecacheMode;
|
|
67
|
+
}>;
|
|
58
68
|
/** Ask the waiting SW to activate immediately. */
|
|
59
69
|
static skipWaiting(): void;
|
|
60
70
|
/** Get the version string from the running SW. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceWorker.d.ts","sourceRoot":"","sources":["../../../src/foundation/worker/ServiceWorker.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,oBAAoB,CAAC;AAE5C,MAAM,MAAM,mBAAmB,GAAG;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAE7D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IAC9B,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAA4B;IAEzD,uEAAuE;IACvE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAoC;IAE/E,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAsB;IACtF,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,cAAc,CAAC,CAA6C;IACnG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAS;IAC7C,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAS;IAG3C,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAS;IAC1C,OAAO,CAAC,MAAM,CAAC,iBAAiB;WAenB,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,yBAAyB,GAAG,SAAS,CAAC;IA0CnG,OAAO,CAAC,MAAM,CAAC,YAAY;IAI3B,OAAO,CAAC,MAAM,CAAC,QAAQ;IAcvB,wCAAwC;WAC3B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBnD,sDAAsD;IACtD,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAI1C,gFAAgF;WACnE,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe3D,iDAAiD;WACpC,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAS9C,gCAAgC;WACnB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAS3C,kDAAkD;WACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpD,kDAAkD;IAClD,MAAM,CAAC,WAAW,IAAI,IAAI;IAI1B,kDAAkD;WACrC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAO1C;;;;OAIG;WACU,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuB1D,oCAAoC;IACpC,MAAM,KAAK,YAAY,IAAI,yBAAyB,GAAG,SAAS,CAE/D;IAID,MAAM,CAAC,mBAAmB,IAAI,IAAI;IAQlC,MAAM,CAAC,oBAAoB,IAAI,IAAI;IAOnC,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAgEpC"}
|
|
1
|
+
{"version":3,"file":"ServiceWorker.d.ts","sourceRoot":"","sources":["../../../src/foundation/worker/ServiceWorker.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,8 @@ export default class ServiceWorker {
|
|
|
21
21
|
static online = new Observable(navigator.onLine);
|
|
22
22
|
static fetchActivities = new Observable([]);
|
|
23
23
|
static pageSource = new Observable('unknown');
|
|
24
|
+
static cacheStrategy = new Observable('cache-first');
|
|
25
|
+
static precacheMode = new Observable('normal');
|
|
24
26
|
static _fetchTrackingEnabled = false;
|
|
25
27
|
static _fetchListenerBound = false;
|
|
26
28
|
// ── Connectivity listeners (bound once) ─────────────────────────
|
|
@@ -167,6 +169,18 @@ export default class ServiceWorker {
|
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
171
|
}
|
|
172
|
+
// ── Cache Strategy & Precache Mode ────────────────────────────
|
|
173
|
+
static setCacheStrategy(strategy) {
|
|
174
|
+
this.cacheStrategy.setObject(strategy);
|
|
175
|
+
this._postMessage({ type: 'SET_CACHE_STRATEGY', strategy });
|
|
176
|
+
}
|
|
177
|
+
static setPrecacheMode(mode) {
|
|
178
|
+
this.precacheMode.setObject(mode);
|
|
179
|
+
this._postMessage({ type: 'SET_PRECACHE_MODE', mode });
|
|
180
|
+
}
|
|
181
|
+
static async getConfig() {
|
|
182
|
+
return this._request({ type: 'GET_CONFIG' });
|
|
183
|
+
}
|
|
170
184
|
// ── Version & lifecycle ─────────────────────────────────────────
|
|
171
185
|
/** Ask the waiting SW to activate immediately. */
|
|
172
186
|
static skipWaiting() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceWorker.js","sourceRoot":"","sources":["../../../src/foundation/worker/ServiceWorker.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ServiceWorker.js","sourceRoot":"","sources":["../../../src/foundation/worker/ServiceWorker.ts"],"names":[],"mappings":"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"}
|
package/out/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { Implementation, ImplementationStruct, Placeholder } from './foundation/
|
|
|
13
13
|
export { default as Fetcher } from './foundation/Fetcher.js';
|
|
14
14
|
export * from './foundation/engine/TemplateEngine.js';
|
|
15
15
|
export { Router } from './foundation/worker/Router.js';
|
|
16
|
-
export { default as ServiceWorker, ServiceWorkerConfig, FetchActivityItem, PageSourceType } from './foundation/worker/ServiceWorker.js';
|
|
16
|
+
export { default as ServiceWorker, ServiceWorkerConfig, FetchActivityItem, PageSourceType, CacheStrategy, PrecacheMode } from './foundation/worker/ServiceWorker.js';
|
|
17
17
|
export * from './foundation/Hosting.js';
|
|
18
18
|
export * from './foundation/Theme.js';
|
|
19
19
|
//# sourceMappingURL=index.d.ts.map
|
package/out/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAC1D,OAAO,EACN,OAAO,IAAI,UAAU,EACrB,SAAS,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAC3F,YAAY,EACZ,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAE7D,cAAc,uCAAuC,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAC1D,OAAO,EACN,OAAO,IAAI,UAAU,EACrB,SAAS,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAC3F,YAAY,EACZ,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAE7D,cAAc,uCAAuC,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAErK,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
|
package/out/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAC1D,OAAO,EACN,OAAO,IAAI,UAAU,EAC+B,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAC3F,YAAY,EACZ,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAiB,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAwB,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAE7D,cAAc,uCAAuC,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAC1D,OAAO,EACN,OAAO,IAAI,UAAU,EAC+B,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAC3F,YAAY,EACZ,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAiB,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAwB,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAE7D,cAAc,uCAAuC,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAuF,MAAM,sCAAsC,CAAC;AAErK,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AAGtC,qEAAqE;AACrE;;WAEQ;AAER,yEAAyE"}
|
package/package.json
CHANGED
package/src/foundation/Theme.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import Fetcher from "./Fetcher.js";
|
|
2
|
+
import Observable from "./api/Observer.js";
|
|
2
3
|
|
|
3
4
|
export let ACTIVE_THEME_KEY = "Empty";
|
|
4
5
|
let activeThemeSheet: CSSStyleSheet | null = null;
|
|
6
|
+
let _internalThemeSwitch = false;
|
|
5
7
|
|
|
6
8
|
export async function loadTheme(name: string): Promise<string> {
|
|
7
9
|
// Use hosting-root absolute path so GitHub Pages subfolder deployments (e.g. /Hellper/) keep the subfolder.
|
|
@@ -22,6 +24,14 @@ export async function init() {
|
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
export async function setTheme(name: string) {
|
|
27
|
+
// Deactivate AppTheme when switching to a plain palette (but not when called from activateAppTheme)
|
|
28
|
+
if (!_internalThemeSwitch && activeAppTheme.getObject()) {
|
|
29
|
+
const current = activeAppTheme.getObject()!;
|
|
30
|
+
current.onDeactivate?.();
|
|
31
|
+
activeAppTheme.setObject(null);
|
|
32
|
+
localStorage.removeItem('appTheme');
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
let theme: string = await loadTheme(name);
|
|
26
36
|
theme = theme.replace(/\.[\w-]+-theme/g, ":root");
|
|
27
37
|
const sheet = new CSSStyleSheet();
|
|
@@ -41,3 +51,120 @@ export async function setTheme(name: string) {
|
|
|
41
51
|
activeThemeSheet = sheet;
|
|
42
52
|
}
|
|
43
53
|
|
|
54
|
+
// ── AppTheme system ─────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* AppTheme descriptor — combines a color palette with optional
|
|
58
|
+
* component implementation switches and lifecycle callbacks.
|
|
59
|
+
*/
|
|
60
|
+
export interface AppThemeConfig {
|
|
61
|
+
/** Name of the theme */
|
|
62
|
+
name: string;
|
|
63
|
+
/** Color palette CSS file name (without .theme.css extension), e.g. "Winter" */
|
|
64
|
+
palette: string;
|
|
65
|
+
/** Map of placeholder name → implementation name to switch when theme activates */
|
|
66
|
+
implementations?: Map<string, string>;
|
|
67
|
+
/** Called when theme is activated — use for effects (e.g., snow animation) */
|
|
68
|
+
onActivate?: () => void;
|
|
69
|
+
/** Called when theme is deactivated — use to clean up effects */
|
|
70
|
+
onDeactivate?: () => void;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Currently active AppTheme, or null if only a color palette is active */
|
|
74
|
+
export const activeAppTheme: Observable<AppThemeConfig | null> = new Observable<AppThemeConfig | null>(null);
|
|
75
|
+
|
|
76
|
+
/** Registry of all registered AppThemes */
|
|
77
|
+
const appThemeRegistry: Map<string, AppThemeConfig> = new Map();
|
|
78
|
+
|
|
79
|
+
/** Register an AppTheme so it can be activated by name */
|
|
80
|
+
export function registerAppTheme(config: AppThemeConfig): void {
|
|
81
|
+
appThemeRegistry.set(config.name, config);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Get a registered AppTheme by name */
|
|
85
|
+
export function getAppTheme(name: string): AppThemeConfig | undefined {
|
|
86
|
+
return appThemeRegistry.get(name);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Get all registered AppTheme names */
|
|
90
|
+
export function getAppThemeNames(): string[] {
|
|
91
|
+
return Array.from(appThemeRegistry.keys());
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Activate an AppTheme by name.
|
|
96
|
+
* - Applies its color palette
|
|
97
|
+
* - Switches component implementations listed in the config
|
|
98
|
+
* - Calls onActivate callback
|
|
99
|
+
*/
|
|
100
|
+
export async function activateAppTheme(name: string): Promise<void> {
|
|
101
|
+
const config = appThemeRegistry.get(name);
|
|
102
|
+
if (!config) throw new Error(`[Theme]: AppTheme "${name}" not registered`);
|
|
103
|
+
|
|
104
|
+
// Deactivate current AppTheme if any
|
|
105
|
+
await deactivateAppTheme();
|
|
106
|
+
|
|
107
|
+
// Apply palette (guarded to avoid deactivation inside setTheme)
|
|
108
|
+
_internalThemeSwitch = true;
|
|
109
|
+
await setTheme(config.palette);
|
|
110
|
+
_internalThemeSwitch = false;
|
|
111
|
+
ACTIVE_THEME_KEY = config.palette;
|
|
112
|
+
|
|
113
|
+
// Switch implementations
|
|
114
|
+
if (config.implementations) {
|
|
115
|
+
// Dynamic import to avoid circular dependency
|
|
116
|
+
const { Placeholder } = await import('./Injection.js');
|
|
117
|
+
for (const [placeholder, impl] of config.implementations) {
|
|
118
|
+
try {
|
|
119
|
+
await Placeholder.switchTo(placeholder, impl);
|
|
120
|
+
} catch (e) {
|
|
121
|
+
console.warn(`[Theme]: Failed to switch "${placeholder}" to "${impl}":`, e);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Set active
|
|
127
|
+
activeAppTheme.setObject(config);
|
|
128
|
+
localStorage.setItem('appTheme', name);
|
|
129
|
+
|
|
130
|
+
// Call activate callback
|
|
131
|
+
config.onActivate?.();
|
|
132
|
+
|
|
133
|
+
console.info(`[Theme]: AppTheme "${name}" activated`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Deactivate the currently active AppTheme.
|
|
138
|
+
* - Calls onDeactivate callback
|
|
139
|
+
* - Reverts implementations to defaults
|
|
140
|
+
* - Does NOT change the color palette (that's separate)
|
|
141
|
+
*/
|
|
142
|
+
export async function deactivateAppTheme(): Promise<void> {
|
|
143
|
+
const current = activeAppTheme.getObject();
|
|
144
|
+
if (!current) return;
|
|
145
|
+
|
|
146
|
+
// Call deactivate callback
|
|
147
|
+
current.onDeactivate?.();
|
|
148
|
+
|
|
149
|
+
// Revert implementations to defaults
|
|
150
|
+
if (current.implementations) {
|
|
151
|
+
const { Placeholder } = await import('./Injection.js');
|
|
152
|
+
for (const [placeholder] of current.implementations) {
|
|
153
|
+
try {
|
|
154
|
+
const p = Placeholder.get(placeholder);
|
|
155
|
+
const firstImpl = p.implementations.entries().next().value;
|
|
156
|
+
if (firstImpl) {
|
|
157
|
+
await Placeholder.switchTo(placeholder, firstImpl[0]);
|
|
158
|
+
}
|
|
159
|
+
} catch (e) {
|
|
160
|
+
console.warn(`[Theme]: Failed to revert "${placeholder}":`, e);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
activeAppTheme.setObject(null);
|
|
166
|
+
localStorage.removeItem('appTheme');
|
|
167
|
+
|
|
168
|
+
console.info(`[Theme]: AppTheme "${current.name}" deactivated`);
|
|
169
|
+
}
|
|
170
|
+
|
|
@@ -18,6 +18,9 @@ export interface FetchActivityItem {
|
|
|
18
18
|
|
|
19
19
|
export type PageSourceType = 'cache' | 'network' | 'unknown';
|
|
20
20
|
|
|
21
|
+
export type CacheStrategy = 'cache-first' | 'network-first';
|
|
22
|
+
export type PrecacheMode = 'precache' | 'normal' | 'disabled';
|
|
23
|
+
|
|
21
24
|
/**
|
|
22
25
|
* Client-side Service Worker manager for Purper SPA.
|
|
23
26
|
*
|
|
@@ -42,6 +45,8 @@ export default class ServiceWorker {
|
|
|
42
45
|
|
|
43
46
|
static readonly fetchActivities: Observable<FetchActivityItem[]> = new Observable([]);
|
|
44
47
|
static readonly pageSource: Observable<PageSourceType> = new Observable<PageSourceType>('unknown');
|
|
48
|
+
static readonly cacheStrategy: Observable<CacheStrategy> = new Observable<CacheStrategy>('cache-first');
|
|
49
|
+
static readonly precacheMode: Observable<PrecacheMode> = new Observable<PrecacheMode>('normal');
|
|
45
50
|
private static _fetchTrackingEnabled = false;
|
|
46
51
|
private static _fetchListenerBound = false;
|
|
47
52
|
|
|
@@ -197,6 +202,22 @@ export default class ServiceWorker {
|
|
|
197
202
|
}
|
|
198
203
|
}
|
|
199
204
|
|
|
205
|
+
// ── Cache Strategy & Precache Mode ────────────────────────────
|
|
206
|
+
|
|
207
|
+
static setCacheStrategy(strategy: CacheStrategy): void {
|
|
208
|
+
this.cacheStrategy.setObject(strategy);
|
|
209
|
+
this._postMessage({ type: 'SET_CACHE_STRATEGY', strategy });
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
static setPrecacheMode(mode: PrecacheMode): void {
|
|
213
|
+
this.precacheMode.setObject(mode);
|
|
214
|
+
this._postMessage({ type: 'SET_PRECACHE_MODE', mode });
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
static async getConfig(): Promise<{ strategy: CacheStrategy; precacheMode: PrecacheMode }> {
|
|
218
|
+
return this._request<{ strategy: CacheStrategy; precacheMode: PrecacheMode }>({ type: 'GET_CONFIG' });
|
|
219
|
+
}
|
|
220
|
+
|
|
200
221
|
// ── Version & lifecycle ─────────────────────────────────────────
|
|
201
222
|
|
|
202
223
|
/** Ask the waiting SW to activate immediately. */
|
|
@@ -20,6 +20,9 @@ const SW_VERSION = '1.0.0';
|
|
|
20
20
|
let fetchCounter = 0;
|
|
21
21
|
let fetchTrackingEnabled = false;
|
|
22
22
|
|
|
23
|
+
let cacheStrategy = 'cache-first';
|
|
24
|
+
let precacheMode = 'normal';
|
|
25
|
+
|
|
23
26
|
function broadcastToClients(message) {
|
|
24
27
|
self.clients.matchAll().then((clients) => {
|
|
25
28
|
clients.forEach((c) => c.postMessage(message));
|
|
@@ -108,7 +111,63 @@ self.addEventListener('fetch', (event) => {
|
|
|
108
111
|
return;
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
// Sub-resources (CSS, JS, images, fonts, JSON)
|
|
114
|
+
// Sub-resources (CSS, JS, images, fonts, JSON)
|
|
115
|
+
// Strategy depends on cacheStrategy and precacheMode settings.
|
|
116
|
+
|
|
117
|
+
// Disabled mode — always fetch from network, never cache
|
|
118
|
+
if (precacheMode === 'disabled') {
|
|
119
|
+
event.respondWith(
|
|
120
|
+
fetch(request)
|
|
121
|
+
.then((response) => {
|
|
122
|
+
if (tracking) {
|
|
123
|
+
const duration = Date.now() - startTime;
|
|
124
|
+
const size = parseInt(response.headers.get('Content-Length')) || -1;
|
|
125
|
+
broadcastToClients({ type: 'FETCH_COMPLETE', id: fetchId, url: request.url, size, duration, fromCache: false, timestamp: Date.now() });
|
|
126
|
+
}
|
|
127
|
+
return response;
|
|
128
|
+
})
|
|
129
|
+
.catch((err) => {
|
|
130
|
+
if (tracking) {
|
|
131
|
+
broadcastToClients({ type: 'FETCH_ERROR', id: fetchId, url: request.url, error: err.message || String(err), timestamp: Date.now() });
|
|
132
|
+
}
|
|
133
|
+
throw err;
|
|
134
|
+
})
|
|
135
|
+
);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Network-first for sub-resources
|
|
140
|
+
if (cacheStrategy === 'network-first') {
|
|
141
|
+
event.respondWith(
|
|
142
|
+
fetch(request)
|
|
143
|
+
.then((response) => {
|
|
144
|
+
if (response.ok && response.type === 'basic') {
|
|
145
|
+
const clone = response.clone();
|
|
146
|
+
caches.open(CACHE_VERSION).then((cache) => cache.put(request, clone));
|
|
147
|
+
}
|
|
148
|
+
if (tracking) {
|
|
149
|
+
const duration = Date.now() - startTime;
|
|
150
|
+
const size = parseInt(response.headers.get('Content-Length')) || -1;
|
|
151
|
+
broadcastToClients({ type: 'FETCH_COMPLETE', id: fetchId, url: request.url, size, duration, fromCache: false, timestamp: Date.now() });
|
|
152
|
+
}
|
|
153
|
+
return response;
|
|
154
|
+
})
|
|
155
|
+
.catch(() => {
|
|
156
|
+
return caches.match(request).then((cached) => {
|
|
157
|
+
if (tracking) {
|
|
158
|
+
const duration = Date.now() - startTime;
|
|
159
|
+
const size = cached ? (parseInt(cached.headers.get('Content-Length')) || -1) : -1;
|
|
160
|
+
broadcastToClients({ type: 'FETCH_COMPLETE', id: fetchId, url: request.url, size, duration, fromCache: true, timestamp: Date.now() });
|
|
161
|
+
}
|
|
162
|
+
if (cached) return cached;
|
|
163
|
+
throw new Error('No cached response available');
|
|
164
|
+
});
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Cache-first for sub-resources (default)
|
|
112
171
|
event.respondWith(
|
|
113
172
|
caches.match(request).then((cached) => {
|
|
114
173
|
if (cached) {
|
|
@@ -243,6 +302,24 @@ self.addEventListener('message', (event) => {
|
|
|
243
302
|
console.log('[ServiceWorker]: Fetch tracking disabled');
|
|
244
303
|
break;
|
|
245
304
|
|
|
305
|
+
case 'SET_CACHE_STRATEGY':
|
|
306
|
+
if (event.data.strategy === 'cache-first' || event.data.strategy === 'network-first') {
|
|
307
|
+
cacheStrategy = event.data.strategy;
|
|
308
|
+
console.log(`[ServiceWorker]: Cache strategy set to "${cacheStrategy}"`);
|
|
309
|
+
}
|
|
310
|
+
break;
|
|
311
|
+
|
|
312
|
+
case 'SET_PRECACHE_MODE':
|
|
313
|
+
if (event.data.mode === 'precache' || event.data.mode === 'normal' || event.data.mode === 'disabled') {
|
|
314
|
+
precacheMode = event.data.mode;
|
|
315
|
+
console.log(`[ServiceWorker]: Precache mode set to "${precacheMode}"`);
|
|
316
|
+
}
|
|
317
|
+
break;
|
|
318
|
+
|
|
319
|
+
case 'GET_CONFIG':
|
|
320
|
+
if (port) port.postMessage({ strategy: cacheStrategy, precacheMode: precacheMode });
|
|
321
|
+
break;
|
|
322
|
+
|
|
246
323
|
default:
|
|
247
324
|
console.warn(`[ServiceWorker]: Unknown message type "${type}"`);
|
|
248
325
|
}
|
package/src/index.ts
CHANGED
|
@@ -24,7 +24,7 @@ export { default as Fetcher } from './foundation/Fetcher.js';
|
|
|
24
24
|
export * from './foundation/engine/TemplateEngine.js';
|
|
25
25
|
|
|
26
26
|
export { Router } from './foundation/worker/Router.js';
|
|
27
|
-
export { default as ServiceWorker, ServiceWorkerConfig, FetchActivityItem, PageSourceType } from './foundation/worker/ServiceWorker.js';
|
|
27
|
+
export { default as ServiceWorker, ServiceWorkerConfig, FetchActivityItem, PageSourceType, CacheStrategy, PrecacheMode } from './foundation/worker/ServiceWorker.js';
|
|
28
28
|
|
|
29
29
|
export * from './foundation/Hosting.js';
|
|
30
30
|
export * from './foundation/Theme.js';
|