Skip to content

Commit 137f292

Browse files
committed
feat: Simplify options.
BREAKING CHANGE: Some types related to options are removed/renamed. The options code was some of the first I wrote for this project and it was awkward to use. A lot of APIs expected a concrete options reader instead of just the options interface in a read-only state. The options reader is no longer exported, the new normalizeOptions function should be used to get a read-only options object populated with default values where necessary. Where user-supplied options are accepted, the SparseOptions type is accepted and then normalized.
1 parent 6dc6a36 commit 137f292

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+517
-608
lines changed

packages/css-blocks/src/Block/AttrValue.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
import { assertNever, assertNeverCalled } from "@opticss/util";
88

99
import { ATTR_PRESENT } from "../BlockSyntax";
10-
import { OptionsReader } from "../OptionsReader";
10+
import { ReadonlyOptions } from "../options";
1111
import { OutputMode } from "../OutputMode";
1212

1313
import { Attribute } from "./Attribute";
@@ -78,7 +78,7 @@ export class AttrValue extends Style<AttrValue, Block, Attribute, never> {
7878
return this.parent.asSource(this.value);
7979
}
8080

81-
public cssClass(opts: OptionsReader): string {
81+
public cssClass(opts: ReadonlyOptions): string {
8282
switch (opts.outputMode) {
8383
case OutputMode.BEM:
8484
return `${this.parent.cssClass(opts)}${ this.isPresenceRule ? "" : `-${this.value}`}`;

packages/css-blocks/src/Block/Attribute.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { assertNever, ObjectDictionary } from "@opticss/util";
1010

1111
import { ATTR_PRESENT, IAttrToken as AttrToken } from "../BlockSyntax";
12-
import { OptionsReader } from "../OptionsReader";
12+
import { ReadonlyOptions } from "../options";
1313
import { OutputMode } from "../OutputMode";
1414

1515
import { AttrValue } from "./AttrValue";
@@ -177,7 +177,7 @@ export class Attribute extends Inheritable<Attribute, Block, BlockClass, AttrVal
177177
* @param opts Option hash configuring output mode.
178178
* @returns String representing output class.
179179
*/
180-
cssClass(opts: OptionsReader) {
180+
cssClass(opts: ReadonlyOptions) {
181181
switch (opts.outputMode) {
182182
case OutputMode.BEM:
183183
let cssClassName = this.blockClass.cssClass(opts);

packages/css-blocks/src/Block/Block.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from "../BlockParser";
1717
import { isRootNode, toAttrToken } from "../BlockParser";
1818
import { BlockPath, CLASS_NAME_IDENT, ROOT_CLASS } from "../BlockSyntax";
19-
import { OptionsReader } from "../OptionsReader";
19+
import { ReadonlyOptions } from "../options";
2020
import { SourceLocation } from "../SourceLocation";
2121
import { CssBlockError, InvalidBlockSyntax } from "../errors";
2222
import { FileIdentifier } from "../importing";
@@ -367,7 +367,7 @@ export class Block
367367
return null;
368368
}
369369

370-
rewriteSelectorNodes(nodes: selectorParser.Node[], opts: OptionsReader): selectorParser.Node[] {
370+
rewriteSelectorNodes(nodes: selectorParser.Node[], opts: ReadonlyOptions): selectorParser.Node[] {
371371
let newNodes: selectorParser.Node[] = [];
372372
for (let i = 0; i < nodes.length; i++) {
373373
let node = nodes[i];
@@ -382,7 +382,7 @@ export class Block
382382
return newNodes;
383383
}
384384

385-
rewriteSelectorToString(selector: ParsedSelector, opts: OptionsReader): string {
385+
rewriteSelectorToString(selector: ParsedSelector, opts: ReadonlyOptions): string {
386386
let firstNewSelector = new CompoundSelector();
387387
let newSelector = firstNewSelector;
388388
let newCurrentSelector = newSelector;
@@ -402,14 +402,14 @@ export class Block
402402
return firstNewSelector.toString();
403403
}
404404

405-
rewriteSelector(selector: ParsedSelector, opts: OptionsReader): ParsedSelector {
405+
rewriteSelector(selector: ParsedSelector, opts: ReadonlyOptions): ParsedSelector {
406406
// generating a string and re-parsing ensures the internal structure is consistent
407407
// otherwise the parent/next/prev relationships will be wonky with the new nodes.
408408
let s = this.rewriteSelectorToString(selector, opts);
409409
return parseSelector(s)[0];
410410
}
411411

412-
debug(opts: OptionsReader): string[] {
412+
debug(opts: ReadonlyOptions): string[] {
413413
let result: string[] = [`Source: ${this.identifier}`, this.rootClass.asDebug(opts)];
414414
let sourceNames = new Set<string>(this.all().map(s => s.asSource()));
415415
let sortedNames = [...sourceNames].sort();

packages/css-blocks/src/Block/BlockClass.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { isString } from "util";
33

44
import { ATTR_PRESENT, IAttrToken as AttrToken, ROOT_CLASS } from "../BlockSyntax";
55
import { BlockPath } from "../BlockSyntax";
6-
import { OptionsReader } from "../OptionsReader";
6+
import { ReadonlyOptions } from "../options";
77
import { OutputMode } from "../OutputMode";
88

99
import { AttrValue } from "./AttrValue";
@@ -184,7 +184,7 @@ export class BlockClass extends Style<BlockClass, Block, Block, Attribute> {
184184
* @param opts Option hash configuring output mode.
185185
* @returns String representing output class.
186186
*/
187-
public cssClass(opts: OptionsReader): string {
187+
public cssClass(opts: ReadonlyOptions): string {
188188
switch (opts.outputMode) {
189189
case OutputMode.BEM:
190190
if (this.isRoot) {
@@ -219,7 +219,7 @@ export class BlockClass extends Style<BlockClass, Block, Block, Attribute> {
219219
* @param options Options to pass to BlockClass' asDebug method.
220220
* @return Array of debug strings for this BlockClass
221221
*/
222-
debug(opts: OptionsReader): string[] {
222+
debug(opts: ReadonlyOptions): string[] {
223223
let result: string[] = [];
224224
for (let style of this.all()) {
225225
result.push(style.asDebug(opts));

packages/css-blocks/src/Block/Style.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Attr } from "@opticss/element-analysis";
22

3-
import { OptionsReader } from "../OptionsReader";
3+
import { ReadonlyOptions } from "../options";
44
import { unionInto } from "../util/unionInto";
55

66
import { AnyNode, Inheritable } from "./Inheritable";
@@ -41,7 +41,7 @@ export abstract class Style<
4141
* @param opts Option hash configuring output mode.
4242
* @returns The CSS class.
4343
*/
44-
public abstract cssClass(opts: OptionsReader): string;
44+
public abstract cssClass(opts: ReadonlyOptions): string;
4545

4646
/**
4747
* Return the source selector this `Style` was read from.
@@ -59,7 +59,7 @@ export abstract class Style<
5959
* including inherited classes.
6060
* @returns this object's css class and all inherited classes.
6161
*/
62-
cssClasses(opts: OptionsReader): string[] {
62+
cssClasses(opts: ReadonlyOptions): string[] {
6363
let classes: string[] = [];
6464
for (let style of this.resolveStyles()) {
6565
classes.push(style.cssClass(opts));
@@ -110,7 +110,7 @@ export abstract class Style<
110110
* @param opts Options for rendering cssClass.
111111
* @returns A debug string.
112112
*/
113-
asDebug(opts: OptionsReader) {
113+
asDebug(opts: ReadonlyOptions) {
114114
return `${this.asSource()} => ${this.cssClasses(opts).map(n => `.${n}`).join(" ")}`;
115115
}
116116

packages/css-blocks/src/BlockCompiler/ConflictResolver.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import selectorParser = require("postcss-selector-parser");
66
import { Block, Style } from "../Block";
77
import { getBlockNode } from "../BlockParser";
88
import { RESOLVE_RE } from "../BlockSyntax";
9-
import { OptionsReader } from "../OptionsReader";
9+
import { ReadonlyOptions } from "../options";
1010
import { SourceLocation, sourceLocation } from "../SourceLocation";
1111
import * as errors from "../errors";
1212
import { QueryKeySelector } from "../query";
@@ -61,9 +61,9 @@ function updateConflict(t1: ConflictType, t2: ConflictType): ConflictType {
6161
* resolves property values accordingly.
6262
*/
6363
export class ConflictResolver {
64-
readonly opts: OptionsReader;
64+
readonly opts: ReadonlyOptions;
6565

66-
constructor(opts: OptionsReader) {
66+
constructor(opts: ReadonlyOptions) {
6767
this.opts = opts;
6868
}
6969

packages/css-blocks/src/BlockCompiler/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@ import {
88
parseBlockDebug,
99
ROOT_CLASS,
1010
} from "../BlockSyntax";
11-
import { OptionsReader } from "../OptionsReader";
11+
import { normalizeOptions } from "../normalizeOptions";
1212
import { StyleAnalysis } from "../TemplateAnalysis/StyleAnalysis";
13-
import { PluginOptions } from "../options";
13+
import { SparseOptions, ReadonlyOptions } from "../options";
1414

1515
import { ConflictResolver } from "./ConflictResolver";
1616
/**
1717
* Compiler that, given a Block will return a transformed AST
1818
* interface is `BlockParser.parse`.
1919
*/
2020
export class BlockCompiler {
21-
private opts: OptionsReader;
21+
private opts: ReadonlyOptions;
2222
private postcss: typeof postcss;
2323

24-
constructor(postcssImpl: typeof postcss, opts?: PluginOptions) {
25-
this.opts = new OptionsReader(opts);
24+
constructor(postcssImpl: typeof postcss, opts?: SparseOptions) {
25+
this.opts = normalizeOptions(opts);
2626
this.postcss = postcssImpl;
2727
}
2828

packages/css-blocks/src/BlockParser/BlockFactory.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { RawSourceMap } from "source-map";
66

77
import { Block } from "../Block";
88
import { FileIdentifier, ImportedFile, Importer } from "../importing";
9-
import { CssBlockOptionsReadonly } from "../options";
9+
import { ReadonlyOptions, SparseOptions } from "../options";
10+
import { normalizeOptions } from "../normalizeOptions";
1011
import { PromiseQueue } from "../util/PromiseQueue";
1112

1213
import { BlockParser, ParsedSource } from "./BlockParser";
@@ -35,7 +36,7 @@ interface ErrorWithErrNum {
3536
export class BlockFactory {
3637
postcssImpl: typeof postcss;
3738
importer: Importer;
38-
options: CssBlockOptionsReadonly;
39+
options: ReadonlyOptions;
3940
blockNames: ObjectDictionary<number>;
4041
parser: BlockParser;
4142
preprocessors: Preprocessors;
@@ -45,9 +46,9 @@ export class BlockFactory {
4546
private paths: ObjectDictionary<string>;
4647
private preprocessQueue: PromiseQueue<PreprocessJob, ProcessedFile>;
4748

48-
constructor(options: CssBlockOptionsReadonly, postcssImpl = postcss) {
49+
constructor(options: SparseOptions, postcssImpl = postcss) {
4950
this.postcssImpl = postcssImpl;
50-
this.options = options;
51+
this.options = normalizeOptions(options);
5152
this.importer = this.options.importer;
5253
this.preprocessors = this.options.preprocessors;
5354
this.parser = new BlockParser(options, this);
@@ -216,7 +217,7 @@ export class BlockFactory {
216217
if (firstPreprocessor) {
217218
if (syntax !== Syntax.css && this.preprocessors.css && !this.options.disablePreprocessChaining) {
218219
let cssProcessor = this.preprocessors.css;
219-
preprocessor = (fullPath: string, content: string, options: CssBlockOptionsReadonly): Promise<ProcessedFile> => {
220+
preprocessor = (fullPath: string, content: string, options: ReadonlyOptions): Promise<ProcessedFile> => {
220221
return firstPreprocessor!(fullPath, content, options).then(result => {
221222
let content = result.content.toString();
222223
return cssProcessor(fullPath, content, options, sourceMapFromProcessedFile(result)).then(result2 => {
@@ -234,7 +235,7 @@ export class BlockFactory {
234235
} else if (syntax !== Syntax.css) {
235236
throw new Error(`No preprocessor provided for ${syntaxName(syntax)}.`);
236237
} else {
237-
preprocessor = (_fullPath: string, content: string, _options: CssBlockOptionsReadonly): Promise<ProcessedFile> => {
238+
preprocessor = (_fullPath: string, content: string, _options: ReadonlyOptions): Promise<ProcessedFile> => {
238239
return Promise.resolve({
239240
content: content,
240241
});

packages/css-blocks/src/BlockParser/BlockParser.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as postcss from "postcss";
22

33
import { Block } from "../Block";
4-
import { OptionsReader } from "../OptionsReader";
4+
import { normalizeOptions } from "../normalizeOptions";
55
import * as errors from "../errors";
66
import { FileIdentifier } from "../importing";
7-
import { PluginOptions } from "../options";
7+
import { SparseOptions, ReadonlyOptions } from "../options";
88

99
import { assertForeignGlobalAttribute } from "./features/assert-foreign-global-attribute";
1010
import { constructBlock } from "./features/construct-block";
@@ -32,11 +32,11 @@ export interface ParsedSource {
3232
* interface is `BlockParser.parse`.
3333
*/
3434
export class BlockParser {
35-
private opts: OptionsReader;
35+
private opts: ReadonlyOptions;
3636
private factory: BlockFactory;
3737

38-
constructor(opts: PluginOptions, factory: BlockFactory) {
39-
this.opts = new OptionsReader(opts);
38+
constructor(opts: SparseOptions, factory: BlockFactory) {
39+
this.opts = normalizeOptions(opts);
4040
this.factory = factory;
4141
}
4242

packages/css-blocks/src/BlockParser/features/process-debug-statements.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import * as postcss from "postcss";
33

44
import { Block } from "../../Block";
55
import { BLOCK_DEBUG, parseBlockDebug } from "../../BlockSyntax";
6-
import { OptionsReader } from "../../OptionsReader";
6+
import { ReadonlyOptions } from "../../options";
77

88
/**
99
* Process all `@block-debug` statements, output debug statement to console or in comment as requested.
1010
* @param sourceFile File name of block in question.
1111
* @param root PostCSS Root for block.
1212
* @param block Block to resolve references for
1313
*/
14-
export async function processDebugStatements(root: postcss.Root, block: Block, file: string, opts: OptionsReader) {
14+
export async function processDebugStatements(root: postcss.Root, block: Block, file: string, opts: ReadonlyOptions) {
1515
root.walkAtRules(BLOCK_DEBUG, (atRule) => {
1616
let { block: ref, channel } = parseBlockDebug(atRule, file, block);
1717
let debugStr = ref.debug(opts);

packages/css-blocks/src/BlockParser/preprocessing.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
} from "source-map";
66

77
import {
8-
CssBlockOptionsReadonly,
8+
ReadonlyOptions,
99
} from "../options";
1010

1111
export enum Syntax {
@@ -41,7 +41,7 @@ export interface ProcessedFile {
4141
}
4242

4343
// export type ContentPreprocessor = (content: string) => Promise<ProcessedFile>;
44-
export type Preprocessor = (fullPath: string, content: string, options: CssBlockOptionsReadonly, sourceMap?: RawSourceMap | string) => Promise<ProcessedFile>;
44+
export type Preprocessor = (fullPath: string, content: string, options: ReadonlyOptions, sourceMap?: RawSourceMap | string) => Promise<ProcessedFile>;
4545

4646
/**
4747
* A map of supported syntaxes to the preprocessor function for that syntax.

packages/css-blocks/src/OptionsReader.ts

-38
This file was deleted.

packages/css-blocks/src/Plugin.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@ import * as postcss from "postcss";
22

33
import { BlockCompiler } from "./BlockCompiler";
44
import { BlockFactory } from "./BlockParser";
5-
import { OptionsReader } from "./OptionsReader";
5+
import { normalizeOptions } from "./normalizeOptions";
66
import * as errors from "./errors";
7-
import { PluginOptions } from "./options";
8-
export { PluginOptions } from "./options";
7+
import { SparseOptions, ReadonlyOptions } from "./options";
8+
export { SparseOptions } from "./options";
99

1010
/**
1111
* CSS Blocks PostCSS plugin.
1212
*/
1313
export class Plugin {
14-
private opts: OptionsReader;
14+
private opts: ReadonlyOptions;
1515
private postcss: typeof postcss;
1616

1717
/**
1818
* @param postcssImpl PostCSS instance to use
1919
* @param opts Optional plugin config options
2020
*/
21-
constructor(postcssImpl: typeof postcss, opts?: PluginOptions) {
22-
this.opts = new OptionsReader(opts);
21+
constructor(postcssImpl: typeof postcss, opts?: SparseOptions) {
22+
this.opts = normalizeOptions(opts);
2323
this.postcss = postcssImpl;
2424
}
2525

0 commit comments

Comments
 (0)