@hkdigital/lib-sveltekit 0.2.20 → 0.2.21
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 +135 -135
- package/dist/assets/autospuiten/car-paint-picker.js +41 -41
- package/dist/assets/autospuiten/labels.js +7 -7
- package/dist/classes/cache/IndexedDbCache.js +1407 -1407
- package/dist/classes/cache/MemoryResponseCache.js +138 -138
- package/dist/classes/cache/index.js +5 -5
- package/dist/classes/cache/typedef.js +41 -41
- package/dist/classes/data/IterableTree.js +243 -243
- package/dist/classes/data/Selector.js +190 -190
- package/dist/classes/data/index.js +2 -2
- package/dist/classes/events/EventEmitter.js +275 -275
- package/dist/classes/events/index.js +2 -2
- package/dist/classes/index.js +4 -4
- package/dist/classes/logging/Logger.js +210 -210
- package/dist/classes/logging/constants.js +16 -16
- package/dist/classes/logging/index.js +4 -4
- package/dist/classes/logging/typedef.js +17 -17
- package/dist/classes/promise/HkPromise.js +377 -377
- package/dist/classes/promise/index.js +1 -1
- package/dist/classes/services/ServiceBase.js +463 -463
- package/dist/classes/services/ServiceManager.js +614 -614
- package/dist/classes/services/index.js +5 -5
- package/dist/classes/services/service-states.js +205 -205
- package/dist/classes/services/typedef.js +179 -179
- package/dist/classes/stores/SubscribersCount.js +107 -107
- package/dist/classes/stores/index.js +1 -1
- package/dist/classes/streams/LogTransformStream.js +19 -19
- package/dist/classes/streams/ServerEventsStore.js +110 -110
- package/dist/classes/streams/TimeStampSource.js +26 -26
- package/dist/classes/streams/index.js +3 -3
- package/dist/classes/svelte/audio/AudioLoader.svelte.js +58 -58
- package/dist/classes/svelte/audio/AudioScene.svelte.js +324 -324
- package/dist/classes/svelte/audio/mocks.js +35 -35
- package/dist/classes/svelte/finite-state-machine/FiniteStateMachine.svelte.js +133 -133
- package/dist/classes/svelte/finite-state-machine/index.js +1 -1
- package/dist/classes/svelte/image/ImageLoader.svelte.js +45 -45
- package/dist/classes/svelte/image/ImageScene.svelte.js +249 -249
- package/dist/classes/svelte/image/ImageVariantsLoader.svelte.js +152 -152
- package/dist/classes/svelte/image/index.js +4 -4
- package/dist/classes/svelte/image/mocks.js +35 -35
- package/dist/classes/svelte/image/typedef.js +8 -8
- package/dist/classes/svelte/index.js +14 -14
- package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +109 -109
- package/dist/classes/svelte/loading-state-machine/constants.js +16 -16
- package/dist/classes/svelte/loading-state-machine/index.js +3 -3
- package/dist/classes/svelte/network-loader/NetworkLoader.svelte.js +338 -338
- package/dist/classes/svelte/network-loader/constants.js +3 -3
- package/dist/classes/svelte/network-loader/index.js +3 -3
- package/dist/classes/svelte/network-loader/mocks.js +30 -30
- package/dist/classes/svelte/network-loader/typedef.js +8 -8
- package/dist/components/area/HkArea.svelte +49 -49
- package/dist/components/area/HkGridArea.svelte +77 -77
- package/dist/components/area/index.js +2 -2
- package/dist/components/buttons/button/Button.svelte +82 -82
- package/dist/components/buttons/button-icon-steeze/SteezeIconButton.svelte +30 -30
- package/dist/components/buttons/button-text/TextButton.svelte +21 -21
- package/dist/components/buttons/index.js +3 -3
- package/dist/components/debug/debug-panel-design-scaling/DebugPanelDesignScaling.svelte +146 -146
- package/dist/components/debug/index.js +1 -1
- package/dist/components/drag-drop/DragController.js +44 -44
- package/dist/components/drag-drop/DragDropContext.svelte +111 -111
- package/dist/components/drag-drop/Draggable.svelte +519 -519
- package/dist/components/drag-drop/DropZoneArea.svelte +119 -119
- package/dist/components/drag-drop/DropZoneList.svelte +125 -125
- package/dist/components/drag-drop/{DropZone.svelte → Dropzone.svelte} +258 -258
- package/dist/components/drag-drop/actions.js +26 -26
- package/dist/components/drag-drop/drag-state.svelte.js +322 -322
- package/dist/components/drag-drop/index.js +7 -7
- package/dist/components/drag-drop/util.js +85 -85
- package/dist/components/hkdev/blocks/TextBlock.svelte +46 -46
- package/dist/components/hkdev/buttons/CheckButton.svelte +62 -62
- package/dist/components/icons/HkIcon.svelte +86 -86
- package/dist/components/icons/HkTabIcon.svelte +116 -116
- package/dist/components/icons/SteezeIcon.svelte +97 -97
- package/dist/components/icons/index.js +6 -6
- package/dist/components/icons/typedef.js +16 -16
- package/dist/components/index.js +2 -2
- package/dist/components/inputs/index.js +1 -1
- package/dist/components/inputs/text-input/TestTextInput.svelte__ +102 -102
- package/dist/components/inputs/text-input/TextInput.svelte +223 -223
- package/dist/components/inputs/text-input/TextInput.svelte___ +83 -83
- package/dist/components/inputs/text-input/assets/IconInvalid.svelte +14 -14
- package/dist/components/inputs/text-input/assets/IconValid.svelte +12 -12
- package/dist/components/layout/grid-layers/GridLayers.svelte +63 -63
- package/dist/components/layout/grid-layers/util.js +74 -74
- package/dist/components/layout/index.js +1 -1
- package/dist/components/panels/index.js +1 -1
- package/dist/components/panels/panel/Panel.svelte +43 -43
- package/dist/components/rows/index.js +3 -3
- package/dist/components/rows/panel-grid-row/PanelGridRow.svelte +104 -104
- package/dist/components/rows/panel-row-2/PanelRow2.svelte +40 -40
- package/dist/components/tab-bar/HkTabBar.state.svelte.js +149 -149
- package/dist/components/tab-bar/HkTabBar.svelte +74 -74
- package/dist/components/tab-bar/HkTabBarSelector.state.svelte.js +93 -93
- package/dist/components/tab-bar/HkTabBarSelector.svelte +49 -49
- package/dist/components/tab-bar/index.js +17 -17
- package/dist/components/tab-bar/typedef.js +11 -11
- package/dist/config/imagetools-config.js +189 -189
- package/dist/config/imagetools.d.ts +72 -72
- package/dist/constants/bases.js +13 -13
- package/dist/constants/errors/api.js +9 -9
- package/dist/constants/errors/generic.js +5 -5
- package/dist/constants/errors/index.js +3 -3
- package/dist/constants/errors/jwt.js +5 -5
- package/dist/constants/http/headers.js +6 -6
- package/dist/constants/http/index.js +2 -2
- package/dist/constants/http/methods.js +14 -14
- package/dist/constants/index.js +3 -3
- package/dist/constants/mime/application.js +5 -5
- package/dist/constants/mime/audio.js +13 -13
- package/dist/constants/mime/image.js +3 -3
- package/dist/constants/mime/index.js +4 -4
- package/dist/constants/mime/text.js +2 -2
- package/dist/constants/regexp/index.js +31 -31
- package/dist/constants/regexp/inspiratie.js__ +95 -95
- package/dist/constants/regexp/text.js +49 -49
- package/dist/constants/regexp/user.js +32 -32
- package/dist/constants/regexp/web.js +3 -3
- package/dist/constants/state-labels/drag-states.js +6 -6
- package/dist/constants/state-labels/drop-states.js +6 -6
- package/dist/constants/state-labels/input-states.js +11 -11
- package/dist/constants/state-labels/submit-states.js +4 -4
- package/dist/constants/time.js +28 -28
- package/dist/css/utilities.css +43 -43
- package/dist/design/design-config.js +73 -73
- package/dist/design/tailwind-theme-extend.js +158 -158
- package/dist/features/button-group/ButtonGroup.svelte +82 -82
- package/dist/features/button-group/typedef.js +10 -10
- package/dist/features/compare-left-right/CompareLeftRight.svelte +179 -179
- package/dist/features/compare-left-right/index.js +1 -1
- package/dist/features/game-box/GameBox.svelte +577 -577
- package/dist/features/game-box/gamebox.util.js +83 -83
- package/dist/features/hk-app-layout/HkAppLayout.state.svelte.js +25 -25
- package/dist/features/hk-app-layout/HkAppLayout.svelte +251 -251
- package/dist/features/image-box/ImageBox.svelte +210 -210
- package/dist/features/image-box/index.js +5 -5
- package/dist/features/image-box/typedef.js +32 -32
- package/dist/features/index.js +23 -23
- package/dist/features/presenter/ImageSlide.svelte +64 -64
- package/dist/features/presenter/Presenter.state.svelte.js +638 -638
- package/dist/features/presenter/Presenter.svelte +142 -142
- package/dist/features/presenter/constants.js +7 -7
- package/dist/features/presenter/index.js +10 -10
- package/dist/features/presenter/typedef.js +106 -106
- package/dist/features/presenter/util.js +210 -210
- package/dist/features/virtual-viewport/VirtualViewport.svelte +196 -196
- package/dist/logging/adapters/console.js +114 -114
- package/dist/logging/adapters/pino.js +60 -60
- package/dist/logging/constants.js +1 -1
- package/dist/logging/factories/client.js +21 -21
- package/dist/logging/factories/server.js +22 -22
- package/dist/logging/factories/universal.js +23 -23
- package/dist/logging/index.js +8 -8
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/validate-url.js +180 -180
- package/dist/server/index.js +1 -1
- package/dist/server/logger.js +94 -94
- package/dist/states/index.js +1 -1
- package/dist/states/navigation.svelte.js +55 -55
- package/dist/stores/index.js +1 -1
- package/dist/stores/theme.js +80 -80
- package/dist/themes/hkdev/components/blocks/text-block.css +34 -41
- package/dist/themes/hkdev/components/boxes/game-box.css +11 -12
- package/dist/themes/hkdev/components/buttons/button-icon-steeze.css +22 -22
- package/dist/themes/hkdev/components/buttons/button-text.css +32 -32
- package/dist/themes/hkdev/components/buttons/button.css +146 -146
- package/dist/themes/hkdev/components/buttons/skip-button.css +5 -6
- package/dist/themes/hkdev/components/drag-drop/draggable.css +73 -73
- package/dist/themes/hkdev/components/drag-drop/drop-zone.css +58 -48
- package/dist/themes/hkdev/components/icons/icon-steeze.css +16 -22
- package/dist/themes/hkdev/components/inputs/text-input.css +102 -104
- package/dist/themes/hkdev/components/panels/panel.css +25 -27
- package/dist/themes/hkdev/components/rows/panel-grid-row.css +4 -6
- package/dist/themes/hkdev/components/rows/panel-row-2.css +5 -7
- package/dist/themes/hkdev/components.css +29 -53
- package/dist/themes/hkdev/debug.css +1 -1
- package/dist/themes/hkdev/global/layout.css +32 -39
- package/dist/themes/hkdev/global/on-colors.css +32 -53
- package/dist/themes/hkdev/globals.css +4 -11
- package/dist/themes/hkdev/responsive.css +12 -12
- package/dist/themes/hkdev/theme-ext.js +12 -15
- package/dist/themes/hkdev/theme.css +219 -0
- package/dist/themes/index.d.ts +1 -1
- package/dist/themes/index.js +1 -1
- package/dist/typedef/context.js +6 -6
- package/dist/typedef/drag.js +25 -25
- package/dist/typedef/drop.js +12 -12
- package/dist/typedef/image.js +38 -38
- package/dist/typedef/index.js +4 -4
- package/dist/util/array/index.js +436 -436
- package/dist/util/bases/base58.js +262 -262
- package/dist/util/bases/index.js +1 -1
- package/dist/util/compare/index.js +247 -247
- package/dist/util/css/css-vars.js +83 -83
- package/dist/util/css/index.js +1 -1
- package/dist/util/design-system/components/states.js +22 -22
- package/dist/util/design-system/css/clamp.js +66 -66
- package/dist/util/design-system/css/root-design-vars.js +102 -102
- package/dist/util/design-system/index.js +5 -5
- package/dist/util/design-system/layout/scaling.js +228 -228
- package/dist/util/design-system/skeleton.js +208 -208
- package/dist/util/design-system/tailwind.js +288 -288
- package/dist/util/env/index.js +9 -9
- package/dist/util/expect/arrays.js +47 -47
- package/dist/util/expect/index.js +259 -259
- package/dist/util/expect/primitives.js +55 -55
- package/dist/util/expect/url.js +60 -60
- package/dist/util/function/index.js +218 -218
- package/dist/util/geo/index.js +26 -26
- package/dist/util/http/caching.js +263 -263
- package/dist/util/http/errors.js +97 -97
- package/dist/util/http/headers.js +75 -75
- package/dist/util/http/http-request.js +578 -578
- package/dist/util/http/index.js +22 -22
- package/dist/util/http/json-request.js +224 -224
- package/dist/util/http/mocks.js +65 -65
- package/dist/util/http/response.js +294 -294
- package/dist/util/http/typedef.js +93 -93
- package/dist/util/http/url.js +52 -52
- package/dist/util/image/index.js +86 -86
- package/dist/util/index.js +2 -2
- package/dist/util/is/index.js +140 -140
- package/dist/util/iterate/index.js +234 -234
- package/dist/util/object/index.js +1361 -1361
- package/dist/util/singleton/index.js +97 -97
- package/dist/util/string/array-path.js +75 -75
- package/dist/util/string/convert.js +54 -54
- package/dist/util/string/fs.js +226 -226
- package/dist/util/string/index.js +5 -5
- package/dist/util/string/interpolate.js +61 -61
- package/dist/util/string/pad.js +10 -10
- package/dist/util/svelte/index.js +4 -4
- package/dist/util/svelte/loading/loading-tracker.svelte.js +108 -108
- package/dist/util/svelte/observe/index.js +49 -49
- package/dist/util/svelte/state-context/index.js +117 -117
- package/dist/util/svelte/wait/index.js +38 -38
- package/dist/util/sveltekit/index.js +1 -1
- package/dist/util/sveltekit/route-folders/index.js +101 -101
- package/dist/util/time/index.js +323 -323
- package/dist/util/unique/index.js +249 -249
- package/dist/valibot/date.js__ +10 -10
- package/dist/valibot/index.js +9 -9
- package/dist/valibot/url.js +95 -95
- package/dist/valibot/user.js +23 -23
- package/dist/zod/all.js +33 -33
- package/dist/zod/generic.js +11 -11
- package/dist/zod/javascript.js +32 -32
- package/dist/zod/user.js +16 -16
- package/dist/zod/web.js +52 -52
- package/package.json +132 -129
- package/dist/components/layout/grid-layers/GridLayers.svelte__heightFrom__ +0 -372
- package/dist/themes/hkdev/theme.d.ts +0 -234
- package/dist/themes/hkdev/theme.js +0 -235
- package/dist/util/http/test-data__/content-length-test-hkdigital-small.V4HfZyBQ.avif +0 -0
package/dist/util/geo/index.js
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
/**
|
2
|
-
* Check if a point lies within a polygon
|
3
|
-
*
|
4
|
-
* @param {number} xPct - X-coordinate as percentage
|
5
|
-
* @param {number} yPct - Y-coordinate as percentage
|
6
|
-
* @param {Array} polygon - Array of [x, y] points
|
7
|
-
*
|
8
|
-
* @returns {boolean} True if the point lies within the polygon
|
9
|
-
*/
|
10
|
-
export function isPointInPolygon(xPct, yPct, polygon) {
|
11
|
-
let inside = false;
|
12
|
-
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
13
|
-
const xi = polygon[i][0];
|
14
|
-
const yi = polygon[i][1];
|
15
|
-
const xj = polygon[j][0];
|
16
|
-
const yj = polygon[j][1];
|
17
|
-
|
18
|
-
const intersect =
|
19
|
-
yi > yPct !== yj > yPct &&
|
20
|
-
xPct < ((xj - xi) * (yPct - yi)) / (yj - yi) + xi;
|
21
|
-
if (intersect) {
|
22
|
-
inside = !inside;
|
23
|
-
}
|
24
|
-
}
|
25
|
-
return inside;
|
26
|
-
}
|
1
|
+
/**
|
2
|
+
* Check if a point lies within a polygon
|
3
|
+
*
|
4
|
+
* @param {number} xPct - X-coordinate as percentage
|
5
|
+
* @param {number} yPct - Y-coordinate as percentage
|
6
|
+
* @param {Array} polygon - Array of [x, y] points
|
7
|
+
*
|
8
|
+
* @returns {boolean} True if the point lies within the polygon
|
9
|
+
*/
|
10
|
+
export function isPointInPolygon(xPct, yPct, polygon) {
|
11
|
+
let inside = false;
|
12
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
13
|
+
const xi = polygon[i][0];
|
14
|
+
const yi = polygon[i][1];
|
15
|
+
const xj = polygon[j][0];
|
16
|
+
const yj = polygon[j][1];
|
17
|
+
|
18
|
+
const intersect =
|
19
|
+
yi > yPct !== yj > yPct &&
|
20
|
+
xPct < ((xj - xi) * (yPct - yi)) / (yj - yi) + xi;
|
21
|
+
if (intersect) {
|
22
|
+
inside = !inside;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
return inside;
|
26
|
+
}
|
@@ -1,263 +1,263 @@
|
|
1
|
-
import {
|
2
|
-
MemoryResponseCache,
|
3
|
-
IndexedDbCache
|
4
|
-
} from '../../classes/cache';
|
5
|
-
|
6
|
-
import { browser } from '$app/environment';
|
7
|
-
|
8
|
-
import { isTestEnv } from '../env';
|
9
|
-
|
10
|
-
let defaultCacheStorage = null;
|
11
|
-
|
12
|
-
function getCacheStorage()
|
13
|
-
{
|
14
|
-
if( !defaultCacheStorage )
|
15
|
-
{
|
16
|
-
let type;
|
17
|
-
|
18
|
-
if( !browser || isTestEnv )
|
19
|
-
{
|
20
|
-
type = 'memory';
|
21
|
-
}
|
22
|
-
else {
|
23
|
-
type = 'indexed-db';
|
24
|
-
}
|
25
|
-
|
26
|
-
defaultCacheStorage = createCacheStorage( type);
|
27
|
-
}
|
28
|
-
|
29
|
-
return defaultCacheStorage
|
30
|
-
}
|
31
|
-
|
32
|
-
/**
|
33
|
-
* Store a response in the cache
|
34
|
-
*
|
35
|
-
* @param {object} cacheKeyParams - Parameters to use for cache key generation
|
36
|
-
* @param {string|URL} cacheKeyParams.url - URL string or URL object
|
37
|
-
* @param {object} [cacheKeyParams.headers] - Request headers that affect caching
|
38
|
-
* @param {Response} response - Response to cache
|
39
|
-
* @param {object} metadata - Cache metadata
|
40
|
-
* @returns {Promise<void>}
|
41
|
-
*/
|
42
|
-
export async function storeResponseInCache(cacheKeyParams, response, metadata) {
|
43
|
-
try {
|
44
|
-
const { url: rawUrl, ...headers } = cacheKeyParams;
|
45
|
-
const url = typeof rawUrl === 'string' ? rawUrl : rawUrl.toString();
|
46
|
-
|
47
|
-
// Generate cache key
|
48
|
-
const cacheKey = generateCacheKey(url, headers);
|
49
|
-
|
50
|
-
// Extract Vary header info
|
51
|
-
const varyHeader = response.headers.get('Vary');
|
52
|
-
let varyHeaders = null;
|
53
|
-
|
54
|
-
if (varyHeader) {
|
55
|
-
varyHeaders = {};
|
56
|
-
const varyFields = varyHeader.split(',').map(field => field.trim().toLowerCase());
|
57
|
-
|
58
|
-
// Store hashes of headers mentioned in Vary
|
59
|
-
for (const field of varyFields) {
|
60
|
-
if (field !== '*') {
|
61
|
-
const value = headers[field];
|
62
|
-
varyHeaders[field] = hashValue(value);
|
63
|
-
}
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
// Add vary headers to metadata
|
68
|
-
const enhancedMetadata = {
|
69
|
-
...metadata,
|
70
|
-
varyHeaders
|
71
|
-
};
|
72
|
-
|
73
|
-
// Store in cache
|
74
|
-
await getCacheStorage().set(cacheKey, response, enhancedMetadata);
|
75
|
-
} catch (error) {
|
76
|
-
console.error('Cache storage error:', error);
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
|
-
/**
|
81
|
-
* Get a cached response if available and valid
|
82
|
-
*
|
83
|
-
* @param {object} cacheKeyParams - Parameters to use for cache key generation
|
84
|
-
* @param {string|URL} cacheKeyParams.url - URL string or URL object
|
85
|
-
* @param {object} [cacheKeyParams.headers] - Request headers that affect caching
|
86
|
-
*
|
87
|
-
* @returns {Promise<Response|import('./typedef').ResponseWithStale|null>}
|
88
|
-
* Cached response or null
|
89
|
-
*/
|
90
|
-
export async function getCachedResponse(cacheKeyParams) {
|
91
|
-
try {
|
92
|
-
const { url: rawUrl, ...headers } = cacheKeyParams;
|
93
|
-
const url = typeof rawUrl === 'string' ? rawUrl : rawUrl.toString();
|
94
|
-
|
95
|
-
// Generate cache key
|
96
|
-
const cacheKey = generateCacheKey(url, headers);
|
97
|
-
|
98
|
-
// Get cached entry
|
99
|
-
const cachedEntry = await getCacheStorage().get(cacheKey);
|
100
|
-
|
101
|
-
if (!cachedEntry) {
|
102
|
-
return null;
|
103
|
-
}
|
104
|
-
|
105
|
-
// Validate based on Vary headers
|
106
|
-
if (!isValidForVaryHeaders(cachedEntry, headers)) {
|
107
|
-
return null;
|
108
|
-
}
|
109
|
-
|
110
|
-
const { response, metadata } = cachedEntry;
|
111
|
-
|
112
|
-
// Check if expired
|
113
|
-
const isExpired = metadata.expires && Date.now() > metadata.expires;
|
114
|
-
|
115
|
-
if (!isExpired) {
|
116
|
-
// Not expired, return as-is
|
117
|
-
return response;
|
118
|
-
}
|
119
|
-
|
120
|
-
// Response is stale, add stale info
|
121
|
-
return enhanceResponseWithStale(response, {
|
122
|
-
isStale: true,
|
123
|
-
fresh: null, // No fresh data available yet
|
124
|
-
timestamp: metadata.timestamp,
|
125
|
-
expires: metadata.expires
|
126
|
-
});
|
127
|
-
} catch (error) {
|
128
|
-
console.error('Cache retrieval error:', error);
|
129
|
-
return null;
|
130
|
-
}
|
131
|
-
}
|
132
|
-
|
133
|
-
// > Internal functions
|
134
|
-
|
135
|
-
/**
|
136
|
-
* Create a cache storage adapter
|
137
|
-
* @param {string} type Type of storage ('indexed-db', 'memory')
|
138
|
-
* @param {Object} options Options for the storage adapter
|
139
|
-
*
|
140
|
-
* @returns {import('../../classes/cache').CacheStorage}
|
141
|
-
*/
|
142
|
-
function createCacheStorage(type = 'indexed-db', options = {}) {
|
143
|
-
switch (type) {
|
144
|
-
case 'indexed-db':
|
145
|
-
return new IndexedDbCache(
|
146
|
-
{
|
147
|
-
dbName: 'http-cache',
|
148
|
-
storeName: 'responses'
|
149
|
-
} );
|
150
|
-
|
151
|
-
case 'memory':
|
152
|
-
return new MemoryResponseCache();
|
153
|
-
|
154
|
-
default:
|
155
|
-
throw new Error(`Unsupported cache storage type: ${type}`);
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
/**
|
160
|
-
* Check if cached entry is valid based on Vary headers
|
161
|
-
*
|
162
|
-
* @param {object} cachedEntry - Cached entry with response and metadata
|
163
|
-
* @param {object} headers - Current request headers
|
164
|
-
* @returns {boolean} True if valid for these headers
|
165
|
-
*/
|
166
|
-
function isValidForVaryHeaders(cachedEntry, headers) {
|
167
|
-
const { metadata } = cachedEntry;
|
168
|
-
|
169
|
-
// If no vary headers stored, consider valid
|
170
|
-
if (!metadata.varyHeaders) {
|
171
|
-
return true;
|
172
|
-
}
|
173
|
-
|
174
|
-
// Check each stored vary header
|
175
|
-
for (const [name, storedHash] of Object.entries(metadata.varyHeaders)) {
|
176
|
-
const currentValue = headers[name];
|
177
|
-
const currentHash = hashValue(currentValue);
|
178
|
-
|
179
|
-
// Compare hashes
|
180
|
-
if (currentHash !== storedHash) {
|
181
|
-
return false;
|
182
|
-
}
|
183
|
-
}
|
184
|
-
|
185
|
-
return true;
|
186
|
-
}
|
187
|
-
|
188
|
-
/**
|
189
|
-
* Generate a cache key based on URL and relevant headers
|
190
|
-
*
|
191
|
-
* @param {string} url - URL string
|
192
|
-
* @param {object} headers - Request headers
|
193
|
-
* @returns {string} Cache key
|
194
|
-
*/
|
195
|
-
function generateCacheKey(url, headers) {
|
196
|
-
// Start with a hash of the URL
|
197
|
-
const keyParts = [hashValue(url)];
|
198
|
-
|
199
|
-
// If we have headers
|
200
|
-
if (headers && Object.keys(headers).length > 0) {
|
201
|
-
// Get all header names, sorted for consistency
|
202
|
-
const headerNames = Object.keys(headers).sort();
|
203
|
-
|
204
|
-
// Create a hash for each header value
|
205
|
-
const headerHashes = headerNames.map(name => {
|
206
|
-
const value = headers[name];
|
207
|
-
// Format: "name:hash_of_value"
|
208
|
-
return `${name}:${hashValue(value)}`;
|
209
|
-
});
|
210
|
-
|
211
|
-
if (headerHashes.length > 0) {
|
212
|
-
keyParts.push(headerHashes.join('|'));
|
213
|
-
}
|
214
|
-
}
|
215
|
-
|
216
|
-
return keyParts.join('::');
|
217
|
-
}
|
218
|
-
|
219
|
-
/**
|
220
|
-
* Create a hash of a value
|
221
|
-
*
|
222
|
-
* @param {string} value - Value to hash
|
223
|
-
* @returns {string} Hash representation
|
224
|
-
*/
|
225
|
-
function hashValue(value) {
|
226
|
-
if (!value) return '';
|
227
|
-
|
228
|
-
// Convert to string if not already
|
229
|
-
const stringValue = String(value);
|
230
|
-
|
231
|
-
// Simple non-cryptographic hash function
|
232
|
-
let hash = 0;
|
233
|
-
for (let i = 0; i < stringValue.length; i++) {
|
234
|
-
const char = stringValue.charCodeAt(i);
|
235
|
-
hash = ((hash << 5) - hash) + char;
|
236
|
-
hash = hash & hash; // Convert to 32bit integer
|
237
|
-
}
|
238
|
-
return hash.toString(16); // Convert to hex
|
239
|
-
}
|
240
|
-
|
241
|
-
|
242
|
-
/**
|
243
|
-
* Enhance a Response object with stale data properties
|
244
|
-
*
|
245
|
-
* @param {Response} response - The original Response object
|
246
|
-
* @param {import('./typedef').StaleInfo} staleInfo - Stale data information
|
247
|
-
*
|
248
|
-
* @returns {import('./typedef').ResponseWithStale}
|
249
|
-
* Enhanced response with stale data properties
|
250
|
-
*/
|
251
|
-
function enhanceResponseWithStale(response, staleInfo) {
|
252
|
-
// Create a new object that inherits from Response prototype
|
253
|
-
const enhanced = Object.create(
|
254
|
-
Object.getPrototypeOf(response),
|
255
|
-
Object.getOwnPropertyDescriptors(response)
|
256
|
-
);
|
257
|
-
|
258
|
-
// Add stale properties
|
259
|
-
enhanced.isStale = staleInfo.isStale || false;
|
260
|
-
enhanced.fresh = staleInfo.fresh || null;
|
261
|
-
|
262
|
-
return enhanced;
|
263
|
-
}
|
1
|
+
import {
|
2
|
+
MemoryResponseCache,
|
3
|
+
IndexedDbCache
|
4
|
+
} from '../../classes/cache';
|
5
|
+
|
6
|
+
import { browser } from '$app/environment';
|
7
|
+
|
8
|
+
import { isTestEnv } from '../env';
|
9
|
+
|
10
|
+
let defaultCacheStorage = null;
|
11
|
+
|
12
|
+
function getCacheStorage()
|
13
|
+
{
|
14
|
+
if( !defaultCacheStorage )
|
15
|
+
{
|
16
|
+
let type;
|
17
|
+
|
18
|
+
if( !browser || isTestEnv )
|
19
|
+
{
|
20
|
+
type = 'memory';
|
21
|
+
}
|
22
|
+
else {
|
23
|
+
type = 'indexed-db';
|
24
|
+
}
|
25
|
+
|
26
|
+
defaultCacheStorage = createCacheStorage( type);
|
27
|
+
}
|
28
|
+
|
29
|
+
return defaultCacheStorage
|
30
|
+
}
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Store a response in the cache
|
34
|
+
*
|
35
|
+
* @param {object} cacheKeyParams - Parameters to use for cache key generation
|
36
|
+
* @param {string|URL} cacheKeyParams.url - URL string or URL object
|
37
|
+
* @param {object} [cacheKeyParams.headers] - Request headers that affect caching
|
38
|
+
* @param {Response} response - Response to cache
|
39
|
+
* @param {object} metadata - Cache metadata
|
40
|
+
* @returns {Promise<void>}
|
41
|
+
*/
|
42
|
+
export async function storeResponseInCache(cacheKeyParams, response, metadata) {
|
43
|
+
try {
|
44
|
+
const { url: rawUrl, ...headers } = cacheKeyParams;
|
45
|
+
const url = typeof rawUrl === 'string' ? rawUrl : rawUrl.toString();
|
46
|
+
|
47
|
+
// Generate cache key
|
48
|
+
const cacheKey = generateCacheKey(url, headers);
|
49
|
+
|
50
|
+
// Extract Vary header info
|
51
|
+
const varyHeader = response.headers.get('Vary');
|
52
|
+
let varyHeaders = null;
|
53
|
+
|
54
|
+
if (varyHeader) {
|
55
|
+
varyHeaders = {};
|
56
|
+
const varyFields = varyHeader.split(',').map(field => field.trim().toLowerCase());
|
57
|
+
|
58
|
+
// Store hashes of headers mentioned in Vary
|
59
|
+
for (const field of varyFields) {
|
60
|
+
if (field !== '*') {
|
61
|
+
const value = headers[field];
|
62
|
+
varyHeaders[field] = hashValue(value);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
// Add vary headers to metadata
|
68
|
+
const enhancedMetadata = {
|
69
|
+
...metadata,
|
70
|
+
varyHeaders
|
71
|
+
};
|
72
|
+
|
73
|
+
// Store in cache
|
74
|
+
await getCacheStorage().set(cacheKey, response, enhancedMetadata);
|
75
|
+
} catch (error) {
|
76
|
+
console.error('Cache storage error:', error);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* Get a cached response if available and valid
|
82
|
+
*
|
83
|
+
* @param {object} cacheKeyParams - Parameters to use for cache key generation
|
84
|
+
* @param {string|URL} cacheKeyParams.url - URL string or URL object
|
85
|
+
* @param {object} [cacheKeyParams.headers] - Request headers that affect caching
|
86
|
+
*
|
87
|
+
* @returns {Promise<Response|import('./typedef').ResponseWithStale|null>}
|
88
|
+
* Cached response or null
|
89
|
+
*/
|
90
|
+
export async function getCachedResponse(cacheKeyParams) {
|
91
|
+
try {
|
92
|
+
const { url: rawUrl, ...headers } = cacheKeyParams;
|
93
|
+
const url = typeof rawUrl === 'string' ? rawUrl : rawUrl.toString();
|
94
|
+
|
95
|
+
// Generate cache key
|
96
|
+
const cacheKey = generateCacheKey(url, headers);
|
97
|
+
|
98
|
+
// Get cached entry
|
99
|
+
const cachedEntry = await getCacheStorage().get(cacheKey);
|
100
|
+
|
101
|
+
if (!cachedEntry) {
|
102
|
+
return null;
|
103
|
+
}
|
104
|
+
|
105
|
+
// Validate based on Vary headers
|
106
|
+
if (!isValidForVaryHeaders(cachedEntry, headers)) {
|
107
|
+
return null;
|
108
|
+
}
|
109
|
+
|
110
|
+
const { response, metadata } = cachedEntry;
|
111
|
+
|
112
|
+
// Check if expired
|
113
|
+
const isExpired = metadata.expires && Date.now() > metadata.expires;
|
114
|
+
|
115
|
+
if (!isExpired) {
|
116
|
+
// Not expired, return as-is
|
117
|
+
return response;
|
118
|
+
}
|
119
|
+
|
120
|
+
// Response is stale, add stale info
|
121
|
+
return enhanceResponseWithStale(response, {
|
122
|
+
isStale: true,
|
123
|
+
fresh: null, // No fresh data available yet
|
124
|
+
timestamp: metadata.timestamp,
|
125
|
+
expires: metadata.expires
|
126
|
+
});
|
127
|
+
} catch (error) {
|
128
|
+
console.error('Cache retrieval error:', error);
|
129
|
+
return null;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
// > Internal functions
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Create a cache storage adapter
|
137
|
+
* @param {string} type Type of storage ('indexed-db', 'memory')
|
138
|
+
* @param {Object} options Options for the storage adapter
|
139
|
+
*
|
140
|
+
* @returns {import('../../classes/cache').CacheStorage}
|
141
|
+
*/
|
142
|
+
function createCacheStorage(type = 'indexed-db', options = {}) {
|
143
|
+
switch (type) {
|
144
|
+
case 'indexed-db':
|
145
|
+
return new IndexedDbCache(
|
146
|
+
{
|
147
|
+
dbName: 'http-cache',
|
148
|
+
storeName: 'responses'
|
149
|
+
} );
|
150
|
+
|
151
|
+
case 'memory':
|
152
|
+
return new MemoryResponseCache();
|
153
|
+
|
154
|
+
default:
|
155
|
+
throw new Error(`Unsupported cache storage type: ${type}`);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
/**
|
160
|
+
* Check if cached entry is valid based on Vary headers
|
161
|
+
*
|
162
|
+
* @param {object} cachedEntry - Cached entry with response and metadata
|
163
|
+
* @param {object} headers - Current request headers
|
164
|
+
* @returns {boolean} True if valid for these headers
|
165
|
+
*/
|
166
|
+
function isValidForVaryHeaders(cachedEntry, headers) {
|
167
|
+
const { metadata } = cachedEntry;
|
168
|
+
|
169
|
+
// If no vary headers stored, consider valid
|
170
|
+
if (!metadata.varyHeaders) {
|
171
|
+
return true;
|
172
|
+
}
|
173
|
+
|
174
|
+
// Check each stored vary header
|
175
|
+
for (const [name, storedHash] of Object.entries(metadata.varyHeaders)) {
|
176
|
+
const currentValue = headers[name];
|
177
|
+
const currentHash = hashValue(currentValue);
|
178
|
+
|
179
|
+
// Compare hashes
|
180
|
+
if (currentHash !== storedHash) {
|
181
|
+
return false;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
return true;
|
186
|
+
}
|
187
|
+
|
188
|
+
/**
|
189
|
+
* Generate a cache key based on URL and relevant headers
|
190
|
+
*
|
191
|
+
* @param {string} url - URL string
|
192
|
+
* @param {object} headers - Request headers
|
193
|
+
* @returns {string} Cache key
|
194
|
+
*/
|
195
|
+
function generateCacheKey(url, headers) {
|
196
|
+
// Start with a hash of the URL
|
197
|
+
const keyParts = [hashValue(url)];
|
198
|
+
|
199
|
+
// If we have headers
|
200
|
+
if (headers && Object.keys(headers).length > 0) {
|
201
|
+
// Get all header names, sorted for consistency
|
202
|
+
const headerNames = Object.keys(headers).sort();
|
203
|
+
|
204
|
+
// Create a hash for each header value
|
205
|
+
const headerHashes = headerNames.map(name => {
|
206
|
+
const value = headers[name];
|
207
|
+
// Format: "name:hash_of_value"
|
208
|
+
return `${name}:${hashValue(value)}`;
|
209
|
+
});
|
210
|
+
|
211
|
+
if (headerHashes.length > 0) {
|
212
|
+
keyParts.push(headerHashes.join('|'));
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
return keyParts.join('::');
|
217
|
+
}
|
218
|
+
|
219
|
+
/**
|
220
|
+
* Create a hash of a value
|
221
|
+
*
|
222
|
+
* @param {string} value - Value to hash
|
223
|
+
* @returns {string} Hash representation
|
224
|
+
*/
|
225
|
+
function hashValue(value) {
|
226
|
+
if (!value) return '';
|
227
|
+
|
228
|
+
// Convert to string if not already
|
229
|
+
const stringValue = String(value);
|
230
|
+
|
231
|
+
// Simple non-cryptographic hash function
|
232
|
+
let hash = 0;
|
233
|
+
for (let i = 0; i < stringValue.length; i++) {
|
234
|
+
const char = stringValue.charCodeAt(i);
|
235
|
+
hash = ((hash << 5) - hash) + char;
|
236
|
+
hash = hash & hash; // Convert to 32bit integer
|
237
|
+
}
|
238
|
+
return hash.toString(16); // Convert to hex
|
239
|
+
}
|
240
|
+
|
241
|
+
|
242
|
+
/**
|
243
|
+
* Enhance a Response object with stale data properties
|
244
|
+
*
|
245
|
+
* @param {Response} response - The original Response object
|
246
|
+
* @param {import('./typedef').StaleInfo} staleInfo - Stale data information
|
247
|
+
*
|
248
|
+
* @returns {import('./typedef').ResponseWithStale}
|
249
|
+
* Enhanced response with stale data properties
|
250
|
+
*/
|
251
|
+
function enhanceResponseWithStale(response, staleInfo) {
|
252
|
+
// Create a new object that inherits from Response prototype
|
253
|
+
const enhanced = Object.create(
|
254
|
+
Object.getPrototypeOf(response),
|
255
|
+
Object.getOwnPropertyDescriptors(response)
|
256
|
+
);
|
257
|
+
|
258
|
+
// Add stale properties
|
259
|
+
enhanced.isStale = staleInfo.isStale || false;
|
260
|
+
enhanced.fresh = staleInfo.fresh || null;
|
261
|
+
|
262
|
+
return enhanced;
|
263
|
+
}
|