-
Notifications
You must be signed in to change notification settings - Fork 14
/
Spa.astro
127 lines (114 loc) · 2.94 KB
/
Spa.astro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
---
import fs from "node:fs";
import crypto from "node:crypto";
import { minify } from "./terser.js";
import buildScript from "./script.js";
export interface scrollIntoViewOptions {
behavior?: "smooth" | "auto";
block?: "start" | "center" | "end" | "nearest";
inline?: "start" | "center" | "end" | "nearest";
}
export interface IntersectionObserverInit {
root?: string;
rootMargin?: string;
threshold?: number | number[];
}
export interface progressBarOptions {
height?: string;
secondary?: boolean;
colors?: {
foreground?: string;
background?: string;
};
}
export interface analytics {
trackingID: string;
anonymizeIP?: boolean;
colorDepth?: boolean;
characterSet?: boolean;
screenSize?: boolean;
language?: boolean;
fingerprinting?: boolean;
trackingPeriod?: "year" | "month" | "day";
}
export interface Props {
analytics?: analytics;
attributes?: Partial<HTMLScriptElement>;
cache?: boolean;
containerSelector?: string;
defaultAnimation?: boolean;
delay?: number;
external?: boolean;
forceRequestIdleCallback?: boolean;
highPriorityPrefetch?: boolean;
ignores?: string[];
intersectionObserverOptions?: IntersectionObserverInit;
limit?: number;
localLinkDetector?: boolean;
prefetch?: boolean;
prefetchUpgradation?: boolean;
progressBar?: boolean;
progressBarOptions?: progressBarOptions;
scanOnMount?: boolean;
scrollIntoView?: boolean;
scrollIntoViewOptions?: boolean | scrollIntoViewOptions;
timeout?: number | false;
}
const {
analytics,
attributes,
cache = true,
containerSelector = "",
defaultAnimation = true,
delay = 500,
external = false,
forceRequestIdleCallback = false,
highPriorityPrefetch = false,
ignores = [],
intersectionObserverOptions,
limit = 0,
localLinkDetector = true,
prefetch = true,
prefetchUpgradation = true,
progressBar = true,
progressBarOptions,
scanOnMount = true,
scrollIntoView = true,
scrollIntoViewOptions = { block: "start", behavior: "smooth" },
timeout = 2000,
} = Astro.props as Props;
const scriptContent = buildScript(
analytics,
cache,
containerSelector,
defaultAnimation,
delay,
forceRequestIdleCallback,
highPriorityPrefetch,
ignores,
intersectionObserverOptions,
limit,
localLinkDetector,
prefetch,
prefetchUpgradation,
progressBar,
progressBarOptions,
scanOnMount,
scrollIntoView,
scrollIntoViewOptions,
timeout
);
const { code } = await minify(scriptContent);
fs.existsSync("public") || fs.mkdirSync("public");
const path = `public/astro-spa-${crypto
.createHash("sha256")
.update(code)
.digest("hex")
.slice(0, 8)}.js`;
if (external) {
(fs.existsSync(path) && fs.readFileSync(path, "utf8") === code) ||
fs.writeFileSync(path, code);
}
const Tag = "script";
---
<Tag {...attributes} src={external && path.substring(6)} set:html={code} />