@zealamic/css-doctor-binding 0.0.0-stage → 1.0.0-beta.1
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 +47 -2
- package/css-doctor-binding.darwin-arm64.node +0 -0
- package/css-doctor-binding.linux-x64-gnu.node +0 -0
- package/index.d.ts +298 -0
- package/index.js +321 -0
- package/package.json +38 -3
package/README.md
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# @zealamic/css-doctor-binding
|
|
4
|
+
|
|
5
|
+
**Native NAPI-RS bridge for the css-doctor LightningCSS engine.**
|
|
6
|
+
|
|
7
|
+
Version 1.0.0-beta.1
|
|
8
|
+
|
|
9
|
+
[English](./README.md) | [Tiếng Việt](./README_VI.md) | [简体中文](./README_CN.md)
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add @zealamic/css-doctor-binding
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { analyzeCss, optimizeCss } from "@zealamic/css-doctor-binding";
|
|
25
|
+
|
|
26
|
+
const analysis = analyzeCss(".card { color: red; }");
|
|
27
|
+
|
|
28
|
+
const result = optimizeCss({
|
|
29
|
+
cssContent: ".card { color: red; } :root { --brand: red; }",
|
|
30
|
+
pageUsage: { home: ["card"] },
|
|
31
|
+
pageCoverage: { enabled: true, minPageRatio: 0.5 },
|
|
32
|
+
sizeBudget: { enabled: true, maxChunkSize: 40 * 1024, isolateVariables: true },
|
|
33
|
+
minify: true,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
console.log(analysis.stats.selectorCount);
|
|
37
|
+
console.log(result.chunks);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Safety and limitations
|
|
41
|
+
|
|
42
|
+
- Prebuilt binaries cover darwin-arm64, darwin-x64, linux-x64-gnu, linux-x64-musl, and win32-x64-msvc.
|
|
43
|
+
- The native API is low-level; prefer @zealamic/css-doctor-vite, next, rsbuild, nuxt, or remix for application builds.
|
|
44
|
+
- Never edit generated index.js, index.d.ts, index.d.cts, or *.node files by hand.
|
|
45
|
+
|
|
46
|
+
## Full documentation
|
|
47
|
+
|
|
48
|
+
Project README: [English](../../README.md) | [Tiếng Việt](../../README_VI.md) | [简体中文](../../README_CN.md)
|
|
Binary file
|
|
Binary file
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
/** The kind of a simple selector. */
|
|
7
|
+
export const enum JsSelectorKind {
|
|
8
|
+
/** A class selector such as `.button`. */
|
|
9
|
+
Class = 'class',
|
|
10
|
+
/** An ID selector such as `#app`. */
|
|
11
|
+
Id = 'id',
|
|
12
|
+
/** A type/tag selector such as `section`. */
|
|
13
|
+
Tag = 'tag',
|
|
14
|
+
/** An attribute selector such as `[data-state="open"]`. */
|
|
15
|
+
Attribute = 'attribute',
|
|
16
|
+
/** A pseudo-class such as `:hover`. */
|
|
17
|
+
PseudoClass = 'pseudo_class',
|
|
18
|
+
/** A pseudo-element such as `::before`. */
|
|
19
|
+
PseudoElement = 'pseudo_element',
|
|
20
|
+
/** The universal selector `*`. */
|
|
21
|
+
Universal = 'universal',
|
|
22
|
+
/** The CSS nesting selector `&`. */
|
|
23
|
+
Nesting = 'nesting'
|
|
24
|
+
}
|
|
25
|
+
/** Decoded CSS specificity. */
|
|
26
|
+
export interface JsSpecificity {
|
|
27
|
+
/** Number of ID selectors. */
|
|
28
|
+
ids: number
|
|
29
|
+
/** Number of class, attribute and pseudo-class selectors. */
|
|
30
|
+
classes: number
|
|
31
|
+
/** Number of type and pseudo-element selectors. */
|
|
32
|
+
types: number
|
|
33
|
+
}
|
|
34
|
+
/** A 1-based source location. */
|
|
35
|
+
export interface JsSourceLocation {
|
|
36
|
+
/** 1-based line number. */
|
|
37
|
+
line: number
|
|
38
|
+
/** 1-based column number. */
|
|
39
|
+
column: number
|
|
40
|
+
}
|
|
41
|
+
/** A non-fatal parser warning. */
|
|
42
|
+
export interface JsAnalysisWarning {
|
|
43
|
+
/** Human-readable description of the problem. */
|
|
44
|
+
message: string
|
|
45
|
+
/** Location of the problem, when known. */
|
|
46
|
+
location?: JsSourceLocation
|
|
47
|
+
}
|
|
48
|
+
/** A selector extracted from a style rule. */
|
|
49
|
+
export interface JsSelectorInfo {
|
|
50
|
+
/** Normalized selector text. */
|
|
51
|
+
raw: string
|
|
52
|
+
/** Simple-selector kinds present in the selector. */
|
|
53
|
+
kinds: Array<JsSelectorKind>
|
|
54
|
+
/** Class names without the leading dot. */
|
|
55
|
+
classes: Array<string>
|
|
56
|
+
/** ID names without the leading hash. */
|
|
57
|
+
ids: Array<string>
|
|
58
|
+
/** Local type/tag names. */
|
|
59
|
+
tags: Array<string>
|
|
60
|
+
/** Local attribute names. */
|
|
61
|
+
attributes: Array<string>
|
|
62
|
+
/** Pseudo-class names without the leading colon or arguments. */
|
|
63
|
+
pseudoClasses: Array<string>
|
|
64
|
+
/** Pseudo-element names without the leading `::` or arguments. */
|
|
65
|
+
pseudoElements: Array<string>
|
|
66
|
+
/** Tree combinators present (`" "`, `">"`, `"+"`, `"~"`). */
|
|
67
|
+
combinators: Array<string>
|
|
68
|
+
/** Decoded specificity. */
|
|
69
|
+
specificity: JsSpecificity
|
|
70
|
+
/** Index into `CssAnalysisResult.rules`. */
|
|
71
|
+
ruleIndex: number
|
|
72
|
+
/** Number of enclosing style rules. */
|
|
73
|
+
nestingDepth: number
|
|
74
|
+
}
|
|
75
|
+
/** A style rule and its selectors. */
|
|
76
|
+
export interface JsStyleRuleInfo {
|
|
77
|
+
/** Index of the rule in `CssAnalysisResult.rules`. */
|
|
78
|
+
index: number
|
|
79
|
+
/** Index of the enclosing style rule, when nested. */
|
|
80
|
+
parentRuleIndex?: number
|
|
81
|
+
/** Indices into `CssAnalysisResult.selectors`. */
|
|
82
|
+
selectorIndices: Array<number>
|
|
83
|
+
/** Number of normal declarations. */
|
|
84
|
+
declarationCount: number
|
|
85
|
+
/** Number of `!important` declarations. */
|
|
86
|
+
importantDeclarationCount: number
|
|
87
|
+
/** Number of enclosing style rules. */
|
|
88
|
+
nestingDepth: number
|
|
89
|
+
/** Location of the rule in the source. */
|
|
90
|
+
location: JsSourceLocation
|
|
91
|
+
}
|
|
92
|
+
/** Aggregate counters for an analysis run. */
|
|
93
|
+
export interface JsAnalysisStats {
|
|
94
|
+
/** Number of style rules. */
|
|
95
|
+
ruleCount: number
|
|
96
|
+
/** Number of selectors. */
|
|
97
|
+
selectorCount: number
|
|
98
|
+
/** Total number of normal declarations. */
|
|
99
|
+
declarationCount: number
|
|
100
|
+
/** Total number of `!important` declarations. */
|
|
101
|
+
importantDeclarationCount: number
|
|
102
|
+
/** Number of distinct class names. */
|
|
103
|
+
uniqueClassCount: number
|
|
104
|
+
/** Number of distinct ID names. */
|
|
105
|
+
uniqueIdCount: number
|
|
106
|
+
/** Number of distinct type/tag names. */
|
|
107
|
+
uniqueTagCount: number
|
|
108
|
+
/** Number of distinct attribute names. */
|
|
109
|
+
uniqueAttributeCount: number
|
|
110
|
+
/** Deepest style-rule nesting observed. */
|
|
111
|
+
maxNestingDepth: number
|
|
112
|
+
/** Number of parser warnings. */
|
|
113
|
+
warningCount: number
|
|
114
|
+
}
|
|
115
|
+
/** The complete result of analyzing a stylesheet. */
|
|
116
|
+
export interface JsCssAnalysisResult {
|
|
117
|
+
/** All selectors in document order. */
|
|
118
|
+
selectors: Array<JsSelectorInfo>
|
|
119
|
+
/** All style rules in document order. */
|
|
120
|
+
rules: Array<JsStyleRuleInfo>
|
|
121
|
+
/** Aggregate counters. */
|
|
122
|
+
stats: JsAnalysisStats
|
|
123
|
+
/** Recoverable parser warnings. */
|
|
124
|
+
warnings: Array<JsAnalysisWarning>
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Analyzes a CSS string synchronously.
|
|
128
|
+
*
|
|
129
|
+
* # Errors
|
|
130
|
+
*
|
|
131
|
+
* Rejects with a JavaScript `Error` when the stylesheet cannot be parsed at
|
|
132
|
+
* all. Recoverable syntax errors are returned as `warnings` instead.
|
|
133
|
+
*/
|
|
134
|
+
export declare function analyzeCss(cssContent: string): JsCssAnalysisResult
|
|
135
|
+
/**
|
|
136
|
+
* Analyzes a CSS string on the libuv thread pool and returns a `Promise`.
|
|
137
|
+
*
|
|
138
|
+
* This is the preferred entry point for large stylesheets because it does not
|
|
139
|
+
* block the Node.js event loop.
|
|
140
|
+
*
|
|
141
|
+
* # Errors
|
|
142
|
+
*
|
|
143
|
+
* Rejects with a JavaScript `Error` when the stylesheet cannot be parsed.
|
|
144
|
+
*/
|
|
145
|
+
export declare function analyzeCssAsync(cssContent: string): Promise<JsCssAnalysisResult>
|
|
146
|
+
/**
|
|
147
|
+
* Analyzes a CSS string and returns the result as a JSON string.
|
|
148
|
+
*
|
|
149
|
+
* The JSON shape is identical to the object returned by `analyzeCss`.
|
|
150
|
+
*
|
|
151
|
+
* # Errors
|
|
152
|
+
*
|
|
153
|
+
* Rejects with a JavaScript `Error` when parsing or serialization fails.
|
|
154
|
+
*/
|
|
155
|
+
export declare function analyzeCssJson(cssContent: string): string
|
|
156
|
+
/** Configuration for page-coverage chunk splitting. */
|
|
157
|
+
export interface JsChunkConfig {
|
|
158
|
+
/**
|
|
159
|
+
* Minimum share of pages that must use a rule before it is considered
|
|
160
|
+
* common. Range: 0.0..=1.0.
|
|
161
|
+
*/
|
|
162
|
+
minPageRatio: number
|
|
163
|
+
/** Selectors or class names that should always stay in the common chunk. */
|
|
164
|
+
forceCommonSelectors: Array<string>
|
|
165
|
+
/** Minify serialized CSS. Defaults to `true`. */
|
|
166
|
+
minify?: boolean
|
|
167
|
+
}
|
|
168
|
+
/** Input for [`split_css_by_pages`]. */
|
|
169
|
+
export interface JsSplitInput {
|
|
170
|
+
/** Original CSS source. */
|
|
171
|
+
cssContent: string
|
|
172
|
+
/** Page/route name to class names used by that page. */
|
|
173
|
+
pageUsage: Record<string, Array<string>>
|
|
174
|
+
/** Splitting configuration. */
|
|
175
|
+
config: JsChunkConfig
|
|
176
|
+
}
|
|
177
|
+
/** Usage information for one selector. */
|
|
178
|
+
export interface JsSelectorStat {
|
|
179
|
+
/** Original selector text. */
|
|
180
|
+
selector: string
|
|
181
|
+
/** Matched class occurrences across pages. */
|
|
182
|
+
totalOccurrences: number
|
|
183
|
+
/** Number of pages using the selector. */
|
|
184
|
+
pageCount: number
|
|
185
|
+
/** Fraction of pages using the selector (0..1). */
|
|
186
|
+
coverageRatio: number
|
|
187
|
+
/** `common`, `dead`, or `page:<name>[,<name>...]`. */
|
|
188
|
+
targetChunk: string
|
|
189
|
+
}
|
|
190
|
+
/** Result of page-coverage chunk splitting. */
|
|
191
|
+
export interface JsSplitOutput {
|
|
192
|
+
/** CSS shared by pages reaching the coverage threshold, plus global rules. */
|
|
193
|
+
commonCss: string
|
|
194
|
+
/** Page name to page-specific CSS. */
|
|
195
|
+
pageChunks: Record<string, string>
|
|
196
|
+
/** Per-selector usage matrix. */
|
|
197
|
+
stats: Array<JsSelectorStat>
|
|
198
|
+
/** Number of dead selector occurrences removed. */
|
|
199
|
+
deadCodeCount: number
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Splits a stylesheet into common and page-specific CSS chunks.
|
|
203
|
+
*
|
|
204
|
+
* # Errors
|
|
205
|
+
*
|
|
206
|
+
* Rejects with a JavaScript `Error` when the configuration is invalid or the
|
|
207
|
+
* stylesheet/AST cannot be processed.
|
|
208
|
+
*/
|
|
209
|
+
export declare function splitCssByPages(input: JsSplitInput): JsSplitOutput
|
|
210
|
+
/** Configuration for the semantic page-coverage tier. */
|
|
211
|
+
export interface JsPageCoverageConfig {
|
|
212
|
+
/** Enable page-coverage splitting. Defaults to `true`. */
|
|
213
|
+
enabled?: boolean
|
|
214
|
+
/** Minimum page coverage for common rules. Defaults to `0.5`. */
|
|
215
|
+
minPageRatio?: number
|
|
216
|
+
/** Selectors or classes that always stay in the common chunk. */
|
|
217
|
+
forceCommon?: Array<string>
|
|
218
|
+
}
|
|
219
|
+
/** Configuration for the physical size-budget tier. */
|
|
220
|
+
export interface JsSizeBudgetConfig {
|
|
221
|
+
/** Enable size-budget splitting. Defaults to `true`. */
|
|
222
|
+
enabled?: boolean
|
|
223
|
+
/** Maximum serialized bytes per body chunk. Defaults to 60 KiB. */
|
|
224
|
+
maxChunkSize?: number
|
|
225
|
+
/** Isolate CSS variables before splitting. Defaults to `true`. */
|
|
226
|
+
isolateVariables?: boolean
|
|
227
|
+
}
|
|
228
|
+
/** Input for [`optimize_css`]. */
|
|
229
|
+
export interface JsPipelineInput {
|
|
230
|
+
/** Original CSS source. */
|
|
231
|
+
cssContent: string
|
|
232
|
+
/** Page/route name to class names used by that page. */
|
|
233
|
+
pageUsage: Record<string, Array<string>>
|
|
234
|
+
/** Optional tier 1 configuration. */
|
|
235
|
+
pageCoverage?: JsPageCoverageConfig
|
|
236
|
+
/** Optional tier 2 configuration. */
|
|
237
|
+
sizeBudget?: JsSizeBudgetConfig
|
|
238
|
+
/** Minify serialized CSS. Defaults to `true`. */
|
|
239
|
+
minify?: boolean
|
|
240
|
+
}
|
|
241
|
+
/** The stage that produced a pipeline chunk. */
|
|
242
|
+
export const enum JsPipelineChunkKind {
|
|
243
|
+
/** Shared/common rules. */
|
|
244
|
+
Common = 'common',
|
|
245
|
+
/** Page-specific rules. */
|
|
246
|
+
Page = 'page',
|
|
247
|
+
/** Isolated CSS variables. */
|
|
248
|
+
Variables = 'variables',
|
|
249
|
+
/** A size-budget part. */
|
|
250
|
+
Part = 'part'
|
|
251
|
+
}
|
|
252
|
+
/** One CSS chunk emitted by the pipeline. */
|
|
253
|
+
export interface JsChunkOutput {
|
|
254
|
+
/** Logical file stem, e.g. `common`, `page-home`, `common-vars`. */
|
|
255
|
+
name: string
|
|
256
|
+
/** Base chunk before physical splitting. */
|
|
257
|
+
sourceChunk: string
|
|
258
|
+
/** Serialized CSS. */
|
|
259
|
+
css: string
|
|
260
|
+
/** Stage/kind of this chunk. */
|
|
261
|
+
kind: JsPipelineChunkKind
|
|
262
|
+
/** Page that owns this chunk, when applicable. */
|
|
263
|
+
page?: string
|
|
264
|
+
/** Whether this chunk contains isolated CSS variables. */
|
|
265
|
+
variables: boolean
|
|
266
|
+
/** 1-based part index when produced by size splitting. */
|
|
267
|
+
part?: number
|
|
268
|
+
/** Serialized byte size. */
|
|
269
|
+
sizeBytes: number
|
|
270
|
+
/** True when an indivisible rule exceeds the budget. */
|
|
271
|
+
oversized: boolean
|
|
272
|
+
/** True when this chunk exists because of the size budget. */
|
|
273
|
+
splitDueToSize: boolean
|
|
274
|
+
}
|
|
275
|
+
/** Result of the two-tier optimization pipeline. */
|
|
276
|
+
export interface JsPipelineOutput {
|
|
277
|
+
/** Final chunks in load order. */
|
|
278
|
+
chunks: Array<JsChunkOutput>
|
|
279
|
+
/** Selector usage matrix from tier 1. */
|
|
280
|
+
stats: Array<JsSelectorStat>
|
|
281
|
+
/** Dead selector occurrences removed by tier 1. */
|
|
282
|
+
deadCodeCount: number
|
|
283
|
+
/** Pages discovered from `page_usage`. */
|
|
284
|
+
pages: Array<string>
|
|
285
|
+
/** Whether page-coverage splitting actually ran. */
|
|
286
|
+
pageCoverageApplied: boolean
|
|
287
|
+
/** Whether size-budget processing was enabled. */
|
|
288
|
+
sizeBudgetApplied: boolean
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Runs the two-tier CSS optimization pipeline.
|
|
292
|
+
*
|
|
293
|
+
* # Errors
|
|
294
|
+
*
|
|
295
|
+
* Rejects with a JavaScript `Error` when the configuration is invalid or the
|
|
296
|
+
* stylesheet/AST cannot be processed.
|
|
297
|
+
*/
|
|
298
|
+
export declare function optimizeCss(input: JsPipelineInput): JsPipelineOutput
|
package/index.js
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/* prettier-ignore */
|
|
4
|
+
|
|
5
|
+
/* auto-generated by NAPI-RS */
|
|
6
|
+
|
|
7
|
+
const { existsSync, readFileSync } = require('fs')
|
|
8
|
+
const { join } = require('path')
|
|
9
|
+
|
|
10
|
+
const { platform, arch } = process
|
|
11
|
+
|
|
12
|
+
let nativeBinding = null
|
|
13
|
+
let localFileExisted = false
|
|
14
|
+
let loadError = null
|
|
15
|
+
|
|
16
|
+
function isMusl() {
|
|
17
|
+
// For Node 10
|
|
18
|
+
if (!process.report || typeof process.report.getReport !== 'function') {
|
|
19
|
+
try {
|
|
20
|
+
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
|
21
|
+
return readFileSync(lddPath, 'utf8').includes('musl')
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return true
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
const { glibcVersionRuntime } = process.report.getReport().header
|
|
27
|
+
return !glibcVersionRuntime
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
switch (platform) {
|
|
32
|
+
case 'android':
|
|
33
|
+
switch (arch) {
|
|
34
|
+
case 'arm64':
|
|
35
|
+
localFileExisted = existsSync(join(__dirname, 'css-doctor-binding.android-arm64.node'))
|
|
36
|
+
try {
|
|
37
|
+
if (localFileExisted) {
|
|
38
|
+
nativeBinding = require('./css-doctor-binding.android-arm64.node')
|
|
39
|
+
} else {
|
|
40
|
+
nativeBinding = require('@zealamic/css-doctor-binding-android-arm64')
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
loadError = e
|
|
44
|
+
}
|
|
45
|
+
break
|
|
46
|
+
case 'arm':
|
|
47
|
+
localFileExisted = existsSync(join(__dirname, 'css-doctor-binding.android-arm-eabi.node'))
|
|
48
|
+
try {
|
|
49
|
+
if (localFileExisted) {
|
|
50
|
+
nativeBinding = require('./css-doctor-binding.android-arm-eabi.node')
|
|
51
|
+
} else {
|
|
52
|
+
nativeBinding = require('@zealamic/css-doctor-binding-android-arm-eabi')
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {
|
|
55
|
+
loadError = e
|
|
56
|
+
}
|
|
57
|
+
break
|
|
58
|
+
default:
|
|
59
|
+
throw new Error(`Unsupported architecture on Android ${arch}`)
|
|
60
|
+
}
|
|
61
|
+
break
|
|
62
|
+
case 'win32':
|
|
63
|
+
switch (arch) {
|
|
64
|
+
case 'x64':
|
|
65
|
+
localFileExisted = existsSync(
|
|
66
|
+
join(__dirname, 'css-doctor-binding.win32-x64-msvc.node')
|
|
67
|
+
)
|
|
68
|
+
try {
|
|
69
|
+
if (localFileExisted) {
|
|
70
|
+
nativeBinding = require('./css-doctor-binding.win32-x64-msvc.node')
|
|
71
|
+
} else {
|
|
72
|
+
nativeBinding = require('@zealamic/css-doctor-binding-win32-x64-msvc')
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
loadError = e
|
|
76
|
+
}
|
|
77
|
+
break
|
|
78
|
+
case 'ia32':
|
|
79
|
+
localFileExisted = existsSync(
|
|
80
|
+
join(__dirname, 'css-doctor-binding.win32-ia32-msvc.node')
|
|
81
|
+
)
|
|
82
|
+
try {
|
|
83
|
+
if (localFileExisted) {
|
|
84
|
+
nativeBinding = require('./css-doctor-binding.win32-ia32-msvc.node')
|
|
85
|
+
} else {
|
|
86
|
+
nativeBinding = require('@zealamic/css-doctor-binding-win32-ia32-msvc')
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
loadError = e
|
|
90
|
+
}
|
|
91
|
+
break
|
|
92
|
+
case 'arm64':
|
|
93
|
+
localFileExisted = existsSync(
|
|
94
|
+
join(__dirname, 'css-doctor-binding.win32-arm64-msvc.node')
|
|
95
|
+
)
|
|
96
|
+
try {
|
|
97
|
+
if (localFileExisted) {
|
|
98
|
+
nativeBinding = require('./css-doctor-binding.win32-arm64-msvc.node')
|
|
99
|
+
} else {
|
|
100
|
+
nativeBinding = require('@zealamic/css-doctor-binding-win32-arm64-msvc')
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
loadError = e
|
|
104
|
+
}
|
|
105
|
+
break
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unsupported architecture on Windows: ${arch}`)
|
|
108
|
+
}
|
|
109
|
+
break
|
|
110
|
+
case 'darwin':
|
|
111
|
+
localFileExisted = existsSync(join(__dirname, 'css-doctor-binding.darwin-universal.node'))
|
|
112
|
+
try {
|
|
113
|
+
if (localFileExisted) {
|
|
114
|
+
nativeBinding = require('./css-doctor-binding.darwin-universal.node')
|
|
115
|
+
} else {
|
|
116
|
+
nativeBinding = require('@zealamic/css-doctor-binding-darwin-universal')
|
|
117
|
+
}
|
|
118
|
+
break
|
|
119
|
+
} catch {}
|
|
120
|
+
switch (arch) {
|
|
121
|
+
case 'x64':
|
|
122
|
+
localFileExisted = existsSync(join(__dirname, 'css-doctor-binding.darwin-x64.node'))
|
|
123
|
+
try {
|
|
124
|
+
if (localFileExisted) {
|
|
125
|
+
nativeBinding = require('./css-doctor-binding.darwin-x64.node')
|
|
126
|
+
} else {
|
|
127
|
+
nativeBinding = require('@zealamic/css-doctor-binding-darwin-x64')
|
|
128
|
+
}
|
|
129
|
+
} catch (e) {
|
|
130
|
+
loadError = e
|
|
131
|
+
}
|
|
132
|
+
break
|
|
133
|
+
case 'arm64':
|
|
134
|
+
localFileExisted = existsSync(
|
|
135
|
+
join(__dirname, 'css-doctor-binding.darwin-arm64.node')
|
|
136
|
+
)
|
|
137
|
+
try {
|
|
138
|
+
if (localFileExisted) {
|
|
139
|
+
nativeBinding = require('./css-doctor-binding.darwin-arm64.node')
|
|
140
|
+
} else {
|
|
141
|
+
nativeBinding = require('@zealamic/css-doctor-binding-darwin-arm64')
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
144
|
+
loadError = e
|
|
145
|
+
}
|
|
146
|
+
break
|
|
147
|
+
default:
|
|
148
|
+
throw new Error(`Unsupported architecture on macOS: ${arch}`)
|
|
149
|
+
}
|
|
150
|
+
break
|
|
151
|
+
case 'freebsd':
|
|
152
|
+
if (arch !== 'x64') {
|
|
153
|
+
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
|
|
154
|
+
}
|
|
155
|
+
localFileExisted = existsSync(join(__dirname, 'css-doctor-binding.freebsd-x64.node'))
|
|
156
|
+
try {
|
|
157
|
+
if (localFileExisted) {
|
|
158
|
+
nativeBinding = require('./css-doctor-binding.freebsd-x64.node')
|
|
159
|
+
} else {
|
|
160
|
+
nativeBinding = require('@zealamic/css-doctor-binding-freebsd-x64')
|
|
161
|
+
}
|
|
162
|
+
} catch (e) {
|
|
163
|
+
loadError = e
|
|
164
|
+
}
|
|
165
|
+
break
|
|
166
|
+
case 'linux':
|
|
167
|
+
switch (arch) {
|
|
168
|
+
case 'x64':
|
|
169
|
+
if (isMusl()) {
|
|
170
|
+
localFileExisted = existsSync(
|
|
171
|
+
join(__dirname, 'css-doctor-binding.linux-x64-musl.node')
|
|
172
|
+
)
|
|
173
|
+
try {
|
|
174
|
+
if (localFileExisted) {
|
|
175
|
+
nativeBinding = require('./css-doctor-binding.linux-x64-musl.node')
|
|
176
|
+
} else {
|
|
177
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-x64-musl')
|
|
178
|
+
}
|
|
179
|
+
} catch (e) {
|
|
180
|
+
loadError = e
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
localFileExisted = existsSync(
|
|
184
|
+
join(__dirname, 'css-doctor-binding.linux-x64-gnu.node')
|
|
185
|
+
)
|
|
186
|
+
try {
|
|
187
|
+
if (localFileExisted) {
|
|
188
|
+
nativeBinding = require('./css-doctor-binding.linux-x64-gnu.node')
|
|
189
|
+
} else {
|
|
190
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-x64-gnu')
|
|
191
|
+
}
|
|
192
|
+
} catch (e) {
|
|
193
|
+
loadError = e
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
break
|
|
197
|
+
case 'arm64':
|
|
198
|
+
if (isMusl()) {
|
|
199
|
+
localFileExisted = existsSync(
|
|
200
|
+
join(__dirname, 'css-doctor-binding.linux-arm64-musl.node')
|
|
201
|
+
)
|
|
202
|
+
try {
|
|
203
|
+
if (localFileExisted) {
|
|
204
|
+
nativeBinding = require('./css-doctor-binding.linux-arm64-musl.node')
|
|
205
|
+
} else {
|
|
206
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-arm64-musl')
|
|
207
|
+
}
|
|
208
|
+
} catch (e) {
|
|
209
|
+
loadError = e
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
localFileExisted = existsSync(
|
|
213
|
+
join(__dirname, 'css-doctor-binding.linux-arm64-gnu.node')
|
|
214
|
+
)
|
|
215
|
+
try {
|
|
216
|
+
if (localFileExisted) {
|
|
217
|
+
nativeBinding = require('./css-doctor-binding.linux-arm64-gnu.node')
|
|
218
|
+
} else {
|
|
219
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-arm64-gnu')
|
|
220
|
+
}
|
|
221
|
+
} catch (e) {
|
|
222
|
+
loadError = e
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
break
|
|
226
|
+
case 'arm':
|
|
227
|
+
if (isMusl()) {
|
|
228
|
+
localFileExisted = existsSync(
|
|
229
|
+
join(__dirname, 'css-doctor-binding.linux-arm-musleabihf.node')
|
|
230
|
+
)
|
|
231
|
+
try {
|
|
232
|
+
if (localFileExisted) {
|
|
233
|
+
nativeBinding = require('./css-doctor-binding.linux-arm-musleabihf.node')
|
|
234
|
+
} else {
|
|
235
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-arm-musleabihf')
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
loadError = e
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
localFileExisted = existsSync(
|
|
242
|
+
join(__dirname, 'css-doctor-binding.linux-arm-gnueabihf.node')
|
|
243
|
+
)
|
|
244
|
+
try {
|
|
245
|
+
if (localFileExisted) {
|
|
246
|
+
nativeBinding = require('./css-doctor-binding.linux-arm-gnueabihf.node')
|
|
247
|
+
} else {
|
|
248
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-arm-gnueabihf')
|
|
249
|
+
}
|
|
250
|
+
} catch (e) {
|
|
251
|
+
loadError = e
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
break
|
|
255
|
+
case 'riscv64':
|
|
256
|
+
if (isMusl()) {
|
|
257
|
+
localFileExisted = existsSync(
|
|
258
|
+
join(__dirname, 'css-doctor-binding.linux-riscv64-musl.node')
|
|
259
|
+
)
|
|
260
|
+
try {
|
|
261
|
+
if (localFileExisted) {
|
|
262
|
+
nativeBinding = require('./css-doctor-binding.linux-riscv64-musl.node')
|
|
263
|
+
} else {
|
|
264
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-riscv64-musl')
|
|
265
|
+
}
|
|
266
|
+
} catch (e) {
|
|
267
|
+
loadError = e
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
localFileExisted = existsSync(
|
|
271
|
+
join(__dirname, 'css-doctor-binding.linux-riscv64-gnu.node')
|
|
272
|
+
)
|
|
273
|
+
try {
|
|
274
|
+
if (localFileExisted) {
|
|
275
|
+
nativeBinding = require('./css-doctor-binding.linux-riscv64-gnu.node')
|
|
276
|
+
} else {
|
|
277
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-riscv64-gnu')
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
loadError = e
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
break
|
|
284
|
+
case 's390x':
|
|
285
|
+
localFileExisted = existsSync(
|
|
286
|
+
join(__dirname, 'css-doctor-binding.linux-s390x-gnu.node')
|
|
287
|
+
)
|
|
288
|
+
try {
|
|
289
|
+
if (localFileExisted) {
|
|
290
|
+
nativeBinding = require('./css-doctor-binding.linux-s390x-gnu.node')
|
|
291
|
+
} else {
|
|
292
|
+
nativeBinding = require('@zealamic/css-doctor-binding-linux-s390x-gnu')
|
|
293
|
+
}
|
|
294
|
+
} catch (e) {
|
|
295
|
+
loadError = e
|
|
296
|
+
}
|
|
297
|
+
break
|
|
298
|
+
default:
|
|
299
|
+
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
|
300
|
+
}
|
|
301
|
+
break
|
|
302
|
+
default:
|
|
303
|
+
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (!nativeBinding) {
|
|
307
|
+
if (loadError) {
|
|
308
|
+
throw loadError
|
|
309
|
+
}
|
|
310
|
+
throw new Error(`Failed to load native binding`)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const { JsSelectorKind, analyzeCss, analyzeCssAsync, analyzeCssJson, splitCssByPages, JsPipelineChunkKind, optimizeCss } = nativeBinding
|
|
314
|
+
|
|
315
|
+
module.exports.JsSelectorKind = JsSelectorKind
|
|
316
|
+
module.exports.analyzeCss = analyzeCss
|
|
317
|
+
module.exports.analyzeCssAsync = analyzeCssAsync
|
|
318
|
+
module.exports.analyzeCssJson = analyzeCssJson
|
|
319
|
+
module.exports.splitCssByPages = splitCssByPages
|
|
320
|
+
module.exports.JsPipelineChunkKind = JsPipelineChunkKind
|
|
321
|
+
module.exports.optimizeCss = optimizeCss
|
package/package.json
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zealamic/css-doctor-binding",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "Native Node.js bindings for the css-doctor CSS analysis engine",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"index.js",
|
|
10
|
+
"index.d.ts",
|
|
11
|
+
"*.node"
|
|
12
|
+
],
|
|
13
|
+
"napi": {
|
|
14
|
+
"name": "css-doctor-binding",
|
|
15
|
+
"triples": {
|
|
16
|
+
"defaults": true
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@napi-rs/cli": "^2.18.4",
|
|
21
|
+
"@types/node": "^22.20.5",
|
|
22
|
+
"tsx": "^4.23.15",
|
|
23
|
+
"typescript": "^5.9.3"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "napi build --platform --release",
|
|
33
|
+
"build:debug": "napi build --platform",
|
|
34
|
+
"test": "pnpm build && pnpm typecheck && tsx test.ts",
|
|
35
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
36
|
+
"lint": "biome lint src test.ts",
|
|
37
|
+
"format": "biome format --write src test.ts",
|
|
38
|
+
"format:check": "biome format src test.ts",
|
|
39
|
+
"check": "biome check src test.ts"
|
|
40
|
+
}
|
|
6
41
|
}
|