swup 3.1.0 → 4.0.0-rc.14

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.
Files changed (71) hide show
  1. package/dist/Swup.cjs +1 -1
  2. package/dist/Swup.cjs.map +1 -1
  3. package/dist/Swup.modern.js +1 -1
  4. package/dist/Swup.modern.js.map +1 -1
  5. package/dist/Swup.module.js +1 -1
  6. package/dist/Swup.module.js.map +1 -1
  7. package/dist/Swup.umd.js +1 -1
  8. package/dist/Swup.umd.js.map +1 -1
  9. package/dist/types/Swup.d.ts +20 -20
  10. package/dist/types/helpers/delegateEvent.d.ts +4 -2
  11. package/dist/types/helpers/fetch.d.ts +2 -2
  12. package/dist/types/helpers.d.ts +10 -10
  13. package/dist/types/index.d.ts +5 -5
  14. package/dist/types/modules/Cache.d.ts +2 -2
  15. package/dist/types/modules/__test__/fetchPage.test.d.ts +1 -0
  16. package/dist/types/modules/destroy.d.ts +2 -0
  17. package/dist/types/modules/enable.d.ts +2 -0
  18. package/dist/types/modules/enterPage.d.ts +2 -2
  19. package/dist/types/modules/events.d.ts +6 -6
  20. package/dist/types/modules/fetchPage.d.ts +3 -3
  21. package/dist/types/modules/getAnchorElement.d.ts +0 -7
  22. package/dist/types/modules/getAnimationPromises.d.ts +1 -1
  23. package/dist/types/modules/getPageData.d.ts +2 -2
  24. package/dist/types/modules/handleLinkToSamePage.d.ts +2 -0
  25. package/dist/types/modules/isSameResolvedUrl.d.ts +8 -0
  26. package/dist/types/modules/leavePage.d.ts +2 -2
  27. package/dist/types/modules/linkClickHandler.d.ts +3 -0
  28. package/dist/types/modules/loadPage.d.ts +2 -5
  29. package/dist/types/modules/off.d.ts +3 -0
  30. package/dist/types/modules/on.d.ts +5 -0
  31. package/dist/types/modules/plugins.d.ts +1 -1
  32. package/dist/types/modules/popStateHandler.d.ts +2 -0
  33. package/dist/types/modules/renderPage.d.ts +2 -2
  34. package/dist/types/modules/resolveUrl.d.ts +7 -0
  35. package/dist/types/modules/shouldIgnoreVisit.d.ts +4 -0
  36. package/dist/types/modules/transitions.d.ts +1 -1
  37. package/dist/types/modules/triggerEvent.d.ts +3 -0
  38. package/dist/types/modules/triggerWillOpenNewWindow.d.ts +2 -0
  39. package/dist/types/modules/updateTransition.d.ts +2 -0
  40. package/dist/types/utils.d.ts +1 -1
  41. package/package.json +8 -5
  42. package/readme.md +30 -12
  43. package/src/Swup.ts +115 -143
  44. package/src/__test__/index.test.ts +6 -1
  45. package/src/helpers/Location.ts +10 -7
  46. package/src/helpers/__test__/matchPath.test.ts +54 -0
  47. package/src/helpers/delegateEvent.ts +1 -0
  48. package/src/helpers/matchPath.ts +22 -0
  49. package/src/helpers.ts +2 -4
  50. package/src/index.ts +7 -4
  51. package/src/modules/Cache.ts +43 -33
  52. package/src/modules/Context.ts +91 -0
  53. package/src/modules/Hooks.ts +393 -0
  54. package/src/modules/__test__/cache.test.ts +142 -0
  55. package/src/modules/__test__/hooks.test.ts +192 -0
  56. package/src/modules/enterPage.ts +19 -17
  57. package/src/modules/fetchPage.ts +74 -29
  58. package/src/modules/getAnchorElement.ts +8 -4
  59. package/src/modules/getAnimationPromises.ts +66 -75
  60. package/src/modules/leavePage.ts +22 -20
  61. package/src/modules/loadPage.ts +72 -54
  62. package/src/modules/renderPage.ts +41 -32
  63. package/src/modules/replaceContent.ts +26 -17
  64. package/src/utils/index.ts +24 -3
  65. package/src/helpers/fetch.ts +0 -33
  66. package/src/helpers/getDataFromHtml.ts +0 -39
  67. package/src/helpers/markSwupElements.ts +0 -16
  68. package/src/modules/__test__/events.test.ts +0 -72
  69. package/src/modules/events.ts +0 -92
  70. package/src/modules/getPageData.ts +0 -24
  71. package/src/modules/transitions.ts +0 -10
@@ -0,0 +1,393 @@
1
+ import { DelegateEvent } from 'delegate-it';
2
+
3
+ import Swup, { Options } from '../Swup.js';
4
+ import { isPromise, runAsPromise } from '../utils.js';
5
+ import { Context } from './Context.js';
6
+ import { FetchOptions, PageData } from './fetchPage.js';
7
+ import { AnimationDirection } from './getAnimationPromises.js';
8
+
9
+ export interface HookDefinitions {
10
+ animationInDone: undefined;
11
+ animationInStart: undefined;
12
+ animationOutDone: undefined;
13
+ animationOutStart: undefined;
14
+ animationSkipped: undefined;
15
+ awaitAnimation: { selector: Options['animationSelector']; direction: AnimationDirection };
16
+ cacheCleared: undefined;
17
+ clickLink: { el: HTMLAnchorElement; event: DelegateEvent<MouseEvent> };
18
+ disabled: undefined;
19
+ enabled: undefined;
20
+ fetchPage: { url: string; options: FetchOptions; response?: Response | Promise<Response> };
21
+ loadPage: { url: string; options: FetchOptions; page?: PageData | Promise<PageData> };
22
+ openPageInNewTab: { href: string };
23
+ pageCached: { page: PageData };
24
+ pageLoaded: { page: PageData; cache?: boolean };
25
+ pageView: { url: string; title: string };
26
+ popState: { event: PopStateEvent };
27
+ replaceContent: { page: PageData; containers: Options['containers'] };
28
+ samePage: undefined;
29
+ samePageWithHash: { hash: string; options: ScrollIntoViewOptions };
30
+ scrollToContent: { options: ScrollIntoViewOptions };
31
+ serverError: { url: string; status: number; response: Response };
32
+ transitionStart: undefined;
33
+ transitionEnd: undefined;
34
+ }
35
+
36
+ export type HookArguments<T extends HookName> = HookDefinitions[T];
37
+
38
+ export type HookName = keyof HookDefinitions;
39
+
40
+ export type Handler<T extends HookName> = (
41
+ context: Context,
42
+ args: HookArguments<T>
43
+ ) => Promise<any> | void;
44
+
45
+ export type Handlers = {
46
+ [K in HookName]: Handler<K>[];
47
+ };
48
+
49
+ export type HookOptions = {
50
+ once?: boolean;
51
+ before?: boolean;
52
+ priority?: number;
53
+ replace?: boolean;
54
+ };
55
+
56
+ export type HookRegistration<T extends HookName> = {
57
+ id: number;
58
+ hook: T;
59
+ handler: Handler<T>;
60
+ } & HookOptions;
61
+
62
+ type HookLedger<T extends HookName> = Map<Handler<T>, HookRegistration<T>>;
63
+
64
+ interface HookRegistry extends Map<HookName, HookLedger<HookName>> {
65
+ get<K extends HookName>(key: K): HookLedger<K> | undefined;
66
+ set<K extends HookName>(key: K, value: HookLedger<K>): this;
67
+ }
68
+
69
+ /**
70
+ * Hook registry.
71
+ *
72
+ * Create, trigger and handle hooks.
73
+ *
74
+ */
75
+ export class Hooks {
76
+ protected swup: Swup;
77
+ protected registry: HookRegistry = new Map();
78
+
79
+ // Can we deduplicate this somehow? Or make it error when not in sync with HookDefinitions?
80
+ // https://stackoverflow.com/questions/53387838/how-to-ensure-an-arrays-values-the-keys-of-a-typescript-interface/53395649
81
+ readonly hooks: HookName[] = [
82
+ 'animationInDone',
83
+ 'animationInStart',
84
+ 'animationOutDone',
85
+ 'animationOutStart',
86
+ 'animationSkipped',
87
+ 'awaitAnimation',
88
+ 'cacheCleared',
89
+ 'clickLink',
90
+ 'disabled',
91
+ 'enabled',
92
+ 'fetchPage',
93
+ 'loadPage',
94
+ 'openPageInNewTab',
95
+ 'pageCached',
96
+ 'pageLoaded',
97
+ 'pageView',
98
+ 'popState',
99
+ 'replaceContent',
100
+ 'samePage',
101
+ 'samePageWithHash',
102
+ 'scrollToContent',
103
+ 'serverError',
104
+ 'transitionStart',
105
+ 'transitionEnd'
106
+ ];
107
+
108
+ constructor(swup: Swup) {
109
+ this.swup = swup;
110
+ this.init();
111
+ }
112
+
113
+ /**
114
+ * Create ledgers for all core hooks.
115
+ */
116
+ protected init() {
117
+ this.hooks.forEach((hook) => this.create(hook));
118
+ }
119
+
120
+ /**
121
+ * Register a new hook.
122
+ */
123
+ create(hook: HookName) {
124
+ if (!this.registry.has(hook)) {
125
+ this.registry.set(hook, new Map());
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Check if a hook is registered.
131
+ */
132
+ has(hook: HookName): boolean {
133
+ return this.registry.has(hook);
134
+ }
135
+
136
+ /**
137
+ * Get the ledger with all registrations for a hook.
138
+ */
139
+ protected get<T extends HookName>(hook: T): HookLedger<T> | undefined {
140
+ const ledger = this.registry.get(hook);
141
+ if (ledger) {
142
+ return ledger;
143
+ } else {
144
+ console.error(`Unknown hook '${hook}'`);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Remove all handlers of all hooks.
150
+ */
151
+ clear() {
152
+ this.registry.forEach((ledger) => ledger.clear());
153
+ }
154
+
155
+ /**
156
+ * Register a new hook handler.
157
+ * @param hook Name of the hook to listen for
158
+ * @param handler The handler function to execute
159
+ * @param options Object to specify how and when the handler is executed
160
+ * Available options:
161
+ * - `once`: Only execute the handler once
162
+ * - `before`: Execute the handler before the default handler
163
+ * - `priority`: Specify the order in which the handlers are executed
164
+ * - `replace`: Replace the default handler with this handler
165
+ * @returns The handler function
166
+ */
167
+ on<T extends HookName>(hook: T, handler: Handler<T>): Handler<T>;
168
+ on<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions): Handler<T>;
169
+ on<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions = {}): Handler<T> {
170
+ const ledger = this.get(hook);
171
+ if (!ledger) {
172
+ console.warn(`Hook '${hook}' not found.`);
173
+ return handler;
174
+ }
175
+
176
+ const id = ledger.size + 1;
177
+ const registration: HookRegistration<T> = { ...options, id, hook, handler };
178
+ ledger.set(handler, registration);
179
+ return handler;
180
+ }
181
+
182
+ /**
183
+ * Register a new hook handler to run before the default handler.
184
+ * Shortcut for `hooks.on(hook, handler, { before: true })`.
185
+ * @param hook Name of the hook to listen for
186
+ * @param handler The handler function to execute
187
+ * @param options Any other event options (see `hooks.on()` for details)
188
+ * @returns The handler function
189
+ * @see on
190
+ */
191
+ before<T extends HookName>(hook: T, handler: Handler<T>): Handler<T>;
192
+ before<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions): Handler<T>;
193
+ before<T extends HookName>(
194
+ hook: T,
195
+ handler: Handler<T>,
196
+ options: HookOptions = {}
197
+ ): Handler<T> {
198
+ return this.on(hook, handler, { ...options, before: true });
199
+ }
200
+
201
+ /**
202
+ * Register a new hook handler to replace the default handler.
203
+ * Shortcut for `hooks.on(hook, handler, { replace: true })`.
204
+ * @param hook Name of the hook to listen for
205
+ * @param handler The handler function to execute instead of the default handler
206
+ * @param options Any other event options (see `hooks.on()` for details)
207
+ * @returns The handler function
208
+ * @see on
209
+ */
210
+ replace<T extends HookName>(hook: T, handler: Handler<T>): Handler<T>;
211
+ replace<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions): Handler<T>;
212
+ replace<T extends HookName>(
213
+ hook: T,
214
+ handler: Handler<T>,
215
+ options: HookOptions = {}
216
+ ): Handler<T> {
217
+ return this.on(hook, handler, { ...options, replace: true });
218
+ }
219
+
220
+ /**
221
+ * Register a new hook handler to run once.
222
+ * Shortcut for `hooks.on(hook, handler, { once: true })`.
223
+ * @param hook Name of the hook to listen for
224
+ * @param handler The handler function to execute
225
+ * @param options Any other event options (see `hooks.on()` for details)
226
+ * @see on
227
+ */
228
+ once<T extends HookName>(hook: T, handler: Handler<T>): Handler<T>;
229
+ once<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions): Handler<T>;
230
+ once<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions = {}): Handler<T> {
231
+ return this.on(hook, handler, { ...options, once: true });
232
+ }
233
+
234
+ /**
235
+ * Unregister a hook handler.
236
+ * @param hook Name of the hook the handler is registered for
237
+ * @param handler The handler function that was registered.
238
+ * If omitted, all handlers for the hook will be removed.
239
+ */
240
+ off<T extends HookName>(hook: T): void;
241
+ off<T extends HookName>(hook: T, handler: Handler<T>): void;
242
+ off<T extends HookName>(hook: T, handler?: Handler<T>): void {
243
+ const ledger = this.get(hook);
244
+
245
+ if (ledger && handler) {
246
+ const deleted = ledger.delete(handler);
247
+ if (!deleted) {
248
+ console.warn(`Handler for hook '${hook}' not found.`);
249
+ }
250
+ } else if (ledger) {
251
+ ledger.clear();
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Trigger a hook asynchronously, executing its default handler and all registered handlers.
257
+ * Will execute all handlers in order and `await` any `Promise`s they return.
258
+ * @param hook Name of the hook to trigger
259
+ * @param args Arguments to pass to the handler
260
+ * @param defaultHandler A default implementation of this hook to execute
261
+ * @returns The resolved return value of the executed default handler
262
+ */
263
+ async trigger<T extends HookName>(
264
+ hook: T,
265
+ args?: HookArguments<T>,
266
+ defaultHandler?: Handler<T>
267
+ ): Promise<any> {
268
+ const { before, handler, after } = this.getHandlers(hook, defaultHandler);
269
+ await this.execute(before, args);
270
+ const [result] = await this.execute(handler, args);
271
+ await this.execute(after, args);
272
+ this.dispatchDomEvent(hook);
273
+ return result;
274
+ }
275
+
276
+ /**
277
+ * Trigger a hook synchronously, executing its default handler and all registered handlers.
278
+ * Will execute all handlers in order, but will **not** `await` any `Promise`s they return.
279
+ * @param hook Name of the hook to trigger
280
+ * @param args Arguments to pass to the handler
281
+ * @param defaultHandler A default implementation of this hook to execute
282
+ * @returns The (possibly unresolved) return value of the executed default handler
283
+ */
284
+ triggerSync<T extends HookName>(
285
+ hook: T,
286
+ args?: HookArguments<T>,
287
+ defaultHandler?: Handler<T>
288
+ ): any {
289
+ const { before, after, handler } = this.getHandlers(hook, defaultHandler);
290
+ this.executeSync(before, args);
291
+ const [result] = this.executeSync(handler, args);
292
+ this.executeSync(after, args);
293
+ this.dispatchDomEvent(hook);
294
+ return result;
295
+ }
296
+
297
+ /**
298
+ * Execute the handlers for a hook, in order, as `Promise`s that will be `await`ed.
299
+ * @param registrations The registrations (handler + options) to execute
300
+ * @param args Arguments to pass to the handler
301
+ */
302
+ async execute<T extends HookName>(
303
+ registrations: HookRegistration<T>[],
304
+ args?: HookArguments<T>
305
+ ): Promise<any> {
306
+ const results = [];
307
+ for (const { hook, handler, once } of registrations) {
308
+ const result = await runAsPromise(handler, [this.swup.context, args]);
309
+ results.push(result);
310
+ if (once) {
311
+ this.off(hook, handler);
312
+ }
313
+ }
314
+ return results;
315
+ }
316
+
317
+ /**
318
+ * Execute the handlers for a hook, in order, without `await`ing any returned `Promise`s.
319
+ * @param registrations The registrations (handler + options) to execute
320
+ * @param args Arguments to pass to the handler
321
+ */
322
+ executeSync<T extends HookName>(
323
+ registrations: HookRegistration<T>[],
324
+ args?: HookArguments<T>
325
+ ): any[] {
326
+ const results = [];
327
+ for (const { hook, handler, once } of registrations) {
328
+ const result = handler(this.swup.context, args as HookArguments<T>);
329
+ results.push(result);
330
+ if (isPromise(result)) {
331
+ console.warn(
332
+ `Promise returned from handler for synchronous hook '${hook}'.` +
333
+ `Swup will not wait for it to resolve.`
334
+ );
335
+ }
336
+ if (once) {
337
+ this.off(hook, handler);
338
+ }
339
+ }
340
+ return results;
341
+ }
342
+
343
+ /**
344
+ * Get all registered handlers for a hook, sorted by priority and registration order.
345
+ * @param hook Name of the hook
346
+ * @param defaultHandler The optional default handler of this hook
347
+ * @returns An object with the handlers sorted into `before` and `after` arrays,
348
+ * as well as a flag indicating if the original handler was replaced
349
+ */
350
+ getHandlers<T extends HookName>(hook: T, defaultHandler?: Handler<T>) {
351
+ const ledger = this.get(hook);
352
+ if (!ledger) {
353
+ return { found: false, before: [], handler: [], after: [], replaced: false };
354
+ }
355
+
356
+ const sort = this.sortRegistrations;
357
+ const registrations = Array.from(ledger.values());
358
+
359
+ const before = registrations.filter(({ before, replace }) => before && !replace).sort(sort);
360
+ const replace = registrations.filter(({ replace }) => replace).sort(sort);
361
+ const after = registrations.filter(({ before, replace }) => !before && !replace).sort(sort);
362
+ const replaced = replace.length > 0;
363
+
364
+ let handler: HookRegistration<T>[] = [];
365
+ if (replaced) {
366
+ handler = [{ id: 0, hook, handler: replace[0].handler }];
367
+ } else if (defaultHandler) {
368
+ handler = [{ id: 0, hook, handler: defaultHandler }];
369
+ }
370
+
371
+ return { found: true, before, handler, after, replaced };
372
+ }
373
+
374
+ /**
375
+ * Sort two hook registrations by priority and registration order.
376
+ * @param a The registration object to compare
377
+ * @param b The other registration object to compare with
378
+ * @returns The sort direction
379
+ */
380
+ sortRegistrations<T extends HookName>(a: HookRegistration<T>, b: HookRegistration<T>): number {
381
+ const priority = (b.priority ?? 0) - (a.priority ?? 0);
382
+ const id = a.id - b.id;
383
+ return priority || id || 0;
384
+ }
385
+
386
+ /**
387
+ * Trigger a custom event on the `document`. Prefixed with `swup:`
388
+ * @param hook Name of the hook to trigger.
389
+ */
390
+ dispatchDomEvent<T extends HookName>(hook: T): void {
391
+ document.dispatchEvent(new CustomEvent(`swup:${hook}`, { detail: hook }));
392
+ }
393
+ }
@@ -0,0 +1,142 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import Swup from '../../Swup.js';
3
+ import { Cache, CacheData } from '../Cache.js';
4
+ import { Context } from '../Context.js';
5
+
6
+ interface CacheTtlData {
7
+ ttl: number;
8
+ created: number;
9
+ }
10
+
11
+ interface CacheIndexData {
12
+ index: number;
13
+ }
14
+
15
+ interface AugmentedCacheData extends CacheData, CacheTtlData, CacheIndexData {}
16
+
17
+ const swup = new Swup();
18
+ const ctx = swup.context;
19
+ const cache = new Cache(swup);
20
+
21
+ const page1 = { url: '/page-1', html: '1' };
22
+ const page2 = { url: '/page-2', html: '2' };
23
+ const page3 = { url: '/page-3', html: '3' };
24
+
25
+ describe('Cache', () => {
26
+ beforeEach(() => {
27
+ cache.clear();
28
+ });
29
+
30
+ it('should be empty', () => {
31
+ expect(cache.size).toBe(0);
32
+ });
33
+
34
+ it('should append pages', () => {
35
+ cache.set(page1.url, page1);
36
+ expect(cache.size).toBe(1);
37
+ });
38
+
39
+ it('should have pages', () => {
40
+ cache.set(page1.url, page1);
41
+ expect(cache.has(page1.url)).toBe(true);
42
+ });
43
+
44
+ it('should get pages', () => {
45
+ cache.set(page1.url, page1);
46
+ expect(cache.get(page1.url)).toEqual(page1);
47
+ });
48
+
49
+ it('should delete pages', () => {
50
+ cache.set(page1.url, page1);
51
+ expect(cache.has(page1.url)).toBe(true);
52
+ cache.delete(page1.url);
53
+ expect(cache.has(page1.url)).toBe(false);
54
+ });
55
+
56
+ it('should clear', () => {
57
+ cache.set(page1.url, page1);
58
+ expect(cache.size).toBe(1);
59
+ cache.clear();
60
+ expect(cache.size).toBe(0);
61
+ });
62
+
63
+ it('should overwrite identical pages', () => {
64
+ cache.set(page1.url, page1);
65
+ expect(cache.size).toBe(1);
66
+ cache.set(page1.url, page1);
67
+ expect(cache.size).toBe(1);
68
+ });
69
+
70
+ it('should not overwrite different pages', () => {
71
+ cache.set(page1.url, page1);
72
+ expect(cache.size).toBe(1);
73
+ cache.set(page2.url, page2);
74
+ expect(cache.size).toBe(2);
75
+ });
76
+
77
+ it('should trigger a hook on set', () => {
78
+ const handler = vi.fn();
79
+
80
+ swup.hooks.on('pageCached', handler);
81
+
82
+ cache.set(page1.url, page1);
83
+
84
+ expect(handler).toBeCalledTimes(1);
85
+ expect(handler).toBeCalledWith(ctx, { page: page1 });
86
+ });
87
+
88
+ it('should allow augmenting cache entries on save', () => {
89
+ const now = Date.now();
90
+
91
+ swup.hooks.on('pageCached', (_, { page }) => {
92
+ const ttl: CacheTtlData = { ttl: 1000, created: now };
93
+ cache.update(page.url, ttl as AugmentedCacheData);
94
+ });
95
+
96
+ cache.set('/page', { url: '/page', html: '' });
97
+
98
+ const page = cache.get('/page') as AugmentedCacheData;
99
+
100
+ expect(page).toEqual({ url: '/page', html: '', ttl: 1000, created: now });
101
+ });
102
+
103
+ it('should allow manual pruning', () => {
104
+ swup.hooks.on('pageCached', (_, { page }) => {
105
+ cache.update(page.url, { index: cache.size } as AugmentedCacheData);
106
+ });
107
+
108
+ cache.set(page1.url, page1);
109
+ cache.set(page2.url, page2);
110
+ cache.set(page3.url, page3);
111
+
112
+ cache.prune((url, page) => (page as AugmentedCacheData).index > 2);
113
+
114
+ expect(cache.size).toBe(2);
115
+ expect(cache.has(page1.url)).toBe(true);
116
+ expect(cache.has(page2.url)).toBe(true);
117
+ expect(cache.has(page3.url)).toBe(false);
118
+ });
119
+ });
120
+
121
+ describe('Types', () => {
122
+ it('error when necessary', async () => {
123
+ const swup = new Swup();
124
+ const cache = new Cache(swup);
125
+
126
+ // @ts-expect-no-error
127
+ swup.hooks.on('popState', (ctx: Context, { event: PopStateEvent }) => {});
128
+ // @ts-expect-no-error
129
+ await swup.hooks.trigger('popState', { event: new PopStateEvent('') });
130
+
131
+ try {
132
+ // @ts-expect-error
133
+ cache.set();
134
+ // @ts-expect-error
135
+ cache.set(url);
136
+ // @ts-expect-error
137
+ cache.set(url, {});
138
+ // @ts-expect-error
139
+ cache.set({ url: '/test' });
140
+ } catch (error) {}
141
+ });
142
+ });