Skip to content

Commit 8dc1a6d

Browse files
authored
Convert @emotion/cache's source code to TypeScript (#3277)
* Convert `@emotion/cache`'s source code to TypeScript * remove extra comment types * tweak pkg json * fixed pkg.json#imports * try with this * use .ts * try this * try this * one more * try this * update `@types/stylis`
1 parent 282b61d commit 8dc1a6d

File tree

13 files changed

+168
-210
lines changed

13 files changed

+168
-210
lines changed

.changeset/fluffy-garlics-smash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@emotion/cache': minor
3+
---
4+
5+
Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written.

packages/cache/package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"description": "emotion's cache",
55
"main": "dist/emotion-cache.cjs.js",
66
"module": "dist/emotion-cache.esm.js",
7+
"types": "dist/emotion-cache.cjs.d.ts",
78
"exports": {
89
".": {
910
"types": {
@@ -63,18 +64,17 @@
6364
},
6465
"imports": {
6566
"#is-development": {
66-
"development": "./src/conditions/true.js",
67-
"default": "./src/conditions/false.js"
67+
"development": "./src/conditions/true.ts",
68+
"default": "./src/conditions/false.ts"
6869
},
6970
"#is-browser": {
70-
"edge-light": "./src/conditions/false.js",
71-
"workerd": "./src/conditions/false.js",
72-
"worker": "./src/conditions/false.js",
73-
"browser": "./src/conditions/true.js",
74-
"default": "./src/conditions/is-browser.js"
71+
"edge-light": "./src/conditions/false.ts",
72+
"workerd": "./src/conditions/false.ts",
73+
"worker": "./src/conditions/false.ts",
74+
"browser": "./src/conditions/true.ts",
75+
"default": "./src/conditions/is-browser.ts"
7576
}
7677
},
77-
"types": "types/index.d.ts",
7878
"license": "MIT",
7979
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/cache",
8080
"scripts": {
@@ -90,11 +90,11 @@
9090
"devDependencies": {
9191
"@definitelytyped/dtslint": "0.0.112",
9292
"@emotion/hash": "*",
93+
"@types/stylis": "^4.2.7",
9394
"typescript": "^5.4.5"
9495
},
9596
"files": [
9697
"src",
97-
"dist",
98-
"types/*.d.ts"
98+
"dist"
9999
]
100100
}

packages/cache/src/index.d.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/cache/src/index.js renamed to packages/cache/src/index.ts

Lines changed: 39 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { StyleSheet } from '@emotion/sheet'
2-
/* import { type EmotionCache, type SerializedStyles } from '@emotion/utils' */
2+
import type { EmotionCache, SerializedStyles } from '@emotion/utils'
33
import {
44
serialize,
55
compile,
@@ -8,6 +8,7 @@ import {
88
stringify,
99
COMMENT
1010
} from 'stylis'
11+
import type { Element as StylisElement } from 'stylis'
1112
import weakMemoize from '@emotion/weak-memoize'
1213
import memoize from '@emotion/memoize'
1314
import isDevelopment from '#is-development'
@@ -19,43 +20,37 @@ import {
1920
incorrectImportAlarm
2021
} from './stylis-plugins'
2122
import { prefixer } from './prefixer'
22-
/* import type { StylisPlugin } from './types' */
23+
import { StylisPlugin } from './types'
2324

24-
/*
25-
export type Options = {
26-
nonce?: string,
27-
stylisPlugins?: StylisPlugin[],
28-
key: string,
29-
container?: HTMLElement,
30-
speedy?: boolean,
31-
prepend?: boolean,
25+
export interface Options {
26+
nonce?: string
27+
stylisPlugins?: Array<StylisPlugin>
28+
key: string
29+
container?: Node
30+
speedy?: boolean
31+
/** @deprecate use `insertionPoint` instead */
32+
prepend?: boolean
3233
insertionPoint?: HTMLElement
3334
}
34-
*/
3535

3636
let getServerStylisCache = isBrowser
3737
? undefined
38-
: weakMemoize(() =>
39-
memoize(() => {
40-
let cache = {}
41-
return name => cache[name]
42-
})
43-
)
38+
: weakMemoize(() => memoize<Record<string, string>>(() => ({})))
4439

4540
const defaultStylisPlugins = [prefixer]
4641

47-
let getSourceMap
42+
let getSourceMap: ((styles: string) => string | undefined) | undefined
4843
if (isDevelopment) {
4944
let sourceMapPattern =
5045
/\/\*#\ssourceMappingURL=data:application\/json;\S+\s+\*\//g
51-
getSourceMap = (styles /*: string */) => {
46+
getSourceMap = styles => {
5247
let matches = styles.match(sourceMapPattern)
5348
if (!matches) return
5449
return matches[matches.length - 1]
5550
}
5651
}
5752

58-
let createCache = (options /*: Options */) /*: EmotionCache */ => {
53+
let createCache = (options: Options): EmotionCache => {
5954
let key = options.key
6055

6156
if (isDevelopment && !key) {
@@ -74,14 +69,14 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
7469
// document.head is a safe place to move them to(though note document.head is not necessarily the last place they will be)
7570
// note this very very intentionally targets all style elements regardless of the key to ensure
7671
// that creating a cache works inside of render of a React component
77-
Array.prototype.forEach.call(ssrStyles, (node /*: HTMLStyleElement */) => {
72+
Array.prototype.forEach.call(ssrStyles, (node: HTMLStyleElement) => {
7873
// we want to only move elements which have a space in the data-emotion attribute value
7974
// because that indicates that it is an Emotion 11 server-side rendered style elements
8075
// while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector
8176
// Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes)
8277
// so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles
8378
// will not result in the Emotion 10 styles being destroyed
84-
const dataEmotionAttribute = node.getAttribute('data-emotion')
79+
const dataEmotionAttribute = node.getAttribute('data-emotion')!
8580
if (dataEmotionAttribute.indexOf(' ') === -1) {
8681
return
8782
}
@@ -100,18 +95,18 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
10095
)
10196
}
10297
}
103-
let inserted = {}
104-
let container /* : Node */
105-
const nodesToHydrate = []
98+
let inserted: EmotionCache['inserted'] = {}
99+
let container: Node
100+
const nodesToHydrate: HTMLStyleElement[] = []
106101
if (isBrowser) {
107102
container = options.container || document.head
108103

109104
Array.prototype.forEach.call(
110105
// this means we will ignore elements which don't have a space in them which
111106
// means that the style elements we're looking at are only Emotion 11 server-rendered style elements
112107
document.querySelectorAll(`style[data-emotion^="${key} "]`),
113-
(node /*: HTMLStyleElement */) => {
114-
const attrib = node.getAttribute(`data-emotion`).split(' ')
108+
(node: HTMLStyleElement) => {
109+
const attrib = node.getAttribute(`data-emotion`)!.split(' ')
115110
for (let i = 1; i < attrib.length; i++) {
116111
inserted[attrib[i]] = true
117112
}
@@ -120,12 +115,12 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
120115
)
121116
}
122117

123-
let insert /*: (
118+
let insert: (
124119
selector: string,
125120
serialized: SerializedStyles,
126121
sheet: StyleSheet,
127122
shouldCache: boolean
128-
) => string | void */
123+
) => string | void
129124
const omnipresentPlugins = [compat, removeLabel]
130125

131126
if (isDevelopment) {
@@ -139,13 +134,13 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
139134
)
140135
}
141136

142-
if (isBrowser) {
143-
let currentSheet
137+
if (!getServerStylisCache) {
138+
let currentSheet: Pick<StyleSheet, 'insert'>
144139

145140
const finalizingPlugins = [
146141
stringify,
147142
isDevelopment
148-
? element => {
143+
? (element: StylisElement) => {
149144
if (!element.root) {
150145
if (element.return) {
151146
currentSheet.insert(element.return)
@@ -164,21 +159,16 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
164159
const serializer = middleware(
165160
omnipresentPlugins.concat(stylisPlugins, finalizingPlugins)
166161
)
167-
const stylis = styles => serialize(compile(styles), serializer)
162+
const stylis = (styles: string) => serialize(compile(styles), serializer)
168163

169-
insert = (
170-
selector /*: string */,
171-
serialized /*: SerializedStyles */,
172-
sheet /*: StyleSheet */,
173-
shouldCache /*: boolean */
174-
) /*: void */ => {
164+
insert = (selector, serialized, sheet, shouldCache) => {
175165
currentSheet = sheet
176166

177-
if (isDevelopment) {
167+
if (getSourceMap) {
178168
let sourceMap = getSourceMap(serialized.styles)
179169
if (sourceMap) {
180170
currentSheet = {
181-
insert: (rule /*: string */) => {
171+
insert: rule => {
182172
sheet.insert(rule + sourceMap)
183173
}
184174
}
@@ -196,13 +186,10 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
196186
const serializer = middleware(
197187
omnipresentPlugins.concat(stylisPlugins, finalizingPlugins)
198188
)
199-
const stylis = styles => serialize(compile(styles), serializer)
189+
const stylis = (styles: string) => serialize(compile(styles), serializer)
200190

201191
let serverStylisCache = getServerStylisCache(stylisPlugins)(key)
202-
let getRules = (
203-
selector /*: string */,
204-
serialized /*: SerializedStyles */
205-
) /*: string */ => {
192+
let getRules = (selector: string, serialized: SerializedStyles): string => {
206193
let name = serialized.name
207194
if (serverStylisCache[name] === undefined) {
208195
serverStylisCache[name] = stylis(
@@ -211,12 +198,7 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
211198
}
212199
return serverStylisCache[name]
213200
}
214-
insert = (
215-
selector /*: string */,
216-
serialized /*: SerializedStyles */,
217-
sheet /*: StyleSheet */,
218-
shouldCache /*: boolean */
219-
) /*: string | void */ => {
201+
insert = (selector, serialized, sheet, shouldCache) => {
220202
let name = serialized.name
221203
let rules = getRules(selector, serialized)
222204
if (cache.compat === undefined) {
@@ -226,7 +208,7 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
226208
if (shouldCache) {
227209
cache.inserted[name] = true
228210
}
229-
if (isDevelopment) {
211+
if (getSourceMap) {
230212
let sourceMap = getSourceMap(serialized.styles)
231213
if (sourceMap) {
232214
return rules + sourceMap
@@ -251,11 +233,11 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
251233
}
252234
}
253235

254-
const cache /*: EmotionCache */ = {
236+
const cache: EmotionCache = {
255237
key,
256238
sheet: new StyleSheet({
257239
key,
258-
container,
240+
container: container!,
259241
nonce: options.nonce,
260242
speedy: options.speedy,
261243
prepend: options.prepend,
@@ -273,3 +255,5 @@ let createCache = (options /*: Options */) /*: EmotionCache */ => {
273255
}
274256

275257
export default createCache
258+
export type { EmotionCache }
259+
export type { StylisElement, StylisPlugin, StylisPluginCallback } from './types'

packages/cache/src/prefixer.js renamed to packages/cache/src/prefixer.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ import {
1515
RULESET,
1616
serialize,
1717
strlen,
18-
WEBKIT
18+
WEBKIT,
19+
Element,
20+
Middleware
1921
} from 'stylis'
2022

2123
// this is a copy of stylis@4.0.13 prefixer, the latter version introduced grid prefixing which we don't want
2224

23-
function prefix(value, length) {
25+
function prefix(value: string, length: number): string {
2426
switch (hash(value, length)) {
2527
// color-adjust
2628
case 5103:
@@ -279,7 +281,12 @@ function prefix(value, length) {
279281
return value
280282
}
281283

282-
export let prefixer = (element, index, children, callback) => {
284+
export let prefixer = (
285+
element: Element,
286+
index: number,
287+
children: Element[],
288+
callback: Middleware
289+
) => {
283290
if (element.length > -1)
284291
if (!element.return)
285292
switch (element.type) {
@@ -297,7 +304,7 @@ export let prefixer = (element, index, children, callback) => {
297304
)
298305
case RULESET:
299306
if (element.length)
300-
return combine(element.props, function (value) {
307+
return combine(element.props as string[], function (value) {
301308
switch (match(value, /(::plac\w+|:read-\w+)/)) {
302309
// :read-(only|write)
303310
case ':read-only':

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy